summaryrefslogtreecommitdiff
path: root/storage/innobase/log/log0log.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/log/log0log.cc')
-rw-r--r--storage/innobase/log/log0log.cc270
1 files changed, 131 insertions, 139 deletions
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 5e4a9dcf515..b6909f4771a 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -37,7 +37,6 @@ Created 12/9/1995 Heikki Tuuri
#endif
#ifndef UNIV_HOTBACKUP
-#include "ha_prototypes.h"
#include "mem0mem.h"
#include "buf0buf.h"
#include "buf0flu.h"
@@ -49,6 +48,7 @@ Created 12/9/1995 Heikki Tuuri
#include "srv0start.h"
#include "trx0sys.h"
#include "trx0trx.h"
+#include "ha_prototypes.h"
#include "srv0mon.h"
/*
@@ -223,7 +223,7 @@ loop:
log_buffer_flush_to_disk();
- srv_log_waits++;
+ srv_stats.log_waits.inc();
ut_ad(++count < 50);
@@ -328,7 +328,7 @@ part_loop:
goto part_loop;
}
- srv_log_write_requests++;
+ srv_stats.log_write_requests.inc();
}
/************************************************************//**
@@ -748,9 +748,6 @@ log_init(void)
log_sys->lsn = LOG_START_LSN;
- MONITOR_SET(MONITOR_LSN_CHECKPOINT_AGE,
- log_sys->lsn - log_sys->last_checkpoint_lsn);
-
ut_a(LOG_BUFFER_SIZE >= 16 * OS_FILE_LOG_BLOCK_SIZE);
ut_a(LOG_BUFFER_SIZE >= 4 * UNIV_PAGE_SIZE);
@@ -784,11 +781,11 @@ log_init(void)
log_sys->n_pending_writes = 0;
- log_sys->no_flush_event = os_event_create(NULL);
+ log_sys->no_flush_event = os_event_create();
os_event_set(log_sys->no_flush_event);
- log_sys->one_flushed_event = os_event_create(NULL);
+ log_sys->one_flushed_event = os_event_create();
os_event_set(log_sys->one_flushed_event);
@@ -796,7 +793,6 @@ log_init(void)
log_sys->next_checkpoint_no = 0;
log_sys->last_checkpoint_lsn = log_sys->lsn;
- MONITOR_SET(MONITOR_LSN_CHECKPOINT_AGE, 0);
log_sys->n_pending_checkpoint_writes = 0;
@@ -832,7 +828,7 @@ log_init(void)
/* memset(log_sys->archive_buf, '\0', LOG_ARCHIVE_BUF_SIZE); */
- log_sys->archiving_on = os_event_create(NULL);
+ log_sys->archiving_on = os_event_create();
#endif /* UNIV_LOG_ARCHIVE */
/*----------------------------*/
@@ -1163,7 +1159,7 @@ log_group_file_header_flush(
MONITOR_INC(MONITOR_LOG_IO);
- srv_os_log_pending_writes++;
+ srv_stats.os_log_pending_writes.inc();
fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE, group->space_id, 0,
(ulint) (dest_offset / UNIV_PAGE_SIZE),
@@ -1171,7 +1167,7 @@ log_group_file_header_flush(
OS_FILE_LOG_BLOCK_SIZE,
buf, group);
- srv_os_log_pending_writes--;
+ srv_stats.os_log_pending_writes.dec();
}
}
@@ -1238,8 +1234,9 @@ loop:
log_group_file_header_flush(group, (ulint)
(next_offset / group->file_size),
start_lsn);
- srv_os_log_written += OS_FILE_LOG_BLOCK_SIZE;
- srv_log_writes++;
+ srv_stats.os_log_written.add(OS_FILE_LOG_BLOCK_SIZE);
+
+ srv_stats.log_writes.inc();
}
if ((next_offset % group->file_size) + len > group->file_size) {
@@ -1289,7 +1286,7 @@ loop:
MONITOR_INC(MONITOR_LOG_IO);
- srv_os_log_pending_writes++;
+ srv_stats.os_log_pending_writes.inc();
ut_a(next_offset / UNIV_PAGE_SIZE <= ULINT_MAX);
@@ -1298,10 +1295,10 @@ loop:
(ulint) (next_offset % UNIV_PAGE_SIZE), write_len, buf,
group);
- srv_os_log_pending_writes--;
+ srv_stats.os_log_pending_writes.dec();
- srv_os_log_written += write_len;
- srv_log_writes++;
+ srv_stats.os_log_written.add(write_len);
+ srv_stats.log_writes.inc();
}
if (write_len < len) {
@@ -1345,6 +1342,8 @@ log_write_up_to(
ib_uint64_t write_lsn;
ib_uint64_t flush_lsn;
+ ut_ad(!srv_read_only_mode);
+
if (recv_no_ibuf_operations) {
/* Recovery is running and no operations on the log files are
allowed yet (the variable name .._no_ibuf_.. is misleading) */
@@ -1560,6 +1559,7 @@ log_buffer_flush_to_disk(void)
{
lsn_t lsn;
+ ut_ad(!srv_read_only_mode);
mutex_enter(&(log_sys->mutex));
lsn = log_sys->lsn;
@@ -1626,15 +1626,16 @@ log_flush_margin(void)
Advances the smallest lsn for which there are unflushed dirty blocks in the
buffer pool. NOTE: this function may only be called if the calling thread owns
no synchronization objects!
-@return FALSE if there was a flush batch of the same type running,
+@return false if there was a flush batch of the same type running,
which means that we could not start this flush batch */
static
-ibool
+bool
log_preflush_pool_modified_pages(
/*=============================*/
lsn_t new_oldest) /*!< in: try to advance oldest_modified_lsn
at least to this lsn */
{
+ bool success;
ulint n_pages;
if (recv_recovery_on) {
@@ -1650,13 +1651,12 @@ log_preflush_pool_modified_pages(
recv_apply_hashed_log_recs(TRUE);
}
- n_pages = buf_flush_list(ULINT_MAX, new_oldest);
+ success = buf_flush_list(ULINT_MAX, new_oldest, &n_pages);
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
- if (n_pages == ULINT_UNDEFINED) {
-
- return(FALSE);
+ if (!success) {
+ MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS);
}
MONITOR_INC_VALUE_CUMULATIVE(
@@ -1665,7 +1665,7 @@ log_preflush_pool_modified_pages(
MONITOR_FLUSH_SYNC_PAGES,
n_pages);
- return(TRUE);
+ return(success);
}
/******************************************************//**
@@ -1765,6 +1765,7 @@ log_group_checkpoint(
byte* buf;
ulint i;
+ ut_ad(!srv_read_only_mode);
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"
@@ -1952,12 +1953,13 @@ log_groups_write_checkpoint_info(void)
ut_ad(mutex_own(&(log_sys->mutex)));
- group = UT_LIST_GET_FIRST(log_sys->log_groups);
-
- while (group) {
- log_group_checkpoint(group);
+ if (!srv_read_only_mode) {
+ for (group = UT_LIST_GET_FIRST(log_sys->log_groups);
+ group;
+ group = UT_LIST_GET_NEXT(log_groups, group)) {
- group = UT_LIST_GET_NEXT(log_groups, group);
+ log_group_checkpoint(group);
+ }
}
}
@@ -1982,6 +1984,8 @@ log_checkpoint(
{
lsn_t oldest_lsn;
+ ut_ad(!srv_read_only_mode);
+
if (recv_recovery_is_on()) {
recv_apply_hashed_log_recs(TRUE);
}
@@ -2088,38 +2092,6 @@ log_make_checkpoint_at(
}
/****************************************************************//**
-Checks if an asynchronous flushing of dirty pages is required in the
-background. This function is only called from the page cleaner thread.
-@return lsn to which the flushing should happen or LSN_MAX
-if flushing is not required */
-UNIV_INTERN
-lsn_t
-log_async_flush_lsn(void)
-/*=====================*/
-{
- lsn_t age;
- lsn_t oldest_lsn;
- lsn_t new_lsn = LSN_MAX;
-
- mutex_enter(&log_sys->mutex);
-
- oldest_lsn = log_buf_pool_get_oldest_modification();
-
- ut_a(log_sys->lsn >= oldest_lsn);
- age = log_sys->lsn - oldest_lsn;
-
- if (age > log_sys->max_modified_age_async) {
- /* An asynchronous preflush is required */
- ut_a(log_sys->lsn >= log_sys->max_modified_age_async);
- new_lsn = log_sys->lsn - log_sys->max_modified_age_async;
- }
-
- mutex_exit(&log_sys->mutex);
-
- return(new_lsn);
-}
-
-/****************************************************************//**
Tries to establish a big enough margin of free space in the log groups, such
that a new log entry can be catenated without an immediate need for a
checkpoint. NOTE: this function may only be called if the calling thread
@@ -2136,7 +2108,7 @@ log_checkpoint_margin(void)
lsn_t oldest_lsn;
ibool checkpoint_sync;
ibool do_checkpoint;
- ibool success;
+ bool success;
loop:
checkpoint_sync = FALSE;
do_checkpoint = FALSE;
@@ -3131,10 +3103,8 @@ logs_empty_and_mark_files_at_shutdown(void)
const char* thread_name;
ibool server_busy;
- if (srv_print_verbose_log) {
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Starting shutdown...\n");
- }
+ ib_logf(IB_LOG_LEVEL_INFO, "Starting shutdown...");
+
/* Wait until the master thread and all other operations are idle: our
algorithm only works if the server is idle at shutdown */
@@ -3155,9 +3125,8 @@ loop:
threads check will be done later. */
if (srv_print_verbose_log && count > 600) {
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Waiting for %s to exit\n",
- thread_name);
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Waiting for %s to exit", thread_name);
count = 0;
}
@@ -3174,9 +3143,8 @@ loop:
if (total_trx > 0) {
if (srv_print_verbose_log && count > 600) {
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Waiting for %lu "
- "active transactions to finish\n",
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Waiting for %lu active transactions to finish",
(ulong) total_trx);
count = 0;
@@ -3221,9 +3189,9 @@ loop:
break;
}
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Waiting for %s "
- "to be suspended\n", thread_type);
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Waiting for %s to be suspended",
+ thread_type);
count = 0;
}
@@ -3239,10 +3207,9 @@ loop:
++count;
os_thread_sleep(100000);
if (srv_print_verbose_log && count > 600) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Waiting for page_cleaner to "
- "finish flushing of buffer pool\n");
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Waiting for page_cleaner to "
+ "finish flushing of buffer pool");
count = 0;
}
}
@@ -3257,10 +3224,9 @@ loop:
if (server_busy) {
if (srv_print_verbose_log && count > 600) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Pending checkpoint_writes: %lu\n"
- " InnoDB: Pending log flush writes: %lu\n",
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Pending checkpoint_writes: %lu. "
+ "Pending log flush writes: %lu",
(ulong) log_sys->n_pending_checkpoint_writes,
(ulong) log_sys->n_pending_writes);
count = 0;
@@ -3272,9 +3238,8 @@ loop:
if (pending_io) {
if (srv_print_verbose_log && count > 600) {
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Waiting for %lu buffer page "
- "I/Os to complete\n",
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Waiting for %lu buffer page I/Os to complete",
(ulong) pending_io);
count = 0;
}
@@ -3286,41 +3251,50 @@ loop:
log_archive_all();
#endif /* UNIV_LOG_ARCHIVE */
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. */
-
- log_buffer_flush_to_disk();
-
- /* Check that the background threads stay suspended */
- thread_name = srv_any_background_threads_are_active();
- if (thread_name != NULL) {
- fprintf(stderr,
- "InnoDB: Warning: background thread %s"
- " woke up during shutdown\n", thread_name);
- goto loop;
+ if (!srv_read_only_mode) {
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "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!");
+
+ /* 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 the background threads stay suspended */
+ thread_name = srv_any_background_threads_are_active();
+
+ if (thread_name != NULL) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Background thread %s woke up "
+ "during shutdown", thread_name);
+ goto loop;
+ }
}
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
+
fil_close_all_files();
+
thread_name = srv_any_background_threads_are_active();
+
ut_a(!thread_name);
+
return;
}
- log_make_checkpoint_at(LSN_MAX, TRUE);
+ if (!srv_read_only_mode) {
+ log_make_checkpoint_at(LSN_MAX, TRUE);
+ }
mutex_enter(&log_sys->mutex);
@@ -3356,15 +3330,17 @@ loop:
/* Check that the background threads stay suspended */
thread_name = srv_any_background_threads_are_active();
if (thread_name != NULL) {
- fprintf(stderr,
- "InnoDB: Warning: background thread %s"
- " woke up during shutdown\n", thread_name);
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Background thread %s woke up during shutdown",
+ thread_name);
goto loop;
}
- fil_flush_file_spaces(FIL_TABLESPACE);
- fil_flush_file_spaces(FIL_LOG);
+ if (!srv_read_only_mode) {
+ fil_flush_file_spaces(FIL_TABLESPACE);
+ fil_flush_file_spaces(FIL_LOG);
+ }
/* The call fil_write_flushed_lsn_to_data_files() will pass the buffer
pool: therefore it is essential that the buffer pool has been
@@ -3374,9 +3350,8 @@ loop:
if (!buf_all_freed()) {
if (srv_print_verbose_log && count > 600) {
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Waiting for dirty buffer "
- "pages to be flushed\n");
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Waiting for dirty buffer pages to be flushed");
count = 0;
}
@@ -3386,31 +3361,38 @@ loop:
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
/* Make some checks that the server really is quiet */
- ut_a(srv_get_active_thread_type() == SRV_NONE);
+ srv_thread_type type = srv_get_active_thread_type();
+ ut_a(type == SRV_NONE);
+
+ bool freed = buf_all_freed();
+ ut_a(freed);
- ut_a(buf_all_freed());
ut_a(lsn == log_sys->lsn);
if (lsn < srv_start_lsn) {
- fprintf(stderr,
- "InnoDB: Error: log sequence number"
- " at shutdown " LSN_PF "\n"
- "InnoDB: is lower than at startup " LSN_PF "!\n",
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Log sequence number at shutdown " LSN_PF " "
+ "is lower than at startup " LSN_PF "!",
lsn, srv_start_lsn);
}
srv_shutdown_lsn = lsn;
- fil_write_flushed_lsn_to_data_files(lsn, arch_log_no);
+ if (!srv_read_only_mode) {
+ fil_write_flushed_lsn_to_data_files(lsn, arch_log_no);
- fil_flush_file_spaces(FIL_TABLESPACE);
+ fil_flush_file_spaces(FIL_TABLESPACE);
+ }
fil_close_all_files();
/* Make some checks that the server really is quiet */
- ut_a(srv_get_active_thread_type() == SRV_NONE);
+ type = srv_get_active_thread_type();
+ ut_a(type == SRV_NONE);
+
+ freed = buf_all_freed();
+ ut_a(freed);
- ut_a(buf_all_freed());
ut_a(lsn == log_sys->lsn);
}
@@ -3544,7 +3526,7 @@ log_refresh_stats(void)
log_sys->last_printout_time = time(NULL);
}
-/**********************************************************************
+/********************************************************//**
Closes a log group. */
static
void
@@ -3574,12 +3556,12 @@ log_group_close(
mem_free(group);
}
-/**********************************************************
-Shutdown the log system but do not release all the memory. */
+/********************************************************//**
+Closes all log groups. */
UNIV_INTERN
void
-log_shutdown(void)
-/*==============*/
+log_group_close_all(void)
+/*=====================*/
{
log_group_t* group;
@@ -3593,6 +3575,16 @@ log_shutdown(void)
log_group_close(prev_group);
}
+}
+
+/********************************************************//**
+Shutdown the log system but do not release all the memory. */
+UNIV_INTERN
+void
+log_shutdown(void)
+/*==============*/
+{
+ log_group_close_all();
mem_free(log_sys->buf_ptr);
log_sys->buf_ptr = NULL;
@@ -3610,7 +3602,7 @@ log_shutdown(void)
#ifdef UNIV_LOG_ARCHIVE
rw_lock_free(&log_sys->archive_lock);
- os_event_create(log_sys->archiving_on);
+ os_event_create();
#endif /* UNIV_LOG_ARCHIVE */
#ifdef UNIV_LOG_DEBUG
@@ -3620,7 +3612,7 @@ log_shutdown(void)
recv_sys_close();
}
-/**********************************************************
+/********************************************************//**
Free the log system data structures. */
UNIV_INTERN
void