diff options
author | Michael Widenius <monty@askmonty.org> | 2011-04-28 18:02:26 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2011-04-28 18:02:26 +0300 |
commit | 6da8ac5f71a6501cb0fb1304ff144ec41b4d9389 (patch) | |
tree | 25fd264f65836fd6fb0cd183dc670d34ac4b3c37 /sql | |
parent | 24edac2211c46ea9ebeb4a13bc467fb20008916e (diff) | |
download | mariadb-git-6da8ac5f71a6501cb0fb1304ff144ec41b4d9389.tar.gz |
Added option "AND DISABLE CHECKPOINT" to "FLUSH TABLES WITH READ LOCK"
This makes it possible to do safe multi volume snapshots as long as one snapshots the volume with the transaction logs last.
include/mysql_com.h:
Added REFRESH_CHECKPOINT
mysql-test/r/flush.result:
Added test of new FLUSH TABLES syntax + calls to checkpoint_status handler calls
mysql-test/t/flush.test:
Added test of new FLUSH TABLES syntax + calls to checkpoint_status handler calls
sql/handler.cc:
Added code to call checkpoint_state for all handlertons that supports it
sql/handler.h:
Added new checkpoint_state() handlerton call to temporarly disable checkpoints.
sql/lex.h:
Added CHECKPOINT keyword
sql/sql_yacc.yy:
Added support for FLUSH TABLES WITH READ LOCK AND DISABLE CHECKPOINT
storage/maria/ha_maria.cc:
Added handlerton call to disable checkpoints.
storage/maria/ma_checkpoint.c:
Don't do checkpoint if checkpoints are disabled.
storage/maria/ma_static.c:
Added maria_checkpoint_disabled
storage/maria/maria_def.h:
Added maria_checkpoint_disabled
storage/xtradb/handler/ha_innodb.cc:
Added handlerton call to disable checkpoints.
storage/xtradb/include/log0log.h:
Added option to log_checkpoint() to allow one to ignore not critical checkpoints during the time checkpoints are disabled.
storage/xtradb/log/log0log.c:
Added code to allow one to disable checkpoints during a FLUSH TABLES ... DISABLE CHECKPOINT
This was done by adding a new argument to log_checkpoint() which tells us when the checkpoint is called by srv_master_thread (which are safe to ignore)
storage/xtradb/srv/srv0srv.c:
Tell log_checkpoint() that checkpoints from srv_master_thread() are safe to ignore (will just delay recovery time a bit).
Diffstat (limited to 'sql')
-rw-r--r-- | sql/handler.cc | 17 | ||||
-rw-r--r-- | sql/handler.h | 14 | ||||
-rw-r--r-- | sql/lex.h | 1 | ||||
-rw-r--r-- | sql/lock.cc | 28 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 11 |
9 files changed, 74 insertions, 5 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index df5acb98efe..e51ded64336 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -598,6 +598,23 @@ void ha_drop_database(char* path) } +static my_bool checkpoint_state_handlerton(THD *unused1, plugin_ref plugin, + void *disable) +{ + handlerton *hton= plugin_data(plugin, handlerton *); + if (hton->state == SHOW_OPTION_YES && hton->checkpoint_state) + hton->checkpoint_state(hton, (int) *(bool*) disable); + return FALSE; +} + + +void ha_checkpoint_state(bool disable) +{ + plugin_foreach(NULL, checkpoint_state_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, &disable); +} + + + static my_bool closecon_handlerton(THD *thd, plugin_ref plugin, void *unused) { diff --git a/sql/handler.h b/sql/handler.h index 02b96ebefb8..f674a8a56bb 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -865,6 +865,19 @@ struct handlerton int (*recover)(handlerton *hton, XID *xid_list, uint len); int (*commit_by_xid)(handlerton *hton, XID *xid); int (*rollback_by_xid)(handlerton *hton, XID *xid); + /* + "Disable or enable checkpointing internal to the storage engine. This is + used for FLUSH TABLES WITH READ LOCK AND DISABLE CHECKPOINT to ensure that + the engine will never start any recovery from a time between + FLUSH TABLES ... ; UNLOCK TABLES. + + While checkpointing is disabled, the engine should pause any background + write activity (such as tablespace checkpointing) that require consistency + between different files (such as transaction log and tablespace files) for + crash recovery to succeed. The idea is to use this to make safe + multi-volume LVM snapshot backups. + */ + int (*checkpoint_state)(handlerton *hton, bool disabled); void *(*create_cursor_read_view)(handlerton *hton, THD *thd); void (*set_cursor_read_view)(handlerton *hton, THD *thd, void *read_view); void (*close_cursor_read_view)(handlerton *hton, THD *thd, void *read_view); @@ -2629,6 +2642,7 @@ int ha_panic(enum ha_panic_function flag); void ha_close_connection(THD* thd); bool ha_flush_logs(handlerton *db_type); void ha_drop_database(char* path); +void ha_checkpoint_state(bool disable); int ha_create_table(THD *thd, const char *path, const char *db, const char *table_name, HA_CREATE_INFO *create_info, diff --git a/sql/lex.h b/sql/lex.h index 7671f23682d..057b7d1ce96 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -104,6 +104,7 @@ static SYMBOL symbols[] = { { "CHARACTER", SYM(CHAR_SYM)}, { "CHARSET", SYM(CHARSET)}, { "CHECK", SYM(CHECK_SYM)}, + { "CHECKPOINT", SYM(CHECKPOINT_SYM)}, { "CHECKSUM", SYM(CHECKSUM_SYM)}, { "CIPHER", SYM(CIPHER_SYM)}, { "CLIENT", SYM(CLIENT_SYM)}, diff --git a/sql/lock.cc b/sql/lock.cc index 740b54f9153..2dc6bc357f4 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -1449,7 +1449,7 @@ static void print_lock_error(int error, const char *table) ****************************************************************************/ -volatile uint global_read_lock=0; +volatile uint global_read_lock=0, global_disable_checkpoint= 0; volatile uint global_read_lock_blocks_commit=0; static volatile uint protect_against_global_read_lock=0; static volatile uint waiting_for_read_lock=0; @@ -1508,6 +1508,14 @@ void unlock_global_read_lock(THD *thd) tmp= --global_read_lock; if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT) --global_read_lock_blocks_commit; + if (thd->global_disable_checkpoint) + { + thd->global_disable_checkpoint= 0; + if (!--global_disable_checkpoint) + { + ha_checkpoint_state(0); // Enable checkpoints + } + } pthread_mutex_unlock(&LOCK_global_read_lock); /* Send the signal outside the mutex to avoid a context switch */ if (!tmp) @@ -1630,6 +1638,24 @@ bool make_global_read_lock_block_commit(THD *thd) /** + Disable checkpoints for all handlers + This is released in unlock_global_read_lock() +*/ + +void disable_checkpoints(THD *thd) +{ + pthread_mutex_lock(&LOCK_global_read_lock); + if (!thd->global_disable_checkpoint) + { + thd->global_disable_checkpoint= 1; + if (!global_disable_checkpoint++) + ha_checkpoint_state(1); // Disable checkpoints + } + pthread_mutex_unlock(&LOCK_global_read_lock); +} + + +/** Broadcast COND_refresh and COND_global_read_lock. Due to a bug in a threading library it could happen that a signal diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b9bc99e9747..6901da60fbd 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2094,7 +2094,7 @@ extern bool opt_ignore_builtin_innodb; extern my_bool opt_character_set_client_handshake; extern bool volatile abort_loop, shutdown_in_progress; extern bool in_bootstrap; -extern uint volatile thread_count, thread_running, global_read_lock; +extern uint volatile thread_count, thread_running, global_read_lock, global_disable_checkpoint; extern ulong thread_created; extern uint thread_handling; extern uint connection_count, extra_connection_count; @@ -2257,6 +2257,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commit); void start_waiting_global_read_lock(THD *thd); bool make_global_read_lock_block_commit(THD *thd); +void disable_checkpoints(THD *thd); bool set_protect_against_global_read_lock(void); void unset_protect_against_global_read_lock(void); void broadcast_refresh(void); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f8905cd5f8c..a5c06d2aa77 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -674,6 +674,7 @@ THD::THD() stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE), examined_row_count(0), global_read_lock(0), + global_disable_checkpoint(0), is_fatal_error(0), transaction_rollback_request(0), is_fatal_sub_stmt_error(0), diff --git a/sql/sql_class.h b/sql/sql_class.h index 9ea4e37e610..904ffda5c85 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1920,7 +1920,7 @@ public: ulong query_plan_fsort_passes; pthread_t real_id; /* For debugging */ my_thread_id thread_id; - uint tmp_table, global_read_lock; + uint tmp_table, global_read_lock, global_disable_checkpoint; uint server_status,open_options; enum enum_thread_type system_thread; uint select_number; //number of select (used for EXPLAIN) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 103cf72cf14..94d0436fba3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7058,6 +7058,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, unlock_global_read_lock(thd); return 1; } + if (options & REFRESH_CHECKPOINT) + disable_checkpoints(thd); } else { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index bf213b19bb9..27d8029cbbe 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -758,6 +758,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CHANGED %token CHARSET %token CHAR_SYM /* SQL-2003-R */ +%token CHECKPOINT_SYM %token CHECKSUM_SYM %token CHECK_SYM /* SQL-2003-R */ %token CIPHER_SYM @@ -1336,6 +1337,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_natural_language_mode opt_query_expansion opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt + optional_flush_tables_arguments %type <ulong_num> ulong_num real_ulong_num merge_insert_types @@ -10784,8 +10786,8 @@ flush_option: table_or_tables { Lex->type|= REFRESH_TABLES; } opt_table_list {} - | TABLES WITH READ_SYM LOCK_SYM - { Lex->type|= REFRESH_TABLES | REFRESH_READ_LOCK; } + | TABLES WITH READ_SYM LOCK_SYM optional_flush_tables_arguments + { Lex->type|= REFRESH_TABLES | REFRESH_READ_LOCK | $5; } | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE_FREE; } | HOSTS_SYM @@ -10821,6 +10823,10 @@ opt_table_list: | table_list {} ; +optional_flush_tables_arguments: + /* empty */ {$$= 0;} + | AND_SYM DISABLE_SYM CHECKPOINT_SYM {$$= REFRESH_CHECKPOINT; } + reset: RESET_SYM { @@ -11859,6 +11865,7 @@ keyword: | CACHE_SYM {} | CHARSET {} | CHECKSUM_SYM {} + | CHECKPOINT_SYM {} | CLOSE_SYM {} | COMMENT_SYM {} | COMMIT_SYM {} |