~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/log/log0recv.c

Imported InnoDB plugin with changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include "mtr0log.h"
23
23
#include "page0page.h"
24
24
#include "page0cur.h"
 
25
#include "page0zip.h"
25
26
#include "btr0btr.h"
26
27
#include "btr0cur.h"
27
28
#include "ibuf0ibuf.h"
34
35
#include "dict0boot.h"
35
36
#include "fil0fil.h"
36
37
#include "sync0sync.h"
 
38
#include "row0merge.h"
37
39
 
38
40
#ifdef UNIV_HOTBACKUP
39
41
/* This is set to FALSE if the backup was originally taken with the
40
42
ibbackup --include regexp option: then we do not want to create tables in
41
43
directories which were not included */
42
 
ibool   recv_replay_file_ops    = TRUE;
 
44
UNIV_INTERN ibool       recv_replay_file_ops    = TRUE;
43
45
#endif /* UNIV_HOTBACKUP */
44
46
 
45
47
/* Log records are stored in the hash table in chunks at most of this size;
49
51
/* Read-ahead area in applying log records to file pages */
50
52
#define RECV_READ_AHEAD_AREA    32
51
53
 
52
 
recv_sys_t*     recv_sys = NULL;
53
 
ibool           recv_recovery_on = FALSE;
54
 
ibool           recv_recovery_from_backup_on = FALSE;
55
 
 
56
 
ibool           recv_needed_recovery = FALSE;
57
 
 
58
 
ibool           recv_lsn_checks_on = FALSE;
 
54
UNIV_INTERN recv_sys_t* recv_sys = NULL;
 
55
UNIV_INTERN ibool       recv_recovery_on = FALSE;
 
56
UNIV_INTERN ibool       recv_recovery_from_backup_on = FALSE;
 
57
 
 
58
UNIV_INTERN ibool       recv_needed_recovery = FALSE;
 
59
 
 
60
UNIV_INTERN ibool       recv_lsn_checks_on = FALSE;
59
61
 
60
62
/* There are two conditions under which we scan the logs, the first
61
63
is normal startup and the second is when we do a recovery from an
65
67
we know that the server was not cleanly shutdown. We must then initialize
66
68
the crash recovery environment before attempting to store these entries in
67
69
the log hash table. */
68
 
ibool   recv_log_scan_is_startup_type = FALSE;
 
70
UNIV_INTERN ibool       recv_log_scan_is_startup_type = FALSE;
69
71
 
70
72
/* If the following is TRUE, the buffer pool file pages must be invalidated
71
73
after recovery and no ibuf operations are allowed; this becomes TRUE if
77
79
/* Recovery is running and no operations on the log files are allowed
78
80
yet: the variable name is misleading */
79
81
 
80
 
ibool   recv_no_ibuf_operations = FALSE;
 
82
UNIV_INTERN ibool       recv_no_ibuf_operations = FALSE;
81
83
 
82
84
/* The following counter is used to decide when to print info on
83
85
log scan */
84
 
ulint   recv_scan_print_counter = 0;
 
86
UNIV_INTERN ulint       recv_scan_print_counter = 0;
85
87
 
86
 
ibool   recv_is_from_backup     = FALSE;
 
88
UNIV_INTERN ibool       recv_is_from_backup     = FALSE;
87
89
#ifdef UNIV_HOTBACKUP
88
 
ibool   recv_is_making_a_backup = FALSE;
 
90
UNIV_INTERN ibool       recv_is_making_a_backup = FALSE;
89
91
#else
90
92
# define recv_is_making_a_backup FALSE
91
93
#endif /* UNIV_HOTBACKUP */
92
94
 
93
 
ulint   recv_previous_parsed_rec_type   = 999999;
94
 
ulint   recv_previous_parsed_rec_offset = 0;
95
 
ulint   recv_previous_parsed_rec_is_multi = 0;
 
95
UNIV_INTERN ulint       recv_previous_parsed_rec_type   = 999999;
 
96
UNIV_INTERN ulint       recv_previous_parsed_rec_offset = 0;
 
97
UNIV_INTERN ulint       recv_previous_parsed_rec_is_multi = 0;
96
98
 
97
 
ulint   recv_max_parsed_page_no         = 0;
 
99
UNIV_INTERN ulint       recv_max_parsed_page_no         = 0;
98
100
 
99
101
/* This many frames must be left free in the buffer pool when we scan
100
102
the log and store the scanned log records in the buffer pool: we will
101
103
use these free frames to read in pages when we start applying the
102
104
log records to the database. */
103
105
 
104
 
ulint   recv_n_pool_free_frames         = 256;
 
106
UNIV_INTERN ulint       recv_n_pool_free_frames         = 256;
105
107
 
106
108
/* The maximum lsn we see for a page during the recovery process. If this
107
109
is bigger than the lsn we are able to scan up to, that is an indication that
108
110
the recovery failed and the database may be corrupt. */
109
111
 
110
 
dulint  recv_max_page_lsn;
 
112
UNIV_INTERN ib_uint64_t recv_max_page_lsn;
111
113
 
112
114
/* prototypes */
113
115
 
121
123
 
122
124
/************************************************************
123
125
Creates the recovery system. */
124
 
 
 
126
UNIV_INTERN
125
127
void
126
128
recv_sys_create(void)
127
129
/*=================*/
141
143
 
142
144
/************************************************************
143
145
Inits the recovery system for a recovery operation. */
144
 
 
 
146
UNIV_INTERN
145
147
void
146
148
recv_sys_init(
147
149
/*==========*/
179
181
                                        OS_FILE_LOG_BLOCK_SIZE);
180
182
        recv_sys->found_corrupt_log = FALSE;
181
183
 
182
 
        recv_max_page_lsn = ut_dulint_zero;
 
184
        recv_max_page_lsn = 0;
183
185
 
184
186
        mutex_exit(&(recv_sys->mutex));
185
187
}
239
241
recv_truncate_group(
240
242
/*================*/
241
243
        log_group_t*    group,          /* in: log group */
242
 
        dulint          recovered_lsn,  /* in: recovery succeeded up to this
 
244
        ib_uint64_t     recovered_lsn,  /* in: recovery succeeded up to this
243
245
                                        lsn */
244
 
        dulint          limit_lsn,      /* in: this was the limit for
 
246
        ib_uint64_t     limit_lsn,      /* in: this was the limit for
245
247
                                        recovery */
246
 
        dulint          checkpoint_lsn, /* in: recovery was started from this
 
248
        ib_uint64_t     checkpoint_lsn, /* in: recovery was started from this
247
249
                                        checkpoint */
248
 
        dulint          archived_lsn)   /* in: the log has been archived up to
 
250
        ib_uint64_t     archived_lsn)   /* in: the log has been archived up to
249
251
                                        this lsn */
