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., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 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
84
99
/* Global log system variable */
85
100
UNIV_INTERN log_t* log_sys = NULL;
87
#ifdef UNIV_PFS_RWLOCK
88
UNIV_INTERN mysql_pfs_key_t checkpoint_lock_key;
89
# ifdef UNIV_LOG_ARCHIVE
90
UNIV_INTERN mysql_pfs_key_t archive_lock_key;
92
#endif /* UNIV_PFS_RWLOCK */
95
UNIV_INTERN mysql_pfs_key_t log_sys_mutex_key;
96
UNIV_INTERN mysql_pfs_key_t log_flush_order_mutex_key;
97
#endif /* UNIV_PFS_MUTEX */
100
103
UNIV_INTERN ibool log_do_write = TRUE;
101
104
#endif /* UNIV_DEBUG */
333
log_block = static_cast<unsigned char *>(ut_align_down(log->buf + log->buf_free,
334
OS_FILE_LOG_BLOCK_SIZE));
336
log_block = ut_align_down(log->buf + log->buf_free,
337
OS_FILE_LOG_BLOCK_SIZE);
335
338
log_block_set_data_len(log_block, data_len);
337
340
if (data_len == OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
383
log_block = static_cast<unsigned char *>(ut_align_down(log->buf + log->buf_free,
384
OS_FILE_LOG_BLOCK_SIZE));
386
log_block = ut_align_down(log->buf + log->buf_free,
387
OS_FILE_LOG_BLOCK_SIZE);
385
388
first_rec_group = log_block_get_first_rec_group(log_block);
387
390
if (first_rec_group == 0) {
771
log_sys = static_cast<log_t *>(mem_alloc(sizeof(log_t)));
773
mutex_create(log_sys_mutex_key, &log_sys->mutex, SYNC_LOG);
775
mutex_create(log_flush_order_mutex_key,
776
&log_sys->log_flush_order_mutex,
777
SYNC_LOG_FLUSH_ORDER);
774
log_sys = mem_alloc(sizeof(log_t));
776
mutex_create(&log_sys->mutex, SYNC_LOG);
779
778
mutex_enter(&(log_sys->mutex));
786
785
ut_a(LOG_BUFFER_SIZE >= 16 * OS_FILE_LOG_BLOCK_SIZE);
787
786
ut_a(LOG_BUFFER_SIZE >= 4 * UNIV_PAGE_SIZE);
789
log_sys->buf_ptr = static_cast<unsigned char *>(mem_alloc(LOG_BUFFER_SIZE + OS_FILE_LOG_BLOCK_SIZE));
790
log_sys->buf = static_cast<unsigned char *>(ut_align(log_sys->buf_ptr, OS_FILE_LOG_BLOCK_SIZE));
788
log_sys->buf_ptr = mem_alloc(LOG_BUFFER_SIZE + OS_FILE_LOG_BLOCK_SIZE);
789
log_sys->buf = ut_align(log_sys->buf_ptr, OS_FILE_LOG_BLOCK_SIZE);
792
791
log_sys->buf_size = LOG_BUFFER_SIZE;
830
829
log_sys->last_checkpoint_lsn = log_sys->lsn;
831
830
log_sys->n_pending_checkpoint_writes = 0;
833
rw_lock_create(checkpoint_lock_key, &log_sys->checkpoint_lock,
834
SYNC_NO_ORDER_CHECK);
832
rw_lock_create(&log_sys->checkpoint_lock, SYNC_NO_ORDER_CHECK);
836
log_sys->checkpoint_buf_ptr = static_cast<unsigned char *>(mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE));
837
log_sys->checkpoint_buf = static_cast<unsigned char *>(ut_align(log_sys->checkpoint_buf_ptr,
838
OS_FILE_LOG_BLOCK_SIZE));
834
log_sys->checkpoint_buf_ptr = mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE);
835
log_sys->checkpoint_buf = ut_align(log_sys->checkpoint_buf_ptr,
836
OS_FILE_LOG_BLOCK_SIZE);
839
837
memset(log_sys->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
840
838
/*----------------------------*/
848
846
log_sys->n_pending_archive_ios = 0;
850
rw_lock_create(archive_lock_key, &log_sys->archive_lock,
851
SYNC_NO_ORDER_CHECK);
848
rw_lock_create(&log_sys->archive_lock, SYNC_NO_ORDER_CHECK);
853
850
log_sys->archive_buf = NULL;
897
894
ulint space_id, /*!< in: space id of the file space
898
895
which contains the log files of this
900
ulint /*archive_space_id __attribute__((unused))*/)
897
ulint archive_space_id __attribute__((unused)))
901
898
/*!< in: space id of the file space
902
899
which contains some archived log
903
900
files for this group; currently, only
919
916
group->lsn_offset = LOG_FILE_HDR_SIZE;
920
917
group->n_pending_writes = 0;
922
group->file_header_bufs_ptr = static_cast<unsigned char **>(mem_alloc(sizeof(byte*) * n_files));
923
group->file_header_bufs = static_cast<unsigned char **>(mem_alloc(sizeof(byte*) * n_files));
919
group->file_header_bufs_ptr = mem_alloc(sizeof(byte*) * n_files);
920
group->file_header_bufs = mem_alloc(sizeof(byte*) * n_files);
924
921
#ifdef UNIV_LOG_ARCHIVE
925
922
group->archive_file_header_bufs_ptr = mem_alloc(
926
923
sizeof(byte*) * n_files);
928
925
#endif /* UNIV_LOG_ARCHIVE */
930
927
for (i = 0; i < n_files; i++) {
931
group->file_header_bufs_ptr[i] = static_cast<unsigned char *>(mem_alloc(
932
LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE));
928
group->file_header_bufs_ptr[i] = mem_alloc(
929
LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
934
group->file_header_bufs[i] = static_cast<unsigned char *>(ut_align(
931
group->file_header_bufs[i] = ut_align(
935
932
group->file_header_bufs_ptr[i],
936
OS_FILE_LOG_BLOCK_SIZE));
933
OS_FILE_LOG_BLOCK_SIZE);
938
935
memset(*(group->file_header_bufs + i), '\0',
939
936
LOG_FILE_HDR_SIZE);
958
955
group->archived_offset = 0;
959
956
#endif /* UNIV_LOG_ARCHIVE */
961
group->checkpoint_buf_ptr = static_cast<unsigned char *>(mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE));
962
group->checkpoint_buf = static_cast<unsigned char*>(ut_align(group->checkpoint_buf_ptr,
963
OS_FILE_LOG_BLOCK_SIZE));
958
group->checkpoint_buf_ptr = mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE);
959
group->checkpoint_buf = ut_align(group->checkpoint_buf_ptr,
960
OS_FILE_LOG_BLOCK_SIZE);
965
962
memset(group->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
1168
1165
buf = *(group->file_header_bufs + nth_file);
1170
1167
mach_write_to_4(buf + LOG_GROUP_ID, group->id);
1171
mach_write_to_8(buf + LOG_FILE_START_LSN, start_lsn);
1168
mach_write_ull(buf + LOG_FILE_START_LSN, start_lsn);
1173
1170
/* Wipe over possible label of ibbackup --restore */
1174
1171
memcpy(buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, " ", 4);
1657
1654
recv_apply_hashed_log_recs(TRUE);
1660
n_pages = buf_flush_list(ULINT_MAX, new_oldest);
1657
n_pages = buf_flush_batch(BUF_FLUSH_LIST, ULINT_MAX, new_oldest);
1663
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
1660
buf_flush_wait_batch_end(BUF_FLUSH_LIST);
1666
1663
if (n_pages == ULINT_UNDEFINED) {
1772
1769
buf = group->checkpoint_buf;
1774
mach_write_to_8(buf + LOG_CHECKPOINT_NO, log_sys->next_checkpoint_no);
1775
mach_write_to_8(buf + LOG_CHECKPOINT_LSN, log_sys->next_checkpoint_lsn);
1771
mach_write_ull(buf + LOG_CHECKPOINT_NO, log_sys->next_checkpoint_no);
1772
mach_write_ull(buf + LOG_CHECKPOINT_LSN, log_sys->next_checkpoint_lsn);
1777
1774
mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,
1778
1775
log_group_calc_lsn_offset(
1795
mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn);
1792
mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn);
1796
1793
#else /* UNIV_LOG_ARCHIVE */
1797
mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
1794
mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
1798
1795
#endif /* UNIV_LOG_ARCHIVE */
1800
1797
for (i = 0; i < LOG_MAX_N_GROUPS; i++) {
1886
1883
ib_uint64_t lsn;
1888
1885
mach_write_to_4(hdr_buf + LOG_GROUP_ID, 0);
1889
mach_write_to_8(hdr_buf + LOG_FILE_START_LSN, start);
1886
mach_write_ull(hdr_buf + LOG_FILE_START_LSN, start);
1891
1888
lsn = start + LOG_BLOCK_HDR_SIZE;
1898
1895
+ (sizeof "ibbackup ") - 1));
1899
1896
buf = hdr_buf + LOG_CHECKPOINT_1;
1901
mach_write_to_8(buf + LOG_CHECKPOINT_NO, 0);
1902
mach_write_to_8(buf + LOG_CHECKPOINT_LSN, lsn);
1898
mach_write_ull(buf + LOG_CHECKPOINT_NO, 0);
1899
mach_write_ull(buf + LOG_CHECKPOINT_LSN, lsn);
1904
1901
mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,
1905
1902
LOG_FILE_HDR_SIZE + LOG_BLOCK_HDR_SIZE);
1907
1904
mach_write_to_4(buf + LOG_CHECKPOINT_LOG_BUF_SIZE, 2 * 1024 * 1024);
1909
mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
1906
mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
1911
1908
fold = ut_fold_binary(buf, LOG_CHECKPOINT_CHECKSUM_1);
1912
1909
mach_write_to_4(buf + LOG_CHECKPOINT_CHECKSUM_1, fold);
2075
2072
/* Preflush pages synchronously */
2077
while (!log_preflush_pool_modified_pages(lsn, TRUE)) {}
2074
while (!log_preflush_pool_modified_pages(lsn, TRUE));
2079
while (!log_checkpoint(TRUE, write_always)) {}
2076
while (!log_checkpoint(TRUE, write_always));
2082
2079
/****************************************************************//**
2243
2240
log_archived_file_name_gen(
2244
2241
/*=======================*/
2245
2242
char* buf, /*!< in: buffer where to write */
2246
ulint /*id __attribute__((unused))*/,
2243
ulint id __attribute__((unused)),
2247
2244
/*!< in: group id;
2248
2245
currently we only archive the first group */
2249
2246
ulint file_no)/*!< in: file number */
2274
2271
buf = *(group->archive_file_header_bufs + nth_file);
2276
2273
mach_write_to_4(buf + LOG_GROUP_ID, group->id);
2277
mach_write_to_8(buf + LOG_FILE_START_LSN, start_lsn);
2274
mach_write_ull(buf + LOG_FILE_START_LSN, start_lsn);
2278
2275
mach_write_to_4(buf + LOG_FILE_NO, file_no);
2280
2277
mach_write_to_4(buf + LOG_FILE_ARCH_COMPLETED, FALSE);
2310
2307
buf = *(group->archive_file_header_bufs + nth_file);
2312
2309
mach_write_to_4(buf + LOG_FILE_ARCH_COMPLETED, TRUE);
2313
mach_write_to_8(buf + LOG_FILE_END_LSN, end_lsn);
2310
mach_write_ull(buf + LOG_FILE_END_LSN, end_lsn);
2315
2312
dest_offset = nth_file * group->file_size + LOG_FILE_ARCH_COMPLETED;
2374
2371
log_archived_file_name_gen(name, group->id,
2375
2372
group->archived_file_no + n_files);
2377
file_handle = os_file_create(innodb_file_log_key,
2374
file_handle = os_file_create(name, open_mode, OS_FILE_AIO,
2380
2375
OS_DATA_FILE, &ret);
2382
2377
if (!ret && (open_mode == OS_FILE_CREATE)) {
2383
2378
file_handle = os_file_create(
2384
innodb_file_log_key, name, OS_FILE_OPEN,
2385
OS_FILE_AIO, OS_DATA_FILE, &ret);
2379
name, OS_FILE_OPEN, OS_FILE_AIO,
2380
OS_DATA_FILE, &ret);
3101
3096
if (srv_fast_shutdown < 2
3102
3097
&& (srv_error_monitor_active
3103
|| srv_lock_timeout_active
3104
|| srv_monitor_active)) {
3098
|| srv_lock_timeout_and_monitor_active)) {
3106
3100
mutex_exit(&kernel_mutex);
3108
os_event_set(srv_error_event);
3109
os_event_set(srv_monitor_event);
3110
os_event_set(srv_timeout_event);
3136
3126
log_buffer_flush_to_disk();
3138
mutex_exit(&kernel_mutex);
3140
3128
return; /* We SKIP ALL THE REST !! */
3131
/* Check that the master thread is suspended */
3133
if (srv_n_threads_active[SRV_MASTER] != 0) {
3135
mutex_exit(&kernel_mutex);
3143
3140
mutex_exit(&kernel_mutex);
3145
/* Check that the background threads are suspended */
3147
if (srv_is_any_background_thread_active()) {
3151
3142
mutex_enter(&(log_sys->mutex));
3153
3144
if (log_sys->n_pending_checkpoint_writes
3206
3197
mutex_exit(&(log_sys->mutex));
3208
/* Check that the background threads stay suspended */
3209
if (srv_is_any_background_thread_active()) {
3199
mutex_enter(&kernel_mutex);
3200
/* Check that the master thread has stayed suspended */
3201
if (srv_n_threads_active[SRV_MASTER] != 0) {
3210
3202
fprintf(stderr,
3211
"InnoDB: Warning: some background thread woke up"
3203
"InnoDB: Warning: the master thread woke up"
3212
3204
" during shutdown\n");
3206
mutex_exit(&kernel_mutex);
3210
mutex_exit(&kernel_mutex);
3217
3212
fil_flush_file_spaces(FIL_TABLESPACE);
3218
3213
fil_flush_file_spaces(FIL_LOG);
3230
3225
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
3232
3227
/* Make some checks that the server really is quiet */
3233
ut_a(!srv_is_any_background_thread_active());
3228
ut_a(srv_n_threads_active[SRV_MASTER] == 0);
3235
3229
ut_a(buf_all_freed());
3236
3230
ut_a(lsn == log_sys->lsn);
3238
3232
if (lsn < srv_start_lsn) {
3239
drizzled::errmsg_printf(drizzled::error::ERROR,
3240
"InnoDB: Error: log sequence number at shutdown %"PRIu64" is lower than at startup %"PRIu64"!",
3241
lsn, srv_start_lsn);
3234
"InnoDB: Error: log sequence number"
3235
" at shutdown %"PRIu64"\n"
3236
"InnoDB: is lower than at startup %"PRIu64"!\n",
3237
lsn, srv_start_lsn);
3244
3240
srv_shutdown_lsn = lsn;
3293
3288
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,
3290
recv_scan_log_recs((buf_pool->curr_size
3291
- recv_n_pool_free_frames) * UNIV_PAGE_SIZE,
3292
FALSE, scan_buf, end - start,
3298
3293
ut_uint64_align_down(buf_start_lsn,
3299
3294
OS_FILE_LOG_BLOCK_SIZE),
3300
3295
&contiguous_lsn, &scanned_lsn);