diff options
author | Sergei Golubchik <sergii@pisem.net> | 2011-10-19 21:45:18 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2011-10-19 21:45:18 +0200 |
commit | 76f0b94bb0b2994d639353530c5b251d0f1a204b (patch) | |
tree | 9ed50628aac34f89a37637bab2fc4915b86b5eb4 /storage/xtradb/log/log0log.c | |
parent | 4e46d8e5bff140f2549841167dc4b65a3c0a645d (diff) | |
parent | 5dc1a2231f55bacc9aaf0e24816f3d9c2ee1f21d (diff) | |
download | mariadb-git-76f0b94bb0b2994d639353530c5b251d0f1a204b.tar.gz |
merge with 5.3
sql/sql_insert.cc:
CREATE ... IF NOT EXISTS may do nothing, but
it is still not a failure. don't forget to my_ok it.
******
CREATE ... IF NOT EXISTS may do nothing, but
it is still not a failure. don't forget to my_ok it.
sql/sql_table.cc:
small cleanup
******
small cleanup
Diffstat (limited to 'storage/xtradb/log/log0log.c')
-rw-r--r-- | storage/xtradb/log/log0log.c | 100 |
1 files changed, 94 insertions, 6 deletions
diff --git a/storage/xtradb/log/log0log.c b/storage/xtradb/log/log0log.c index 80449e1c23a..d9676707cfd 100644 --- a/storage/xtradb/log/log0log.c +++ b/storage/xtradb/log/log0log.c @@ -110,6 +110,8 @@ archive */ UNIV_INTERN byte log_archive_io; #endif /* UNIV_LOG_ARCHIVE */ +UNIV_INTERN ulint log_disable_checkpoint_active= 0; + /* A margin for free space in the log buffer before a log entry is catenated */ #define LOG_BUF_WRITE_MARGIN (4 * OS_FILE_LOG_BLOCK_SIZE) @@ -187,7 +189,7 @@ log_fsp_current_free_limit_set_and_checkpoint( success = FALSE; while (!success) { - success = log_checkpoint(TRUE, TRUE); + success = log_checkpoint(TRUE, TRUE, FALSE); } } @@ -2007,12 +2009,14 @@ log_checkpoint( /*===========*/ ibool sync, /*!< in: TRUE if synchronous operation is desired */ - ibool write_always) /*!< in: the function normally checks if the + ibool write_always, /*!< in: the function normally checks if the the new checkpoint would have a greater lsn than the previous one: if not, then no physical write is done; by setting this parameter TRUE, a physical write will always be made to log files */ + ibool safe_to_ignore) /*!< in: TRUE if checkpoint can be ignored in + the case checkpoint's are disabled */ { ib_uint64_t oldest_lsn; @@ -2043,14 +2047,27 @@ log_checkpoint( mutex_enter(&(log_sys->mutex)); + /* Return if this is not a forced checkpoint and either there is no + need for a checkpoint or if checkpoints are disabled */ if (!write_always - && log_sys->last_checkpoint_lsn >= oldest_lsn) { + && (log_sys->last_checkpoint_lsn >= oldest_lsn || + (safe_to_ignore && log_disable_checkpoint_active))) + { mutex_exit(&(log_sys->mutex)); return(TRUE); } + if (log_disable_checkpoint_active) + { + /* Wait until we are allowed to do a checkpoint */ + mutex_exit(&(log_sys->mutex)); + rw_lock_s_lock(&(log_sys->checkpoint_lock)); + rw_lock_s_unlock(&(log_sys->checkpoint_lock)); + mutex_enter(&(log_sys->mutex)); + } + ut_ad(log_sys->flushed_to_disk_lsn >= oldest_lsn); if (log_sys->n_pending_checkpoint_writes > 0) { @@ -2111,7 +2128,73 @@ log_make_checkpoint_at( while (!log_preflush_pool_modified_pages(lsn, TRUE)); - while (!log_checkpoint(TRUE, write_always)); + while (!log_checkpoint(TRUE, write_always, FALSE)); +} + +/****************************************************************//** +Disable checkpoints. This is used when doing a volumne snapshot +to ensure that we don't get checkpoint between snapshoting two +different volumes */ + +UNIV_INTERN +ibool log_disable_checkpoint() +{ + mutex_enter(&(log_sys->mutex)); + + /* + Wait if a checkpoint write is running. + This is the same code that is used in log_checkpoint() to ensure + that two checkpoints are not happening at the same time. + */ + while (log_sys->n_pending_checkpoint_writes > 0) + { + mutex_exit(&(log_sys->mutex)); + rw_lock_s_lock(&(log_sys->checkpoint_lock)); + rw_lock_s_unlock(&(log_sys->checkpoint_lock)); + mutex_enter(&(log_sys->mutex)); + } + /* + The following should never be true; It's is here just in case of + wrong usage of this function. (Better safe than sorry). + */ + + if (log_disable_checkpoint_active) + { + mutex_exit(&(log_sys->mutex)); + return 1; /* Already disabled */ + } + /* + Take the checkpoint lock to ensure we will not get any checkpoints + running + */ + rw_lock_x_lock_gen(&(log_sys->checkpoint_lock), LOG_CHECKPOINT); + log_disable_checkpoint_active= 1; + mutex_exit(&(log_sys->mutex)); + return 0; +} + + +/****************************************************************//** +Enable checkpoints that was disabled with log_disable_checkpoint() +This lock is called by MariaDB and only when we have done call earlier +to log_disable_checkpoint(). + +Note: We can't take a log->mutex lock here running log_checkpoint() +which is waiting (log_sys->checkpoint_lock may already have it. +This is however safe to do without a mutex as log_disable_checkpoint +is protected by log_sys->checkpoint_lock. +*/ + +UNIV_INTERN +void log_enable_checkpoint() +{ + ut_ad(log_disable_checkpoint_active); + /* Test variable, mostly to protect against wrong usage */ + if (log_disable_checkpoint_active) + { + log_disable_checkpoint_active= 0; + rw_lock_x_unlock_gen(&(log_sys->checkpoint_lock), LOG_CHECKPOINT); + } } /****************************************************************//** @@ -2208,7 +2291,7 @@ loop: } if (do_checkpoint) { - log_checkpoint(checkpoint_sync, FALSE); + log_checkpoint(checkpoint_sync, FALSE, FALSE); if (checkpoint_sync) { @@ -3121,11 +3204,16 @@ logs_empty_and_mark_files_at_shutdown(void) ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Starting shutdown...\n"); } + + /* Enable checkpoints if someone had turned them off */ + if (log_disable_checkpoint_active) + log_enable_checkpoint(); + /* Wait until the master thread and all other operations are idle: our algorithm only works if the server is idle at shutdown */ srv_shutdown_state = SRV_SHUTDOWN_CLEANUP; - os_event_set(srv_purge_thread_event); + os_event_set(srv_shutdown_event); loop: os_thread_sleep(100000); |