1
1
/*****************************************************************************
3
Copyright (C) 1995, 2010, Innobase Oy. All Rights Reserved.
4
Copyright (C) 2009 Google Inc.
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15
Place, Suite 330, Boston, MA 02111-1307 USA
17
*****************************************************************************/
18
/*****************************************************************************
20
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
21
Copyright (c) 2009, Google Inc.
6
23
Portions of this file contain modifications contributed and copyrighted by
7
24
Google, Inc. Those modifications are gratefully acknowledged and are described
18
35
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
37
You should have received a copy of the GNU General Public License along with
21
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22
St, Fifth Floor, Boston, MA 02110-1301 USA
38
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
39
Place, Suite 330, Boston, MA 02111-1307 USA
24
41
*****************************************************************************/
82
99
/* Global log system variable */
83
100
UNIV_INTERN log_t* log_sys = NULL;
85
#ifdef UNIV_PFS_RWLOCK
86
UNIV_INTERN mysql_pfs_key_t checkpoint_lock_key;
87
# ifdef UNIV_LOG_ARCHIVE
88
UNIV_INTERN mysql_pfs_key_t archive_lock_key;
90
#endif /* UNIV_PFS_RWLOCK */
93
UNIV_INTERN mysql_pfs_key_t log_sys_mutex_key;
94
UNIV_INTERN mysql_pfs_key_t log_flush_order_mutex_key;
95
#endif /* UNIV_PFS_MUTEX */
98
103
UNIV_INTERN ibool log_do_write = TRUE;
99
104
#endif /* UNIV_DEBUG */
331
log_block = static_cast<unsigned char *>(ut_align_down(log->buf + log->buf_free,
332
OS_FILE_LOG_BLOCK_SIZE));
334
log_block = ut_align_down(log->buf + log->buf_free,
335
OS_FILE_LOG_BLOCK_SIZE);
333
336
log_block_set_data_len(log_block, data_len);
335
338
if (data_len == OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
374
377
ib_uint64_t checkpoint_age;
376
379
ut_ad(mutex_own(&(log->mutex)));
377
ut_ad(!recv_no_log_write);
381
log_block = static_cast<unsigned char *>(ut_align_down(log->buf + log->buf_free,
382
OS_FILE_LOG_BLOCK_SIZE));
383
log_block = ut_align_down(log->buf + log->buf_free,
384
OS_FILE_LOG_BLOCK_SIZE);
383
385
first_rec_group = log_block_get_first_rec_group(log_block);
385
387
if (first_rec_group == 0) {
769
log_sys = static_cast<log_t *>(mem_alloc(sizeof(log_t)));
771
mutex_create(log_sys_mutex_key, &log_sys->mutex, SYNC_LOG);
773
mutex_create(log_flush_order_mutex_key,
774
&log_sys->log_flush_order_mutex,
775
SYNC_LOG_FLUSH_ORDER);
775
log_sys = mem_alloc(sizeof(log_t));
777
mutex_create(&log_sys->mutex, SYNC_LOG);
777
779
mutex_enter(&(log_sys->mutex));
784
786
ut_a(LOG_BUFFER_SIZE >= 16 * OS_FILE_LOG_BLOCK_SIZE);
785
787
ut_a(LOG_BUFFER_SIZE >= 4 * UNIV_PAGE_SIZE);
787
log_sys->buf_ptr = static_cast<unsigned char *>(mem_alloc(LOG_BUFFER_SIZE + OS_FILE_LOG_BLOCK_SIZE));
788
log_sys->buf = static_cast<unsigned char *>(ut_align(log_sys->buf_ptr, OS_FILE_LOG_BLOCK_SIZE));
789
buf = mem_alloc(LOG_BUFFER_SIZE + OS_FILE_LOG_BLOCK_SIZE);
790
log_sys->buf = ut_align(buf, OS_FILE_LOG_BLOCK_SIZE);
790
792
log_sys->buf_size = LOG_BUFFER_SIZE;
828
830
log_sys->last_checkpoint_lsn = log_sys->lsn;
829
831
log_sys->n_pending_checkpoint_writes = 0;
831
rw_lock_create(checkpoint_lock_key, &log_sys->checkpoint_lock,
832
SYNC_NO_ORDER_CHECK);
833
rw_lock_create(&log_sys->checkpoint_lock, SYNC_NO_ORDER_CHECK);
834
log_sys->checkpoint_buf_ptr = static_cast<unsigned char *>(mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE));
835
log_sys->checkpoint_buf = static_cast<unsigned char *>(ut_align(log_sys->checkpoint_buf_ptr,
836
OS_FILE_LOG_BLOCK_SIZE));
835
log_sys->checkpoint_buf
836
= ut_align(mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE),
837
OS_FILE_LOG_BLOCK_SIZE);
837
838
memset(log_sys->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
838
839
/*----------------------------*/
846
847
log_sys->n_pending_archive_ios = 0;
848
rw_lock_create(archive_lock_key, &log_sys->archive_lock,
849
SYNC_NO_ORDER_CHECK);
849
rw_lock_create(&log_sys->archive_lock, SYNC_NO_ORDER_CHECK);
851
851
log_sys->archive_buf = NULL;
895
895
ulint space_id, /*!< in: space id of the file space
896
896
which contains the log files of this
898
ulint /*archive_space_id __attribute__((unused))*/)
898
ulint archive_space_id __attribute__((unused)))
899
899
/*!< in: space id of the file space
900
900
which contains some archived log
901
901
files for this group; currently, only
917
917
group->lsn_offset = LOG_FILE_HDR_SIZE;
918
918
group->n_pending_writes = 0;
920
group->file_header_bufs_ptr = static_cast<unsigned char **>(mem_alloc(sizeof(byte*) * n_files));
921
group->file_header_bufs = static_cast<unsigned char **>(mem_alloc(sizeof(byte*) * n_files));
920
group->file_header_bufs = mem_alloc(sizeof(byte*) * n_files);
922
921
#ifdef UNIV_LOG_ARCHIVE
923
group->archive_file_header_bufs_ptr = mem_alloc(
924
sizeof(byte*) * n_files);
925
922
group->archive_file_header_bufs = mem_alloc(sizeof(byte*) * n_files);
926
923
#endif /* UNIV_LOG_ARCHIVE */
928
925
for (i = 0; i < n_files; i++) {
929
group->file_header_bufs_ptr[i] = static_cast<unsigned char *>(mem_alloc(
930
LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE));
932
group->file_header_bufs[i] = static_cast<unsigned char *>(ut_align(
933
group->file_header_bufs_ptr[i],
934
OS_FILE_LOG_BLOCK_SIZE));
926
*(group->file_header_bufs + i) = ut_align(
927
mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
928
OS_FILE_LOG_BLOCK_SIZE);
936
930
memset(*(group->file_header_bufs + i), '\0',
937
931
LOG_FILE_HDR_SIZE);
939
933
#ifdef UNIV_LOG_ARCHIVE
940
group->archive_file_header_bufs_ptr[i] = mem_alloc(
941
LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
943
group->archive_file_header_bufs[i] = ut_align(
944
group->archive_file_header_bufs_ptr[i],
934
*(group->archive_file_header_bufs + i) = ut_align(
935
mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),
945
936
OS_FILE_LOG_BLOCK_SIZE);
947
937
memset(*(group->archive_file_header_bufs + i), '\0',
948
938
LOG_FILE_HDR_SIZE);
949
939
#endif /* UNIV_LOG_ARCHIVE */
956
946
group->archived_offset = 0;
957
947
#endif /* UNIV_LOG_ARCHIVE */
959
group->checkpoint_buf_ptr = static_cast<unsigned char *>(mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE));
960
group->checkpoint_buf = static_cast<unsigned char*>(ut_align(group->checkpoint_buf_ptr,
961
OS_FILE_LOG_BLOCK_SIZE));
949
group->checkpoint_buf = ut_align(
950
mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE), OS_FILE_LOG_BLOCK_SIZE);
963
952
memset(group->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
1160
1148
ulint dest_offset;
1162
1150
ut_ad(mutex_own(&(log_sys->mutex)));
1163
ut_ad(!recv_no_log_write);
1164
1151
ut_a(nth_file < group->n_files);
1166
1153
buf = *(group->file_header_bufs + nth_file);
1168
1155
mach_write_to_4(buf + LOG_GROUP_ID, group->id);
1169
mach_write_to_8(buf + LOG_FILE_START_LSN, start_lsn);
1156
mach_write_ull(buf + LOG_FILE_START_LSN, start_lsn);
1171
1158
/* Wipe over possible label of ibbackup --restore */
1172
1159
memcpy(buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, " ", 4);
1655
1640
recv_apply_hashed_log_recs(TRUE);
1658
n_pages = buf_flush_list(ULINT_MAX, new_oldest);
1643
n_pages = buf_flush_batch(BUF_FLUSH_LIST, ULINT_MAX, new_oldest);
1661
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
1646
buf_flush_wait_batch_end(BUF_FLUSH_LIST);
1664
1649
if (n_pages == ULINT_UNDEFINED) {
1770
1755
buf = group->checkpoint_buf;
1772
mach_write_to_8(buf + LOG_CHECKPOINT_NO, log_sys->next_checkpoint_no);
1773
mach_write_to_8(buf + LOG_CHECKPOINT_LSN, log_sys->next_checkpoint_lsn);
1757
mach_write_ull(buf + LOG_CHECKPOINT_NO, log_sys->next_checkpoint_no);
1758
mach_write_ull(buf + LOG_CHECKPOINT_LSN, log_sys->next_checkpoint_lsn);
1775
1760
mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,
1776
1761
log_group_calc_lsn_offset(
1793
mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn);
1778
mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn);
1794
1779
#else /* UNIV_LOG_ARCHIVE */
1795
mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
1780
mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
1796
1781
#endif /* UNIV_LOG_ARCHIVE */
1798
1783
for (i = 0; i < LOG_MAX_N_GROUPS; i++) {
1884
1869
ib_uint64_t lsn;
1886
1871
mach_write_to_4(hdr_buf + LOG_GROUP_ID, 0);
1887
mach_write_to_8(hdr_buf + LOG_FILE_START_LSN, start);
1872
mach_write_ull(hdr_buf + LOG_FILE_START_LSN, start);
1889
1874
lsn = start + LOG_BLOCK_HDR_SIZE;
1896
1881
+ (sizeof "ibbackup ") - 1));
1897
1882
buf = hdr_buf + LOG_CHECKPOINT_1;
1899
mach_write_to_8(buf + LOG_CHECKPOINT_NO, 0);
1900
mach_write_to_8(buf + LOG_CHECKPOINT_LSN, lsn);
1884
mach_write_ull(buf + LOG_CHECKPOINT_NO, 0);
1885
mach_write_ull(buf + LOG_CHECKPOINT_LSN, lsn);
1902
1887
mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,
1903
1888
LOG_FILE_HDR_SIZE + LOG_BLOCK_HDR_SIZE);
1905
1890
mach_write_to_4(buf + LOG_CHECKPOINT_LOG_BUF_SIZE, 2 * 1024 * 1024);
1907
mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
1892
mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
1909
1894
fold = ut_fold_binary(buf, LOG_CHECKPOINT_CHECKSUM_1);
1910
1895
mach_write_to_4(buf + LOG_CHECKPOINT_CHECKSUM_1, fold);
2073
2057
/* Preflush pages synchronously */
2075
while (!log_preflush_pool_modified_pages(lsn, TRUE)) {}
2059
while (!log_preflush_pool_modified_pages(lsn, TRUE));
2077
while (!log_checkpoint(TRUE, write_always)) {}
2061
while (!log_checkpoint(TRUE, write_always));
2080
2064
/****************************************************************//**
2241
2224
log_archived_file_name_gen(
2242
2225
/*=======================*/
2243
2226
char* buf, /*!< in: buffer where to write */
2244
ulint /*id __attribute__((unused))*/,
2227
ulint id __attribute__((unused)),
2245
2228
/*!< in: group id;
2246
2229
currently we only archive the first group */
2247
2230
ulint file_no)/*!< in: file number */
2272
2255
buf = *(group->archive_file_header_bufs + nth_file);
2274
2257
mach_write_to_4(buf + LOG_GROUP_ID, group->id);
2275
mach_write_to_8(buf + LOG_FILE_START_LSN, start_lsn);
2258
mach_write_ull(buf + LOG_FILE_START_LSN, start_lsn);
2276
2259
mach_write_to_4(buf + LOG_FILE_NO, file_no);
2278
2261
mach_write_to_4(buf + LOG_FILE_ARCH_COMPLETED, FALSE);
2308
2291
buf = *(group->archive_file_header_bufs + nth_file);
2310
2293
mach_write_to_4(buf + LOG_FILE_ARCH_COMPLETED, TRUE);
2311
mach_write_to_8(buf + LOG_FILE_END_LSN, end_lsn);
2294
mach_write_ull(buf + LOG_FILE_END_LSN, end_lsn);
2313
2296
dest_offset = nth_file * group->file_size + LOG_FILE_ARCH_COMPLETED;
2372
2355
log_archived_file_name_gen(name, group->id,
2373
2356
group->archived_file_no + n_files);
2375
file_handle = os_file_create(innodb_file_log_key,
2358
file_handle = os_file_create(name, open_mode, OS_FILE_AIO,
2378
2359
OS_DATA_FILE, &ret);
2380
2361
if (!ret && (open_mode == OS_FILE_CREATE)) {
2381
2362
file_handle = os_file_create(
2382
innodb_file_log_key, name, OS_FILE_OPEN,
2383
OS_FILE_AIO, OS_DATA_FILE, &ret);
2363
name, OS_FILE_OPEN, OS_FILE_AIO,
2364
OS_DATA_FILE, &ret);
3099
3079
if (srv_fast_shutdown < 2
3100
3080
&& (srv_error_monitor_active
3101
|| srv_lock_timeout_active
3102
|| srv_monitor_active)) {
3081
|| srv_lock_timeout_and_monitor_active)) {
3104
3083
mutex_exit(&kernel_mutex);
3106
os_event_set(srv_error_event);
3107
os_event_set(srv_monitor_event);
3108
os_event_set(srv_timeout_event);
3134
3109
log_buffer_flush_to_disk();
3136
mutex_exit(&kernel_mutex);
3138
3111
return; /* We SKIP ALL THE REST !! */
3114
/* Check that the master thread is suspended */
3116
if (srv_n_threads_active[SRV_MASTER] != 0) {
3118
mutex_exit(&kernel_mutex);
3141
3123
mutex_exit(&kernel_mutex);
3143
/* Check that the background threads are suspended */
3145
if (srv_is_any_background_thread_active()) {
3149
3125
mutex_enter(&(log_sys->mutex));
3151
3127
if (log_sys->n_pending_checkpoint_writes
3204
3180
mutex_exit(&(log_sys->mutex));
3206
/* Check that the background threads stay suspended */
3207
if (srv_is_any_background_thread_active()) {
3182
mutex_enter(&kernel_mutex);
3183
/* Check that the master thread has stayed suspended */
3184
if (srv_n_threads_active[SRV_MASTER] != 0) {
3208
3185
fprintf(stderr,
3209
"InnoDB: Warning: some background thread woke up"
3186
"InnoDB: Warning: the master thread woke up"
3210
3187
" during shutdown\n");
3189
mutex_exit(&kernel_mutex);
3193
mutex_exit(&kernel_mutex);
3215
3195
fil_flush_file_spaces(FIL_TABLESPACE);
3216
3196
fil_flush_file_spaces(FIL_LOG);
3228
3208
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
3230
3210
/* Make some checks that the server really is quiet */
3231
ut_a(!srv_is_any_background_thread_active());
3211
ut_a(srv_n_threads_active[SRV_MASTER] == 0);
3233
3212
ut_a(buf_all_freed());
3234
3213
ut_a(lsn == log_sys->lsn);
3250
3229
fil_close_all_files();
3252
3231
/* Make some checks that the server really is quiet */
3253
ut_a(!srv_is_any_background_thread_active());
3232
ut_a(srv_n_threads_active[SRV_MASTER] == 0);
3255
3233
ut_a(buf_all_freed());
3256
3234
ut_a(lsn == log_sys->lsn);
3259
#ifdef UNIV_LOG_DEBUG
3260
3237
/******************************************************//**
3261
3238
Checks by parsing that the catenated log segment for a single mtr is
3265
3242
log_check_log_recs(
3266
3243
/*===============*/
3267
const byte* buf, /*!< in: pointer to the start of
3244
byte* buf, /*!< in: pointer to the start of
3268
3245
the log segment in the
3269
3246
log_sys->buf log buffer */
3270
3247
ulint len, /*!< in: segment length in bytes */
3293
3270
ut_memcpy(scan_buf, start, end - start);
3295
recv_scan_log_recs((buf_pool_get_n_pages()
3296
- (recv_n_pool_free_frames * srv_buf_pool_instances))
3297
* UNIV_PAGE_SIZE, FALSE, scan_buf, end - start,
3272
recv_scan_log_recs((buf_pool->curr_size
3273
- recv_n_pool_free_frames) * UNIV_PAGE_SIZE,
3274
FALSE, scan_buf, end - start,
3298
3275
ut_uint64_align_down(buf_start_lsn,
3299
3276
OS_FILE_LOG_BLOCK_SIZE),
3300
3277
&contiguous_lsn, &scanned_lsn);
3378
3354
log_sys->n_log_ios_old = log_sys->n_log_ios;
3379
3355
log_sys->last_printout_time = time(NULL);
3382
/**********************************************************************
3383
Closes a log group. */
3388
log_group_t* group) /* in,own: log group to close */
3392
for (i = 0; i < group->n_files; i++) {
3393
mem_free(group->file_header_bufs_ptr[i]);
3394
#ifdef UNIV_LOG_ARCHIVE
3395
mem_free(group->archive_file_header_bufs_ptr[i]);
3396
#endif /* UNIV_LOG_ARCHIVE */
3399
mem_free(group->file_header_bufs_ptr);
3400
mem_free(group->file_header_bufs);
3402
#ifdef UNIV_LOG_ARCHIVE
3403
mem_free(group->archive_file_header_bufs_ptr);
3404
mem_free(group->archive_file_header_bufs);
3405
#endif /* UNIV_LOG_ARCHIVE */
3407
mem_free(group->checkpoint_buf_ptr);
3412
/**********************************************************
3413
Shutdown the log system but do not release all the memory. */
3421
group = UT_LIST_GET_FIRST(log_sys->log_groups);
3423
while (UT_LIST_GET_LEN(log_sys->log_groups) > 0) {
3424
log_group_t* prev_group = group;
3426
group = UT_LIST_GET_NEXT(log_groups, group);
3427
UT_LIST_REMOVE(log_groups, log_sys->log_groups, prev_group);
3429
log_group_close(prev_group);
3432
mem_free(log_sys->buf_ptr);
3433
log_sys->buf_ptr = NULL;
3434
log_sys->buf = NULL;
3435
mem_free(log_sys->checkpoint_buf_ptr);
3436
log_sys->checkpoint_buf_ptr = NULL;
3437
log_sys->checkpoint_buf = NULL;
3439
os_event_free(log_sys->no_flush_event);
3440
os_event_free(log_sys->one_flushed_event);
3442
rw_lock_free(&log_sys->checkpoint_lock);
3444
mutex_free(&log_sys->mutex);
3446
#ifdef UNIV_LOG_ARCHIVE
3447
rw_lock_free(&log_sys->archive_lock);
3448
os_event_create(log_sys->archiving_on);
3449
#endif /* UNIV_LOG_ARCHIVE */
3451
#ifdef UNIV_LOG_DEBUG
3452
recv_sys_debug_free();
3458
/**********************************************************
3459
Free the log system data structures. */
3465
if (log_sys != NULL) {
3466
recv_sys_mem_free();
3472
3357
#endif /* !UNIV_HOTBACKUP */