250
252
{
251
 
        dulint  start_lsn;
252
 
        dulint  end_lsn;
253
 
        dulint  finish_lsn1;
254
 
        dulint  finish_lsn2;
255
 
        dulint  finish_lsn;
256
 
        ulint   len;
257
 
        ulint   i;
 
253
        ib_uint64_t     start_lsn;
 
254
        ib_uint64_t     end_lsn;
 
255
        ib_uint64_t     finish_lsn1;
 
256
        ib_uint64_t     finish_lsn2;
 
257
        ib_uint64_t     finish_lsn;
 
258
        ulint           len;
 
259
        ulint           i;
258
260
 
259
 
        if (ut_dulint_cmp(archived_lsn, ut_dulint_max) == 0) {
 
261
        if (archived_lsn == IB_ULONGLONG_MAX) {
260
262
                /* Checkpoint was taken in the NOARCHIVELOG mode */
261
263
                archived_lsn = checkpoint_lsn;
262
264
        }
263
265
 
264
 
        finish_lsn1 = ut_dulint_add(ut_dulint_align_down(
265
 
                                            archived_lsn,
266
 
                                            OS_FILE_LOG_BLOCK_SIZE),
267
 
                                    log_group_get_capacity(group));
268
 
 
269
 
        finish_lsn2 = ut_dulint_add(ut_dulint_align_up(
270
 
                                            recovered_lsn,
271
 
                                            OS_FILE_LOG_BLOCK_SIZE),
272
 
                                    recv_sys->last_log_buf_size);
273
 
 
274
 
        if (ut_dulint_cmp(limit_lsn, ut_dulint_max) != 0) {
 
266
        finish_lsn1 = ut_uint64_align_down(archived_lsn,
 
267
                                           OS_FILE_LOG_BLOCK_SIZE)
 
268
                + log_group_get_capacity(group);
 
269
 
 
270
        finish_lsn2 = ut_uint64_align_up(recovered_lsn,
 
271
                                         OS_FILE_LOG_BLOCK_SIZE)
 
272
                + recv_sys->last_log_buf_size;
 
273
 
 
274
        if (limit_lsn != IB_ULONGLONG_MAX) {
275
275
                /* We do not know how far we should erase log records: erase
276
276
                as much as possible */
277
277
 
278
278
                finish_lsn = finish_lsn1;
279
279
        } else {
280
280
                /* It is enough to erase the length of the log buffer */
281
 
                finish_lsn = ut_dulint_get_min(finish_lsn1, finish_lsn2);
 
281
                finish_lsn = finish_lsn1 < finish_lsn2
 
282
                        ? finish_lsn1 : finish_lsn2;
282
283
        }
283
284
 
284
285
        ut_a(RECV_SCAN_SIZE <= log_sys->buf_size);
289
290
                *(log_sys->buf + i) = '\0';
290
291
        }
291
292
 
292
 
        start_lsn = ut_dulint_align_down(recovered_lsn,
 
293
        start_lsn = ut_uint64_align_down(recovered_lsn,
293
294
                                         OS_FILE_LOG_BLOCK_SIZE);
294
295
 
295
 
        if (ut_dulint_cmp(start_lsn, recovered_lsn) != 0) {
 
296
        if (start_lsn != recovered_lsn) {
296
297
                /* Copy the last incomplete log block to the log buffer and
297
298
                edit its data length: */
298
299
 
299
300
                ut_memcpy(log_sys->buf, recv_sys->last_block,
300
301
                          OS_FILE_LOG_BLOCK_SIZE);
301
 
                log_block_set_data_len(log_sys->buf, ut_dulint_minus(
302
 
                                               recovered_lsn, start_lsn));
 
302
                log_block_set_data_len(log_sys->buf,
 
303
                                       (ulint) (recovered_lsn - start_lsn));
303
304
        }
304
305
 
305
 
        if (ut_dulint_cmp(start_lsn, finish_lsn) >= 0) {
 
306
        if (start_lsn >= finish_lsn) {
306
307
 
307
308
                return;
308
309
        }
309
310
 
310
311
        for (;;) {
311
 
                end_lsn = ut_dulint_add(start_lsn, RECV_SCAN_SIZE);
 
312
                end_lsn = start_lsn + RECV_SCAN_SIZE;
312
313
 
313
 
                if (ut_dulint_cmp(end_lsn, finish_lsn) > 0) {
 
314
                if (end_lsn > finish_lsn) {
314
315
 
315
316
                        end_lsn = finish_lsn;
316
317
                }
317
318
 
318
 
                len = ut_dulint_minus(end_lsn, start_lsn);
 
319
                len = (ulint) (end_lsn - start_lsn);
319
320
 
320
321
                log_group_write_buf(group, log_sys->buf, len, start_lsn, 0);
321
 
                if (ut_dulint_cmp(end_lsn, finish_lsn) >= 0) {
 
322
                if (end_lsn >= finish_lsn) {
322
323
 
323
324
                        return;
324
325
                }
344
345
                                                group */
345
346
        log_group_t*    group,                  /* in: copy to this log
346
347
                                                group */
347
 
        dulint          recovered_lsn)          /* in: recovery succeeded up
 
348
        ib_uint64_t     recovered_lsn)          /* in: recovery succeeded up
348
349
                                                to this lsn */
349
350
{
350
 
        dulint  start_lsn;
351
 
        dulint  end_lsn;
352
 
        ulint   len;
 
351
        ib_uint64_t     start_lsn;
 
352
        ib_uint64_t     end_lsn;
 
353
        ulint           len;
353
354
 
354
 
        if (ut_dulint_cmp(group->scanned_lsn, recovered_lsn) >= 0) {
 
355
        if (group->scanned_lsn >= recovered_lsn) {
355
356
 
356
357
                return;
357
358
        }
358
359
 
359
360
        ut_a(RECV_SCAN_SIZE <= log_sys->buf_size);
360
361
 
361
 
        start_lsn = ut_dulint_align_down(group->scanned_lsn,
 
362
        start_lsn = ut_uint64_align_down(group->scanned_lsn,
362
363
                                         OS_FILE_LOG_BLOCK_SIZE);
363
364
        for (;;) {
364
 
                end_lsn = ut_dulint_add(start_lsn, RECV_SCAN_SIZE);
 
365
                end_lsn = start_lsn + RECV_SCAN_SIZE;
365
366
 
366
 
                if (ut_dulint_cmp(end_lsn, recovered_lsn) > 0) {
367
 
                        end_lsn = ut_dulint_align_up(recovered_lsn,
 
367
                if (end_lsn > recovered_lsn) {
 
368
                        end_lsn = ut_uint64_align_up(recovered_lsn,
368
369
                                                     OS_FILE_LOG_BLOCK_SIZE);
369
370
                }
370
371
 
371
372
                log_group_read_log_seg(LOG_RECOVER, log_sys->buf,
372
373
                                       up_to_date_group, start_lsn, end_lsn);
373
374
 
374
 
                len = ut_dulint_minus(end_lsn, start_lsn);
 
375
                len = (ulint) (end_lsn - start_lsn);
375
376
 
376
377
                log_group_write_buf(group, log_sys->buf, len, start_lsn, 0);
377
378
 
378
 
                if (ut_dulint_cmp(end_lsn, recovered_lsn) >= 0) {
 
379
                if (end_lsn >= recovered_lsn) {
379
380
 
380
381
                        return;
381
382
                }
397
398
                                                log group */
398
399
{
399
400
        log_group_t*    group;
400
 
        dulint          start_lsn;
401
 
        dulint          end_lsn;
402
 
        dulint          recovered_lsn;
403
 
        dulint          limit_lsn;
 
401
        ib_uint64_t     start_lsn;
 
402
        ib_uint64_t     end_lsn;
 
403
        ib_uint64_t     recovered_lsn;
 
404
        ib_uint64_t     limit_lsn;
404
405
 
405
406
        recovered_lsn = recv_sys->recovered_lsn;
406
407
        limit_lsn = recv_sys->limit_lsn;
408
409
        /* Read the last recovered log block to the recovery system buffer:
409
410
        the block is always incomplete */
410
411
 
411
 
        start_lsn = ut_dulint_align_down(recovered_lsn,
 
412
        start_lsn = ut_uint64_align_down(recovered_lsn,
412
413
                                         OS_FILE_LOG_BLOCK_SIZE);
413
 
        end_lsn = ut_dulint_align_up(recovered_lsn, OS_FILE_LOG_BLOCK_SIZE);
 
414
        end_lsn = ut_uint64_align_up(recovered_lsn, OS_FILE_LOG_BLOCK_SIZE);
414
415
 
415
 
        ut_a(ut_dulint_cmp(start_lsn, end_lsn) != 0);
 
416
        ut_a(start_lsn != end_lsn);
416
417
 
417
418
        log_group_read_log_seg(LOG_RECOVER, recv_sys->last_block,
418
419
                               up_to_date_group, start_lsn, end_lsn);
493
494
                                        LOG_CHECKPOINT_2 */
494
495
{
495
496
        log_group_t*    group;
496
 
        dulint          max_no;
497
 
        dulint          checkpoint_no;
 
497
        ib_uint64_t     max_no;
 
498
        ib_uint64_t     checkpoint_no;
498
499
        ulint           field;
499
500
        byte*           buf;
500
501
 
501
502
        group = UT_LIST_GET_FIRST(log_sys->log_groups);
502
503
 
503
 
        max_no = ut_dulint_zero;
 
504
        max_no = 0;
504
505
        *max_group = NULL;
505
506
        *max_field = 0;
506
507
 
533
534
 
534
535
                        group->state = LOG_GROUP_OK;
535
536
 
536
 
                        group->lsn = mach_read_from_8(
 
537
                        group->lsn = mach_read_ull(
537
538
                                buf + LOG_CHECKPOINT_LSN);
538
539
                        group->lsn_offset = mach_read_from_4(
539
540
                                buf + LOG_CHECKPOINT_OFFSET);
540
 
                        checkpoint_no = mach_read_from_8(
 
541
                        checkpoint_no = mach_read_ull(
541
542
                                buf + LOG_CHECKPOINT_NO);
542
543
 
543
544
#ifdef UNIV_DEBUG
545
546
                                fprintf(stderr,
546
547
                                        "InnoDB: Checkpoint number %lu"
547
548
                                        " found in group %lu\n",
548
 
                                        (ulong) ut_dulint_get_low(
549
 
                                                checkpoint_no),
 
549
                                        (ulong) checkpoint_no,
550
550
                                        (ulong) group->id);
551
551
                        }
552
552
#endif /* UNIV_DEBUG */
553
553
 
554
 
                        if (ut_dulint_cmp(checkpoint_no, max_no) >= 0) {
 
554
                        if (checkpoint_no >= max_no) {
555
555
                                *max_group = group;
556
556
                                *max_field = field;
557
557
                                max_no = checkpoint_no;
585
585
 
586
586
/***********************************************************************
587
587
Reads the checkpoint info needed in hot backup. */
588
 
 
 
588
UNIV_INTERN
589
589
ibool
590
590
recv_read_cp_info_for_backup(
591
591
/*=========================*/
592
 
                        /* out: TRUE if success */
593
 
        byte*   hdr,    /* in: buffer containing the log group header */
594
 
        dulint* lsn,    /* out: checkpoint lsn */
595
 
        ulint*  offset, /* out: checkpoint offset in the log group */
596
 
        ulint*  fsp_limit,/* out: fsp limit of space 0, 1000000000 if the
597
 
                        database is running with < version 3.23.50 of InnoDB */
598
 
        dulint* cp_no,  /* out: checkpoint number */
599
 
        dulint* first_header_lsn)
600
 
                        /* out: lsn of of the start of the first log file */
 
592
                                /* out: TRUE if success */
 
593
        byte*           hdr,    /* in: buffer containing the log group
 
594
                                header */
 
595
        ib_uint64_t*    lsn,    /* out: checkpoint lsn */
 
596
        ulint*          offset, /* out: checkpoint offset in the log group */
 
597
        ulint*          fsp_limit,/* out: fsp limit of space 0,
 
598
                                1000000000 if the database is running
 
599
                                with < version 3.23.50 of InnoDB */
 
600
        ib_uint64_t*    cp_no,  /* out: checkpoint number */
 
601
        ib_uint64_t*    first_header_lsn)
 
602
                                /* out: lsn of of the start of the
 
603
                                first log file */
601
604
{
602
 
        ulint   max_cp          = 0;
603
 
        dulint  max_cp_no       = ut_dulint_zero;
604
 
        byte*   cp_buf;
 
605
        ulint           max_cp          = 0;
 
606
        ib_uint64_t     max_cp_no       = 0;
 
607
        byte*           cp_buf;
605
608
 
606
609
        cp_buf = hdr + LOG_CHECKPOINT_1;
607
610
 
608
611
        if (recv_check_cp_is_consistent(cp_buf)) {
609
 
                max_cp_no = mach_read_from_8(cp_buf + LOG_CHECKPOINT_NO);
 
612
                max_cp_no = mach_read_ull(cp_buf + LOG_CHECKPOINT_NO);
610
613
                max_cp = LOG_CHECKPOINT_1;
611
614
        }
612
615
 
613
616
        cp_buf = hdr + LOG_CHECKPOINT_2;
614
617
 
615
618
        if (recv_check_cp_is_consistent(cp_buf)) {
616
 
                if (ut_dulint_cmp(mach_read_from_8(cp_buf + LOG_CHECKPOINT_NO),
617
 
                                  max_cp_no) > 0) {
 
619
                if (mach_read_ull(cp_buf + LOG_CHECKPOINT_NO) > max_cp_no) {
618
620
                        max_cp = LOG_CHECKPOINT_2;
619
621
                }
620
622
        }
625
627
 
626
628
        cp_buf = hdr + max_cp;
627
629
 
628
 
        *lsn = mach_read_from_8(cp_buf + LOG_CHECKPOINT_LSN);
 
630
        *lsn = mach_read_ull(cp_buf + LOG_CHECKPOINT_LSN);
629
631
        *offset = mach_read_from_4(cp_buf + LOG_CHECKPOINT_OFFSET);
630
632
 
631
633
        /* If the user is running a pre-3.23.50 version of InnoDB, its
645
647
 
646
648
        /*      fprintf(stderr, "fsp limit %lu MB\n", *fsp_limit); */
647
649
 
648
 
        *cp_no = mach_read_from_8(cp_buf + LOG_CHECKPOINT_NO);
 
650
        *cp_no = mach_read_ull(cp_buf + LOG_CHECKPOINT_NO);
649
651
 
650
 
        *first_header_lsn = mach_read_from_8(hdr + LOG_FILE_START_LSN);
 
652
        *first_header_lsn = mach_read_ull(hdr + LOG_FILE_START_LSN);
651
653
 
652
654
        return(TRUE);
653
655
}
691
693
/***********************************************************************
692
694
Scans the log segment and n_bytes_scanned is set to the length of valid
693
695
log scanned. */
694
 
 
 
696
UNIV_INTERN
695
697
void
696
698
recv_scan_log_seg_for_backup(
697
699
/*=========================*/
698
700
        byte*           buf,            /* in: buffer containing log data */
699
701
        ulint           buf_len,        /* in: data length in that buffer */
700
 
        dulint*         scanned_lsn,    /* in/out: lsn of buffer start,
 
702
        ib_uint64_t*    scanned_lsn,    /* in/out: lsn of buffer start,
701
703
                                        we return scanned lsn */
702
704
        ulint*          scanned_checkpoint_no,
703
705
                                        /* in/out: 4 lowest bytes of the
762
764
 
763
765
                *scanned_checkpoint_no
764
766
                        = log_block_get_checkpoint_no(log_block);
765
 
                *scanned_lsn = ut_dulint_add(*scanned_lsn, data_len);
 
767
                *scanned_lsn += data_len;
766
768
 
767
769
                *n_bytes_scanned += data_len;
768
770
 
785
787
byte*
786
788
recv_parse_or_apply_log_rec_body(
787
789
/*=============================*/
788
 
                        /* out: log record end, NULL if not a complete
789
 
                        record */
790
 
        byte    type,   /* in: type */
791
 
        byte*   ptr,    /* in: pointer to a buffer */
792
 
        byte*   end_ptr,/* in: pointer to the buffer end */
793
 
        page_t* page,   /* in: buffer page or NULL; if not NULL, then the log
794
 
                        record is applied to the page, and the log record
795
 
                        should be complete then */
796
 
        mtr_t*  mtr)    /* in: mtr or NULL; should be non-NULL if and only if
797
 
                        page is non-NULL */
 
790
                                /* out: log record end, NULL if not a
 
791
                                complete record */
 
792
        byte            type,   /* in: type */
 
793
        byte*           ptr,    /* in: pointer to a buffer */
 
794
        byte*           end_ptr,/* in: pointer to the buffer end */
 
795
        buf_block_t*    block,  /* in/out: buffer block or NULL; if
 
796
                                not NULL, then the log record is
 
797
                                applied to the page, and the log
 
798
                                record should be complete then */
 
799
        mtr_t*          mtr)    /* in: mtr or NULL; should be non-NULL
 
800
                                if and only if block is non-NULL */
798
801
{
799
 
        dict_index_t*   index = NULL;
 
802
        dict_index_t*   index   = NULL;
 
803
        page_t*         page;
 
804
        page_zip_des_t* page_zip;
 
805
 
 
806
        ut_ad(!block == !mtr);
 
807
 
 
808
        if (block) {
 
809
                page = block->frame;
 
810
                page_zip = buf_block_get_page_zip(block);
 
811
        } else {
 
812
                page = NULL;
 
813
                page_zip = NULL;
 
814
        }
800
815
 
801
816
        switch (type) {
802
817
        case MLOG_1BYTE: case MLOG_2BYTES: case MLOG_4BYTES: case MLOG_8BYTES:
803
 
                ptr = mlog_parse_nbytes(type, ptr, end_ptr, page);
 
818
                ptr = mlog_parse_nbytes(type, ptr, end_ptr, page, page_zip);
804
819
                break;
805
820
        case MLOG_REC_INSERT: case MLOG_COMP_REC_INSERT:
806
821
                if (NULL != (ptr = mlog_parse_index(
811
826
                             || (ibool)!!page_is_comp(page)
812
827
                             == dict_table_is_comp(index->table));
813
828
                        ptr = page_cur_parse_insert_rec(FALSE, ptr, end_ptr,
814
 
                                                        index, page, mtr);
 
829
                                                        block, index, mtr);
815
830
                }
816
831
                break;
817
832
        case MLOG_REC_CLUST_DELETE_MARK: case MLOG_COMP_REC_CLUST_DELETE_MARK:
823
838
                             || (ibool)!!page_is_comp(page)
824
839
                             == dict_table_is_comp(index->table));
825
840
                        ptr = btr_cur_parse_del_mark_set_clust_rec(
826
 
                                ptr, end_ptr, index, page);
 
841
                                ptr, end_ptr, page, page_zip, index);
827
842
                }
828
843
                break;
829
844
        case MLOG_COMP_REC_SEC_DELETE_MARK:
830
845
                /* This log record type is obsolete, but we process it for
831
846
                backward compatibility with MySQL 5.0.3 and 5.0.4. */
832
847
                ut_a(!page || page_is_comp(page));
 
848
                ut_a(!page_zip);
833
849
                ptr = mlog_parse_index(ptr, end_ptr, TRUE, &index);
834
850
                if (!ptr) {
835
851
                        break;
836
852
                }
837
853
                /* Fall through */
838
854
        case MLOG_REC_SEC_DELETE_MARK:
839
 
                ptr = btr_cur_parse_del_mark_set_sec_rec(ptr, end_ptr, page);
 
855
                ptr = btr_cur_parse_del_mark_set_sec_rec(ptr, end_ptr,
 
856
                                                         page, page_zip);
840
857
                break;
841
858
        case MLOG_REC_UPDATE_IN_PLACE: case MLOG_COMP_REC_UPDATE_IN_PLACE:
842
859
                if (NULL != (ptr = mlog_parse_index(
846
863
                        ut_a(!page
847
864
                             || (ibool)!!page_is_comp(page)
848
865
                             == dict_table_is_comp(index->table));
849
 
                        ptr = btr_cur_parse_update_in_place(ptr, end_ptr,
850
 
                                                            page, index);
 
866
                        ptr = btr_cur_parse_update_in_place(ptr, end_ptr, page,
 
867
                                                            page_zip, index);
851
868
                }
852
869
                break;
853
870
        case MLOG_LIST_END_DELETE: case MLOG_COMP_LIST_END_DELETE:
861
878
                             || (ibool)!!page_is_comp(page)
862
879
                             == dict_table_is_comp(index->table));
863
880
                        ptr = page_parse_delete_rec_list(type, ptr, end_ptr,
864
 
                                                         index, page, mtr);
 
881
                                                         block, index, mtr);
865
882
                }
866
883
                break;
867
884
        case MLOG_LIST_END_COPY_CREATED: case MLOG_COMP_LIST_END_COPY_CREATED:
873
890
                             || (ibool)!!page_is_comp(page)
874
891
                             == dict_table_is_comp(index->table));
875
892
                        ptr = page_parse_copy_rec_list_to_created_page(
876
 
                                ptr, end_ptr, index, page, mtr);
 
893
                                ptr, end_ptr, block, index, mtr);
877
894
                }
878
895
                break;
879
896
        case MLOG_PAGE_REORGANIZE: case MLOG_COMP_PAGE_REORGANIZE:
885
902
                             || (ibool)!!page_is_comp(page)
886
903
                             == dict_table_is_comp(index->table));
887
904
                        ptr = btr_parse_page_reorganize(ptr, end_ptr, index,
888
 
                                                        page, mtr);
 
905
                                                        block, mtr);
889
906
                }
890
907
                break;
891
908
        case MLOG_PAGE_CREATE: case MLOG_COMP_PAGE_CREATE:
 
909
                ut_a(!page_zip);
892
910
                ptr = page_parse_create(ptr, end_ptr,
893
911
                                        type == MLOG_COMP_PAGE_CREATE,
894
 
                                        page, mtr);
 
912
                                        block, mtr);
895
913
                break;
896
914
        case MLOG_UNDO_INSERT:
897
915
                ptr = trx_undo_parse_add_undo_rec(ptr, end_ptr, page);
911
929
                                                 page, mtr);
912
930
                break;
913
931
        case MLOG_REC_MIN_MARK: case MLOG_COMP_REC_MIN_MARK:
 
932
                /* On a compressed page, MLOG_COMP_REC_MIN_MARK
 
933
                will be followed by MLOG_COMP_REC_DELETE
 
934
                or MLOG_ZIP_WRITE_HEADER(FIL_PAGE_PREV, FIL_NULL)
 
935
                in the same mini-transaction. */
 
936
                ut_a(type == MLOG_COMP_REC_MIN_MARK || !page_zip);
914
937
                ptr = btr_parse_set_min_rec_mark(
915
938
                        ptr, end_ptr, type == MLOG_COMP_REC_MIN_MARK,
916
939
                        page, mtr);
924
947
                             || (ibool)!!page_is_comp(page)
925
948
                             == dict_table_is_comp(index->table));
926
949
                        ptr = page_cur_parse_delete_rec(ptr, end_ptr,
927
 
                                                        index, page, mtr);
 
950
                                                        block, index, mtr);
928
951
                }
929
952
                break;
930
953
        case MLOG_IBUF_BITMAP_INIT:
931
 
                ptr = ibuf_parse_bitmap_init(ptr, end_ptr, page, mtr);
 
954
                ptr = ibuf_parse_bitmap_init(ptr, end_ptr, block, mtr);
932
955
                break;
933
956
        case MLOG_INIT_FILE_PAGE:
934
 
                ptr = fsp_parse_init_file_page(ptr, end_ptr, page);
 
957
                ptr = fsp_parse_init_file_page(ptr, end_ptr, block);
935
958
                break;
936
959
        case MLOG_WRITE_STRING:
937
 
                ptr = mlog_parse_string(ptr, end_ptr, page);
 
960
                ptr = mlog_parse_string(ptr, end_ptr, page, page_zip);
938
961
                break;
939
962
        case MLOG_FILE_CREATE:
940
963
        case MLOG_FILE_RENAME:
941
964
        case MLOG_FILE_DELETE:
942
 
                ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, FALSE,
943
 
                                                 ULINT_UNDEFINED);
 
965
        case MLOG_FILE_CREATE2:
 
966
                ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0);
 
967
                break;
 
968
        case MLOG_ZIP_WRITE_NODE_PTR:
 
969
                ptr = page_zip_parse_write_node_ptr(ptr, end_ptr,
 
970
                                                    page, page_zip);
 
971
                break;
 
972
        case MLOG_ZIP_WRITE_BLOB_PTR:
 
973
                ptr = page_zip_parse_write_blob_ptr(ptr, end_ptr,
 
974
                                                    page, page_zip);
 
975
                break;
 
976
        case MLOG_ZIP_WRITE_HEADER:
 
977
                ptr = page_zip_parse_write_header(ptr, end_ptr,
 
978
                                                  page, page_zip);
 
979
                break;
 
980
        case MLOG_ZIP_PAGE_COMPRESS:
 
981
                ptr = page_zip_parse_compress(ptr, end_ptr,
 
982
                                              page, page_zip);
944
983
                break;
945
984
        default:
946
985
                ptr = NULL;
1019
1058
void
1020
1059
recv_add_to_hash_table(
1021
1060
/*===================*/
1022
 
        byte    type,           /* in: log record type */
1023
 
        ulint   space,          /* in: space id */
1024
 
        ulint   page_no,        /* in: page number */
1025
 
        byte*   body,           /* in: log record body */
1026
 
        byte*   rec_end,        /* in: log record end */
1027
 
        dulint  start_lsn,      /* in: start lsn of the mtr */
1028
 
        dulint  end_lsn)        /* in: end lsn of the mtr */
 
1061
        byte            type,           /* in: log record type */
 
1062
        ulint           space,          /* in: space id */
 
1063
        ulint           page_no,        /* in: page number */
 
1064
        byte*           body,           /* in: log record body */
 
1065
        byte*           rec_end,        /* in: log record end */
 
1066
        ib_uint64_t     start_lsn,      /* in: start lsn of the mtr */
 
1067
        ib_uint64_t     end_lsn)        /* in: end lsn of the mtr */
1029
1068
{
1030
1069
        recv_t*         recv;
1031
1070
        ulint           len;
1134
1173
Applies the hashed log records to the page, if the page lsn is less than the
1135
1174
lsn of a log record. This can be called when a buffer page has just been
1136
1175
read in, or also for a page already in the buffer pool. */
1137
 
 
 
1176
UNIV_INTERN
1138
1177
void
1139
1178
recv_recover_page(
1140
1179
/*==============*/
1141
 
        ibool   recover_backup, /* in: TRUE if we are recovering a backup
 
1180
        ibool           recover_backup,
 
1181
                                /* in: TRUE if we are recovering a backup
1142
1182
                                page: then we do not acquire any latches
1143
1183
                                since the page was read in outside the
1144
1184
                                buffer pool */
1145
 
        ibool   just_read_in,   /* in: TRUE if the i/o-handler calls this for
 
1185
        ibool           just_read_in,
 
1186
                                /* in: TRUE if the i/o-handler calls this for
1146
1187
                                a freshly read page */
1147
 
        page_t* page,           /* in: buffer page */
1148
 
        ulint   space,          /* in: space id */
1149
 
        ulint   page_no)        /* in: page number */
 
1188
        buf_block_t*    block)  /* in: buffer block */
1150
1189
{
1151
 
        buf_block_t*    block           = NULL;
 
1190
        page_t*         page;
1152
1191
        recv_addr_t*    recv_addr;
1153
1192
        recv_t*         recv;
1154
1193
        byte*           buf;
1155
 
        dulint          start_lsn;
1156
 
        dulint          end_lsn;
1157
 
        dulint          page_lsn;
1158
 
        dulint          page_newest_lsn;
 
1194
        ib_uint64_t     start_lsn;
 
1195
        ib_uint64_t     end_lsn;
 
1196
        ib_uint64_t     page_lsn;
 
1197
        ib_uint64_t     page_newest_lsn;
1159
1198
        ibool           modification_to_page;
1160
1199
        ibool           success;
1161
1200
        mtr_t           mtr;
1171
1210
                return;
1172
1211
        }
1173
1212
 
1174
 
        recv_addr = recv_get_fil_addr_struct(space, page_no);
 
1213
        recv_addr = recv_get_fil_addr_struct(buf_block_get_space(block),
 
1214
                                             buf_block_get_page_no(block));
1175
1215
 
1176
1216
        if ((recv_addr == NULL)
1177
1217
            || (recv_addr->state == RECV_BEING_PROCESSED)
1183
1223
        }
1184
1224
 
1185
1225
#if 0
1186
 
        fprintf(stderr, "Recovering space %lu, page %lu\n", space, page_no);
 
1226
        fprintf(stderr, "Recovering space %lu, page %lu\n",
 
1227
                buf_block_get_space(block), buf_block_get_page_no(block));
1187
1228
#endif
1188
1229
 
1189
1230
        recv_addr->state = RECV_BEING_PROCESSED;
1193
1234
        mtr_start(&mtr);
1194
1235
        mtr_set_log_mode(&mtr, MTR_LOG_NONE);
1195
1236
 
 
1237
        page = block->frame;
 
1238
 
1196
1239
        if (!recover_backup) {
1197
 
                block = buf_block_align(page);
1198
 
 
1199
1240
                if (just_read_in) {
1200
1241
                        /* Move the ownership of the x-latch on the
1201
1242
                        page to this OS thread, so that we can acquire
1206
1247
                        rw_lock_x_lock_move_ownership(&(block->lock));
1207
1248
                }
1208
1249
 
1209
 
                success = buf_page_get_known_nowait(RW_X_LATCH, page,
 
1250
                success = buf_page_get_known_nowait(RW_X_LATCH, block,
1210
1251
                                                    BUF_KEEP_OLD,
1211
1252
                                                    __FILE__, __LINE__,
1212
1253
                                                    &mtr);
1213
1254
                ut_a(success);
1214
1255
 
1215
1256
#ifdef UNIV_SYNC_DEBUG
1216
 
                buf_page_dbg_add_level(page, SYNC_NO_ORDER_CHECK);
 
1257
                buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
1217
1258
#endif /* UNIV_SYNC_DEBUG */
1218
1259
        }
1219
1260
 
1220
1261
        /* Read the newest modification lsn from the page */
1221
 
        page_lsn = mach_read_from_8(page + FIL_PAGE_LSN);
 
1262
        page_lsn = mach_read_ull(page + FIL_PAGE_LSN);
1222
1263
 
1223
1264
        if (!recover_backup) {
1224
1265
                /* It may be that the page has been modified in the buffer
1225
1266
                pool: read the newest modification lsn there */
1226
1267
 
1227
 
                page_newest_lsn = buf_frame_get_newest_modification(page);
 
1268
                page_newest_lsn
 
1269
                        = buf_page_get_newest_modification(&block->page);
1228
1270
 
1229
 
                if (!ut_dulint_is_zero(page_newest_lsn)) {
 
1271
                if (page_newest_lsn) {
1230
1272
 
1231
1273
                        page_lsn = page_newest_lsn;
1232
1274
                }
1234
1276
                /* In recovery from a backup we do not really use the buffer
1235
1277
                pool */
1236
1278
 
1237
 
                page_newest_lsn = ut_dulint_zero;
 
1279
                page_newest_lsn = 0;
1238
1280
        }
1239
1281
 
1240
1282
        modification_to_page = FALSE;
1241
 
        start_lsn = end_lsn = ut_dulint_zero;
 
1283
        start_lsn = end_lsn = 0;
1242
1284
 
1243
1285
        recv = UT_LIST_GET_FIRST(recv_addr->rec_list);
1244
1286
 
1259
1301
                if (recv->type == MLOG_INIT_FILE_PAGE) {
1260
1302
                        page_lsn = page_newest_lsn;
1261
1303
 
1262
 
                        mach_write_to_8(page + UNIV_PAGE_SIZE
1263
 
                                        - FIL_PAGE_END_LSN_OLD_CHKSUM,
1264
 
                                        ut_dulint_zero);
1265
 
                        mach_write_to_8(page + FIL_PAGE_LSN, ut_dulint_zero);
 
1304
                        mach_write_ull(page + UNIV_PAGE_SIZE
 
1305
                                       - FIL_PAGE_END_LSN_OLD_CHKSUM, 0);
 
1306
                        mach_write_ull(page + FIL_PAGE_LSN, 0);
1266
1307
                }
1267
1308
 
1268
 
                if (ut_dulint_cmp(recv->start_lsn, page_lsn) >= 0) {
 
1309
                if (recv->start_lsn >= page_lsn) {
1269
1310
 
1270
1311
                        if (!modification_to_page) {
1271
1312
 
1287
1328
 
1288
1329
                        recv_parse_or_apply_log_rec_body(recv->type, buf,
1289
1330
                                                         buf + recv->len,
1290
 
                                                         page, &mtr);
1291
 
                        mach_write_to_8(page + UNIV_PAGE_SIZE
1292
 
                                        - FIL_PAGE_END_LSN_OLD_CHKSUM,
1293
 
                                        ut_dulint_add(recv->start_lsn,
1294
 
                                                      recv->len));
1295
 
                        mach_write_to_8(page + FIL_PAGE_LSN,
1296
 
                                        ut_dulint_add(recv->start_lsn,
1297
 
                                                      recv->len));
 
1331
                                                         block, &mtr);
 
1332
                        mach_write_ull(page + UNIV_PAGE_SIZE
 
1333
                                       - FIL_PAGE_END_LSN_OLD_CHKSUM,
 
1334
                                       recv->start_lsn + recv->len);
 
1335
                        mach_write_ull(page + FIL_PAGE_LSN,
 
1336
                                       recv->start_lsn + recv->len);
1298
1337
                }
1299
1338
 
1300
1339
                if (recv->len > RECV_DATA_BLOCK_SIZE) {
1306
1345
 
1307
1346
        mutex_enter(&(recv_sys->mutex));
1308
1347
 
1309
 
        if (ut_dulint_cmp(recv_max_page_lsn, page_lsn) < 0) {
 
1348
        if (recv_max_page_lsn < page_lsn) {
1310
1349
                recv_max_page_lsn = page_lsn;
1311
1350
        }
1312
1351
 
1340
1379
/*==============*/
1341
1380
                        /* out: number of pages found */
1342
1381
        ulint   space,  /* in: space */
 
1382
        ulint   zip_size,/* in: compressed page size in bytes, or 0 */
1343
1383
        ulint   page_no)/* in: page number */
1344
1384
{
1345
1385
        recv_addr_t* recv_addr;
1371
1411
                }
1372
1412
        }
1373
1413
 
1374
 
        buf_read_recv_pages(FALSE, space, page_nos, n);
 
1414
        buf_read_recv_pages(FALSE, space, zip_size, page_nos, n);
1375
1415
        /*
1376
1416
        fprintf(stderr, "Recv pages at %lu n %lu\n", page_nos[0], n);
1377
1417
        */
1381
1421
/***********************************************************************
1382
1422
Empties the hash table of stored log records, applying them to appropriate
1383
1423
pages. */
1384
 
 
 
1424
UNIV_INTERN
1385
1425
void
1386
1426
recv_apply_hashed_log_recs(
1387
1427
/*=======================*/
1396
1436
                                mutex */
1397
1437
{
1398
1438
        recv_addr_t* recv_addr;
1399
 
        page_t* page;
1400
1439
        ulint   i;
1401
 
        ulint   space;
1402
 
        ulint   page_no;
1403
1440
        ulint   n_pages;
1404
1441
        ibool   has_printed     = FALSE;
1405
1442
        mtr_t   mtr;
1429
1466
                recv_addr = HASH_GET_FIRST(recv_sys->addr_hash, i);
1430
1467
 
1431
1468
                while (recv_addr) {
1432
 
                        space = recv_addr->space;
1433
 
                        page_no = recv_addr->page_no;
 
1469
                        ulint   space = recv_addr->space;
 
1470
                        ulint   zip_size = fil_space_get_zip_size(space);
 
1471
                        ulint   page_no = recv_addr->page_no;
1434
1472
 
1435
1473
                        if (recv_addr->state == RECV_NOT_PROCESSED) {
1436
1474
                                if (!has_printed) {
1446
1484
                                mutex_exit(&(recv_sys->mutex));
1447
1485
 
1448
1486
                                if (buf_page_peek(space, page_no)) {
 
1487
                                        buf_block_t*    block;
1449
1488
 
1450
1489
                                        mtr_start(&mtr);
1451
1490
 
1452
 
                                        page = buf_page_get(space, page_no,
1453
 
                                                            RW_X_LATCH, &mtr);
1454
 
 
 
1491
                                        block = buf_page_get(
 
1492
                                                space, zip_size, page_no,
 
1493
                                                RW_X_LATCH, &mtr);
1455
1494
#ifdef UNIV_SYNC_DEBUG
1456
 
                                        buf_page_dbg_add_level(
1457
 
                                                page, SYNC_NO_ORDER_CHECK);
 
1495
                                        buf_block_dbg_add_level(
 
1496
                                                block, SYNC_NO_ORDER_CHECK);
1458
1497
#endif /* UNIV_SYNC_DEBUG */
1459
 
                                        recv_recover_page(FALSE, FALSE, page,
1460
 
                                                          space, page_no);
 
1498
                                        recv_recover_page(FALSE, FALSE, block);
1461
1499
                                        mtr_commit(&mtr);
1462
1500
                                } else {
1463
 
                                        recv_read_in_area(space, page_no);
 
1501
                                        recv_read_in_area(space, zip_size,
 
1502
                                                          page_no);
1464
1503
                                }
1465
1504
 
1466
1505
                                mutex_enter(&(recv_sys->mutex));
1504
1543
                mutex_exit(&(log_sys->mutex));
1505
1544
 
1506
1545
                n_pages = buf_flush_batch(BUF_FLUSH_LIST, ULINT_MAX,
1507
 
                                          ut_dulint_max);
 
1546
                                          IB_ULONGLONG_MAX);
1508
1547
                ut_a(n_pages != ULINT_UNDEFINED);
1509
1548
 
1510
1549
                buf_flush_wait_batch_end(BUF_FLUSH_LIST);
1529
1568
        mutex_exit(&(recv_sys->mutex));
1530
1569
}
1531
1570
 
 
1571
#ifdef UNIV_HOTBACKUP
 
1572
/***********************************************************************
 
1573
Applies log records in the hash table to a backup. */
 
1574
UNIV_INTERN
 
1575
void
 
1576
recv_apply_log_recs_for_backup(void)
 
1577
/*================================*/
 
1578
{
 
1579
        recv_addr_t*    recv_addr;
 
1580
        ulint           n_hash_cells;
 
1581
        buf_block_t*    block;
 
1582
        ulint           actual_size;
 
1583
        ibool           success;
 
1584
        ulint           error;
 
1585
        ulint           i;
 
1586
 
 
1587
        recv_sys->apply_log_recs = TRUE;
 
1588
        recv_sys->apply_batch_on = TRUE;
 
1589
 
 
1590
        block = buf_LRU_get_free_block(UNIV_PAGE_SIZE);
 
1591
 
 
1592
        fputs("InnoDB: Starting an apply batch of log records"
 
1593
              " to the database...\n"
 
1594
              "InnoDB: Progress in percents: ", stderr);
 
1595
 
 
1596
        n_hash_cells = hash_get_n_cells(recv_sys->addr_hash);
 
1597
 
 
1598
        for (i = 0; i < n_hash_cells; i++) {
 
1599
                /* The address hash table is externally chained */
 
1600
                recv_addr = hash_get_nth_cell(recv_sys->addr_hash, i)->node;
 
1601
 
 
1602
                while (recv_addr != NULL) {
 
1603
 
 
1604
                        ulint   zip_size
 
1605
                                = fil_space_get_zip_size(recv_addr->space);
 
1606
 
 
1607
                        if (zip_size == ULINT_UNDEFINED) {
 
1608
#if 0
 
1609
                                fprintf(stderr,
 
1610
                                        "InnoDB: Warning: cannot apply"
 
1611
                                        " log record to"
 
1612
                                        " tablespace %lu page %lu,\n"
 
1613
                                        "InnoDB: because tablespace with"
 
1614
                                        " that id does not exist.\n",
 
1615
                                        recv_addr->space, recv_addr->page_no);
 
1616
#endif
 
1617
                                recv_addr->state = RECV_PROCESSED;
 
1618
 
 
1619
                                ut_a(recv_sys->n_addrs);
 
1620
                                recv_sys->n_addrs--;
 
1621
 
 
1622
                                goto skip_this_recv_addr;
 
1623
                        }
 
1624
 
 
1625
                        /* We simulate a page read made by the buffer pool, to
 
1626
                        make sure the recovery apparatus works ok. We must init
 
1627
                        the block. */
 
1628
 
 
1629
                        buf_page_init_for_backup_restore(
 
1630
                                recv_addr->space, recv_addr->page_no,
 
1631
                                zip_size, block);
 
1632
 
 
1633
                        /* Extend the tablespace's last file if the page_no
 
1634
                        does not fall inside its bounds; we assume the last
 
1635
                        file is auto-extending, and ibbackup copied the file
 
1636
                        when it still was smaller */
 
1637
 
 
1638
                        success = fil_extend_space_to_desired_size(
 
1639
                                &actual_size,
 
1640
                                recv_addr->space, recv_addr->page_no + 1);
 
1641
                        if (!success) {
 
1642
                                fprintf(stderr,
 
1643
                                        "InnoDB: Fatal error: cannot extend"
 
1644
                                        " tablespace %lu to hold %lu pages\n",
 
1645
                                        recv_addr->space, recv_addr->page_no);
 
1646
 
 
1647
                                exit(1);
 
1648
                        }
 
1649
 
 
1650
                        /* Read the page from the tablespace file using the
 
1651
                        fil0fil.c routines */
 
1652
 
 
1653
                        if (zip_size) {
 
1654
                                error = fil_io(OS_FILE_READ, TRUE,
 
1655
                                               recv_addr->space, zip_size,
 
1656
                                               recv_addr->page_no, 0, zip_size,
 
1657
                                               block->page.zip.data, NULL);
 
1658
                        } else {
 
1659
                                error = fil_io(OS_FILE_READ, TRUE,
 
1660
                                               recv_addr->space, 0,
 
1661
                                               recv_addr->page_no, 0,
 
1662
                                               UNIV_PAGE_SIZE,
 
1663
                                               block->frame, NULL);
 
1664
                        }
 
1665
 
 
1666
                        if (error != DB_SUCCESS) {
 
1667
                                fprintf(stderr,
 
1668
                                        "InnoDB: Fatal error: cannot read"
 
1669
                                        " from tablespace"
 
1670
                                        " %lu page number %lu\n",
 
1671
                                        (ulong) recv_addr->space,
 
1672
                                        (ulong) recv_addr->page_no);
 
1673
 
 
1674
                                exit(1);
 
1675
                        }
 
1676
 
 
1677
                        /* Apply the log records to this page */
 
1678
                        recv_recover_page(TRUE, FALSE, block);
 
1679
 
 
1680
                        /* Write the page back to the tablespace file using the
 
1681
                        fil0fil.c routines */
 
1682
 
 
1683
                        buf_flush_init_for_writing(
 
1684
                                block->frame, buf_block_get_page_zip(block),
 
1685
                                mach_read_ull(block->frame + FIL_PAGE_LSN));
 
1686
 
 
1687
                        if (zip_size) {
 
1688
                                error = fil_io(OS_FILE_WRITE, TRUE,
 
1689
                                               recv_addr->space, zip_size,
 
1690
                                               recv_addr->page_no, 0,
 
1691
                                               zip_size,
 
1692
                                               block->page.zip.data, NULL);
 
1693
                        } else {
 
1694
                                error = fil_io(OS_FILE_WRITE, TRUE,
 
1695
                                               recv_addr->space, 0,
 
1696
                                               recv_addr->page_no, 0,
 
1697
                                               UNIV_PAGE_SIZE,
 
1698
                                               block->frame, NULL);
 
1699
                        }
 
1700
skip_this_recv_addr:
 
1701
                        recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
 
1702
                }
 
1703
 
 
1704
                if ((100 * i) / n_hash_cells
 
1705
                    != (100 * (i + 1)) / n_hash_cells) {
 
1706
                        fprintf(stderr, "%lu ",
 
1707
                                (ulong) ((100 * i) / n_hash_cells));
 
1708
                        fflush(stderr);
 
1709
                }
 
1710
        }
 
1711
 
 
1712
        buf_block_free(block);
 
1713
        recv_sys_empty_hash();
 
1714
}
 
1715
#endif /* UNIV_HOTBACKUP */
1532
1716
 
1533
1717
/***********************************************************************
1534
1718
Tries to parse a single log record and returns its length. */
1604
1788
/***********************************************************
1605
1789
Calculates the new value for lsn when more data is added to the log. */
1606
1790
static
1607
 
dulint
 
1791
ib_uint64_t
1608
1792
recv_calc_lsn_on_data_add(
1609
1793
/*======================*/
1610
 
        dulint  lsn,    /* in: old lsn */
1611
 
        ulint   len)    /* in: this many bytes of data is added, log block
1612
 
                        headers not included */
 
1794
        ib_uint64_t     lsn,    /* in: old lsn */
 
1795
        ib_uint64_t     len)    /* in: this many bytes of data is
 
1796
                                added, log block headers not included */
1613
1797
{
1614
1798
        ulint   frag_len;
1615
1799
        ulint   lsn_len;
1616
1800
 
1617
 
        frag_len = (ut_dulint_get_low(lsn) % OS_FILE_LOG_BLOCK_SIZE)
 
1801
        frag_len = (((ulint) lsn) % OS_FILE_LOG_BLOCK_SIZE)
1618
1802
                - LOG_BLOCK_HDR_SIZE;
1619
1803
        ut_ad(frag_len < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE
1620
1804
              - LOG_BLOCK_TRL_SIZE);
1621
 
        lsn_len = len + ((len + frag_len)
1622
 
                         / (OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE
1623
 
                            - LOG_BLOCK_TRL_SIZE))
 
1805
        lsn_len = (ulint) len;
 
1806
        lsn_len += (lsn_len + frag_len)
 
1807
                / (OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE
 
1808
                   - LOG_BLOCK_TRL_SIZE)
1624
1809
                * (LOG_BLOCK_HDR_SIZE + LOG_BLOCK_TRL_SIZE);
1625
1810
 
1626
 
        return(ut_dulint_add(lsn, lsn_len));
1627
 
}
 
1811
        return(lsn + lsn_len);
 
1812
}
 
1813
 
 
1814
#ifdef UNIV_LOG_DEBUG
 
1815
/***********************************************************
 
1816
Checks that the parser recognizes incomplete initial segments of a log
 
1817
record as incomplete. */
 
1818
static
 
1819
void
 
1820
recv_check_incomplete_log_recs(
 
1821
/*===========================*/
 
1822
        byte*   ptr,    /* in: pointer to a complete log record */
 
1823
        ulint   len)    /* in: length of the log record */
 
1824
{
 
1825
        ulint   i;
 
1826
        byte    type;
 
1827
        ulint   space;
 
1828
        ulint   page_no;
 
1829
        byte*   body;
 
1830
 
 
1831
        for (i = 0; i < len; i++) {
 
1832
                ut_a(0 == recv_parse_log_rec(ptr, ptr + i, &type, &space,
 
1833
                                             &page_no, &body));
 
1834
        }
 
1835
}
 
1836
#endif /* UNIV_LOG_DEBUG */
1628
1837
 
1629
1838
/***********************************************************
1630
1839
Prints diagnostic info of corrupt log. */
1640
1849
        fprintf(stderr,
1641
1850
                "InnoDB: ############### CORRUPT LOG RECORD FOUND\n"
1642
1851
                "InnoDB: Log record type %lu, space id %lu, page number %lu\n"
1643
 
                "InnoDB: Log parsing proceeded successfully up to %lu %lu\n"
 
1852
                "InnoDB: Log parsing proceeded successfully up to %"PRIu64"\n"
1644
1853
                "InnoDB: Previous log record type %lu, is multi %lu\n"
1645
1854
                "InnoDB: Recv offset %lu, prev %lu\n",
1646
1855
                (ulong) type, (ulong) space, (ulong) page_no,
1647
 
                (ulong) ut_dulint_get_high(recv_sys->recovered_lsn),
1648
 
                (ulong) ut_dulint_get_low(recv_sys->recovered_lsn),
 
1856
                recv_sys->recovered_lsn,
1649
1857
                (ulong) recv_previous_parsed_rec_type,
1650
1858
                (ulong) recv_previous_parsed_rec_is_multi,
1651
1859
                (ulong) (ptr - recv_sys->buf),
1695
1903
                                to the hash table; this is set to FALSE if just
1696
1904
                                debug checking is needed */
1697
1905
{
1698
 
        byte*   ptr;
1699
 
        byte*   end_ptr;
1700
 
        ulint   single_rec;
1701
 
        ulint   len;
1702
 
        ulint   total_len;
1703
 
        dulint  new_recovered_lsn;
1704
 
        dulint  old_lsn;
1705
 
        byte    type;
1706
 
        ulint   space;
1707
 
        ulint   page_no;
1708
 
        byte*   body;
1709
 
        ulint   n_recs;
 
1906
        byte*           ptr;
 
1907
        byte*           end_ptr;
 
1908
        ulint           single_rec;
 
1909
        ulint           len;
 
1910
        ulint           total_len;
 
1911
        ib_uint64_t     new_recovered_lsn;
 
1912
        ib_uint64_t     old_lsn;
 
1913
        byte            type;
 
1914
        ulint           space;
 
1915
        ulint           page_no;
 
1916
        byte*           body;
 
1917
        ulint           n_recs;
1710
1918
 
1711
1919
        ut_ad(mutex_own(&(log_sys->mutex)));
1712
 
        ut_ad(!ut_dulint_is_zero(recv_sys->parse_start_lsn));
 
1920
        ut_ad(recv_sys->parse_start_lsn != 0);
1713
1921
loop:
1714
1922
        ptr = recv_sys->buf + recv_sys->recovered_offset;
1715
1923
 
1745
1953
 
1746
1954
                new_recovered_lsn = recv_calc_lsn_on_data_add(old_lsn, len);
1747
1955
 
1748
 
                if (ut_dulint_cmp(new_recovered_lsn, recv_sys->scanned_lsn)
1749
 
                    > 0) {
 
1956
                if (new_recovered_lsn > recv_sys->scanned_lsn) {
1750
1957
                        /* The log record filled a log block, and we require
1751
1958
                        that also the next log block should have been scanned
1752
1959
                        in */
1774
1981
                if (type == MLOG_DUMMY_RECORD) {
1775
1982
                        /* Do nothing */
1776
1983
 
1777
 
                } else if (store_to_hash && (type == MLOG_FILE_CREATE
1778
 
                                             || type == MLOG_FILE_RENAME
1779
 
                                             || type == MLOG_FILE_DELETE)) {
 
1984
                } else if (!store_to_hash) {
 
1985
                        /* In debug checking, update a replicate page
 
1986
                        according to the log record, and check that it
 
1987
                        becomes identical with the original page */
 
1988
#ifdef UNIV_LOG_DEBUG
 
1989
                        recv_check_incomplete_log_recs(ptr, len);
 
1990
#endif/* UNIV_LOG_DEBUG */
 
1991
 
 
1992
                } else if (type == MLOG_FILE_CREATE
 
1993
                           || type == MLOG_FILE_CREATE2
 
1994
                           || type == MLOG_FILE_RENAME
 
1995
                           || type == MLOG_FILE_DELETE) {
 
1996
                        ut_a(space);
1780
1997
#ifdef UNIV_HOTBACKUP
1781
1998
                        if (recv_replay_file_ops) {
1782
1999
 
1786
2003
                                point to the datadir we should use there */
1787
2004
 
1788
2005
                                if (NULL == fil_op_log_parse_or_replay(
1789
 
                                            body, end_ptr, type, TRUE,
1790
 
                                            space)) {
 
2006
                                            body, end_ptr, type, space)) {
1791
2007
                                        fprintf(stderr,
1792
2008
                                                "InnoDB: Error: file op"
1793
2009
                                                " log record of type %lu"
1797
2013
                                                (ulint)type, space,
1798
2014
                                                (char*)(body + 2));
1799
2015
 
1800
 
                                        ut_a(0);
 
2016
                                        ut_error;
1801
2017
                                }
1802
2018
                        }
1803
2019
#endif
1804
2020
                        /* In normal mysqld crash recovery we do not try to
1805
2021
                        replay file operations */
1806
 
                } else if (store_to_hash) {
 
2022
                } else {
1807
2023
                        recv_add_to_hash_table(type, space, page_no, body,
1808
2024
                                               ptr + len, old_lsn,
1809
2025
                                               recv_sys->recovered_lsn);
1810
 
                } else {
1811
 
#ifdef UNIV_LOG_DEBUG
1812
 
                        recv_check_incomplete_log_recs(ptr, len);
1813
 
#endif/* UNIV_LOG_DEBUG */
1814
2026
                }
1815
2027
        } else {
1816
2028
                /* Check that all the records associated with the single mtr
1871
2083
                new_recovered_lsn = recv_calc_lsn_on_data_add(
1872
2084
                        recv_sys->recovered_lsn, total_len);
1873
2085
 
1874
 
                if (ut_dulint_cmp(new_recovered_lsn, recv_sys->scanned_lsn)
1875
 
                    > 0) {
 
2086
                if (new_recovered_lsn > recv_sys->scanned_lsn) {
1876
2087
                        /* The log record filled a log block, and we require
1877
2088
                        that also the next log block should have been scanned
1878
2089
                        in */
1928
2139
ibool
1929
2140
recv_sys_add_to_parsing_buf(
1930
2141
/*========================*/
1931
 
                                /* out: TRUE if more data added */
1932
 
        byte*   log_block,      /* in: log block */
1933
 
        dulint  scanned_lsn)    /* in: lsn of how far we were able to find
1934
 
                                data in this log block */
 
2142
                                        /* out: TRUE if more data added */
 
2143
        byte*           log_block,      /* in: log block */
 
2144
        ib_uint64_t     scanned_lsn)    /* in: lsn of how far we were able
 
2145
                                        to find data in this log block */
1935
2146
{
1936
2147
        ulint   more_len;
1937
2148
        ulint   data_len;
1938
2149
        ulint   start_offset;
1939
2150
        ulint   end_offset;
1940
2151
 
1941
 
        ut_ad(ut_dulint_cmp(scanned_lsn, recv_sys->scanned_lsn) >= 0);
 
2152
        ut_ad(scanned_lsn >= recv_sys->scanned_lsn);
1942
2153
 
1943
 
        if (ut_dulint_is_zero(recv_sys->parse_start_lsn)) {
 
2154
        if (!recv_sys->parse_start_lsn) {
1944
2155
                /* Cannot start parsing yet because no start point for
1945
2156
                it found */
1946
2157
 
1949
2160
 
1950
2161
        data_len = log_block_get_data_len(log_block);
1951
2162
 
1952
 
        if (ut_dulint_cmp(recv_sys->parse_start_lsn, scanned_lsn) >= 0) {
1953
 
 
1954
 
                return(FALSE);
1955
 
 
1956
 
        } else if (ut_dulint_cmp(recv_sys->scanned_lsn, scanned_lsn) >= 0) {
1957
 
 
1958
 
                return(FALSE);
1959
 
 
1960
 
        } else if (ut_dulint_cmp(recv_sys->parse_start_lsn,
1961
 
                                 recv_sys->scanned_lsn) > 0) {
1962
 
                more_len = ut_dulint_minus(scanned_lsn,
1963
 
                                           recv_sys->parse_start_lsn);
 
2163
        if (recv_sys->parse_start_lsn >= scanned_lsn) {
 
2164
 
 
2165
                return(FALSE);
 
2166
 
 
2167
        } else if (recv_sys->scanned_lsn >= scanned_lsn) {
 
2168
 
 
2169
                return(FALSE);
 
2170
 
 
2171
        } else if (recv_sys->parse_start_lsn > recv_sys->scanned_lsn) {
 
2172
                more_len = (ulint) (scanned_lsn - recv_sys->parse_start_lsn);
1964
2173
        } else {
1965
 
                more_len = ut_dulint_minus(scanned_lsn, recv_sys->scanned_lsn);
 
2174
                more_len = (ulint) (scanned_lsn - recv_sys->scanned_lsn);
1966
2175
        }
1967
2176
 
1968
2177
        if (more_len == 0) {
2016
2225
/***********************************************************
2017
2226
Scans log from a buffer and stores new log data to the parsing buffer. Parses
2018
2227
and hashes the log records if new data found. */
2019
 
 
 
2228
UNIV_INTERN
2020
2229
ibool
2021
2230
recv_scan_log_recs(
2022
2231
/*===============*/
2023
 
                                /* out: TRUE if limit_lsn has been reached, or
2024
 
                                not able to scan any more in this log group */
2025
 
        ibool   apply_automatically,/* in: TRUE if we want this function to
2026
 
                                apply log records automatically when the
2027
 
                                hash table becomes full; in the hot backup tool
2028
 
                                the tool does the applying, not this
2029
 
                                function */
2030
 
        ulint   available_memory,/* in: we let the hash table of recs to grow
2031
 
                                to this size, at the maximum */
2032
 
        ibool   store_to_hash,  /* in: TRUE if the records should be stored
2033
 
                                to the hash table; this is set to FALSE if just
2034
 
                                debug checking is needed */
2035
 
        byte*   buf,            /* in: buffer containing a log segment or
2036
 
                                garbage */
2037
 
        ulint   len,            /* in: buffer length */
2038
 
        dulint  start_lsn,      /* in: buffer start lsn */
2039
 
        dulint* contiguous_lsn, /* in/out: it is known that all log groups
2040
 
                                contain contiguous log data up to this lsn */
2041
 
        dulint* group_scanned_lsn)/* out: scanning succeeded up to this lsn */
 
2232
                                        /* out: TRUE if limit_lsn has been
 
2233
                                        reached, or not able to scan any more
 
2234
                                        in this log group */
 
2235
        ibool           apply_automatically,/* in: TRUE if we want this
 
2236
                                        function to apply log records
 
2237
                                        automatically when the hash table
 
2238
                                        becomes full; in the hot backup tool
 
2239
                                        the tool does the applying, not this
 
2240
                                        function */
 
2241
        ulint           available_memory,/* in: we let the hash table of recs
 
2242
                                        to grow to this size, at the maximum */
 
2243
        ibool           store_to_hash,  /* in: TRUE if the records should be
 
2244
                                        stored to the hash table; this is set
 
2245
                                        to FALSE if just debug checking is
 
2246
                                        needed */
 
2247
        byte*           buf,            /* in: buffer containing a log segment
 
2248
                                        or garbage */
 
2249
        ulint           len,            /* in: buffer length */
 
2250
        ib_uint64_t     start_lsn,      /* in: buffer start lsn */
 
2251
        ib_uint64_t*    contiguous_lsn, /* in/out: it is known that all log
 
2252
                                        groups contain contiguous log data up
 
2253
                                        to this lsn */
 
2254
        ib_uint64_t*    group_scanned_lsn)/* out: scanning succeeded up to
 
2255
                                        this lsn */
2042
2256
{
2043
 
        byte*   log_block;
2044
 
        ulint   no;
2045
 
        dulint  scanned_lsn;
2046
 
        ibool   finished;
2047
 
        ulint   data_len;
2048
 
        ibool   more_data;
 
2257
        byte*           log_block;
 
2258
        ulint           no;
 
2259
        ib_uint64_t     scanned_lsn;
 
2260
        ibool           finished;
 
2261
        ulint           data_len;
 
2262
        ibool           more_data;
2049
2263
 
2050
 
        ut_ad(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
 
2264
        ut_ad(start_lsn % OS_FILE_LOG_BLOCK_SIZE == 0);
2051
2265
        ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0);
2052
2266
        ut_ad(len > 0);
2053
2267
        ut_a(apply_automatically <= TRUE);
2076
2290
                                    log_block)) {
2077
2291
                                fprintf(stderr,
2078
2292
                                        "InnoDB: Log block no %lu at"
2079
 
                                        " lsn %lu %lu has\n"
 
2293
                                        " lsn %"PRIu64" has\n"
2080
2294
                                        "InnoDB: ok header, but checksum field"
2081
2295
                                        " contains %lu, should be %lu\n",
2082
2296
                                        (ulong) no,
2083
 
                                        (ulong) ut_dulint_get_high(
2084
 
                                                scanned_lsn),
2085
 
                                        (ulong) ut_dulint_get_low(scanned_lsn),
 
2297
                                        scanned_lsn,
2086
2298
                                        (ulong) log_block_get_checksum(
2087
2299
                                                log_block),
2088
2300
                                        (ulong) log_block_calc_checksum(
2104
2316
                        we know that log data is contiguous up to scanned_lsn
2105
2317
                        in all non-corrupt log groups. */
2106
2318
 
2107
 
                        if (ut_dulint_cmp(scanned_lsn, *contiguous_lsn) > 0) {
 
2319
                        if (scanned_lsn > *contiguous_lsn) {
2108
2320
                                *contiguous_lsn = scanned_lsn;
2109
2321
                        }
2110
2322
                }
2112
2324
                data_len = log_block_get_data_len(log_block);
2113
2325
 
2114
2326
                if ((store_to_hash || (data_len == OS_FILE_LOG_BLOCK_SIZE))
2115
 
                    && (ut_dulint_cmp(ut_dulint_add(scanned_lsn, data_len),
2116
 
                                      recv_sys->scanned_lsn) > 0)
 
2327
                    && scanned_lsn + data_len > recv_sys->scanned_lsn
2117
2328
                    && (recv_sys->scanned_checkpoint_no > 0)
2118
2329
                    && (log_block_get_checkpoint_no(log_block)
2119
2330
                        < recv_sys->scanned_checkpoint_no)
2134
2345
                        break;
2135
2346
                }
2136
2347
 
2137
 
                if (ut_dulint_is_zero(recv_sys->parse_start_lsn)
 
2348
                if (!recv_sys->parse_start_lsn
2138
2349
                    && (log_block_get_first_rec_group(log_block) > 0)) {
2139
2350
 
2140
2351
                        /* We found a point from which to start the parsing
2141
2352
                        of log records */
2142
2353
 
2143
 
                        recv_sys->parse_start_lsn
2144
 
                                = ut_dulint_add(scanned_lsn,
2145
 
                                                log_block_get_first_rec_group(
2146
 
                                                        log_block));
 
2354
                        recv_sys->parse_start_lsn = scanned_lsn
 
2355
                                + log_block_get_first_rec_group(log_block);
2147
2356
                        recv_sys->scanned_lsn = recv_sys->parse_start_lsn;
2148
2357
                        recv_sys->recovered_lsn = recv_sys->parse_start_lsn;
2149
2358
                }
2150
2359
 
2151
 
                scanned_lsn = ut_dulint_add(scanned_lsn, data_len);
 
2360
                scanned_lsn += data_len;
2152
2361
 
2153
 
                if (ut_dulint_cmp(scanned_lsn, recv_sys->scanned_lsn) > 0) {
 
2362
                if (scanned_lsn > recv_sys->scanned_lsn) {
2154
2363
 
2155
2364
                        /* We have found more entries. If this scan is
2156
2365
                        of startup type, we must initiate crash recovery
2161
2370
 
2162
2371
                                fprintf(stderr,
2163
2372
                                        "InnoDB: Log scan progressed"
2164
 
                                        " past the checkpoint lsn %lu %lu\n",
2165
 
                                        (ulong) ut_dulint_get_high(
2166
 
                                                recv_sys->scanned_lsn),
2167
 
                                        (ulong) ut_dulint_get_low(
2168
 
                                                recv_sys->scanned_lsn));
 
2373
                                        " past the checkpoint lsn %"PRIu64"\n",
 
2374
                                        recv_sys->scanned_lsn);
2169
2375
                                recv_init_crash_recovery();
2170
2376
                        }
2171
2377
 
2211
2417
 
2212
2418
                        fprintf(stderr,
2213
2419
                                "InnoDB: Doing recovery: scanned up to"
2214
 
                                " log sequence number %lu %lu\n",
2215
 
                                (ulong) ut_dulint_get_high(*group_scanned_lsn),
2216
 
                                (ulong) ut_dulint_get_low(*group_scanned_lsn));
 
2420
                                " log sequence number %"PRIu64"\n",
 
2421
                                *group_scanned_lsn);
2217
2422
                }
2218
2423
        }
2219
2424
 
2252
2457
void
2253
2458
recv_group_scan_log_recs(
2254
2459
/*=====================*/
2255
 
        log_group_t* group,     /* in: log group */
2256
 
        dulint* contiguous_lsn, /* in/out: it is known that all log groups
2257
 
                                contain contiguous log data up to this lsn */
2258
 
        dulint* group_scanned_lsn)/* out: scanning succeeded up to this lsn */
 
2460
        log_group_t*    group,          /* in: log group */
 
2461
        ib_uint64_t*    contiguous_lsn, /* in/out: it is known that all log
 
2462
                                        groups contain contiguous log data up
 
2463
                                        to this lsn */
 
2464
        ib_uint64_t*    group_scanned_lsn)/* out: scanning succeeded up to
 
2465
                                        this lsn */
2259
2466
{
2260
 
        ibool   finished;
2261
 
        dulint  start_lsn;
2262
 
        dulint  end_lsn;
 
2467
        ibool           finished;
 
2468
        ib_uint64_t     start_lsn;
 
2469
        ib_uint64_t     end_lsn;
2263
2470
 
2264
2471
        finished = FALSE;
2265
2472
 
2266
2473
        start_lsn = *contiguous_lsn;
2267
2474
 
2268
2475
        while (!finished) {
2269
 
                end_lsn = ut_dulint_add(start_lsn, RECV_SCAN_SIZE);
 
2476
                end_lsn = start_lsn + RECV_SCAN_SIZE;
2270
2477
 
2271
2478
                log_group_read_log_seg(LOG_RECOVER, log_sys->buf,
2272
2479
                                       group, start_lsn, end_lsn);
2273
2480
 
2274
2481
                finished = recv_scan_log_recs(
2275
 
                        TRUE, (buf_pool->n_frames - recv_n_pool_free_frames)
 
2482
                        TRUE, (buf_pool->curr_size - recv_n_pool_free_frames)
2276
2483
                        * UNIV_PAGE_SIZE, TRUE, log_sys->buf, RECV_SCAN_SIZE,
2277
2484
                        start_lsn, contiguous_lsn, group_scanned_lsn);
2278
2485
                start_lsn = end_lsn;
2282
2489
        if (log_debug_writes) {
2283
2490
                fprintf(stderr,
2284
2491
                        "InnoDB: Scanned group %lu up to"
2285
 
                        " log sequence number %lu %lu\n",
 
2492
                        " log sequence number %"PRIu64"\n",
2286
2493
                        (ulong) group->id,
2287
 
                        (ulong) ut_dulint_get_high(*group_scanned_lsn),
2288
 
                        (ulong) ut_dulint_get_low(*group_scanned_lsn));
 
2494
                        *group_scanned_lsn);
2289
2495
        }
2290
2496
#endif /* UNIV_DEBUG */
2291
2497
}
2336
2542
to start processing of new user transactions, but the function
2337
2543
recv_recovery_from_checkpoint_finish should be called later to complete
2338
2544
the recovery and free the resources used in it. */
2339
 
 
 
2545
UNIV_INTERN
2340
2546
ulint
2341
2547
recv_recovery_from_checkpoint_start(
2342
2548
/*================================*/
2343
 
                                /* out: error code or DB_SUCCESS */
2344
 
        ulint   type,           /* in: LOG_CHECKPOINT or LOG_ARCHIVE */
2345
 
        dulint  limit_lsn,      /* in: recover up to this lsn if possible */
2346
 
        dulint  min_flushed_lsn,/* in: min flushed lsn from data files */
2347
 
        dulint  max_flushed_lsn)/* in: max flushed lsn from data files */
 
2549
                                        /* out: error code or DB_SUCCESS */
 
2550
        ulint           type,           /* in: LOG_CHECKPOINT or LOG_ARCHIVE */
 
2551
        ib_uint64_t     limit_lsn,      /* in: recover up to this lsn
 
2552
                                        if possible */
 
2553
        ib_uint64_t     min_flushed_lsn,/* in: min flushed lsn from
 
2554
                                        data files */
 
2555
        ib_uint64_t     max_flushed_lsn)/* in: max flushed lsn from
 
2556
                                        data files */
2348
2557
{
2349
2558
        log_group_t*    group;
2350
2559
        log_group_t*    max_cp_group;
2351
2560
        log_group_t*    up_to_date_group;
2352
2561
        ulint           max_cp_field;
2353
 
        dulint          checkpoint_lsn;
2354
 
        dulint          checkpoint_no;
2355
 
        dulint          old_scanned_lsn;
2356
 
        dulint          group_scanned_lsn;
2357
 
        dulint          contiguous_lsn;
2358
 
        dulint          archived_lsn;
 
2562
        ib_uint64_t     checkpoint_lsn;
 
2563
        ib_uint64_t     checkpoint_no;
 
2564
        ib_uint64_t     old_scanned_lsn;
 
2565
        ib_uint64_t     group_scanned_lsn;
 
2566
        ib_uint64_t     contiguous_lsn;
 
2567
        ib_uint64_t     archived_lsn;
2359
2568
        ulint           capacity;
2360
2569
        byte*           buf;
2361
2570
        byte            log_hdr_buf[LOG_FILE_HDR_SIZE];
2362
2571
        ulint           err;
2363
2572
 
2364
 
        ut_ad((type != LOG_CHECKPOINT)
2365
 
              || (ut_dulint_cmp(limit_lsn, ut_dulint_max) == 0));
 
2573
        ut_ad(type != LOG_CHECKPOINT || limit_lsn == IB_ULONGLONG_MAX);
2366
2574
 
2367
2575
        if (type == LOG_CHECKPOINT) {
2368
2576
                recv_sys_create();
2399
2607
 
2400
2608
        buf = log_sys->checkpoint_buf;
2401
2609
 
2402
 
        checkpoint_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_LSN);
2403
 
        checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO);
2404
 
        archived_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN);
 
2610
        checkpoint_lsn = mach_read_ull(buf + LOG_CHECKPOINT_LSN);
 
2611
        checkpoint_no = mach_read_ull(buf + LOG_CHECKPOINT_NO);
 
2612
        archived_lsn = mach_read_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN);
2405
2613
 
2406
2614
        /* Read the first log file header to print a note if this is
2407
2615
        a recovery from a restored InnoDB Hot Backup */
2408
2616
 
2409
 
        fil_io(OS_FILE_READ | OS_FILE_LOG, TRUE, max_cp_group->space_id,
 
2617
        fil_io(OS_FILE_READ | OS_FILE_LOG, TRUE, max_cp_group->space_id, 0,
2410
2618
               0, 0, LOG_FILE_HDR_SIZE,
2411
2619
               log_hdr_buf, max_cp_group);
2412
2620
 
2430
2638
                       ' ', 4);
2431
2639
                /* Write to the log file to wipe over the label */
2432
2640
                fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE,
2433
 
                       max_cp_group->space_id,
 
2641
                       max_cp_group->space_id, 0,
2434
2642
                       0, 0, OS_FILE_LOG_BLOCK_SIZE,
2435
2643
                       log_hdr_buf, max_cp_group);
2436
2644
        }
2460
2668
                srv_start_lsn = checkpoint_lsn;
2461
2669
        }
2462
2670
 
2463
 
        contiguous_lsn = ut_dulint_align_down(recv_sys->scanned_lsn,
 
2671
        contiguous_lsn = ut_uint64_align_down(recv_sys->scanned_lsn,
2464
2672
                                              OS_FILE_LOG_BLOCK_SIZE);
2465
2673
        if (type == LOG_ARCHIVE) {
2466
2674
                /* Try to recover the remaining part from logs: first from
2469
2677
                group = recv_sys->archive_group;
2470
2678
                capacity = log_group_get_capacity(group);
2471
2679
 
2472
 
                if ((ut_dulint_cmp(recv_sys->scanned_lsn, ut_dulint_add(
2473
 
                                           checkpoint_lsn, capacity)) > 0)
2474
 
                    || (ut_dulint_cmp(checkpoint_lsn, ut_dulint_add(
2475
 
                                              recv_sys->scanned_lsn, capacity))
2476
 
                        > 0)) {
 
2680
                if (recv_sys->scanned_lsn > checkpoint_lsn + capacity
 
2681
                    || checkpoint_lsn > recv_sys->scanned_lsn + capacity) {
2477
2682
 
2478
2683
                        mutex_exit(&(log_sys->mutex));
2479
2684
 
2485
2690
 
2486
2691
                recv_group_scan_log_recs(group, &contiguous_lsn,
2487
2692
                                         &group_scanned_lsn);
2488
 
                if (ut_dulint_cmp(recv_sys->scanned_lsn, checkpoint_lsn) < 0) {
 
2693
                if (recv_sys->scanned_lsn < checkpoint_lsn) {
2489
2694
 
2490
2695
                        mutex_exit(&(log_sys->mutex));
2491
2696
 
2519
2724
                                         &group_scanned_lsn);
2520
2725
                group->scanned_lsn = group_scanned_lsn;
2521
2726
 
2522
 
                if (ut_dulint_cmp(old_scanned_lsn, group_scanned_lsn) < 0) {
 
2727
                if (old_scanned_lsn < group_scanned_lsn) {
2523
2728
                        /* We found a more up-to-date group */
2524
2729
 
2525
2730
                        up_to_date_group = group;
2540
2745
                there is something wrong we will print a message to the
2541
2746
                user about recovery: */
2542
2747
 
2543
 
                if (ut_dulint_cmp(checkpoint_lsn, max_flushed_lsn) != 0
2544
 
                    || ut_dulint_cmp(checkpoint_lsn, min_flushed_lsn) != 0) {
 
2748
                if (checkpoint_lsn != max_flushed_lsn
 
2749
                    || checkpoint_lsn != min_flushed_lsn) {
2545
2750
 
2546
 
                        if (ut_dulint_cmp(checkpoint_lsn, max_flushed_lsn)
2547
 
                            < 0) {
 
2751
                        if (checkpoint_lsn < max_flushed_lsn) {
2548
2752
                                fprintf(stderr,
2549
2753
                                        "InnoDB: #########################"
2550
2754
                                        "#################################\n"
2558
2762
                                        " ib_logfiles to start up"
2559
2763
                                        " the database?\n"
2560
2764
                                        "InnoDB: Log sequence number in"
2561
 
                                        " ib_logfiles is %lu %lu, log\n"
 
2765
                                        " ib_logfiles is %"PRIu64", log\n"
2562
2766
                                        "InnoDB: sequence numbers stamped"
2563
2767
                                        " to ibdata file headers are between\n"
2564
 
                                        "InnoDB: %lu %lu and %lu %lu.\n"
 
2768
                                        "InnoDB: %"PRIu64" and %"PRIu64".\n"
2565
2769
                                        "InnoDB: #########################"
2566
2770
                                        "#################################\n",
2567
 
                                        (ulong) ut_dulint_get_high(
2568
 
                                                checkpoint_lsn),
2569
 
                                        (ulong) ut_dulint_get_low(
2570
 
                                                checkpoint_lsn),
2571
 
                                        (ulong) ut_dulint_get_high(
2572
 
                                                min_flushed_lsn),
2573
 
                                        (ulong) ut_dulint_get_low(
2574
 
                                                min_flushed_lsn),
2575
 
                                        (ulong) ut_dulint_get_high(
2576
 
                                                max_flushed_lsn),
2577
 
                                        (ulong) ut_dulint_get_low(
2578
 
                                                max_flushed_lsn));
2579
 
 
2580
 
 
 
2771
                                        checkpoint_lsn,
 
2772
                                        min_flushed_lsn,
 
2773
                                        max_flushed_lsn);
2581
2774
                        }
2582
2775
 
2583
2776
                        if (!recv_needed_recovery) {
2588
2781
                                        " in the ib_logfiles!\n");
2589
2782
                                recv_init_crash_recovery();
2590
2783
                        }
 
2784
                }
2591
2785
 
2592
 
                }
2593
2786
                if (!recv_needed_recovery) {
2594
2787
                        /* Init the doublewrite buffer memory structure */
2595
2788
                        trx_sys_doublewrite_init_or_restore_pages(FALSE);
2597
2790
        }
2598
2791
 
2599
2792
        /* We currently have only one log group */
2600
 
        if (ut_dulint_cmp(group_scanned_lsn, checkpoint_lsn) < 0) {
 
2793
        if (group_scanned_lsn < checkpoint_lsn) {
2601
2794
                ut_print_timestamp(stderr);
2602
2795
                fprintf(stderr,
2603
2796
                        "  InnoDB: ERROR: We were only able to scan the log"
2604
2797
                        " up to\n"
2605
 
                        "InnoDB: %lu %lu, but a checkpoint was at %lu %lu.\n"
 
2798
                        "InnoDB: %"PRIu64", but a checkpoint was at %"PRIu64".\n"
2606
2799
                        "InnoDB: It is possible that"
2607
2800
                        " the database is now corrupt!\n",
2608
 
                        (ulong) ut_dulint_get_high(group_scanned_lsn),
2609
 
                        (ulong) ut_dulint_get_low(group_scanned_lsn),
2610
 
                        (ulong) ut_dulint_get_high(checkpoint_lsn),
2611
 
                        (ulong) ut_dulint_get_low(checkpoint_lsn));
 
2801
                        group_scanned_lsn,
 
2802
                        checkpoint_lsn);
2612
2803
        }
2613
2804
 
2614
 
        if (ut_dulint_cmp(group_scanned_lsn, recv_max_page_lsn) < 0) {
 
2805
        if (group_scanned_lsn < recv_max_page_lsn) {
2615
2806
                ut_print_timestamp(stderr);
2616
2807
                fprintf(stderr,
2617
2808
                        "  InnoDB: ERROR: We were only able to scan the log"
2618
 
                        " up to %lu %lu\n"
2619
 
                        "InnoDB: but a database page a had an lsn %lu %lu."
 
2809
                        " up to %"PRIu64"\n"
 
2810
                        "InnoDB: but a database page a had an lsn %"PRIu64"."
2620
2811
                        " It is possible that the\n"
2621
2812
                        "InnoDB: database is now corrupt!\n",
2622
 
                        (ulong) ut_dulint_get_high(group_scanned_lsn),
2623
 
                        (ulong) ut_dulint_get_low(group_scanned_lsn),
2624
 
                        (ulong) ut_dulint_get_high(recv_max_page_lsn),
2625
 
                        (ulong) ut_dulint_get_low(recv_max_page_lsn));
 
2813
                        group_scanned_lsn,
 
2814
                        recv_max_page_lsn);
2626
2815
        }
2627
2816
 
2628
 
        if (ut_dulint_cmp(recv_sys->recovered_lsn, checkpoint_lsn) < 0) {
 
2817
        if (recv_sys->recovered_lsn < checkpoint_lsn) {
2629
2818
 
2630
2819
                mutex_exit(&(log_sys->mutex));
2631
2820
 
2632
 
                if (ut_dulint_cmp(recv_sys->recovered_lsn, limit_lsn) >= 0) {
 
2821
                if (recv_sys->recovered_lsn >= limit_lsn) {
2633
2822
 
2634
2823
                        return(DB_SUCCESS);
2635
2824
                }
2643
2832
        group; we also copy checkpoint info to groups */
2644
2833
 
2645
2834
        log_sys->next_checkpoint_lsn = checkpoint_lsn;
2646
 
        log_sys->next_checkpoint_no = ut_dulint_add(checkpoint_no, 1);
 
2835
        log_sys->next_checkpoint_no = checkpoint_no + 1;
2647
2836
 
2648
2837
#ifdef UNIV_LOG_ARCHIVE
2649
2838
        log_sys->archived_lsn = archived_lsn;
2652
2841
        recv_synchronize_groups(up_to_date_group);
2653
2842
 
2654
2843
        if (!recv_needed_recovery) {
2655
 
                ut_a(ut_dulint_cmp(checkpoint_lsn,
2656
 
                                   recv_sys->recovered_lsn) == 0);
2657
 
 
 
2844
                ut_a(checkpoint_lsn == recv_sys->recovered_lsn);
2658
2845
        } else {
2659
2846
                srv_start_lsn = recv_sys->recovered_lsn;
2660
2847
        }
2663
2850
 
2664
2851
        ut_memcpy(log_sys->buf, recv_sys->last_block, OS_FILE_LOG_BLOCK_SIZE);
2665
2852
 
2666
 
        log_sys->buf_free = ut_dulint_get_low(log_sys->lsn)
2667
 
                % OS_FILE_LOG_BLOCK_SIZE;
 
2853
        log_sys->buf_free = (ulint) log_sys->lsn % OS_FILE_LOG_BLOCK_SIZE;
2668
2854
        log_sys->buf_next_to_write = log_sys->buf_free;
2669
2855
        log_sys->written_to_some_lsn = log_sys->lsn;
2670
2856
        log_sys->written_to_all_lsn = log_sys->lsn;
2671
2857
 
2672
2858
        log_sys->last_checkpoint_lsn = checkpoint_lsn;
2673
2859
 
2674
 
        log_sys->next_checkpoint_no = ut_dulint_add(checkpoint_no, 1);
 
2860
        log_sys->next_checkpoint_no = checkpoint_no + 1;
2675
2861
 
2676
2862
#ifdef UNIV_LOG_ARCHIVE
2677
 
        if (ut_dulint_cmp(archived_lsn, ut_dulint_max) == 0) {
 
2863
        if (archived_lsn == IB_ULONGLONG_MAX) {
2678
2864
 
2679
2865
                log_sys->archiving_state = LOG_ARCH_OFF;
2680
2866
        }
2699
2885
 
2700
2886
/************************************************************
2701
2887
Completes recovery from a checkpoint. */
2702
 
 
 
2888
UNIV_INTERN
2703
2889
void
2704
2890
recv_recovery_from_checkpoint_finish(void)
2705
2891
/*======================================*/
2749
2935
        recv_sys_free();
2750
2936
#endif
2751
2937
 
 
2938
        /* Drop partially created indexes. */
 
2939
        row_merge_drop_temp_indexes();
 
2940
 
2752
2941
#ifdef UNIV_SYNC_DEBUG
2753
2942
        /* Wait for a while so that created threads have time to suspend
2754
2943
        themselves before we switch the latching order checks on */
2761
2950
                /* Rollback the uncommitted transactions which have no user
2762
2951
                session */
2763
2952
 
2764
 
                os_thread_create(trx_rollback_or_clean_all_without_sess,
 
2953
                os_thread_create(trx_rollback_or_clean_all_recovered,
2765
2954
                                 (void *)&i, NULL);
2766
2955
        }
2767
2956
}
2768
2957
 
2769
2958
/**********************************************************
2770
2959
Resets the logs. The contents of log files will be lost! */
2771
 
 
 
2960
UNIV_INTERN
2772
2961
void
2773
2962
recv_reset_logs(
2774
2963
/*============*/
2775
 
        dulint  lsn,            /* in: reset to this lsn rounded up to
2776
 
                                be divisible by OS_FILE_LOG_BLOCK_SIZE,
2777
 
                                after which we add LOG_BLOCK_HDR_SIZE */
 
2964
        ib_uint64_t     lsn,            /* in: reset to this lsn
 
2965
                                        rounded up to be divisible by
 
2966
                                        OS_FILE_LOG_BLOCK_SIZE, after
 
2967
                                        which we add
 
2968
                                        LOG_BLOCK_HDR_SIZE */
2778
2969
#ifdef UNIV_LOG_ARCHIVE
2779
 
        ulint   arch_log_no,    /* in: next archived log file number */
 
2970
        ulint           arch_log_no,    /* in: next archived log file number */
2780
2971
#endif /* UNIV_LOG_ARCHIVE */
2781
 
        ibool   new_logs_created)/* in: TRUE if resetting logs is done
2782
 
                                at the log creation; FALSE if it is done
2783
 
                                after archive recovery */
 
2972
        ibool           new_logs_created)/* in: TRUE if resetting logs
 
2973
                                        is done at the log creation;
 
2974
                                        FALSE if it is done after
 
2975
                                        archive recovery */
2784
2976
{
2785
2977
        log_group_t*    group;
2786
2978
 
2787
2979
        ut_ad(mutex_own(&(log_sys->mutex)));
2788
2980
 
2789
 
        log_sys->lsn = ut_dulint_align_up(lsn, OS_FILE_LOG_BLOCK_SIZE);
 
2981
        log_sys->lsn = ut_uint64_align_up(lsn, OS_FILE_LOG_BLOCK_SIZE);
2790
2982
 
2791
2983
        group = UT_LIST_GET_FIRST(log_sys->log_groups);
2792
2984
 
2810
3002
        log_sys->written_to_some_lsn = log_sys->lsn;
2811
3003
        log_sys->written_to_all_lsn = log_sys->lsn;
2812
3004
 
2813
 
        log_sys->next_checkpoint_no = ut_dulint_zero;
2814
 
        log_sys->last_checkpoint_lsn = ut_dulint_zero;
 
3005
        log_sys->next_checkpoint_no = 0;
 
3006
        log_sys->last_checkpoint_lsn = 0;
2815
3007
 
2816
3008
#ifdef UNIV_LOG_ARCHIVE
2817
3009
        log_sys->archived_lsn = log_sys->lsn;
2821
3013
        log_block_set_first_rec_group(log_sys->buf, LOG_BLOCK_HDR_SIZE);
2822
3014
 
2823
3015
        log_sys->buf_free = LOG_BLOCK_HDR_SIZE;
2824
 
        log_sys->lsn = ut_dulint_add(log_sys->lsn, LOG_BLOCK_HDR_SIZE);
 
3016
        log_sys->lsn += LOG_BLOCK_HDR_SIZE;
2825
3017
 
2826
3018
        mutex_exit(&(log_sys->mutex));
2827
3019
 
2828
3020
        /* Reset the checkpoint fields in logs */
2829
3021
 
2830
 
        log_make_checkpoint_at(ut_dulint_max, TRUE);
2831
 
        log_make_checkpoint_at(ut_dulint_max, TRUE);
 
3022
        log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE);
 
3023
        log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE);
2832
3024
 
2833
3025
        mutex_enter(&(log_sys->mutex));
2834
3026
}
2836
3028
#ifdef UNIV_HOTBACKUP
2837
3029
/**********************************************************
2838
3030
Creates new log files after a backup has been restored. */
2839
 
 
 
3031
UNIV_INTERN
2840
3032
void
2841
3033
recv_reset_log_files_for_backup(
2842
3034
/*============================*/
2843
3035
        const char*     log_dir,        /* in: log file directory path */
2844
3036
        ulint           n_log_files,    /* in: number of log files */
2845
3037
        ulint           log_file_size,  /* in: log file size */
2846
 
        dulint          lsn)            /* in: new start lsn, must be
 
3038
        ib_uint64_t     lsn)            /* in: new start lsn, must be
2847
3039
                                        divisible by OS_FILE_LOG_BLOCK_SIZE */
2848
3040
{
2849
3041
        os_file_t       log_file;
2936
3128
                                        consistent archive files */
2937
3129
        log_group_t*    group)          /* in: log group */
2938
3130
{
2939
 
        os_file_t file_handle;
2940
 
        dulint  start_lsn;
2941
 
        dulint  file_end_lsn;
2942
 
        dulint  dummy_lsn;
2943
 
        dulint  scanned_lsn;
2944
 
        ulint   len;
2945
 
        ibool   ret;
2946
 
        byte*   buf;
2947
 
        ulint   read_offset;
2948
 
        ulint   file_size;
2949
 
        ulint   file_size_high;
2950
 
        int     input_char;
2951
 
        char    name[10000];
 
3131
        os_file_t       file_handle;
 
3132
        ib_uint64_t     start_lsn;
 
3133
        ib_uint64_t     file_end_lsn;
 
3134
        ib_uint64_t     dummy_lsn;
 
3135
        ib_uint64_t     scanned_lsn;
 
3136
        ulint           len;
 
3137
        ibool           ret;
 
3138
        byte*           buf;
 
3139
        ulint           read_offset;
 
3140
        ulint           file_size;
 
3141
        ulint           file_size_high;
 
3142
        int             input_char;
 
3143
        char            name[10000];
2952
3144
 
2953
3145
        ut_a(0);
2954
3146
 
3036
3228
                return(TRUE);
3037
3229
        }
3038
3230
 
3039
 
        start_lsn = mach_read_from_8(buf + LOG_FILE_START_LSN);
3040
 
        file_end_lsn = mach_read_from_8(buf + LOG_FILE_END_LSN);
3041
 
 
3042
 
        if (ut_dulint_is_zero(recv_sys->scanned_lsn)) {
3043
 
 
3044
 
                if (ut_dulint_cmp(recv_sys->parse_start_lsn, start_lsn) < 0) {
 
3231
        start_lsn = mach_read_ull(buf + LOG_FILE_START_LSN);
 
3232
        file_end_lsn = mach_read_ull(buf + LOG_FILE_END_LSN);
 
3233
 
 
3234
        if (!recv_sys->scanned_lsn) {
 
3235
 
 
3236
                if (recv_sys->parse_start_lsn < start_lsn) {
3045
3237
                        fprintf(stderr,
3046
3238
                                "InnoDB: Archive log file %s"
3047
3239
                                " starts from too big a lsn\n",
3052
3244
                recv_sys->scanned_lsn = start_lsn;
3053
3245
        }
3054
3246
 
3055
 
        if (ut_dulint_cmp(recv_sys->scanned_lsn, start_lsn) != 0) {
 
3247
        if (recv_sys->scanned_lsn != start_lsn) {
3056
3248
 
3057
3249
                fprintf(stderr,
3058
3250
                        "InnoDB: Archive log file %s starts from"
3080
3272
                if (log_debug_writes) {
3081
3273
                        fprintf(stderr,
3082
3274
                                "InnoDB: Archive read starting at"
3083
 
                                " lsn %lu %lu, len %lu from file %s\n",
3084
 
                                (ulong) ut_dulint_get_high(start_lsn),
3085
 
                                (ulong) ut_dulint_get_low(start_lsn),
 
3275
                                " lsn %"PRIu64", len %lu from file %s\n",
 
3276
                                start_lsn,
3086
3277
                                (ulong) len, name);
3087
3278
                }
3088
3279
#endif /* UNIV_DEBUG */
3096
3287
                        * UNIV_PAGE_SIZE, TRUE, buf, len, start_lsn,
3097
3288
                        &dummy_lsn, &scanned_lsn);
3098
3289
 
3099
 
                if (ut_dulint_cmp(scanned_lsn, file_end_lsn) == 0) {
 
3290
                if (scanned_lsn == file_end_lsn) {
3100
3291
 
3101
3292
                        return(FALSE);
3102
3293
                }
3110
3301
                }
3111
3302
 
3112
3303
                read_offset += len;
3113
 
                start_lsn = ut_dulint_add(start_lsn, len);
 
3304
                start_lsn += len;
3114
3305
 
3115
 
                ut_ad(ut_dulint_cmp(start_lsn, scanned_lsn) == 0);
 
3306
                ut_ad(start_lsn == scanned_lsn);
3116
3307
        }
3117
3308
 
3118
3309
        return(FALSE);
3120
3311
 
3121
3312
/************************************************************
3122
3313
Recovers from archived log files, and also from log files, if they exist. */
3123
 
 
 
3314
UNIV_INTERN
3124
3315
ulint
3125
3316
recv_recovery_from_archive_start(
3126
3317
/*=============================*/
3127
 
                                /* out: error code or DB_SUCCESS */
3128
 
        dulint  min_flushed_lsn,/* in: min flushed lsn field from the
3129
 
                                data files */
3130
 
        dulint  limit_lsn,      /* in: recover up to this lsn if possible */
3131
 
        ulint   first_log_no)   /* in: number of the first archived log file
3132
 
                                to use in the recovery; the file will be
3133
 
                                searched from INNOBASE_LOG_ARCH_DIR specified
3134
 
                                in server config file */
 
3318
                                        /* out: error code or DB_SUCCESS */
 
3319
        ib_uint64_t     min_flushed_lsn,/* in: min flushed lsn field from the
 
3320
                                        data files */
 
3321
        ib_uint64_t     limit_lsn,      /* in: recover up to this lsn if
 
3322
                                        possible */
 
3323
        ulint           first_log_no)   /* in: number of the first archived
 
3324
                                        log file to use in the recovery; the
 
3325
                                        file will be searched from
 
3326
                                        INNOBASE_LOG_ARCH_DIR specified in
 
3327
                                        server config file */
3135
3328
{
3136
3329
        log_group_t*    group;
3137
3330
        ulint           group_id;
3173
3366
 
3174
3367
        recv_sys->parse_start_lsn = min_flushed_lsn;
3175
3368
 
3176
 
        recv_sys->scanned_lsn = ut_dulint_zero;
 
3369
        recv_sys->scanned_lsn = 0;
3177
3370
        recv_sys->scanned_checkpoint_no = 0;
3178
3371
        recv_sys->recovered_lsn = recv_sys->parse_start_lsn;
3179
3372
 
3199
3392
                group->archived_file_no++;
3200
3393
        }
3201
3394
 
3202
 
        if (ut_dulint_cmp(recv_sys->recovered_lsn, limit_lsn) < 0) {
 
3395
        if (recv_sys->recovered_lsn < limit_lsn) {
3203
3396
 
3204
 
                if (ut_dulint_is_zero(recv_sys->scanned_lsn)) {
 
3397
                if (!recv_sys->scanned_lsn) {
3205
3398
 
3206
3399
                        recv_sys->scanned_lsn = recv_sys->parse_start_lsn;
3207
3400
                }
3210
3403
 
3211
3404
                err = recv_recovery_from_checkpoint_start(LOG_ARCHIVE,
3212
3405
                                                          limit_lsn,
3213
 
                                                          ut_dulint_max,
3214
 
                                                          ut_dulint_max);
 
3406
                                                          IB_ULONGLONG_MAX,
 
3407
                                                          IB_ULONGLONG_MAX);
3215
3408
                if (err != DB_SUCCESS) {
3216
3409
 
3217
3410
                        return(err);
3220
3413
                mutex_enter(&(log_sys->mutex));
3221
3414
        }
3222
3415
 
3223
 
        if (ut_dulint_cmp(limit_lsn, ut_dulint_max) != 0) {
 
3416
        if (limit_lsn != IB_ULONGLONG_MAX) {
3224
3417
 
3225
3418
                recv_apply_hashed_log_recs(FALSE);
3226
3419
 
3234
3427
 
3235
3428
/************************************************************
3236
3429
Completes recovery from archive. */
3237
 
 
 
3430
UNIV_INTERN
3238
3431
void
3239
3432
recv_recovery_from_archive_finish(void)
3240
3433
/*===================================*/