diff options
author | Sergei Golubchik <sergii@pisem.net> | 2014-02-02 10:00:36 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2014-02-02 10:00:36 +0100 |
commit | d929342b0f8d5a85aac4e76486b0ff2aff7ca54f (patch) | |
tree | e14f3a61137bf5d0adc190262c26fa62d2c02ec0 /sql | |
parent | 65121806da41ba0354c53b0b8ea22445c71ea33b (diff) | |
download | mariadb-git-d929342b0f8d5a85aac4e76486b0ff2aff7ca54f.tar.gz |
Merge the server part of MySQL WL#5522 - InnoDB transportable tablespaces.
Syntax. Server support. Test cases.
InnoDB bugfixes:
* don't mess around with system sprintf's, always use my_error() for errors.
* don't use InnoDB internal error codes where OS error codes are expected.
* don't say "file not found", when it was.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/handler.h | 7 | ||||
-rw-r--r-- | sql/lex.h | 1 | ||||
-rw-r--r-- | sql/share/errmsg-utf8.txt | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 11 | ||||
-rw-r--r-- | sql/sql_reload.cc | 81 | ||||
-rw-r--r-- | sql/sql_reload.h | 1 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 27 |
7 files changed, 125 insertions, 5 deletions
diff --git a/sql/handler.h b/sql/handler.h index 69b9c3e071e..c0746b37fbc 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -248,6 +248,13 @@ enum enum_alter_inplace_result { #define HA_CAN_FULLTEXT_EXT (1LL << 44) /* + Storage engine supports table export using the + FLUSH TABLE <table_list> FOR EXPORT statement. + */ +#define HA_CAN_EXPORT (1LL << 45) + + +/* Set of all binlog flags. Currently only contain the capabilities flags. */ diff --git a/sql/lex.h b/sql/lex.h index 88d73b9b169..10a52160cf0 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -223,6 +223,7 @@ static SYMBOL symbols[] = { { "EXISTS", SYM(EXISTS)}, { "EXIT", SYM(EXIT_SYM)}, { "EXPANSION", SYM(EXPANSION_SYM)}, + { "EXPORT", SYM(EXPORT_SYM)}, { "EXPLAIN", SYM(DESCRIBE)}, { "EXTENDED", SYM(EXTENDED_SYM)}, { "EXTENT_SIZE", SYM(EXTENT_SIZE_SYM)}, diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 2d061fc314c..8da5b3a5c12 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6757,7 +6757,7 @@ ER_TABLESPACE_DISCARDED eng "Tablespace has been discarded for table '%-.192s'" ER_INTERNAL_ERROR - eng "Internal error: '%-.192s'" + eng "Internal error: %-.192s" ER_INNODB_IMPORT_ERROR eng "ALTER TABLE '%-.192s' IMPORT TABLESPACE failed with error %lu : '%s'" diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f9bfa6d120b..ec4e873f8ec 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4232,6 +4232,17 @@ end_with_restore_list: my_ok(thd); break; } + else if (first_table && lex->type & REFRESH_FOR_EXPORT) + { + /* Check table-level privileges. */ + if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, + FALSE, UINT_MAX, FALSE)) + goto error; + if (flush_tables_for_export(thd, all_tables)) + goto error; + my_ok(thd); + break; + } /* reload_acl_and_cache() will tell us if we are allowed to write to the diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 5df5b0ab3f7..c7038b6522d 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -522,7 +522,7 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables) /* Before opening and locking tables the below call also waits for old shares to go away, so the fact that we don't pass - MYSQL_LOCK_IGNORE_FLUSH flag to it is important. + MYSQL_OPEN_IGNORE_FLUSH flag to it is important. Also we don't pass MYSQL_OPEN_HAS_MDL_LOCK flag as we want to open underlying tables if merge table is flushed. For underlying tables of the merge the below call has to @@ -553,6 +553,85 @@ error: /** + Prepare tables for export (transportable tablespaces) by + a) waiting until write transactions/DDL operations using these + tables have completed. + b) block new write operations/DDL operations on these tables. + + Once this is done, notify the storage engines using handler::extra(). + + Finally, enter LOCK TABLES mode, so that locks are held + until UNLOCK TABLES is executed. + + @param thd Thread handler + @param all_tables TABLE_LIST for tables to be exported + + @retval false Ok + @retval true Error +*/ + +bool flush_tables_for_export(THD *thd, TABLE_LIST *all_tables) +{ + Lock_tables_prelocking_strategy lock_tables_prelocking_strategy; + + /* + This is called from SQLCOM_FLUSH, the transaction has + been committed implicitly. + */ + + if (thd->locked_tables_mode) + { + my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); + return true; + } + + /* + Acquire SNW locks on tables to be exported. Don't acquire + global IX as this will make this statement incompatible + with FLUSH TABLES WITH READ LOCK. + */ + if (open_and_lock_tables(thd, all_tables, false, + MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK, + &lock_tables_prelocking_strategy)) + { + return true; + } + + // Check if all storage engines support FOR EXPORT. + for (TABLE_LIST *table_list= all_tables; table_list; + table_list= table_list->next_global) + { + if (!(table_list->table->file->ha_table_flags() & HA_CAN_EXPORT)) + { + my_error(ER_ILLEGAL_HA, MYF(0),table_list->table->file->table_type(), + table_list->db, table_list->table_name); + return true; + } + } + + // Notify the storage engines that the tables should be made ready for export. + for (TABLE_LIST *table_list= all_tables; table_list; + table_list= table_list->next_global) + { + handler *handler_file= table_list->table->file; + int error= handler_file->extra(HA_EXTRA_EXPORT); + if (error) + { + handler_file->print_error(error, MYF(0)); + return true; + } + } + + // Enter LOCKED TABLES mode. + if (thd->locked_tables_list.init_locked_tables(thd)) + return true; + thd->variables.option_bits|= OPTION_TABLE_LOCK; + + return false; +} + + +/** Disable checkpoints for all handlers This is released in unlock_global_read_lock() */ diff --git a/sql/sql_reload.h b/sql/sql_reload.h index 33ca022dc14..554fe8ade4d 100644 --- a/sql/sql_reload.h +++ b/sql/sql_reload.h @@ -22,5 +22,6 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, TABLE_LIST *tables, int *write_to_binlog); bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables); +bool flush_tables_for_export(THD *thd, TABLE_LIST *all_tables); #endif diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e13687530ee..e7045abf7d7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1155,6 +1155,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token EXISTS /* SQL-2003-R */ %token EXIT_SYM %token EXPANSION_SYM +%token EXPORT_SYM %token EXTENDED_SYM %token EXTENT_SIZE_SYM %token EXTRACT_SYM /* SQL-2003-N */ @@ -1828,7 +1829,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); object_privilege object_privilege_list user_list user_and_role_list rename_list clear_privileges flush_options flush_option - opt_with_read_lock flush_options_list + opt_flush_lock flush_options_list equal optional_braces opt_mi_check_type opt_to mi_check_types table_to_table_list table_to_table opt_table_list opt_as @@ -12779,11 +12780,11 @@ flush_options: YYPS->m_mdl_type= MDL_SHARED_HIGH_PRIO; } opt_table_list {} - opt_with_read_lock {} + opt_flush_lock {} | flush_options_list ; -opt_with_read_lock: +opt_flush_lock: /* empty */ {} | WITH READ_SYM LOCK_SYM optional_flush_tables_arguments { @@ -12796,6 +12797,25 @@ opt_with_read_lock: tables->open_type= OT_BASE_ONLY; /* Ignore temporary tables. */ } } + | FOR_SYM + { + if (Lex->query_tables == NULL) // Table list can't be empty + { + my_parse_error(ER(ER_NO_TABLES_USED)); + MYSQL_YYABORT; + } + } + EXPORT_SYM + { + TABLE_LIST *tables= Lex->query_tables; + Lex->type|= REFRESH_FOR_EXPORT; + for (; tables; tables= tables->next_global) + { + tables->mdl_request.set_type(MDL_SHARED_NO_WRITE); + tables->required_type= FRMTYPE_TABLE; /* Don't try to flush views. */ + tables->open_type= OT_BASE_ONLY; /* Ignore temporary tables. */ + } + } ; flush_options_list: @@ -14139,6 +14159,7 @@ keyword_sp: | EVERY_SYM {} | EXCHANGE_SYM {} | EXPANSION_SYM {} + | EXPORT_SYM {} | EXTENDED_SYM {} | EXTENT_SIZE_SYM {} | FAULTS_SYM {} |