summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2014-02-02 10:00:36 +0100
committerSergei Golubchik <sergii@pisem.net>2014-02-02 10:00:36 +0100
commitd929342b0f8d5a85aac4e76486b0ff2aff7ca54f (patch)
treee14f3a61137bf5d0adc190262c26fa62d2c02ec0 /sql
parent65121806da41ba0354c53b0b8ea22445c71ea33b (diff)
downloadmariadb-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.h7
-rw-r--r--sql/lex.h1
-rw-r--r--sql/share/errmsg-utf8.txt2
-rw-r--r--sql/sql_parse.cc11
-rw-r--r--sql/sql_reload.cc81
-rw-r--r--sql/sql_reload.h1
-rw-r--r--sql/sql_yacc.yy27
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 {}