~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2008-11-04 15:39:09 UTC
  • mfrom: (575.1.2 devel)
  • Revision ID: brian@tangent.org-20081104153909-c72hn65udxs1ccal
Merge of Monty's work

Show diffs side-by-side

added added

removed removed

Lines of Context:
52
52
 
53
53
/* Current free limit of space 0; protected by the log sys mutex; 0 means
54
54
uninitialized */
55
 
ulint   log_fsp_current_free_limit              = 0;
 
55
UNIV_INTERN ulint       log_fsp_current_free_limit              = 0;
56
56
 
57
57
/* Global log system variable */
58
 
log_t*  log_sys = NULL;
 
58
UNIV_INTERN log_t*      log_sys = NULL;
59
59
 
60
60
#ifdef UNIV_DEBUG
61
 
ibool   log_do_write = TRUE;
 
61
UNIV_INTERN ibool       log_do_write = TRUE;
62
62
 
63
 
ibool   log_debug_writes = FALSE;
 
63
UNIV_INTERN ibool       log_debug_writes = FALSE;
64
64
#endif /* UNIV_DEBUG */
65
65
 
66
66
/* These control how often we print warnings if the last checkpoint is too
67
67
old */
68
 
ibool   log_has_printed_chkp_warning = FALSE;
69
 
time_t  log_last_warning_time;
 
68
UNIV_INTERN ibool       log_has_printed_chkp_warning = FALSE;
 
69
UNIV_INTERN time_t      log_last_warning_time;
70
70
 
71
71
#ifdef UNIV_LOG_ARCHIVE
72
72
/* Pointer to this variable is used as the i/o-message when we do i/o to an
73
73
archive */
74
 
byte    log_archive_io;
 
74
UNIV_INTERN byte        log_archive_io;
75
75
#endif /* UNIV_LOG_ARCHIVE */
76
76
 
77
77
/* A margin for free space in the log buffer before a log entry is catenated */
102
102
/* Extra margin, in addition to one log file, used in archiving */
103
103
#define LOG_ARCHIVE_EXTRA_MARGIN        (4 * UNIV_PAGE_SIZE)
104
104
 
 
105
#ifdef UNIV_LOG_ARCHIVE
105
106
/* This parameter controls asynchronous writing to the archive */
106
107
#define LOG_ARCHIVE_RATIO_ASYNC         16
107
108
 
 
109
/* States of an archiving operation */
 
110
#define LOG_ARCHIVE_READ        1
 
111
#define LOG_ARCHIVE_WRITE       2
 
112
 
 
113
#endif /* UNIV_LOG_ARCHIVE */
 
114
 
108
115
/* Codes used in unlocking flush latches */
109
116
#define LOG_UNLOCK_NONE_FLUSHED_LOCK    1
110
117
#define LOG_UNLOCK_FLUSH_LOCK           2
111
118
 
112
 
/* States of an archiving operation */
113
 
#define LOG_ARCHIVE_READ        1
114
 
#define LOG_ARCHIVE_WRITE       2
115
 
 
116
119
/**********************************************************
117
120
Completes a checkpoint write i/o to a log file. */
118
121
static
132
135
Sets the global variable log_fsp_current_free_limit. Also makes a checkpoint,
133
136
so that we know that the limit has been written to a log checkpoint field
134
137
on disk. */
135
 
 
 
