~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2008-08-04 19:37:18 UTC
  • mto: (261.2.2 codestyle)
  • mto: This revision was merged to the branch mainline in revision 262.
  • Revision ID: monty@inaugust.com-20080804193718-f0rz13uli4429ozb
Changed gettext_noop() to N_()

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