summaryrefslogtreecommitdiff
path: root/storage/xtradb/log/log0log.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/log/log0log.c')
-rw-r--r--storage/xtradb/log/log0log.c228
1 files changed, 121 insertions, 107 deletions
diff --git a/storage/xtradb/log/log0log.c b/storage/xtradb/log/log0log.c
index b9f19aeff31..80449e1c23a 100644
--- a/storage/xtradb/log/log0log.c
+++ b/storage/xtradb/log/log0log.c
@@ -48,6 +48,7 @@ Created 12/9/1995 Heikki Tuuri
#include "srv0start.h"
#include "trx0sys.h"
#include "trx0trx.h"
+#include "ha_prototypes.h"
/*
General philosophy of InnoDB redo-logs:
@@ -82,6 +83,18 @@ UNIV_INTERN ulint log_fsp_current_free_limit = 0;
/* Global log system variable */
UNIV_INTERN log_t* log_sys = NULL;
+#ifdef UNIV_PFS_RWLOCK
+UNIV_INTERN mysql_pfs_key_t checkpoint_lock_key;
+# ifdef UNIV_LOG_ARCHIVE
+UNIV_INTERN mysql_pfs_key_t archive_lock_key;
+# endif
+#endif /* UNIV_PFS_RWLOCK */
+
+#ifdef UNIV_PFS_MUTEX
+UNIV_INTERN mysql_pfs_key_t log_sys_mutex_key;
+UNIV_INTERN mysql_pfs_key_t log_flush_order_mutex_key;
+#endif /* UNIV_PFS_MUTEX */
+
#ifdef UNIV_DEBUG
UNIV_INTERN ibool log_do_write = TRUE;
#endif /* UNIV_DEBUG */
@@ -785,7 +798,11 @@ log_init(void)
{
log_sys = mem_alloc(sizeof(log_t));
- mutex_create(&log_sys->mutex, SYNC_LOG);
+ mutex_create(log_sys_mutex_key, &log_sys->mutex, SYNC_LOG);
+
+ mutex_create(log_flush_order_mutex_key,
+ &log_sys->log_flush_order_mutex,
+ SYNC_LOG_FLUSH_ORDER);
mutex_enter(&(log_sys->mutex));
@@ -841,7 +858,8 @@ log_init(void)
log_sys->last_checkpoint_lsn = log_sys->lsn;
log_sys->n_pending_checkpoint_writes = 0;
- rw_lock_create(&log_sys->checkpoint_lock, SYNC_NO_ORDER_CHECK);
+ rw_lock_create(checkpoint_lock_key, &log_sys->checkpoint_lock,
+ SYNC_NO_ORDER_CHECK);
log_sys->checkpoint_buf_ptr = mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE);
log_sys->checkpoint_buf = ut_align(log_sys->checkpoint_buf_ptr,
@@ -857,7 +875,8 @@ log_init(void)
log_sys->n_pending_archive_ios = 0;
- rw_lock_create(&log_sys->archive_lock, SYNC_NO_ORDER_CHECK);
+ rw_lock_create(archive_lock_key, &log_sys->archive_lock,
+ SYNC_NO_ORDER_CHECK);
log_sys->archive_buf = NULL;
@@ -1114,7 +1133,7 @@ log_io_complete(
&& srv_unix_file_flush_method != SRV_UNIX_ALL_O_DIRECT
&& srv_unix_file_flush_method != SRV_UNIX_NOSYNC) {
- fil_flush(group->space_id);
+ fil_flush(group->space_id, FALSE);
}
#ifdef UNIV_DEBUG
@@ -1135,9 +1154,9 @@ log_io_complete(
if (srv_unix_file_flush_method != SRV_UNIX_O_DSYNC
&& srv_unix_file_flush_method != SRV_UNIX_ALL_O_DIRECT
&& srv_unix_file_flush_method != SRV_UNIX_NOSYNC
- && srv_flush_log_at_trx_commit != 2) {
+ && thd_flush_log_at_trx_commit(NULL) != 2) {
- fil_flush(group->space_id);
+ fil_flush(group->space_id, FALSE);
}
mutex_enter(&(log_sys->mutex));
@@ -1179,11 +1198,14 @@ log_group_file_header_flush(
buf = *(group->file_header_bufs + nth_file);
mach_write_to_4(buf + LOG_GROUP_ID, group->id);
- mach_write_ull(buf + LOG_FILE_START_LSN, start_lsn);
+ mach_write_to_8(buf + LOG_FILE_START_LSN, start_lsn);
/* Wipe over possible label of ibbackup --restore */
memcpy(buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, " ", 4);
+ mach_write_to_4(buf + LOG_FILE_OS_FILE_LOG_BLOCK_SIZE,
+ srv_log_block_size);
+
dest_offset = nth_file * group->file_size;
#ifdef UNIV_DEBUG
@@ -1525,7 +1547,7 @@ loop:
group = UT_LIST_GET_FIRST(log_sys->log_groups);
- fil_flush(group->space_id);
+ fil_flush(group->space_id, FALSE);
log_sys->flushed_to_disk_lsn = log_sys->write_lsn;
}
@@ -1669,10 +1691,10 @@ log_preflush_pool_modified_pages(
recv_apply_hashed_log_recs(TRUE);
}
- n_pages = buf_flush_batch(BUF_FLUSH_LIST, ULINT_MAX, new_oldest);
+ n_pages = buf_flush_list(ULINT_MAX, new_oldest);
if (sync) {
- buf_flush_wait_batch_end(BUF_FLUSH_LIST);
+ buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
}
if (n_pages == ULINT_UNDEFINED) {
@@ -1777,14 +1799,12 @@ log_group_checkpoint(
ulint i;
ut_ad(mutex_own(&(log_sys->mutex)));
-#if LOG_CHECKPOINT_SIZE > OS_FILE_LOG_BLOCK_SIZE
-# error "LOG_CHECKPOINT_SIZE > OS_FILE_LOG_BLOCK_SIZE"
-#endif
+ ut_a(LOG_CHECKPOINT_SIZE <= OS_FILE_LOG_BLOCK_SIZE);
buf = group->checkpoint_buf;
- mach_write_ull(buf + LOG_CHECKPOINT_NO, log_sys->next_checkpoint_no);
- mach_write_ull(buf + LOG_CHECKPOINT_LSN, log_sys->next_checkpoint_lsn);
+ mach_write_to_8(buf + LOG_CHECKPOINT_NO, log_sys->next_checkpoint_no);
+ mach_write_to_8(buf + LOG_CHECKPOINT_LSN, log_sys->next_checkpoint_lsn);
mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,
log_group_calc_lsn_offset(
@@ -1805,9 +1825,9 @@ log_group_checkpoint(
}
}
- mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn);
+ mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn);
#else /* UNIV_LOG_ARCHIVE */
- mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN,
+ mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN,
(ib_uint64_t)log_group_calc_lsn_offset(
log_sys->next_checkpoint_lsn, group));
#endif /* UNIV_LOG_ARCHIVE */
@@ -1901,7 +1921,7 @@ log_reset_first_header_and_checkpoint(
ib_uint64_t lsn;
mach_write_to_4(hdr_buf + LOG_GROUP_ID, 0);
- mach_write_ull(hdr_buf + LOG_FILE_START_LSN, start);
+ mach_write_to_8(hdr_buf + LOG_FILE_START_LSN, start);
lsn = start + LOG_BLOCK_HDR_SIZE;
@@ -1913,15 +1933,15 @@ log_reset_first_header_and_checkpoint(
+ (sizeof "ibbackup ") - 1));
buf = hdr_buf + LOG_CHECKPOINT_1;
- mach_write_ull(buf + LOG_CHECKPOINT_NO, 0);
- mach_write_ull(buf + LOG_CHECKPOINT_LSN, lsn);
+ mach_write_to_8(buf + LOG_CHECKPOINT_NO, 0);
+ mach_write_to_8(buf + LOG_CHECKPOINT_LSN, lsn);
mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,
LOG_FILE_HDR_SIZE + LOG_BLOCK_HDR_SIZE);
mach_write_to_4(buf + LOG_CHECKPOINT_LOG_BUF_SIZE, 2 * 1024 * 1024);
- mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
+ mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
fold = ut_fold_binary(buf, LOG_CHECKPOINT_CHECKSUM_1);
mach_write_to_4(buf + LOG_CHECKPOINT_CHECKSUM_1, fold);
@@ -2289,7 +2309,7 @@ log_group_archive_file_header_write(
buf = *(group->archive_file_header_bufs + nth_file);
mach_write_to_4(buf + LOG_GROUP_ID, group->id);
- mach_write_ull(buf + LOG_FILE_START_LSN, start_lsn);
+ mach_write_to_8(buf + LOG_FILE_START_LSN, start_lsn);
mach_write_to_4(buf + LOG_FILE_NO, file_no);
mach_write_to_4(buf + LOG_FILE_ARCH_COMPLETED, FALSE);
@@ -2325,7 +2345,7 @@ log_group_archive_completed_header_write(
buf = *(group->archive_file_header_bufs + nth_file);
mach_write_to_4(buf + LOG_FILE_ARCH_COMPLETED, TRUE);
- mach_write_ull(buf + LOG_FILE_END_LSN, end_lsn);
+ mach_write_to_8(buf + LOG_FILE_END_LSN, end_lsn);
dest_offset = nth_file * group->file_size + LOG_FILE_ARCH_COMPLETED;
@@ -2389,13 +2409,15 @@ loop:
log_archived_file_name_gen(name, group->id,
group->archived_file_no + n_files);
- file_handle = os_file_create(name, open_mode, OS_FILE_AIO,
+ file_handle = os_file_create(innodb_file_log_key,
+ name, open_mode,
+ OS_FILE_AIO,
OS_DATA_FILE, &ret);
if (!ret && (open_mode == OS_FILE_CREATE)) {
file_handle = os_file_create(
- name, OS_FILE_OPEN, OS_FILE_AIO,
- OS_DATA_FILE, &ret);
+ innodb_file_log_key, name, OS_FILE_OPEN,
+ OS_FILE_AIO, OS_DATA_FILE, &ret);
}
if (!ret) {
@@ -2622,7 +2644,7 @@ log_io_complete_archive(void)
mutex_exit(&(log_sys->mutex));
- fil_flush(group->archive_space_id);
+ fil_flush(group->archive_space_id, TRUE);
mutex_enter(&(log_sys->mutex));
@@ -3093,6 +3115,7 @@ logs_empty_and_mark_files_at_shutdown(void)
{
ib_uint64_t lsn;
ulint arch_log_no;
+ ibool server_busy;
if (srv_print_verbose_log) {
ut_print_timestamp(stderr);
@@ -3108,93 +3131,86 @@ loop:
mutex_enter(&kernel_mutex);
- /* We need the monitor threads to stop before we proceed with a
- normal shutdown. In case of very fast shutdown, however, we can
- proceed without waiting for monitor threads. */
+ /* We need the monitor threads to stop before we proceed with
+ a shutdown. */
- if (srv_fast_shutdown < 2
- && (srv_error_monitor_active
- || srv_lock_timeout_active || srv_monitor_active)) {
+ if (srv_error_monitor_active
+ || srv_lock_timeout_active
+ || srv_monitor_active) {
mutex_exit(&kernel_mutex);
- goto loop;
- }
-
- /* Check that there are no longer transactions. We need this wait even
- for the 'very fast' shutdown, because the InnoDB layer may have
- committed or prepared transactions and we don't want to lose them. */
-
- if (trx_n_mysql_transactions > 0
- || UT_LIST_GET_LEN(trx_sys->trx_list) > 0) {
-
- mutex_exit(&kernel_mutex);
+ os_event_set(srv_error_event);
+ os_event_set(srv_monitor_event);
+ os_event_set(srv_timeout_event);
goto loop;
}
- if (srv_fast_shutdown == 2) {
- /* In this fastest shutdown we do not flush the buffer pool:
- it is essentially a 'crash' of the InnoDB server. Make sure
- that the log is all flushed to disk, so that we can recover
- all committed transactions in a crash recovery. We must not
- write the lsn stamps to the data files, since at a startup
- InnoDB deduces from the stamps if the previous shutdown was
- clean. */
-
- log_buffer_flush_to_disk();
+ /* Check that there are no longer transactions, except for
+ PREPARED ones. We need this wait even for the 'very fast'
+ shutdown, because the InnoDB layer may have committed or
+ prepared transactions and we don't want to lose them. */
- return; /* We SKIP ALL THE REST !! */
- }
-
- /* Check that the master thread is suspended */
-
- if (srv_n_threads_active[SRV_MASTER] != 0) {
-
- mutex_exit(&kernel_mutex);
+ server_busy = trx_n_mysql_transactions > 0
+ || UT_LIST_GET_LEN(trx_sys->trx_list) > trx_n_prepared;
+ mutex_exit(&kernel_mutex);
+ if (server_busy || srv_is_any_background_thread_active()) {
goto loop;
}
- /* Check that the purge threads ended */
- if (srv_use_purge_thread
- && (srv_n_threads_active[SRV_PURGE] != 0
- || srv_n_threads_active[SRV_PURGE_WORKER] != 0)) {
-
- mutex_exit(&kernel_mutex);
+ mutex_enter(&log_sys->mutex);
+ server_busy = log_sys->n_pending_checkpoint_writes
+#ifdef UNIV_LOG_ARCHIVE
+ || log_sys->n_pending_archive_ios
+#endif /* UNIV_LOG_ARCHIVE */
+ || log_sys->n_pending_writes;
+ mutex_exit(&log_sys->mutex);
+ if (server_busy || !buf_pool_check_no_pending_io()) {
goto loop;
}
- mutex_exit(&kernel_mutex);
-
- mutex_enter(&(log_sys->mutex));
-
- if (log_sys->n_pending_checkpoint_writes
#ifdef UNIV_LOG_ARCHIVE
- || log_sys->n_pending_archive_ios
+ log_archive_all();
#endif /* UNIV_LOG_ARCHIVE */
- || log_sys->n_pending_writes) {
-
- mutex_exit(&(log_sys->mutex));
-
- goto loop;
- }
+ if (srv_fast_shutdown == 2) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: MySQL has requested a very fast shutdown"
+ " without flushing "
+ "the InnoDB buffer pool to data files."
+ " At the next mysqld startup "
+ "InnoDB will do a crash recovery!\n");
+
+ /* In this fastest shutdown we do not flush the buffer
+ pool: it is essentially a 'crash' of the InnoDB
+ server. Make sure that the log is all flushed to disk,
+ so that we can recover all committed transactions in a
+ crash recovery. We must not write the lsn stamps to
+ the data files, since at a startup InnoDB deduces from
+ the stamps if the previous shutdown was clean. */
- mutex_exit(&(log_sys->mutex));
+ log_buffer_flush_to_disk();
- if (!buf_pool_check_no_pending_io()) {
+ /* Check that the background threads stay suspended */
+ if (srv_is_any_background_thread_active()) {
+ fprintf(stderr,
+ "InnoDB: Warning: some background thread"
+ " woke up during shutdown\n");
+ goto loop;
+ }
- goto loop;
+ srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
+ fil_close_all_files();
+ ut_a(!srv_is_any_background_thread_active());
+ return;
}
-#ifdef UNIV_LOG_ARCHIVE
- log_archive_all();
-#endif /* UNIV_LOG_ARCHIVE */
-
log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE);
- mutex_enter(&(log_sys->mutex));
+ mutex_enter(&log_sys->mutex);
lsn = log_sys->lsn;
@@ -3205,7 +3221,7 @@ loop:
#endif /* UNIV_LOG_ARCHIVE */
) {
- mutex_exit(&(log_sys->mutex));
+ mutex_exit(&log_sys->mutex);
goto loop;
}
@@ -3223,20 +3239,16 @@ loop:
log_archive_close_groups(TRUE);
#endif /* UNIV_LOG_ARCHIVE */
- mutex_exit(&(log_sys->mutex));
+ mutex_exit(&log_sys->mutex);
- mutex_enter(&kernel_mutex);
- /* Check that the master thread has stayed suspended */
- if (srv_n_threads_active[SRV_MASTER] != 0) {
+ /* Check that the background threads stay suspended */
+ if (srv_is_any_background_thread_active()) {
fprintf(stderr,
- "InnoDB: Warning: the master thread woke up"
+ "InnoDB: Warning: some background thread woke up"
" during shutdown\n");
- mutex_exit(&kernel_mutex);
-
goto loop;
}
- mutex_exit(&kernel_mutex);
fil_flush_file_spaces(FIL_TABLESPACE);
fil_flush_file_spaces(FIL_LOG);
@@ -3254,7 +3266,8 @@ loop:
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
/* Make some checks that the server really is quiet */
- ut_a(srv_n_threads_active[SRV_MASTER] == 0);
+ ut_a(!srv_is_any_background_thread_active());
+
ut_a(buf_all_freed());
ut_a(lsn == log_sys->lsn);
@@ -3275,7 +3288,8 @@ loop:
fil_close_all_files();
/* Make some checks that the server really is quiet */
- ut_a(srv_n_threads_active[SRV_MASTER] == 0);
+ ut_a(!srv_is_any_background_thread_active());
+
ut_a(buf_all_freed());
ut_a(lsn == log_sys->lsn);
}
@@ -3316,9 +3330,9 @@ log_check_log_recs(
ut_memcpy(scan_buf, start, end - start);
- recv_scan_log_recs((buf_pool->curr_size
- - recv_n_pool_free_frames) * UNIV_PAGE_SIZE,
- FALSE, scan_buf, end - start,
+ recv_scan_log_recs((buf_pool_get_n_pages()
+ - (recv_n_pool_free_frames * srv_buf_pool_instances))
+ * UNIV_PAGE_SIZE, FALSE, scan_buf, end - start,
ut_uint64_align_down(buf_start_lsn,
OS_FILE_LOG_BLOCK_SIZE),
&contiguous_lsn, &scanned_lsn);
@@ -3378,11 +3392,11 @@ log_print(
"Checkpoint age target %lu\n"
"Modified age %lu\n"
"Checkpoint age %lu\n",
- (ulong) log_sys->max_checkpoint_age,
- (ulong) log_max_checkpoint_age_async(),
- (ulong) (log_sys->lsn -
- log_buf_pool_get_oldest_modification()),
- (ulong) (log_sys->lsn - log_sys->last_checkpoint_lsn));
+ (ulong) log_sys->max_checkpoint_age,
+ (ulong) log_max_checkpoint_age_async(),
+ (ulong) (log_sys->lsn -
+ log_buf_pool_get_oldest_modification()),
+ (ulong) (log_sys->lsn - log_sys->last_checkpoint_lsn));
current_time = time(NULL);