138
UNIV_INTERN
136
139
void
137
140
log_fsp_current_free_limit_set_and_checkpoint(
138
141
/*==========================================*/
159
162
Returns the oldest modified block lsn in the pool, or log_sys->lsn if none
160
163
exists. */
161
164
static
162
 
dulint
 
165
ib_uint64_t
163
166
log_buf_pool_get_oldest_modification(void)
164
167
/*======================================*/
165
168
{
166
 
        dulint  lsn;
 
169
        ib_uint64_t     lsn;
167
170
 
168
171
        ut_ad(mutex_own(&(log_sys->mutex)));
169
172
 
170
173
        lsn = buf_pool_get_oldest_modification();
171
174
 
172
 
        if (ut_dulint_is_zero(lsn)) {
 
175
        if (!lsn) {
173
176
 
174
177
                lsn = log_sys->lsn;
175
178
        }
180
183
/****************************************************************
181
184
Opens the log for log_write_low. The log must be closed with log_close and
182
185
released with log_release. */
183
 
 
184
 
dulint
 
186
UNIV_INTERN
 
187
ib_uint64_t
185
188
log_reserve_and_open(
186
189
/*=================*/
187
190
                        /* out: start lsn of the log record */
225
228
#ifdef UNIV_LOG_ARCHIVE
226
229
        if (log->archiving_state != LOG_ARCH_OFF) {
227
230
 
228
 
                archived_lsn_age = ut_dulint_minus(log->lsn,
229
 
                                                   log->archived_lsn);
 
231
                archived_lsn_age = log->lsn - log->archived_lsn;
230
232
                if (archived_lsn_age + len_upper_limit
231
233
                    > log->max_archived_lsn_age) {
232
234
                        /* Not enough free archived space in log groups: do a
255
257
/****************************************************************
256
258
Writes to the log the string given. It is assumed that the caller holds the
257
259
log mutex. */
258
 
 
 
260
UNIV_INTERN
259
261
void
260
262
log_write_low(
261
263
/*==========*/
302
304
                                            log_sys->next_checkpoint_no);
303
305
                len += LOG_BLOCK_HDR_SIZE + LOG_BLOCK_TRL_SIZE;
304
306
 
305
 
                log->lsn = ut_dulint_add(log->lsn, len);
 
307
                log->lsn += len;
306
308
 
307
309
                /* Initialize the next block header */
308
310
                log_block_init(log_block + OS_FILE_LOG_BLOCK_SIZE, log->lsn);
309
311
        } else {
310
 
                log->lsn = ut_dulint_add(log->lsn, len);
 
312
                log->lsn += len;
311
313
        }
312
314
 
313
315
        log->buf_free += len;
323
325
 
324
326
/****************************************************************
325
327
Closes the log. */
326
 
 
327
 
dulint
 
328
UNIV_INTERN
 
329
ib_uint64_t
328
330
log_close(void)
329
331
/*===========*/
330
332
                        /* out: lsn */
331
333
{
332
 
        byte*   log_block;
333
 
        ulint   first_rec_group;
334
 
        dulint  oldest_lsn;
335
 
        dulint  lsn;
336
 
        log_t*  log     = log_sys;
337
 
        ulint   checkpoint_age;
 
334
        byte*           log_block;
 
335
        ulint           first_rec_group;
 
336
        ib_uint64_t     oldest_lsn;
 
337
        ib_uint64_t     lsn;
 
338
        log_t*          log     = log_sys;
 
339
        ib_uint64_t     checkpoint_age;
338
340
 
339
341
        ut_ad(mutex_own(&(log->mutex)));
340
342
 
358
360
                log->check_flush_or_checkpoint = TRUE;
359
361
        }
360
362
 
361
 
        checkpoint_age = ut_dulint_minus(lsn, log->last_checkpoint_lsn);
 
363
        checkpoint_age = lsn - log->last_checkpoint_lsn;
362
364
 
363
365
        if (checkpoint_age >= log->log_group_capacity) {
364
366
                /* TODO: split btr_store_big_rec_extern_fields() into small
396
398
 
397
399
        oldest_lsn = buf_pool_get_oldest_modification();
398
400
 
399
 
        if (ut_dulint_is_zero(oldest_lsn)
400
 
            || (ut_dulint_minus(lsn, oldest_lsn)
401
 
                > log->max_modified_age_async)
 
401
        if (!oldest_lsn
 
402
            || lsn - oldest_lsn > log->max_modified_age_async
402
403
            || checkpoint_age > log->max_checkpoint_age_async) {
403
404
 
404
405
                log->check_flush_or_checkpoint = TRUE;
422
423
log_pad_current_log_block(void)
423
424
/*===========================*/
424
425
{
425
 
        byte    b               = MLOG_DUMMY_RECORD;
426
 
        ulint   pad_length;
427
 
        ulint   i;
428
 
        dulint  lsn;
 
426
        byte            b               = MLOG_DUMMY_RECORD;
 
427
        ulint           pad_length;
 
428
        ulint           i;
 
429
        ib_uint64_t     lsn;
429
430
 
430
431
        /* We retrieve lsn only because otherwise gcc crashed on HP-UX */
431
432
        lsn = log_reserve_and_open(OS_FILE_LOG_BLOCK_SIZE);
443
444
        log_close();
444
445
        log_release();
445
446
 
446
 
        ut_a((ut_dulint_get_low(lsn) % OS_FILE_LOG_BLOCK_SIZE)
447
 
             == LOG_BLOCK_HDR_SIZE);
 
447
        ut_a(lsn % OS_FILE_LOG_BLOCK_SIZE == LOG_BLOCK_HDR_SIZE);
448
448
}
449
449
#endif /* UNIV_LOG_ARCHIVE */
450
450
 
451
451
/**********************************************************
452
452
Calculates the data capacity of a log group, when the log file headers are not
453
453
included. */
454
 
 
 
454
UNIV_INTERN
455
455
ulint
456
456
log_group_get_capacity(
457
457
/*===================*/
503
503
log_group_calc_lsn_offset(
504
504
/*======================*/
505
505
                                /* out: offset within the log group */
506
 
        dulint          lsn,    /* in: lsn, must be within 4 GB of
 
506
        ib_uint64_t     lsn,    /* in: lsn, must be within 4 GB of
507
507
                                group->lsn */
508
508
        log_group_t*    group)  /* in: log group */
509
509
{
510
 
        dulint          gr_lsn;
511
 
        ib_longlong     gr_lsn_size_offset;
512
 
        ib_longlong     difference;
513
 
        ib_longlong     group_size;
514
 
        ib_longlong     offset;
 
510
        ib_uint64_t     gr_lsn;
 
511
        ib_int64_t      gr_lsn_size_offset;
 
512
        ib_int64_t      difference;
 
513
        ib_int64_t      group_size;
 
514
        ib_int64_t      offset;
515
515
 
516
516
        ut_ad(mutex_own(&(log_sys->mutex)));
517
517
 
520
520
 
521
521
        gr_lsn = group->lsn;
522
522
 
523
 
        gr_lsn_size_offset = (ib_longlong)
 
523
        gr_lsn_size_offset = (ib_int64_t)
524
524
                log_group_calc_size_offset(group->lsn_offset, group);
525
525
 
526
 
        group_size = (ib_longlong) log_group_get_capacity(group);
527
 
 
528
 
        if (ut_dulint_cmp(lsn, gr_lsn) >= 0) {
529
 
 
530
 
                difference = (ib_longlong) ut_dulint_minus(lsn, gr_lsn);
 
526
        group_size = (ib_int64_t) log_group_get_capacity(group);
 
527
 
 
528
        if (lsn >= gr_lsn) {
 
529
 
 
530
                difference = (ib_int64_t) (lsn - gr_lsn);
531
531
        } else {
532
 
                difference = (ib_longlong) ut_dulint_minus(gr_lsn, lsn);
 
532
                difference = (ib_int64_t) (gr_lsn - lsn);
533
533
 
534
534
                difference = difference % group_size;
535
535
 
538
538
 
539
539
        offset = (gr_lsn_size_offset + difference) % group_size;
540
540
 
541
 
        ut_a(offset < (((ib_longlong) 1) << 32)); /* offset must be < 4 GB */
 
541
        ut_a(offset < (((ib_int64_t) 1) << 32)); /* offset must be < 4 GB */
542
542
 
543
543
        /* fprintf(stderr,
544
544
        "Offset is %lu gr_lsn_offset is %lu difference is %lu\n",
550
550
 
551
551
/***********************************************************************
552
552
Calculates where in log files we find a specified lsn. */
553
 
 
 
553
UNIV_INTERN
554
554
ulint
555
555
log_calc_where_lsn_is(
556
556
/*==================*/
557
557
                                                /* out: log file number */
558
 
        ib_longlong*    log_file_offset,        /* out: offset in that file
 
558
        ib_int64_t*     log_file_offset,        /* out: offset in that file
559
559
                                                (including the header) */
560
 
        dulint          first_header_lsn,       /* in: first log file start
 
560
        ib_uint64_t     first_header_lsn,       /* in: first log file start
561
561
                                                lsn */
562
 
        dulint          lsn,                    /* in: lsn whose position to
 
562
        ib_uint64_t     lsn,                    /* in: lsn whose position to
563
563
                                                determine */
564
564
        ulint           n_log_files,            /* in: total number of log
565
565
                                                files */
566
 
        ib_longlong     log_file_size)          /* in: log file size
 
566
        ib_int64_t      log_file_size)          /* in: log file size
567
567
                                                (including the header) */
568
568
{
569
 
        ib_longlong     ib_lsn;
570
 
        ib_longlong     ib_first_header_lsn;
571
 
        ib_longlong     capacity        = log_file_size - LOG_FILE_HDR_SIZE;
 
569
        ib_int64_t      capacity        = log_file_size - LOG_FILE_HDR_SIZE;
572
570
        ulint           file_no;
573
 
        ib_longlong     add_this_many;
574
 
 
575
 
        ib_lsn = ut_conv_dulint_to_longlong(lsn);
576
 
        ib_first_header_lsn = ut_conv_dulint_to_longlong(first_header_lsn);
577
 
 
578
 
        if (ib_lsn < ib_first_header_lsn) {
579
 
                add_this_many = 1 + (ib_first_header_lsn - ib_lsn)
580
 
                        / (capacity * (ib_longlong)n_log_files);
581
 
                ib_lsn += add_this_many
582
 
                        * capacity * (ib_longlong)n_log_files;
 
571
        ib_int64_t      add_this_many;
 
572
 
 
573
        if (lsn < first_header_lsn) {
 
574
                add_this_many = 1 + (first_header_lsn - lsn)
 
575
                        / (capacity * (ib_int64_t)n_log_files);
 
576
                lsn += add_this_many
 
577
                        * capacity * (ib_int64_t)n_log_files;
583
578
        }
584
579
 
585
 
        ut_a(ib_lsn >= ib_first_header_lsn);
 
580
        ut_a(lsn >= first_header_lsn);
586
581
 
587
 
        file_no = ((ulint)((ib_lsn - ib_first_header_lsn) / capacity))
 
582
        file_no = ((ulint)((lsn - first_header_lsn) / capacity))
588
583
                % n_log_files;
589
 
        *log_file_offset = (ib_lsn - ib_first_header_lsn) % capacity;
 
584
        *log_file_offset = (lsn - first_header_lsn) % capacity;
590
585
 
591
586
        *log_file_offset = *log_file_offset + LOG_FILE_HDR_SIZE;
592
587
 
597
592
Sets the field values in group to correspond to a given lsn. For this function
598
593
to work, the values must already be correctly initialized to correspond to
599
594
some lsn, for instance, a checkpoint lsn. */
600
 
 
 
595
UNIV_INTERN
601
596
void
602
597
log_group_set_fields(
603
598
/*=================*/
604
599
        log_group_t*    group,  /* in: group */
605
 
        dulint          lsn)    /* in: lsn for which the values should be
 
600
        ib_uint64_t     lsn)    /* in: lsn for which the values should be
606
601
                                set */
607
602
{
608
603
        group->lsn_offset = log_group_calc_lsn_offset(lsn, group);
726
721
 
727
722
/**********************************************************
728
723
Initializes the log. */
729
 
 
 
724
UNIV_INTERN
730
725
void
731
726
log_init(void)
732
727
/*==========*/
767
762
 
768
763
        log_sys->buf_next_to_write = 0;
769
764
 
770
 
        log_sys->write_lsn = ut_dulint_zero;
771
 
        log_sys->current_flush_lsn = ut_dulint_zero;
772
 
        log_sys->flushed_to_disk_lsn = ut_dulint_zero;
 
765
        log_sys->write_lsn = 0;
 
766
        log_sys->current_flush_lsn = 0;
 
767
        log_sys->flushed_to_disk_lsn = 0;
773
768
 
774
769
        log_sys->written_to_some_lsn = log_sys->lsn;
775
770
        log_sys->written_to_all_lsn = log_sys->lsn;
787
782
        /*----------------------------*/
788
783
        log_sys->adm_checkpoint_interval = ULINT_MAX;
789
784
 
790
 
        log_sys->next_checkpoint_no = ut_dulint_zero;
 
785
        log_sys->next_checkpoint_no = 0;
791
786
        log_sys->last_checkpoint_lsn = log_sys->lsn;
792
787
        log_sys->n_pending_checkpoint_writes = 0;
793
788
 
803
798
        /* Under MySQL, log archiving is always off */
804
799
        log_sys->archiving_state = LOG_ARCH_OFF;
805
800
        log_sys->archived_lsn = log_sys->lsn;
806
 
        log_sys->next_archived_lsn = ut_dulint_zero;
 
801
        log_sys->next_archived_lsn = 0;
807
802
 
808
803
        log_sys->n_pending_archive_ios = 0;
809
804
 
828
823
        log_block_set_first_rec_group(log_sys->buf, LOG_BLOCK_HDR_SIZE);
829
824
 
830
825
        log_sys->buf_free = LOG_BLOCK_HDR_SIZE;
831
 
        log_sys->lsn = ut_dulint_add(LOG_START_LSN, LOG_BLOCK_HDR_SIZE);
 
826
        log_sys->lsn = LOG_START_LSN + LOG_BLOCK_HDR_SIZE;
832
827
 
833
828
        mutex_exit(&(log_sys->mutex));
834
829
 
840
835
        recv_sys->scanned_lsn = log_sys->lsn;
841
836
        recv_sys->scanned_checkpoint_no = 0;
842
837
        recv_sys->recovered_lsn = log_sys->lsn;
843
 
        recv_sys->limit_lsn = ut_dulint_max;
 
838
        recv_sys->limit_lsn = IB_ULONGLONG_MAX;
844
839
#endif
845
840
}
846
841
 
847
842
/**********************************************************************
848
843
Inits a log group to the log system. */
849
 
 
 
844
UNIV_INTERN
850
845
void
851
846
log_group_init(
852
847
/*===========*/
1027
1022
 
1028
1023
/**********************************************************
1029
1024
Completes an i/o to a log file. */
1030
 
 
 
1025
UNIV_INTERN
1031
1026
void
1032
1027
log_io_complete(
1033
1028
/*============*/
1102
1097
        log_group_t*    group,          /* in: log group */
1103
1098
        ulint           nth_file,       /* in: header to the nth file in the
1104
1099
                                        log file space */
1105
 
        dulint          start_lsn)      /* in: log file data starts at this
 
1100
        ib_uint64_t     start_lsn)      /* in: log file data starts at this
1106
1101
                                        lsn */
1107
1102
{
1108
1103
        byte*   buf;
1114
1109
        buf = *(group->file_header_bufs + nth_file);
1115
1110
 
1116
1111
        mach_write_to_4(buf + LOG_GROUP_ID, group->id);
1117
 
        mach_write_to_8(buf + LOG_FILE_START_LSN, start_lsn);
 
1112
        mach_write_ull(buf + LOG_FILE_START_LSN, start_lsn);
1118
1113
 
1119
1114
        /* Wipe over possible label of ibbackup --restore */
1120
1115
        memcpy(buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, "    ", 4);
1133
1128
 
1134
1129
                srv_os_log_pending_writes++;
1135
1130
 
1136
 
                fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE, group->space_id,
 
1131
                fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE, group->space_id, 0,
1137
1132
                       dest_offset / UNIV_PAGE_SIZE,
1138
1133
                       dest_offset % UNIV_PAGE_SIZE,
1139
1134
                       OS_FILE_LOG_BLOCK_SIZE,
1158
1153
 
1159
1154
/**********************************************************
1160
1155
Writes a buffer to a log file group. */
1161
 
 
 
1156
UNIV_INTERN
1162
1157
void
1163
1158
log_group_write_buf(
1164
1159
/*================*/
1166
1161
        byte*           buf,            /* in: buffer */
1167
1162
        ulint           len,            /* in: buffer len; must be divisible
1168
1163
                                        by OS_FILE_LOG_BLOCK_SIZE */
1169
 
        dulint          start_lsn,      /* in: start lsn of the buffer; must
 
1164
        ib_uint64_t     start_lsn,      /* in: start lsn of the buffer; must
1170
1165
                                        be divisible by
1171
1166
                                        OS_FILE_LOG_BLOCK_SIZE */
1172
1167
        ulint           new_data_offset)/* in: start offset of new data in
1181
1176
 
1182
1177
        ut_ad(mutex_own(&(log_sys->mutex)));
1183
1178
        ut_a(len % OS_FILE_LOG_BLOCK_SIZE == 0);
1184
 
        ut_a(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
 
1179
        ut_a(((ulint) start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
1185
1180
 
1186
1181
        if (new_data_offset == 0) {
1187
1182
                write_header = TRUE;
1221
1216
                fprintf(stderr,
1222
1217
                        "Writing log file segment to group %lu"
1223
1218
                        " offset %lu len %lu\n"
1224
 
                        "start lsn %lu %lu\n"
 
1219
                        "start lsn %"PRIu64"\n"
1225
1220
                        "First block n:o %lu last block n:o %lu\n",
1226
1221
                        (ulong) group->id, (ulong) next_offset,
1227
1222
                        (ulong) write_len,
1228
 
                        (ulong) ut_dulint_get_high(start_lsn),
1229
 
                        (ulong) ut_dulint_get_low(start_lsn),
 
1223
                        start_lsn,
1230
1224
                        (ulong) log_block_get_hdr_no(buf),
1231
1225
                        (ulong) log_block_get_hdr_no(
1232
1226
                                buf + write_len - OS_FILE_LOG_BLOCK_SIZE));
1253
1247
 
1254
1248
                srv_os_log_pending_writes++;
1255
1249
 
1256
 
                fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE, group->space_id,
 
1250
                fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE, group->space_id, 0,
1257
1251
                       next_offset / UNIV_PAGE_SIZE,
1258
1252
                       next_offset % UNIV_PAGE_SIZE, write_len, buf, group);
1259
1253
 
1264
1258
        }
1265
1259
 
1266
1260
        if (write_len < len) {
1267
 
                start_lsn = ut_dulint_add(start_lsn, write_len);
 
1261
                start_lsn += write_len;
1268
1262
                len -= write_len;
1269
1263
                buf += write_len;
1270
1264
 
1279
1273
that the log has been written to the log file up to the last log entry written
1280
1274
by the transaction. If there is a flush running, it waits and checks if the
1281
1275
flush flushed enough. If not, starts a new flush. */
1282
 
 
 
1276
UNIV_INTERN
1283
1277
void
1284
1278
log_write_up_to(
1285
1279
/*============*/
1286
 
        dulint  lsn,    /* in: log sequence number up to which the log should
1287
 
                        be written, ut_dulint_max if not specified */
1288
 
        ulint   wait,   /* in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
1289
 
                        or LOG_WAIT_ALL_GROUPS */
1290
 
        ibool   flush_to_disk)
1291
 
                        /* in: TRUE if we want the written log also to be
1292
 
                        flushed to disk */
 
1280
        ib_uint64_t     lsn,    /* in: log sequence number up to which
 
1281
                                the log should be written,
 
1282
                                IB_ULONGLONG_MAX if not specified */
 
1283
        ulint           wait,   /* in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
 
1284
                                or LOG_WAIT_ALL_GROUPS */
 
1285
        ibool           flush_to_disk)
 
1286
                                /* in: TRUE if we want the written log
 
1287
                                also to be flushed to disk */
1293
1288
{
1294
1289
        log_group_t*    group;
1295
1290
        ulint           start_offset;
1324
1319
        mutex_enter(&(log_sys->mutex));
1325
1320
 
1326
1321
        if (flush_to_disk
1327
 
            && ut_dulint_cmp(log_sys->flushed_to_disk_lsn, lsn) >= 0) {
 
1322
            && log_sys->flushed_to_disk_lsn >= lsn) {
1328
1323
 
1329
1324
                mutex_exit(&(log_sys->mutex));
1330
1325
 
1332
1327
        }
1333
1328
 
1334
1329
        if (!flush_to_disk
1335
 
            && (ut_dulint_cmp(log_sys->written_to_all_lsn, lsn) >= 0
1336
 
                || (ut_dulint_cmp(log_sys->written_to_some_lsn, lsn)
1337
 
                    >= 0
 
1330
            && (log_sys->written_to_all_lsn >= lsn
 
1331
                || (log_sys->written_to_some_lsn >= lsn
1338
1332
                    && wait != LOG_WAIT_ALL_GROUPS))) {
1339
1333
 
1340
1334
                mutex_exit(&(log_sys->mutex));
1346
1340
                /* A write (+ possibly flush to disk) is running */
1347
1341
 
1348
1342
                if (flush_to_disk
1349
 
                    && ut_dulint_cmp(log_sys->current_flush_lsn, lsn)
1350
 
                    >= 0) {
 
1343
                    && log_sys->current_flush_lsn >= lsn) {
1351
1344
                        /* The write + flush will write enough: wait for it to
1352
1345
                        complete  */
1353
1346
 
1355
1348
                }
1356
1349
 
1357
1350
                if (!flush_to_disk
1358
 
                    && ut_dulint_cmp(log_sys->write_lsn, lsn) >= 0) {
 
1351
                    && log_sys->write_lsn >= lsn) {
1359
1352
                        /* The write will write enough: wait for it to
1360
1353
                        complete  */
1361
1354
 
1384
1377
#ifdef UNIV_DEBUG
1385
1378
        if (log_debug_writes) {
1386
1379
                fprintf(stderr,
1387
 
                        "Writing log from %lu %lu up to lsn %lu %lu\n",
1388
 
                        (ulong) ut_dulint_get_high(
1389
 
                                log_sys->written_to_all_lsn),
1390
 
                        (ulong) ut_dulint_get_low(
1391
 
                                log_sys->written_to_all_lsn),
1392
 
                        (ulong) ut_dulint_get_high(log_sys->lsn),
1393
 
                        (ulong) ut_dulint_get_low(log_sys->lsn));
 
1380
                        "Writing log from %"PRIu64" up to lsn %"PRIu64"\n",
 
1381
                        log_sys->written_to_all_lsn,
 
1382
                        log_sys->lsn);
1394
1383
        }
1395
1384
#endif /* UNIV_DEBUG */
1396
1385
        log_sys->n_pending_writes++;
1442
1431
                log_group_write_buf(
1443
1432
                        group, log_sys->buf + area_start,
1444
1433
                        area_end - area_start,
1445
 
                        ut_dulint_align_down(log_sys->written_to_all_lsn,
 
1434
                        ut_uint64_align_down(log_sys->written_to_all_lsn,
1446
1435
                                             OS_FILE_LOG_BLOCK_SIZE),
1447
1436
                        start_offset - area_start);
1448
1437
 
1489
1478
do_waits:
1490
1479
        mutex_exit(&(log_sys->mutex));
1491
1480
 
1492
 
        if (wait == LOG_WAIT_ONE_GROUP) {
 
1481
        switch (wait) {
 
1482
        case LOG_WAIT_ONE_GROUP:
1493
1483
                os_event_wait(log_sys->one_flushed_event);
1494
 
        } else if (wait == LOG_WAIT_ALL_GROUPS) {
 
1484
                break;
 
1485
        case LOG_WAIT_ALL_GROUPS:
1495
1486
                os_event_wait(log_sys->no_flush_event);
1496
 
        } else {
1497
 
                ut_ad(wait == LOG_NO_WAIT);
 
1487
                break;
 
1488
#ifdef UNIV_DEBUG
 
1489
        case LOG_NO_WAIT:
 
1490
                break;
 
1491
        default:
 
1492
                ut_error;
 
1493
#endif /* UNIV_DEBUG */
1498
1494
        }
1499
1495
}
1500
1496
 
1501
1497
/********************************************************************
1502
1498
Does a syncronous flush of the log buffer to disk. */
1503
 
 
 
1499
UNIV_INTERN
1504
1500
void
1505
1501
log_buffer_flush_to_disk(void)
1506
1502
/*==========================*/
1507
1503
{
1508
 
        dulint  lsn;
 
1504
        ib_uint64_t     lsn;
1509
1505
 
1510
1506
        mutex_enter(&(log_sys->mutex));
1511
1507
 
1524
1520
log_flush_margin(void)
1525
1521
/*==================*/
1526
1522
{
1527
 
        ibool   do_flush        = FALSE;
1528
 
        log_t*  log             = log_sys;
1529
 
        dulint  lsn;
 
1523
        log_t*          log     = log_sys;
 
1524
        ib_uint64_t     lsn     = 0;
1530
1525
 
1531
1526
        mutex_enter(&(log->mutex));
1532
1527
 
1536
1531
                        /* A flush is running: hope that it will provide enough
1537
1532
                        free space */
1538
1533
                } else {
1539
 
                        do_flush = TRUE;
1540
1534
                        lsn = log->lsn;
1541
1535
                }
1542
1536
        }
1543
1537
 
1544
1538
        mutex_exit(&(log->mutex));
1545
1539
 
1546
 
        if (do_flush) {
 
1540
        if (lsn) {
1547
1541
                log_write_up_to(lsn, LOG_NO_WAIT, FALSE);
1548
1542
        }
1549
1543
}
1552
1546
Advances the smallest lsn for which there are unflushed dirty blocks in the
1553
1547
buffer pool. NOTE: this function may only be called if the calling thread owns
1554
1548
no synchronization objects! */
1555
 
 
 
1549
UNIV_INTERN
1556
1550
ibool
1557
1551
log_preflush_pool_modified_pages(
1558
1552
/*=============================*/
1559
 
                                /* out: FALSE if there was a flush batch of
1560
 
                                the same type running, which means that we
1561
 
                                could not start this flush batch */
1562
 
        dulint  new_oldest,     /* in: try to advance oldest_modified_lsn
1563
 
                                at least to this lsn */
1564
 
        ibool   sync)           /* in: TRUE if synchronous operation is
1565
 
                                desired */
 
1553
                                        /* out: FALSE if there was a
 
1554
                                        flush batch of the same type
 
1555
                                        running, which means that we
 
1556
                                        could not start this flush
 
1557
                                        batch */
 
1558
        ib_uint64_t     new_oldest,     /* in: try to advance
 
1559
                                        oldest_modified_lsn at least
 
1560
                                        to this lsn */
 
1561
        ibool           sync)           /* in: TRUE if synchronous
 
1562
                                        operation is desired */
1566
1563
{
1567
1564
        ulint   n_pages;
1568
1565
 
1603
1600
        ut_ad(mutex_own(&(log_sys->mutex)));
1604
1601
        ut_ad(log_sys->n_pending_checkpoint_writes == 0);
1605
1602
 
1606
 
        log_sys->next_checkpoint_no
1607
 
                = ut_dulint_add(log_sys->next_checkpoint_no, 1);
 
1603
        log_sys->next_checkpoint_no++;
1608
1604
 
1609
1605
        log_sys->last_checkpoint_lsn = log_sys->next_checkpoint_lsn;
1610
1606
 
1652
1648
 
1653
1649
/***********************************************************************
1654
1650
Gets info from a checkpoint about a log group. */
1655
 
 
 
1651
UNIV_INTERN
1656
1652
void
1657
1653
log_checkpoint_get_nth_group_info(
1658
1654
/*==============================*/
1679
1675
{
1680
1676
        log_group_t*    group2;
1681
1677
#ifdef UNIV_LOG_ARCHIVE
1682
 
        dulint  archived_lsn;
1683
 
        dulint  next_archived_lsn;
 
1678
        ib_uint64_t     archived_lsn;
 
1679
        ib_uint64_t     next_archived_lsn;
1684
1680
#endif /* UNIV_LOG_ARCHIVE */
1685
 
        ulint   write_offset;
1686
 
        ulint   fold;
1687
 
        byte*   buf;
1688
 
        ulint   i;
 
1681
        ulint           write_offset;
 
1682
        ulint           fold;
 
1683
        byte*           buf;
 
1684
        ulint           i;
1689
1685
 
1690
1686
        ut_ad(mutex_own(&(log_sys->mutex)));
1691
1687
#if LOG_CHECKPOINT_SIZE > OS_FILE_LOG_BLOCK_SIZE
1694
1690
 
1695
1691
        buf = group->checkpoint_buf;
1696
1692
 
1697
 
        mach_write_to_8(buf + LOG_CHECKPOINT_NO, log_sys->next_checkpoint_no);
1698
 
        mach_write_to_8(buf + LOG_CHECKPOINT_LSN,
1699
 
                        log_sys->next_checkpoint_lsn);
 
1693
        mach_write_ull(buf + LOG_CHECKPOINT_NO, log_sys->next_checkpoint_no);
 
1694
        mach_write_ull(buf + LOG_CHECKPOINT_LSN, log_sys->next_checkpoint_lsn);
1700
1695
 
1701
1696
        mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,
1702
1697
                        log_group_calc_lsn_offset(
1706
1701
 
1707
1702
#ifdef UNIV_LOG_ARCHIVE
1708
1703
        if (log_sys->archiving_state == LOG_ARCH_OFF) {
1709
 
                archived_lsn = ut_dulint_max;
 
1704
                archived_lsn = IB_ULONGLONG_MAX;
1710
1705
        } else {
1711
1706
                archived_lsn = log_sys->archived_lsn;
1712
1707
 
1713
 
                if (0 != ut_dulint_cmp(archived_lsn,
1714
 
                                       log_sys->next_archived_lsn)) {
 
1708
                if (archived_lsn != log_sys->next_archived_lsn) {
1715
1709
                        next_archived_lsn = log_sys->next_archived_lsn;
1716
1710
                        /* For debugging only */
1717
1711
                }
1718
1712
        }
1719
1713
 
1720
 
        mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn);
 
1714
        mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn);
1721
1715
#else /* UNIV_LOG_ARCHIVE */
1722
 
        mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, ut_dulint_max);
 
1716
        mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
1723
1717
#endif /* UNIV_LOG_ARCHIVE */
1724
1718
 
1725
1719
        for (i = 0; i < LOG_MAX_N_GROUPS; i++) {
1760
1754
        /* We alternate the physical place of the checkpoint info in the first
1761
1755
        log file */
1762
1756
 
1763
 
        if (ut_dulint_get_low(log_sys->next_checkpoint_no) % 2 == 0) {
 
1757
        if ((log_sys->next_checkpoint_no & 1) == 0) {
1764
1758
                write_offset = LOG_CHECKPOINT_1;
1765
1759
        } else {
1766
1760
                write_offset = LOG_CHECKPOINT_2;
1781
1775
                added with 1, as we want to distinguish between a normal log
1782
1776
                file write and a checkpoint field write */
1783
1777
 
1784
 
                fil_io(OS_FILE_WRITE | OS_FILE_LOG, FALSE, group->space_id,
 
1778
                fil_io(OS_FILE_WRITE | OS_FILE_LOG, FALSE, group->space_id, 0,
1785
1779
                       write_offset / UNIV_PAGE_SIZE,
1786
1780
                       write_offset % UNIV_PAGE_SIZE,
1787
1781
                       OS_FILE_LOG_BLOCK_SIZE,
1794
1788
/**********************************************************
1795
1789
Writes info to a buffer of a log group when log files are created in
1796
1790
backup restoration. */
1797
 
 
 
1791
UNIV_INTERN
1798
1792
void
1799
1793
log_reset_first_header_and_checkpoint(
1800
1794
/*==================================*/
1801
 
        byte*   hdr_buf,/* in: buffer which will be written to the start
1802
 
                        of the first log file */
1803
 
        dulint  start)  /* in: lsn of the start of the first log file;
1804
 
                        we pretend that there is a checkpoint at
1805
 
                        start + LOG_BLOCK_HDR_SIZE */
 
1795
        byte*           hdr_buf,/* in: buffer which will be written to the
 
1796
                                start of the first log file */
 
1797
        ib_uint64_t     start)  /* in: lsn of the start of the first log file;
 
1798
                                we pretend that there is a checkpoint at
 
1799
                                start + LOG_BLOCK_HDR_SIZE */
1806
1800
{
1807
 
        ulint   fold;
1808
 
        byte*   buf;
1809
 
        dulint  lsn;
 
1801
        ulint           fold;
 
1802
        byte*           buf;
 
1803
        ib_uint64_t     lsn;
1810
1804
 
1811
1805
        mach_write_to_4(hdr_buf + LOG_GROUP_ID, 0);
1812
 
        mach_write_to_8(hdr_buf + LOG_FILE_START_LSN, start);
 
1806
        mach_write_ull(hdr_buf + LOG_FILE_START_LSN, start);
1813
1807
 
1814
 
        lsn = ut_dulint_add(start, LOG_BLOCK_HDR_SIZE);
 
1808
        lsn = start + LOG_BLOCK_HDR_SIZE;
1815
1809
 
1816
1810
        /* Write the label of ibbackup --restore */
1817
1811
        strcpy((char*) hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
1821
1815
                                + (sizeof "ibbackup ") - 1));
1822
1816
        buf = hdr_buf + LOG_CHECKPOINT_1;
1823
1817
 
1824
 
        mach_write_to_8(buf + LOG_CHECKPOINT_NO, ut_dulint_zero);
1825
 
        mach_write_to_8(buf + LOG_CHECKPOINT_LSN, lsn);
 
1818
        mach_write_ull(buf + LOG_CHECKPOINT_NO, 0);
 
1819
        mach_write_ull(buf + LOG_CHECKPOINT_LSN, lsn);
1826
1820
 
1827
1821
        mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,
1828
1822
                        LOG_FILE_HDR_SIZE + LOG_BLOCK_HDR_SIZE);
1829
1823
 
1830
1824
        mach_write_to_4(buf + LOG_CHECKPOINT_LOG_BUF_SIZE, 2 * 1024 * 1024);
1831
1825
 
1832
 
        mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, ut_dulint_max);
 
1826
        mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
1833
1827
 
1834
1828
        fold = ut_fold_binary(buf, LOG_CHECKPOINT_CHECKSUM_1);
1835
1829
        mach_write_to_4(buf + LOG_CHECKPOINT_CHECKSUM_1, fold);
1845
1839
 
1846
1840
/**********************************************************
1847
1841
Reads a checkpoint info from a log group header to log_sys->checkpoint_buf. */
1848
 
 
 
1842
UNIV_INTERN
1849
1843
void
1850
1844
log_group_read_checkpoint_info(
1851
1845
/*===========================*/
1856
1850
 
1857
1851
        log_sys->n_log_ios++;
1858
1852
 
1859
 
        fil_io(OS_FILE_READ | OS_FILE_LOG, TRUE, group->space_id,
 
1853
        fil_io(OS_FILE_READ | OS_FILE_LOG, TRUE, group->space_id, 0,
1860
1854
               field / UNIV_PAGE_SIZE, field % UNIV_PAGE_SIZE,
1861
1855
               OS_FILE_LOG_BLOCK_SIZE, log_sys->checkpoint_buf, NULL);
1862
1856
}
1863
1857
 
1864
1858
/**********************************************************
1865
1859
Writes checkpoint info to groups. */
1866
 
 
 
1860
UNIV_INTERN
1867
1861
void
1868
1862
log_groups_write_checkpoint_info(void)
1869
1863
/*==================================*/
1886
1880
blocks from the buffer pool: it only checks what is lsn of the oldest
1887
1881
modification in the pool, and writes information about the lsn in
1888
1882
log files. Use log_make_checkpoint_at to flush also the pool. */
1889
 
 
 
1883
UNIV_INTERN
1890
1884
ibool
1891
1885
log_checkpoint(
1892
1886
/*===========*/
1901
1895
                                parameter TRUE, a physical write will always be
1902
1896
                                made to log files */
1903
1897
{
1904
 
        dulint  oldest_lsn;
 
1898
        ib_uint64_t     oldest_lsn;
1905
1899
 
1906
1900
        if (recv_recovery_is_on()) {
1907
1901
                recv_apply_hashed_log_recs(TRUE);
1930
1924
        mutex_enter(&(log_sys->mutex));
1931
1925
 
1932
1926
        if (!write_always
1933
 
            && ut_dulint_cmp(log_sys->last_checkpoint_lsn, oldest_lsn) >= 0) {
 
1927
            && log_sys->last_checkpoint_lsn >= oldest_lsn) {
1934
1928
 
1935
1929
                mutex_exit(&(log_sys->mutex));
1936
1930
 
1937
1931
                return(TRUE);
1938
1932
        }
1939
1933
 
1940
 
        ut_ad(ut_dulint_cmp(log_sys->written_to_all_lsn, oldest_lsn) >= 0);
 
1934
        ut_ad(log_sys->written_to_all_lsn >= oldest_lsn);
1941
1935
 
1942
1936
        if (log_sys->n_pending_checkpoint_writes > 0) {
1943
1937
                /* A checkpoint write is running */
1957
1951
 
1958
1952
#ifdef UNIV_DEBUG
1959
1953
        if (log_debug_writes) {
1960
 
                fprintf(stderr, "Making checkpoint no %lu at lsn %lu %lu\n",
1961
 
                        (ulong) ut_dulint_get_low(log_sys->next_checkpoint_no),
1962
 
                        (ulong) ut_dulint_get_high(oldest_lsn),
1963
 
                        (ulong) ut_dulint_get_low(oldest_lsn));
 
1954
                fprintf(stderr, "Making checkpoint no %lu at lsn %"PRIu64"\n",
 
1955
                        (ulong) log_sys->next_checkpoint_no,
 
1956
                        oldest_lsn);
1964
1957
        }
1965
1958
#endif /* UNIV_DEBUG */
1966
1959
 
1979
1972
 
1980
1973
/********************************************************************
1981
1974
Makes a checkpoint at a given lsn or later. */
1982
 
 
 
1975
UNIV_INTERN
1983
1976
void
1984
1977
log_make_checkpoint_at(
1985
1978
/*===================*/
1986
 
        dulint  lsn,            /* in: make a checkpoint at this or a later
1987
 
                                lsn, if ut_dulint_max, makes a checkpoint at
1988
 
                                the latest lsn */
1989
 
        ibool   write_always)   /* in: the function normally checks if the
1990
 
                                the new checkpoint would have a greater
1991
 
                                lsn than the previous one: if not, then no
1992
 
                                physical write is done; by setting this
1993
 
                                parameter TRUE, a physical write will always be
1994
 
                                made to log files */
 
1979
        ib_uint64_t     lsn,            /* in: make a checkpoint at this or a
 
1980
                                        later lsn, if IB_ULONGLONG_MAX, makes
 
1981
                                        a checkpoint at the latest lsn */
 
1982
        ibool           write_always)   /* in: the function normally checks if
 
1983
                                        the the new checkpoint would have a
 
1984
                                        greater lsn than the previous one: if
 
1985
                                        not, then no physical write is done;
 
1986
                                        by setting this parameter TRUE, a
 
1987
                                        physical write will always be made to
 
1988
                                        log files */
1995
1989
{
1996
 
        ibool   success;
1997
 
 
1998
1990
        /* Preflush pages synchronously */
1999
1991
 
2000
 
        success = FALSE;
2001
 
 
2002
 
        while (!success) {
2003
 
                success = log_preflush_pool_modified_pages(lsn, TRUE);
2004
 
        }
2005
 
 
2006
 
        success = FALSE;
2007
 
 
2008
 
        while (!success) {
2009
 
                success = log_checkpoint(TRUE, write_always);
2010
 
        }
 
1992
        while (!log_preflush_pool_modified_pages(lsn, TRUE));
 
1993
 
 
1994
        while (!log_checkpoint(TRUE, write_always));
2011
1995
}
2012
1996
 
2013
1997
/********************************************************************
2020
2004
log_checkpoint_margin(void)
2021
2005
/*=======================*/
2022
2006
{
2023
 
        log_t*  log             = log_sys;
2024
 
        ulint   age;
2025
 
        ulint   checkpoint_age;
2026
 
        ulint   advance;
2027
 
        dulint  oldest_lsn;
2028
 
        ibool   sync;
2029
 
        ibool   checkpoint_sync;
2030
 
        ibool   do_checkpoint;
2031
 
        ibool   success;
 
2007
        log_t*          log             = log_sys;
 
2008
        ib_uint64_t     age;
 
2009
        ib_uint64_t     checkpoint_age;
 
2010
        ib_uint64_t     advance;
 
2011
        ib_uint64_t     oldest_lsn;
 
2012
        ibool           sync;
 
2013
        ibool           checkpoint_sync;
 
2014
        ibool           do_checkpoint;
 
2015
        ibool           success;
2032
2016
loop:
2033
2017
        sync = FALSE;
2034
2018
        checkpoint_sync = FALSE;
2044
2028
 
2045
2029
        oldest_lsn = log_buf_pool_get_oldest_modification();
2046
2030
 
2047
 
        age = ut_dulint_minus(log->lsn, oldest_lsn);
 
2031
        age = log->lsn - oldest_lsn;
2048
2032
 
2049
2033
        if (age > log->max_modified_age_sync) {
2050
2034
 
2060
2044
                advance = 0;
2061
2045
        }
2062
2046
 
2063
 
        checkpoint_age = ut_dulint_minus(log->lsn, log->last_checkpoint_lsn);
 
2047
        checkpoint_age = log->lsn - log->last_checkpoint_lsn;
2064
2048
 
2065
2049
        if (checkpoint_age > log->max_checkpoint_age) {
2066
2050
                /* A checkpoint is urgent: we do it synchronously */
2082
2066
        mutex_exit(&(log->mutex));
2083
2067
 
2084
2068
        if (advance) {
2085
 
                dulint  new_oldest = ut_dulint_add(oldest_lsn, advance);
 
2069
                ib_uint64_t     new_oldest = oldest_lsn + advance;
2086
2070
 
2087
2071
                success = log_preflush_pool_modified_pages(new_oldest, sync);
2088
2072
 
2114
2098
 
2115
2099
/**********************************************************
2116
2100
Reads a specified log segment to a buffer. */
2117
 
 
 
2101
UNIV_INTERN
2118
2102
void
2119
2103
log_group_read_log_seg(
2120
2104
/*===================*/
2121
2105
        ulint           type,           /* in: LOG_ARCHIVE or LOG_RECOVER */
2122
2106
        byte*           buf,            /* in: buffer where to read */
2123
2107
        log_group_t*    group,          /* in: log group */
2124
 
        dulint          start_lsn,      /* in: read area start */
2125
 
        dulint          end_lsn)        /* in: read area end */
 
2108
        ib_uint64_t     start_lsn,      /* in: read area start */
 
2109
        ib_uint64_t     end_lsn)        /* in: read area end */
2126
2110
{
2127
2111
        ulint   len;
2128
2112
        ulint   source_offset;
2130
2114
 
2131
2115
        ut_ad(mutex_own(&(log_sys->mutex)));
2132
2116
 
2133
 
        sync = FALSE;
2134
 
 
2135
 
        if (type == LOG_RECOVER) {
2136
 
                sync = TRUE;
2137
 
        }
 
2117
        sync = (type == LOG_RECOVER);
2138
2118
loop:
2139
2119
        source_offset = log_group_calc_lsn_offset(start_lsn, group);
2140
2120
 
2141
 
        len = ut_dulint_minus(end_lsn, start_lsn);
 
2121
        len = (ulint) (end_lsn - start_lsn);
2142
2122
 
2143
2123
        ut_ad(len != 0);
2144
2124
 
2156
2136
 
2157
2137
        log_sys->n_log_ios++;
2158
2138
 
2159
 
        fil_io(OS_FILE_READ | OS_FILE_LOG, sync, group->space_id,
 
2139
        fil_io(OS_FILE_READ | OS_FILE_LOG, sync, group->space_id, 0,
2160
2140
               source_offset / UNIV_PAGE_SIZE, source_offset % UNIV_PAGE_SIZE,
2161
2141
               len, buf, NULL);
2162
2142
 
2163
 
        start_lsn = ut_dulint_add(start_lsn, len);
 
2143
        start_lsn += len;
2164
2144
        buf += len;
2165
2145
 
2166
 
        if (ut_dulint_cmp(start_lsn, end_lsn) != 0) {
 
2146
        if (start_lsn != end_lsn) {
2167
2147
 
2168
2148
                goto loop;
2169
2149
        }
2172
2152
#ifdef UNIV_LOG_ARCHIVE
2173
2153
/**********************************************************
2174
2154
Generates an archived log file name. */
2175
 
 
 
2155
UNIV_INTERN
2176
2156
void
2177
2157
log_archived_file_name_gen(
2178
2158
/*=======================*/
2195
2175
        ulint           nth_file,       /* in: header to the nth file in the
2196
2176
                                        archive log file space */
2197
2177
        ulint           file_no,        /* in: archived file number */
2198
 
        dulint          start_lsn)      /* in: log file data starts at this
 
2178
        ib_uint64_t     start_lsn)      /* in: log file data starts at this
2199
2179
                                        lsn */
2200
2180
{
2201
2181
        byte*   buf;
2208
2188
        buf = *(group->archive_file_header_bufs + nth_file);
2209
2189
 
2210
2190
        mach_write_to_4(buf + LOG_GROUP_ID, group->id);
2211
 
        mach_write_to_8(buf + LOG_FILE_START_LSN, start_lsn);
 
2191
        mach_write_ull(buf + LOG_FILE_START_LSN, start_lsn);
2212
2192
        mach_write_to_4(buf + LOG_FILE_NO, file_no);
2213
2193
 
2214
2194
        mach_write_to_4(buf + LOG_FILE_ARCH_COMPLETED, FALSE);
2233
2213
        log_group_t*    group,          /* in: log group */
2234
2214
        ulint           nth_file,       /* in: header to the nth file in the
2235
2215
                                        archive log file space */
2236
 
        dulint          end_lsn)        /* in: end lsn of the file */
 
2216
        ib_uint64_t     end_lsn)        /* in: end lsn of the file */
2237
2217
{
2238
2218
        byte*   buf;
2239
2219
        ulint   dest_offset;
2244
2224
        buf = *(group->archive_file_header_bufs + nth_file);
2245
2225
 
2246
2226
        mach_write_to_4(buf + LOG_FILE_ARCH_COMPLETED, TRUE);
2247
 
        mach_write_to_8(buf + LOG_FILE_END_LSN, end_lsn);
 
2227
        mach_write_ull(buf + LOG_FILE_END_LSN, end_lsn);
2248
2228
 
2249
2229
        dest_offset = nth_file * group->file_size + LOG_FILE_ARCH_COMPLETED;
2250
2230
 
2266
2246
/*==============*/
2267
2247
        log_group_t*    group)  /* in: log group */
2268
2248
{
2269
 
        os_file_t file_handle;
2270
 
        dulint  start_lsn;
2271
 
        dulint  end_lsn;
2272
 
        char    name[1024];
2273
 
        byte*   buf;
2274
 
        ulint   len;
2275
 
        ibool   ret;
2276
 
        ulint   next_offset;
2277
 
        ulint   n_files;
2278
 
        ulint   open_mode;
 
2249
        os_file_t        file_handle;
 
2250
        ib_uint64_t     start_lsn;
 
2251
        ib_uint64_t     end_lsn;
 
2252
        char            name[1024];
 
2253
        byte*           buf;
 
2254
        ulint           len;
 
2255
        ibool           ret;
 
2256
        ulint           next_offset;
 
2257
        ulint           n_files;
 
2258
        ulint           open_mode;
2279
2259
 
2280
2260
        ut_ad(mutex_own(&(log_sys->mutex)));
2281
2261
 
2282
2262
        start_lsn = log_sys->archived_lsn;
2283
2263
 
2284
 
        ut_a(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
 
2264
        ut_a(start_lsn % OS_FILE_LOG_BLOCK_SIZE == 0);
2285
2265
 
2286
2266
        end_lsn = log_sys->next_archived_lsn;
2287
2267
 
2288
 
        ut_a(ut_dulint_get_low(end_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
 
2268
        ut_a(end_lsn % OS_FILE_LOG_BLOCK_SIZE == 0);
2289
2269
 
2290
2270
        buf = log_sys->archive_buf;
2291
2271
 
2354
2334
                }
2355
2335
        }
2356
2336
 
2357
 
        len = ut_dulint_minus(end_lsn, start_lsn);
 
2337
        len = end_lsn - start_lsn;
2358
2338
 
2359
2339
        if (group->file_size < (next_offset % group->file_size) + len) {
2360
2340
 
2364
2344
#ifdef UNIV_DEBUG
2365
2345
        if (log_debug_writes) {
2366
2346
                fprintf(stderr,
2367
 
                        "Archiving starting at lsn %lu %lu, len %lu"
 
2347
                        "Archiving starting at lsn %"PRIu64", len %lu"
2368
2348
                        " to group %lu\n",
2369
 
                        (ulong) ut_dulint_get_high(start_lsn),
2370
 
                        (ulong) ut_dulint_get_low(start_lsn),
 
2349
                        start_lsn,
2371
2350
                        (ulong) len, (ulong) group->id);
2372
2351
        }
2373
2352
#endif /* UNIV_DEBUG */
2381
2360
               ut_calc_align(len, OS_FILE_LOG_BLOCK_SIZE), buf,
2382
2361
               &log_archive_io);
2383
2362
 
2384
 
        start_lsn = ut_dulint_add(start_lsn, len);
 
2363
        start_lsn += len;
2385
2364
        next_offset += len;
2386
2365
        buf += len;
2387
2366
 
2389
2368
                n_files++;
2390
2369
        }
2391
2370
 
2392
 
        if (ut_dulint_cmp(end_lsn, start_lsn) != 0) {
 
2371
        if (end_lsn != start_lsn) {
2393
2372
 
2394
2373
                goto loop;
2395
2374
        }
2429
2408
        ulint           end_offset;
2430
2409
        ulint           trunc_files;
2431
2410
        ulint           n_files;
2432
 
        dulint          start_lsn;
2433
 
        dulint          end_lsn;
 
2411
        ib_uint64_t     start_lsn;
 
2412
        ib_uint64_t     end_lsn;
2434
2413
        ulint           i;
2435
2414
 
2436
2415
        ut_ad(mutex_own(&(log_sys->mutex)));
2466
2445
#endif /* UNIV_DEBUG */
2467
2446
 
2468
2447
        /* Calculate the archive file space start lsn */
2469
 
        start_lsn = ut_dulint_subtract(
2470
 
                log_sys->next_archived_lsn,
2471
 
                end_offset - LOG_FILE_HDR_SIZE + trunc_files
2472
 
                * (group->file_size - LOG_FILE_HDR_SIZE));
 
2448
        start_lsn = log_sys->next_archived_lsn
 
2449
                - (end_offset - LOG_FILE_HDR_SIZE + trunc_files
 
2450
                   * (group->file_size - LOG_FILE_HDR_SIZE));
2473
2451
        end_lsn = start_lsn;
2474
2452
 
2475
2453
        for (i = 0; i < trunc_files; i++) {
2476
2454
 
2477
 
                end_lsn = ut_dulint_add(end_lsn,
2478
 
                                        group->file_size - LOG_FILE_HDR_SIZE);
 
2455
                end_lsn += group->file_size - LOG_FILE_HDR_SIZE;
2479
2456
 
2480
2457
                /* Write a notice to the headers of archived log
2481
2458
                files that the file write has been completed */
2559
2536
 
2560
2537
/************************************************************************
2561
2538
Starts an archiving operation. */
2562
 
 
 
2539
UNIV_INTERN
2563
2540
ibool
2564
2541
log_archive_do(
2565
2542
/*===========*/
2569
2546
        ulint*  n_bytes)/* out: archive log buffer size, 0 if nothing to
2570
2547
                        archive */
2571
2548
{
2572
 
        ibool   calc_new_limit;
2573
 
        dulint  start_lsn;
2574
 
        dulint  limit_lsn;
 
2549
        ibool           calc_new_limit;
 
2550
        ib_uint64_t     start_lsn;
 
2551
        ib_uint64_t     limit_lsn;
2575
2552
 
2576
2553
        calc_new_limit = TRUE;
2577
2554
loop:
2578
2555
        mutex_enter(&(log_sys->mutex));
2579
2556
 
2580
 
        if (log_sys->archiving_state == LOG_ARCH_OFF) {
 
2557
        switch (log_sys->archiving_state) {
 
2558
        case LOG_ARCH_OFF:
 
2559
arch_none:
2581
2560
                mutex_exit(&(log_sys->mutex));
2582
2561
 
2583
2562
                *n_bytes = 0;
2584
2563
 
2585
2564
                return(TRUE);
2586
 
 
2587
 
        } else if (log_sys->archiving_state == LOG_ARCH_STOPPED
2588
 
                   || log_sys->archiving_state == LOG_ARCH_STOPPING2) {
2589
 
 
 
2565
        case LOG_ARCH_STOPPED:
 
2566
        case LOG_ARCH_STOPPING2:
2590
2567
                mutex_exit(&(log_sys->mutex));
2591
2568
 
2592
2569
                os_event_wait(log_sys->archiving_on);
2593
2570
 
2594
 
                mutex_enter(&(log_sys->mutex));
2595
 
 
2596
2571
                goto loop;
2597
2572
        }
2598
2573
 
2600
2575
 
2601
2576
        if (calc_new_limit) {
2602
2577
                ut_a(log_sys->archive_buf_size % OS_FILE_LOG_BLOCK_SIZE == 0);
2603
 
                limit_lsn = ut_dulint_add(start_lsn,
2604
 
                                          log_sys->archive_buf_size);
 
2578
                limit_lsn = start_lsn + log_sys->archive_buf_size;
2605
2579
 
2606
2580
                *n_bytes = log_sys->archive_buf_size;
2607
2581
 
2608
 
                if (ut_dulint_cmp(limit_lsn, log_sys->lsn) >= 0) {
 
2582
                if (limit_lsn >= log_sys->lsn) {
2609
2583
 
2610
 
                        limit_lsn = ut_dulint_align_down(
 
2584
                        limit_lsn = ut_uint64_align_down(
2611
2585
                                log_sys->lsn, OS_FILE_LOG_BLOCK_SIZE);
2612
2586
                }
2613
2587
        }
2614
2588
 
2615
 
        if (ut_dulint_cmp(log_sys->archived_lsn, limit_lsn) >= 0) {
2616
 
 
2617
 
                mutex_exit(&(log_sys->mutex));
2618
 
 
2619
 
                *n_bytes = 0;
2620
 
 
2621
 
                return(TRUE);
 
2589
        if (log_sys->archived_lsn >= limit_lsn) {
 
2590
 
 
2591
                goto arch_none;
2622
2592
        }
2623
2593
 
2624
 
        if (ut_dulint_cmp(log_sys->written_to_all_lsn, limit_lsn) < 0) {
 
2594
        if (log_sys->written_to_all_lsn < limit_lsn) {
2625
2595
 
2626
2596
                mutex_exit(&(log_sys->mutex));
2627
2597
 
2656
2626
#ifdef UNIV_DEBUG
2657
2627
        if (log_debug_writes) {
2658
2628
                fprintf(stderr,
2659
 
                        "Archiving from lsn %lu %lu to lsn %lu %lu\n",
2660
 
                        (ulong) ut_dulint_get_high(log_sys->archived_lsn),
2661
 
                        (ulong) ut_dulint_get_low(log_sys->archived_lsn),
2662
 
                        (ulong) ut_dulint_get_high(limit_lsn),
2663
 
                        (ulong) ut_dulint_get_low(limit_lsn));
 
2629
                        "Archiving from lsn %"PRIu64" to lsn %"PRIu64"\n",
 
2630
                        log_sys->archived_lsn, limit_lsn);
2664
2631
        }
2665
2632
#endif /* UNIV_DEBUG */
2666
2633
 
2690
2657
log_archive_all(void)
2691
2658
/*=================*/
2692
2659
{
2693
 
        dulint  present_lsn;
2694
 
        ulint   dummy;
 
2660
        ib_uint64_t     present_lsn;
 
2661
        ulint           dummy;
2695
2662
 
2696
2663
        mutex_enter(&(log_sys->mutex));
2697
2664
 
2710
2677
        for (;;) {
2711
2678
                mutex_enter(&(log_sys->mutex));
2712
2679
 
2713
 
                if (ut_dulint_cmp(present_lsn, log_sys->archived_lsn) <= 0) {
 
2680
                if (present_lsn <= log_sys->archived_lsn) {
2714
2681
 
2715
2682
                        mutex_exit(&(log_sys->mutex));
2716
2683
 
2780
2747
called, and stops the archiving. When archiving is started again, the archived
2781
2748
log file numbers start from 2 higher, so that the archiving will not write
2782
2749
again to the archived log files which exist when this function returns. */
2783
 
 
 
2750
UNIV_INTERN
2784
2751
ulint
2785
2752
log_archive_stop(void)
2786
2753
/*==================*/
2844
2811
 
2845
2812
/********************************************************************
2846
2813
Starts again archiving which has been stopped. */
2847
 
 
 
2814
UNIV_INTERN
2848
2815
ulint
2849
2816
log_archive_start(void)
2850
2817
/*===================*/
2870
2837
 
2871
2838
/********************************************************************
2872
2839
Stop archiving the log so that a gap may occur in the archived log files. */
2873
 
 
 
2840
UNIV_INTERN
2874
2841
ulint
2875
2842
log_archive_noarchivelog(void)
2876
2843
/*==========================*/
2902
2869
 
2903
2870
/********************************************************************
2904
2871
Start archiving the log so that a gap may occur in the archived log files. */
2905
 
 
 
2872
UNIV_INTERN
2906
2873
ulint
2907
2874
log_archive_archivelog(void)
2908
2875
/*========================*/
2915
2882
                log_sys->archiving_state = LOG_ARCH_ON;
2916
2883
 
2917
2884
                log_sys->archived_lsn
2918
 
                        = ut_dulint_align_down(log_sys->lsn,
 
2885
                        = ut_uint64_align_down(log_sys->lsn,
2919
2886
                                               OS_FILE_LOG_BLOCK_SIZE);
2920
2887
                mutex_exit(&(log_sys->mutex));
2921
2888
 
2949
2916
                return;
2950
2917
        }
2951
2918
 
2952
 
        age = ut_dulint_minus(log->lsn, log->archived_lsn);
 
2919
        age = log->lsn - log->archived_lsn;
2953
2920
 
2954
2921
        if (age > log->max_archived_lsn_age) {
2955
2922
 
2987
2954
Flushes the log buffer or makes a new checkpoint if necessary. NOTE: this
2988
2955
function may only be called if the calling thread owns no synchronization
2989
2956
objects! */
2990
 
 
 
2957
UNIV_INTERN
2991
2958
void
2992
2959
log_check_margins(void)
2993
2960
/*===================*/
3018
2985
data file in the database, so that we know that the file spaces contain
3019
2986
all modifications up to that lsn. This can only be called at database
3020
2987
shutdown. This function also writes all log in log files to the log archive. */
3021
 
 
 
2988
UNIV_INTERN
3022
2989
void
3023
2990
logs_empty_and_mark_files_at_shutdown(void)
3024
2991
/*=======================================*/
3025
2992
{
3026
 
        dulint  lsn;
3027
 
        ulint   arch_log_no;
 
2993
        ib_uint64_t     lsn;
 
2994
        ulint           arch_log_no;
3028
2995
 
3029
2996
        if (srv_print_verbose_log) {
3030
2997
                ut_print_timestamp(stderr);
3113
3080
        log_archive_all();
3114
3081
#endif /* UNIV_LOG_ARCHIVE */
3115
3082
 
3116
 
        log_make_checkpoint_at(ut_dulint_max, TRUE);
 
3083
        log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE);
3117
3084
 
3118
3085
        mutex_enter(&(log_sys->mutex));
3119
3086
 
3120
3087
        lsn = log_sys->lsn;
3121
3088
 
3122
 
        if ((ut_dulint_cmp(lsn, log_sys->last_checkpoint_lsn) != 0)
 
3089
        if (lsn != log_sys->last_checkpoint_lsn
3123
3090
#ifdef UNIV_LOG_ARCHIVE
3124
3091
            || (srv_log_archive_on
3125
 
                && ut_dulint_cmp(lsn,
3126
 
                                 ut_dulint_add(log_sys->archived_lsn,
3127
 
                                               LOG_BLOCK_HDR_SIZE))
3128
 
                != 0)
 
3092
                && lsn != log_sys->archived_lsn + LOG_BLOCK_HDR_SIZE)
3129
3093
#endif /* UNIV_LOG_ARCHIVE */
3130
3094
            ) {
3131
3095
 
3180
3144
        /* Make some checks that the server really is quiet */
3181
3145
        ut_a(srv_n_threads_active[SRV_MASTER] == 0);
3182
3146
        ut_a(buf_all_freed());
3183
 
        ut_a(0 == ut_dulint_cmp(lsn, log_sys->lsn));
 
3147
        ut_a(lsn == log_sys->lsn);
3184
3148
 
3185
 
        if (ut_dulint_cmp(lsn, srv_start_lsn) < 0) {
 
3149
        if (lsn < srv_start_lsn) {
3186
3150
                fprintf(stderr,
3187
3151
                        "InnoDB: Error: log sequence number"
3188
 
                        " at shutdown %lu %lu\n"
3189
 
                        "InnoDB: is lower than at startup %lu %lu!\n",
3190
 
                        (ulong) ut_dulint_get_high(lsn),
3191
 
                        (ulong) ut_dulint_get_low(lsn),
3192
 
                        (ulong) ut_dulint_get_high(srv_start_lsn),
3193
 
                        (ulong) ut_dulint_get_low(srv_start_lsn));
 
3152
                        " at shutdown %"PRIu64"\n"
 
3153
                        "InnoDB: is lower than at startup %"PRIu64"!\n",
 
3154
                        lsn, srv_start_lsn);
3194
3155
        }
3195
3156
 
3196
3157
        srv_shutdown_lsn = lsn;
3204
3165
        /* Make some checks that the server really is quiet */
3205
3166
        ut_a(srv_n_threads_active[SRV_MASTER] == 0);
3206
3167
        ut_a(buf_all_freed());
3207
 
        ut_a(0 == ut_dulint_cmp(lsn, log_sys->lsn));
 
3168
        ut_a(lsn == log_sys->lsn);
3208
3169
}
3209
3170
 
3210
3171
/**********************************************************
3211
3172
Checks by parsing that the catenated log segment for a single mtr is
3212
3173
consistent. */
3213
 
 
 
3174
UNIV_INTERN
3214
3175
ibool
3215
3176
log_check_log_recs(
3216
3177
/*===============*/
3217
 
        byte*   buf,            /* in: pointer to the start of the log segment
3218
 
                                in the log_sys->buf log buffer */
3219
 
        ulint   len,            /* in: segment length in bytes */
3220
 
        dulint  buf_start_lsn)  /* in: buffer start lsn */
 
3178
        byte*           buf,            /* in: pointer to the start of
 
3179
                                        the log segment in the
 
3180
                                        log_sys->buf log buffer */
 
3181
        ulint           len,            /* in: segment length in bytes */
 
3182
        ib_uint64_t     buf_start_lsn)  /* in: buffer start lsn */
3221
3183
{
3222
 
        dulint  contiguous_lsn;
3223
 
        dulint  scanned_lsn;
3224
 
        byte*   start;
3225
 
        byte*   end;
3226
 
        byte*   buf1;
3227
 
        byte*   scan_buf;
 
3184
        ib_uint64_t     contiguous_lsn;
 
3185
        ib_uint64_t     scanned_lsn;
 
3186
        byte*           start;
 
3187
        byte*           end;
 
3188
        byte*           buf1;
 
3189
        byte*           scan_buf;
3228
3190
 
3229
3191
        ut_ad(mutex_own(&(log_sys->mutex)));
3230
3192
 
3242
3204
        ut_memcpy(scan_buf, start, end - start);
3243
3205
 
3244
3206
        recv_scan_log_recs(TRUE,
3245
 
                           (buf_pool->n_frames
 
3207
                           (buf_pool->curr_size
3246
3208
                            - recv_n_pool_free_frames) * UNIV_PAGE_SIZE,
3247
3209
                           FALSE, scan_buf, end - start,
3248
 
                           ut_dulint_align_down(buf_start_lsn,
 
3210
                           ut_uint64_align_down(buf_start_lsn,
3249
3211
                                                OS_FILE_LOG_BLOCK_SIZE),
3250
3212
                           &contiguous_lsn, &scanned_lsn);
3251
3213
 
3252
 
        ut_a(ut_dulint_cmp(scanned_lsn, ut_dulint_add(buf_start_lsn, len))
3253
 
             == 0);
3254
 
        ut_a(ut_dulint_cmp(recv_sys->recovered_lsn, scanned_lsn) == 0);
 
3214
        ut_a(scanned_lsn == buf_start_lsn + len);
 
3215
        ut_a(recv_sys->recovered_lsn == scanned_lsn);
3255
3216
 
3256
3217
        mem_free(buf1);
3257
3218
 
3260
3221
 
3261
3222
/**********************************************************
3262
3223
Peeks the current lsn. */
3263
 
 
 
3224
UNIV_INTERN
3264
3225
ibool
3265
3226
log_peek_lsn(
3266
3227
/*=========*/
3267
 
                        /* out: TRUE if success, FALSE if could not get the
3268
 
                        log system mutex */
3269
 
        dulint* lsn)    /* out: if returns TRUE, current lsn is here */
 
3228
                                /* out: TRUE if success, FALSE if
 
3229
                                could not get the log system mutex */
 
3230
        ib_uint64_t*    lsn)    /* out: if returns TRUE, current lsn is here */
3270
3231
{
3271
3232
        if (0 == mutex_enter_nowait(&(log_sys->mutex))) {
3272
3233
                *lsn = log_sys->lsn;
3281
3242
 
3282
3243
/**********************************************************
3283
3244
Prints info of the log. */
3284
 
 
 
3245
UNIV_INTERN
3285
3246
void
3286
3247
log_print(
3287
3248
/*======*/
3293
3254
        mutex_enter(&(log_sys->mutex));
3294
3255
 
3295
3256
        fprintf(file,
3296
 
                "Log sequence number %lu %lu\n"
3297
 
                "Log flushed up to   %lu %lu\n"
3298
 
                "Last checkpoint at  %lu %lu\n",
3299
 
                (ulong) ut_dulint_get_high(log_sys->lsn),
3300
 
                (ulong) ut_dulint_get_low(log_sys->lsn),
3301
 
                (ulong) ut_dulint_get_high(log_sys->flushed_to_disk_lsn),
3302
 
                (ulong) ut_dulint_get_low(log_sys->flushed_to_disk_lsn),
3303
 
                (ulong) ut_dulint_get_high(log_sys->last_checkpoint_lsn),
3304
 
                (ulong) ut_dulint_get_low(log_sys->last_checkpoint_lsn));
 
3257
                "Log sequence number %"PRIu64"\n"
 
3258
                "Log flushed up to   %"PRIu64"\n"
 
3259
                "Last checkpoint at  %"PRIu64"\n",
 
3260
                log_sys->lsn,
 
3261
                log_sys->flushed_to_disk_lsn,
 
3262
                log_sys->last_checkpoint_lsn);
3305
3263
 
3306
3264
        current_time = time(NULL);
3307
3265
 
3324
3282
 
3325
3283
/**************************************************************************
3326
3284
Refreshes the statistics used to print per-second averages. */
3327
 
 
 
3285
UNIV_INTERN
3328
3286
void
3329
3287
log_refresh_stats(void)
3330
3288
/*===================*/