53
53
/* Current free limit of space 0; protected by the log sys mutex; 0 means
55
ulint log_fsp_current_free_limit = 0;
55
UNIV_INTERN ulint log_fsp_current_free_limit = 0;
57
57
/* Global log system variable */
58
log_t* log_sys = NULL;
58
UNIV_INTERN log_t* log_sys = NULL;
61
ibool log_do_write = TRUE;
61
UNIV_INTERN ibool log_do_write = TRUE;
63
ibool log_debug_writes = FALSE;
63
UNIV_INTERN ibool log_debug_writes = FALSE;
64
64
#endif /* UNIV_DEBUG */
66
66
/* These control how often we print warnings if the last checkpoint is too
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;
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
74
UNIV_INTERN byte log_archive_io;
75
75
#endif /* UNIV_LOG_ARCHIVE */
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)
105
#ifdef UNIV_LOG_ARCHIVE
105
106
/* This parameter controls asynchronous writing to the archive */
106
107
#define LOG_ARCHIVE_RATIO_ASYNC 16
109
/* States of an archiving operation */
110
#define LOG_ARCHIVE_READ 1
111
#define LOG_ARCHIVE_WRITE 2
113
#endif /* UNIV_LOG_ARCHIVE */
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
112
/* States of an archiving operation */
113
#define LOG_ARCHIVE_READ 1
114
#define LOG_ARCHIVE_WRITE 2
116
119
/**********************************************************
117
120
Completes a checkpoint write i/o to a log file. */
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
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
163
166
log_buf_pool_get_oldest_modification(void)
164
167
/*======================================*/
168
171
ut_ad(mutex_own(&(log_sys->mutex)));
170
173
lsn = buf_pool_get_oldest_modification();
172
if (ut_dulint_is_zero(lsn)) {
174
177
lsn = log_sys->lsn;
225
228
#ifdef UNIV_LOG_ARCHIVE
226
229
if (log->archiving_state != LOG_ARCH_OFF) {
228
archived_lsn_age = ut_dulint_minus(log->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
302
304
log_sys->next_checkpoint_no);
303
305
len += LOG_BLOCK_HDR_SIZE + LOG_BLOCK_TRL_SIZE;
305
log->lsn = ut_dulint_add(log->lsn, len);
307
309
/* Initialize the next block header */
308
310
log_block_init(log_block + OS_FILE_LOG_BLOCK_SIZE, log->lsn);
310
log->lsn = ut_dulint_add(log->lsn, len);
313
315
log->buf_free += len;
358
360
log->check_flush_or_checkpoint = TRUE;
361
checkpoint_age = ut_dulint_minus(lsn, log->last_checkpoint_lsn);
363
checkpoint_age = lsn - log->last_checkpoint_lsn;
363
365
if (checkpoint_age >= log->log_group_capacity) {
364
366
/* TODO: split btr_store_big_rec_extern_fields() into small
397
399
oldest_lsn = buf_pool_get_oldest_modification();
399
if (ut_dulint_is_zero(oldest_lsn)
400
|| (ut_dulint_minus(lsn, oldest_lsn)
401
> log->max_modified_age_async)
402
|| lsn - oldest_lsn > log->max_modified_age_async
402
403
|| checkpoint_age > log->max_checkpoint_age_async) {
404
405
log->check_flush_or_checkpoint = TRUE;
422
423
log_pad_current_log_block(void)
423
424
/*===========================*/
425
byte b = MLOG_DUMMY_RECORD;
426
byte b = MLOG_DUMMY_RECORD;
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);
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);
449
449
#endif /* UNIV_LOG_ARCHIVE */
451
451
/**********************************************************
452
452
Calculates the data capacity of a log group, when the log file headers are not
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
508
508
log_group_t* group) /* in: log group */
511
ib_longlong gr_lsn_size_offset;
512
ib_longlong difference;
513
ib_longlong group_size;
511
ib_int64_t gr_lsn_size_offset;
512
ib_int64_t difference;
513
ib_int64_t group_size;
516
516
ut_ad(mutex_own(&(log_sys->mutex)));
521
521
gr_lsn = group->lsn;
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);
526
group_size = (ib_longlong) log_group_get_capacity(group);
528
if (ut_dulint_cmp(lsn, gr_lsn) >= 0) {
530
difference = (ib_longlong) ut_dulint_minus(lsn, gr_lsn);
526
group_size = (ib_int64_t) log_group_get_capacity(group);
530
difference = (ib_int64_t) (lsn - gr_lsn);
532
difference = (ib_longlong) ut_dulint_minus(gr_lsn, lsn);
532
difference = (ib_int64_t) (gr_lsn - lsn);
534
534
difference = difference % group_size;
539
539
offset = (gr_lsn_size_offset + difference) % group_size;
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 */
543
543
/* fprintf(stderr,
544
544
"Offset is %lu gr_lsn_offset is %lu difference is %lu\n",
551
551
/***********************************************************************
552
552
Calculates where in log files we find a specified lsn. */
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
562
dulint lsn, /* in: lsn whose position to
562
ib_uint64_t lsn, /* in: lsn whose position to
564
564
ulint n_log_files, /* in: total number of log
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) */
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;
573
ib_longlong add_this_many;
575
ib_lsn = ut_conv_dulint_to_longlong(lsn);
576
ib_first_header_lsn = ut_conv_dulint_to_longlong(first_header_lsn);
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;
573
if (lsn < first_header_lsn) {
574
add_this_many = 1 + (first_header_lsn - lsn)
575
/ (capacity * (ib_int64_t)n_log_files);
577
* capacity * (ib_int64_t)n_log_files;
585
ut_a(ib_lsn >= ib_first_header_lsn);
580
ut_a(lsn >= first_header_lsn);
587
file_no = ((ulint)((ib_lsn - ib_first_header_lsn) / capacity))
582
file_no = ((ulint)((lsn - first_header_lsn) / capacity))
589
*log_file_offset = (ib_lsn - ib_first_header_lsn) % capacity;
584
*log_file_offset = (lsn - first_header_lsn) % capacity;
591
586
*log_file_offset = *log_file_offset + LOG_FILE_HDR_SIZE;
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. */
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
608
603
group->lsn_offset = log_group_calc_lsn_offset(lsn, group);
768
763
log_sys->buf_next_to_write = 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;
765
log_sys->write_lsn = 0;
766
log_sys->current_flush_lsn = 0;
767
log_sys->flushed_to_disk_lsn = 0;
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;
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;
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;
808
803
log_sys->n_pending_archive_ios = 0;
828
823
log_block_set_first_rec_group(log_sys->buf, LOG_BLOCK_HDR_SIZE);
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;
833
828
mutex_exit(&(log_sys->mutex));
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;
847
842
/**********************************************************************
848
843
Inits a log group to the log system. */
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
1114
1109
buf = *(group->file_header_bufs + nth_file);
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);
1119
1114
/* Wipe over possible label of ibbackup --restore */
1120
1115
memcpy(buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, " ", 4);
1134
1129
srv_os_log_pending_writes++;
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,
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
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);
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),
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));
1254
1248
srv_os_log_pending_writes++;
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);
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. */
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
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 */
1294
1289
log_group_t* group;
1295
1290
ulint start_offset;
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)
1330
&& (log_sys->written_to_all_lsn >= lsn
1331
|| (log_sys->written_to_some_lsn >= lsn
1338
1332
&& wait != LOG_WAIT_ALL_GROUPS))) {
1340
1334
mutex_exit(&(log_sys->mutex));
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,
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);
1490
1479
mutex_exit(&(log_sys->mutex));
1492
if (wait == LOG_WAIT_ONE_GROUP) {
1482
case LOG_WAIT_ONE_GROUP:
1493
1483
os_event_wait(log_sys->one_flushed_event);
1494
} else if (wait == LOG_WAIT_ALL_GROUPS) {
1485
case LOG_WAIT_ALL_GROUPS:
1495
1486
os_event_wait(log_sys->no_flush_event);
1497
ut_ad(wait == LOG_NO_WAIT);
1493
#endif /* UNIV_DEBUG */
1501
1497
/********************************************************************
1502
1498
Does a syncronous flush of the log buffer to disk. */
1505
1501
log_buffer_flush_to_disk(void)
1506
1502
/*==========================*/
1510
1506
mutex_enter(&(log_sys->mutex));
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! */
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
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
1558
ib_uint64_t new_oldest, /* in: try to advance
1559
oldest_modified_lsn at least
1561
ibool sync) /* in: TRUE if synchronous
1562
operation is desired */
1603
1600
ut_ad(mutex_own(&(log_sys->mutex)));
1604
1601
ut_ad(log_sys->n_pending_checkpoint_writes == 0);
1606
log_sys->next_checkpoint_no
1607
= ut_dulint_add(log_sys->next_checkpoint_no, 1);
1603
log_sys->next_checkpoint_no++;
1609
1605
log_sys->last_checkpoint_lsn = log_sys->next_checkpoint_lsn;
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 */
1690
1686
ut_ad(mutex_own(&(log_sys->mutex)));
1691
1687
#if LOG_CHECKPOINT_SIZE > OS_FILE_LOG_BLOCK_SIZE
1695
1691
buf = group->checkpoint_buf;
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);
1701
1696
mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,
1702
1697
log_group_calc_lsn_offset(
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;
1711
1706
archived_lsn = log_sys->archived_lsn;
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 */
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 */
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
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;
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 */
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. */
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 */
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);
1814
lsn = ut_dulint_add(start, LOG_BLOCK_HDR_SIZE);
1808
lsn = start + LOG_BLOCK_HDR_SIZE;
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;
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);
1827
1821
mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,
1828
1822
LOG_FILE_HDR_SIZE + LOG_BLOCK_HDR_SIZE);
1830
1824
mach_write_to_4(buf + LOG_CHECKPOINT_LOG_BUF_SIZE, 2 * 1024 * 1024);
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);
1834
1828
fold = ut_fold_binary(buf, LOG_CHECKPOINT_CHECKSUM_1);
1835
1829
mach_write_to_4(buf + LOG_CHECKPOINT_CHECKSUM_1, fold);
1857
1851
log_sys->n_log_ios++;
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);
1864
1858
/**********************************************************
1865
1859
Writes checkpoint info to groups. */
1868
1862
log_groups_write_checkpoint_info(void)
1869
1863
/*==================================*/
1930
1924
mutex_enter(&(log_sys->mutex));
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) {
1935
1929
mutex_exit(&(log_sys->mutex));
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);
1942
1936
if (log_sys->n_pending_checkpoint_writes > 0) {
1943
1937
/* A checkpoint write is running */
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,
1965
1958
#endif /* UNIV_DEBUG */
1980
1973
/********************************************************************
1981
1974
Makes a checkpoint at a given lsn or later. */
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
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
1998
1990
/* Preflush pages synchronously */
2003
success = log_preflush_pool_modified_pages(lsn, TRUE);
2009
success = log_checkpoint(TRUE, write_always);
1992
while (!log_preflush_pool_modified_pages(lsn, TRUE));
1994
while (!log_checkpoint(TRUE, write_always));
2013
1997
/********************************************************************
2063
checkpoint_age = ut_dulint_minus(log->lsn, log->last_checkpoint_lsn);
2047
checkpoint_age = log->lsn - log->last_checkpoint_lsn;
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));
2085
dulint new_oldest = ut_dulint_add(oldest_lsn, advance);
2069
ib_uint64_t new_oldest = oldest_lsn + advance;
2087
2071
success = log_preflush_pool_modified_pages(new_oldest, sync);
2115
2099
/**********************************************************
2116
2100
Reads a specified log segment to a buffer. */
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 */
2128
2112
ulint source_offset;
2131
2115
ut_ad(mutex_own(&(log_sys->mutex)));
2135
if (type == LOG_RECOVER) {
2117
sync = (type == LOG_RECOVER);
2139
2119
source_offset = log_group_calc_lsn_offset(start_lsn, group);
2141
len = ut_dulint_minus(end_lsn, start_lsn);
2121
len = (ulint) (end_lsn - start_lsn);
2143
2123
ut_ad(len != 0);
2157
2137
log_sys->n_log_ios++;
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);
2163
start_lsn = ut_dulint_add(start_lsn, len);
2166
if (ut_dulint_cmp(start_lsn, end_lsn) != 0) {
2146
if (start_lsn != end_lsn) {
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
2208
2188
buf = *(group->archive_file_header_bufs + nth_file);
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);
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 */
2239
2219
ulint dest_offset;
2244
2224
buf = *(group->archive_file_header_bufs + nth_file);
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);
2249
2229
dest_offset = nth_file * group->file_size + LOG_FILE_ARCH_COMPLETED;
2266
2246
/*==============*/
2267
2247
log_group_t* group) /* in: log group */
2269
os_file_t file_handle;
2249
os_file_t file_handle;
2250
ib_uint64_t start_lsn;
2251
ib_uint64_t end_lsn;
2280
2260
ut_ad(mutex_own(&(log_sys->mutex)));
2282
2262
start_lsn = log_sys->archived_lsn;
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);
2286
2266
end_lsn = log_sys->next_archived_lsn;
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);
2290
2270
buf = log_sys->archive_buf;
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),
2371
2350
(ulong) len, (ulong) group->id);
2373
2352
#endif /* UNIV_DEBUG */
2466
2445
#endif /* UNIV_DEBUG */
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;
2475
2453
for (i = 0; i < trunc_files; i++) {
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;
2480
2457
/* Write a notice to the headers of archived log
2481
2458
files that the file write has been completed */
2569
2546
ulint* n_bytes)/* out: archive log buffer size, 0 if nothing to
2572
ibool calc_new_limit;
2549
ibool calc_new_limit;
2550
ib_uint64_t start_lsn;
2551
ib_uint64_t limit_lsn;
2576
2553
calc_new_limit = TRUE;
2578
2555
mutex_enter(&(log_sys->mutex));
2580
if (log_sys->archiving_state == LOG_ARCH_OFF) {
2557
switch (log_sys->archiving_state) {
2581
2560
mutex_exit(&(log_sys->mutex));
2587
} else if (log_sys->archiving_state == LOG_ARCH_STOPPED
2588
|| log_sys->archiving_state == LOG_ARCH_STOPPING2) {
2565
case LOG_ARCH_STOPPED:
2566
case LOG_ARCH_STOPPING2:
2590
2567
mutex_exit(&(log_sys->mutex));
2592
2569
os_event_wait(log_sys->archiving_on);
2594
mutex_enter(&(log_sys->mutex));
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;
2606
2580
*n_bytes = log_sys->archive_buf_size;
2608
if (ut_dulint_cmp(limit_lsn, log_sys->lsn) >= 0) {
2582
if (limit_lsn >= log_sys->lsn) {
2610
limit_lsn = ut_dulint_align_down(
2584
limit_lsn = ut_uint64_align_down(
2611
2585
log_sys->lsn, OS_FILE_LOG_BLOCK_SIZE);
2615
if (ut_dulint_cmp(log_sys->archived_lsn, limit_lsn) >= 0) {
2617
mutex_exit(&(log_sys->mutex));
2589
if (log_sys->archived_lsn >= limit_lsn) {
2624
if (ut_dulint_cmp(log_sys->written_to_all_lsn, limit_lsn) < 0) {
2594
if (log_sys->written_to_all_lsn < limit_lsn) {
2626
2596
mutex_exit(&(log_sys->mutex));
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);
2665
2632
#endif /* UNIV_DEBUG */
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. */
2785
2752
log_archive_stop(void)
2786
2753
/*==================*/
2915
2882
log_sys->archiving_state = LOG_ARCH_ON;
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));
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. */
3023
2990
logs_empty_and_mark_files_at_shutdown(void)
3024
2991
/*=======================================*/
3029
2996
if (srv_print_verbose_log) {
3030
2997
ut_print_timestamp(stderr);
3113
3080
log_archive_all();
3114
3081
#endif /* UNIV_LOG_ARCHIVE */
3116
log_make_checkpoint_at(ut_dulint_max, TRUE);
3083
log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE);
3118
3085
mutex_enter(&(log_sys->mutex));
3120
3087
lsn = log_sys->lsn;
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))
3092
&& lsn != log_sys->archived_lsn + LOG_BLOCK_HDR_SIZE)
3129
3093
#endif /* UNIV_LOG_ARCHIVE */
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);
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);
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);
3210
3171
/**********************************************************
3211
3172
Checks by parsing that the catenated log segment for a single mtr is
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 */
3222
dulint contiguous_lsn;
3184
ib_uint64_t contiguous_lsn;
3185
ib_uint64_t scanned_lsn;
3229
3191
ut_ad(mutex_own(&(log_sys->mutex)));
3242
3204
ut_memcpy(scan_buf, start, end - start);
3244
3206
recv_scan_log_recs(TRUE,
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);
3252
ut_a(ut_dulint_cmp(scanned_lsn, ut_dulint_add(buf_start_lsn, len))
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);
3256
3217
mem_free(buf1);
3261
3222
/**********************************************************
3262
3223
Peeks the current lsn. */
3267
/* out: TRUE if success, FALSE if could not get the
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 */
3271
3232
if (0 == mutex_enter_nowait(&(log_sys->mutex))) {
3272
3233
*lsn = log_sys->lsn;
3293
3254
mutex_enter(&(log_sys->mutex));
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",
3261
log_sys->flushed_to_disk_lsn,
3262
log_sys->last_checkpoint_lsn);
3306
3264
current_time = time(NULL);