3871 Jon Olav Hauglid 2012-05-03
WL#6169 FLUSH TABLES ... FOR EXPORT -- runtime
This worklog adds the runtime side for the new FOR EXPORT
option for FLUSH TABLES <table_list>.
The FLUSH TABLES <table_list> FOR EXPORT statement:
- Acquires MDL_SHARED_NO_WRITE metadata lock on the tables
listed in <table_list>. The effect is that FLUSH TABLES
<table_list> FOR EXPORT will block until all active
transactions that have updated any table in <table_list>
have completed. While FLUSH TABLES <table_list> FOR EXPORT
is in effect, no new updating transactions and no DDL
statements are allowed. Read-only transactions will not be
affected.
- Enters LOCK TABLES mode so that locks are held until
the UNLOCK TABLES statement is executed.
- Notifies the storage engine by calling handler::extra()
using the new flag HA_EXTRA_EXPORT. This allows the storage
engine to perform any steps needed to make the table ready
for export (e.g. quiesce the table and write metadata file).
The worklog also adds a new ha_table_flags() flag:
HA_CAN_EXPORT_TABLESPACE. This flags indicates that a given
storage engine support FLUSH TABLES <table_list> FOR EXPORT.
If such a statement includes tables for which the storage
engine does not have this flag, an error will be returned.
modified:
include/my_base.h
include/mysql_com.h
mysql-test/r/flush_table.result
mysql-test/t/flush_table.test
sql/handler.h
sql/sql_parse.cc
sql/sql_reload.cc
sql/sql_reload.h
sql/sql_yacc.yy
storage/innobase/handler/ha_innodb.cc
3870 Jon Olav Hauglid 2012-05-02 [merge]
Merge from mysql-trunk to mysql-trunk-wl6168
No conflicts
removed:
mysql-test/suite/rpl/r/rpl_row_find_row_debug.result
mysql-test/suite/rpl/t/rpl_row_find_row_debug.test
added:
mysql-test/extra/rpl_tests/rpl_row_idempotency.test
mysql-test/include/rpl_hash_scan_assertion.inc
mysql-test/lib/My/Memcache.pm
mysql-test/r/func_group_innodb_16k.result
mysql-test/suite/innodb/include/innodb_dict.inc
mysql-test/suite/innodb/r/innodb-alter-debug.result
mysql-test/suite/innodb/r/innodb-alter.result
mysql-test/suite/innodb/r/innodb_bug13867871.result
mysql-test/suite/innodb/t/innodb-alter-debug.test
mysql-test/suite/innodb/t/innodb-alter.test
mysql-test/suite/innodb/t/innodb_bug13867871.test
mysql-test/suite/rpl/r/rpl_row_hash_scan.result
mysql-test/suite/rpl/r/rpl_row_hash_scan_sanity.result
mysql-test/suite/rpl/t/rpl_report_port-master.opt
mysql-test/suite/rpl/t/rpl_row_hash_scan.test
mysql-test/suite/rpl/t/rpl_row_hash_scan_sanity.test
mysql-test/suite/sys_vars/r/slave_rows_search_algorithms_basic.result
mysql-test/suite/sys_vars/t/slave_rows_search_algorithms_basic.test
mysql-test/t/func_group_innodb_16k.test
modified:
extra/comp_err.c
libmysqld/lib_sql.cc
mysql-test/collections/default.daily
mysql-test/extra/rpl_tests/rpl_record_compare.test
mysql-test/include/handler.inc
mysql-test/include/order_by.inc
mysql-test/include/subquery.inc
mysql-test/lib/My/ConfigFactory.pm
mysql-test/lib/mtr_cases.pm
mysql-test/mysql-test-run.pl
mysql-test/r/alter_table.result
mysql-test/r/create.result
mysql-test/r/ctype_create.result
mysql-test/r/drop.result
mysql-test/r/events_2.result
mysql-test/r/explain.result
mysql-test/r/explain_json_all.result
mysql-test/r/explain_json_none.result
mysql-test/r/func_group_innodb.result
mysql-test/r/func_time.result
mysql-test/r/handler_innodb.result
mysql-test/r/handler_myisam.result
mysql-test/r/information_schema.result
mysql-test/r/mysql.result
mysql-test/r/mysqld--help-notwin.result
mysql-test/r/mysqld--help-win.result
mysql-test/r/order_by_all.result
mysql-test/r/order_by_icp_mrr.result
mysql-test/r/order_by_none.result
mysql-test/r/subquery_all.result
mysql-test/r/subquery_all_bka.result
mysql-test/r/subquery_all_bka_nixbnl.result
mysql-test/r/subquery_nomat_nosj.result
mysql-test/r/subquery_nomat_nosj_bka.result
mysql-test/r/subquery_nomat_nosj_bka_nixbnl.result
mysql-test/r/subquery_none.result
mysql-test/r/subquery_none_bka.result
mysql-test/r/subquery_none_bka_nixbnl.result
mysql-test/suite/explain_json_validate/r/explain_json_validate.result
mysql-test/suite/innodb/r/innodb-index-online.result
mysql-test/suite/innodb/r/innodb-index.result
mysql-test/suite/innodb/r/innodb_bug21704.result
mysql-test/suite/innodb/r/innodb_corrupt_bit.result
mysql-test/suite/innodb/t/innodb-index-online.test
mysql-test/suite/innodb/t/innodb-index.test
mysql-test/suite/innodb/t/innodb_bug21704.test
mysql-test/suite/innodb/t/innodb_corrupt_bit.test
mysql-test/suite/opt_trace/r/bugs_no_prot_all.result
mysql-test/suite/opt_trace/r/bugs_no_prot_none.result
mysql-test/suite/opt_trace/r/bugs_ps_prot_all.result
mysql-test/suite/opt_trace/r/bugs_ps_prot_none.result
mysql-test/suite/opt_trace/r/range_no_prot.result
mysql-test/suite/opt_trace/r/range_ps_prot.result
mysql-test/suite/rpl/r/rpl_bug26395.result
mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result
mysql-test/suite/rpl/r/rpl_parallel_start_stop.result
mysql-test/suite/rpl/r/rpl_relayrotate.result
mysql-test/suite/rpl/r/rpl_report_port.result
mysql-test/suite/rpl/r/rpl_row_idempotency.result
mysql-test/suite/rpl/r/rpl_row_rec_comp_innodb.result
mysql-test/suite/rpl/r/rpl_row_rec_comp_myisam.result
mysql-test/suite/rpl/r/rpl_stm_relay_ign_space.result
mysql-test/suite/rpl/t/rpl_bug26395.test
mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test
mysql-test/suite/rpl/t/rpl_parallel_start_stop.test
mysql-test/suite/rpl/t/rpl_relayrotate.test
mysql-test/suite/rpl/t/rpl_report_port.test
mysql-test/suite/rpl/t/rpl_row_idempotency.test
mysql-test/suite/rpl/t/rpl_stm_relay_ign_space.test
mysql-test/suite/sys_vars/r/bind_address_basic.result
mysql-test/suite/sys_vars/t/bind_address_basic.test
mysql-test/t/create.test
mysql-test/t/ctype_create.test
mysql-test/t/drop.test
mysql-test/t/events_2.test
mysql-test/t/func_group_innodb.test
mysql-test/t/func_time.test
mysql-test/t/handler_myisam.test
mysql-test/t/information_schema.test
mysql-test/t/overflow.test
sql-common/my_time.c
sql/datadict.cc
sql/derror.cc
sql/event_db_repository.cc
sql/field.cc
sql/field.h
sql/filesort.cc
sql/ha_partition.cc
sql/handler.cc
sql/handler.h
sql/item_buff.cc
sql/item_cmpfunc.cc
sql/item_cmpfunc.h
sql/item_subselect.cc
sql/item_timefunc.cc
sql/log.cc
sql/log_event.cc
sql/log_event.h
sql/log_event_old.cc
sql/mysqld.cc
sql/mysqld.h
sql/opt_range.cc
sql/opt_sum.cc
sql/partition_info.cc
sql/rpl_info_table.cc
sql/rpl_slave.cc
sql/rpl_utility.cc
sql/rpl_utility.h
sql/sp.cc
sql/sql_acl.cc
sql/sql_bitmap.h
sql/sql_class.h
sql/sql_db.cc
sql/sql_executor.cc
sql/sql_handler.cc
sql/sql_help.cc
sql/sql_insert.cc
sql/sql_join_buffer.cc
sql/sql_optimizer.cc
sql/sql_parse.cc
sql/sql_planner.cc
sql/sql_select.cc
sql/sql_show.cc
sql/sql_table.cc
sql/sql_test.cc
sql/sql_time.cc
sql/sql_tmp_table.cc
sql/sql_update.cc
sql/sql_yacc.yy
sql/sys_vars.cc
sql/table.cc
sql/table.h
sql/tztime.cc
storage/blackhole/ha_blackhole.h
storage/csv/ha_tina.cc
storage/federated/ha_federated.cc
storage/innobase/api/api0api.cc
storage/innobase/dict/dict0dict.cc
storage/innobase/dict/dict0load.cc
storage/innobase/dict/dict0mem.cc
storage/innobase/fil/fil0fil.cc
storage/innobase/handler/ha_innodb.cc
storage/innobase/handler/ha_innodb.h
storage/innobase/handler/handler0alter.cc
storage/innobase/include/dict0dict.h
storage/innobase/include/dict0dict.ic
storage/innobase/include/dict0mem.h
storage/innobase/include/dict0stats.ic
storage/innobase/include/fil0fil.h
storage/innobase/include/fts0priv.ic
storage/innobase/include/fts0types.ic
storage/innobase/include/row0merge.h
storage/innobase/include/row0upd.ic
storage/innobase/include/srv0srv.h
storage/innobase/row/row0ins.cc
storage/innobase/row/row0log.cc
storage/innobase/row/row0merge.cc
storage/innobase/row/row0mysql.cc
storage/innobase/row/row0sel.cc
storage/innobase/row/row0upd.cc
storage/innobase/sync/sync0arr.cc
unittest/gunit/decimal-t.cc
unittest/gunit/dynarray-t.cc
unittest/gunit/fake_table.h
unittest/gunit/stdcxx-t.cc
=== modified file 'include/my_base.h'
--- a/include/my_base.h 2012-04-24 06:21:11 +0000
+++ b/include/my_base.h 2012-05-03 08:10:14 +0000
@@ -193,7 +193,12 @@ enum ha_extra_function {
HA_EXTRA_ADD_CHILDREN_LIST,
HA_EXTRA_ATTACH_CHILDREN,
HA_EXTRA_IS_ATTACHED_CHILDREN,
- HA_EXTRA_DETACH_CHILDREN
+ HA_EXTRA_DETACH_CHILDREN,
+ /*
+ Prepare table for export
+ (e.g. quiesce the table and write table metadata).
+ */
+ HA_EXTRA_EXPORT
};
/* Compatible option, to be deleted in 6.0 */
=== modified file 'include/mysql_com.h'
--- a/include/mysql_com.h 2012-04-10 12:20:05 +0000
+++ b/include/mysql_com.h 2012-05-03 08:10:14 +0000
@@ -150,6 +150,7 @@ enum enum_server_command
#define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */
#define REFRESH_DES_KEY_FILE 0x40000L
#define REFRESH_USER_RESOURCES 0x80000L
+#define REFRESH_FOR_EXPORT 0x100000L /* FLUSH TABLES ... FOR EXPORT */
#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */
#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */
=== modified file 'mysql-test/r/flush_table.result'
--- a/mysql-test/r/flush_table.result 2012-04-12 06:38:47 +0000
+++ b/mysql-test/r/flush_table.result 2012-05-03 08:10:14 +0000
@@ -150,15 +150,157 @@ DROP PROCEDURE export;
# new FLUSH TABLES ... FOR EXPORT syntax:
FLUSH TABLES FOR EXPORT;
ERROR 42000: No tables used near 'FOR EXPORT' at line 1
-CREATE TABLE t1 (i INT);
+CREATE TABLE t1 (i INT) engine=InnoDB;
CREATE TABLE t2 LIKE t1;
FLUSH TABLES t1, t2 FOR EXPORT;
UNLOCK TABLES;
DROP TABLES t1, t2;
# new "EXPORT" keyword is a valid table name:
-CREATE TABLE export (i INT);
+CREATE TABLE export (i INT) engine=InnoDB;
# it's ok to lock the "export" table for export:
FLUSH TABLE export FOR EXPORT;
UNLOCK TABLES;
DROP TABLE export;
+#
+# WL#6169 FLUSH TABLES ... FOR EXPORT -- runtime
+#
+# Test 1: Views, temporary tables, non-existent tables
+#
+CREATE VIEW v1 AS SELECT 1;
+CREATE TEMPORARY TABLE t1 (a INT);
+FLUSH TABLES v1 FOR EXPORT;
+ERROR HY000: 'test.v1' is not BASE TABLE
+FLUSH TABLES t1 FOR EXPORT;
+ERROR 42S02: Table 'test.t1' doesn't exist
+FLUSH TABLES non_existent FOR EXPORT;
+ERROR 42S02: Table 'test.non_existent' doesn't exist
+DROP TEMPORARY TABLE t1;
+DROP VIEW v1;
+# Test 2: Blocked by update transactions, blocks updates.
+#
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT) engine= InnoDB;
+CREATE TABLE t2 (a INT) engine= InnoDB;
+# Connection con1
+START TRANSACTION;
+INSERT INTO t1 VALUES (1, 1);
+# Connection default
+# Should be blocked
+# Sending:
+FLUSH TABLES t1 FOR EXPORT;
+# Connection con1
+COMMIT;
+# Connection default
+# Reaping: FLUSH TABLES t1 FOR EXPORT
+# Connection con1
+# Should not be blocked
+INSERT INTO t2 VALUES (1);
+# Should be blocked
+# Sending:
+INSERT INTO t1 VALUES (2, 2);
+# Connection default
+UNLOCK TABLES;
+# Connection con1
+# Reaping: INSERT INTO t1 VALUES (2, 2);
+# Test 3: Read operations should not be affected.
+#
+START TRANSACTION;
+SELECT * FROM t1;
+a b
+1 1
+2 2
+# Connection default
+# Should not be blocked
+FLUSH TABLES t1 FOR EXPORT;
+# Connection con1
+COMMIT;
+# Should not be blocked
+SELECT * FROM t1;
+a b
+1 1
+2 2
+# Connection default
+UNLOCK TABLES;
+# Test 4: Blocked by DDL, blocks DDL.
+#
+START TRANSACTION;
+SELECT * FROM t1;
+a b
+1 1
+2 2
+# Connection con2
+# Sending:
+ALTER TABLE t1 ADD INDEX i1(b);
+# Connection con1
+# Should be blocked
+FLUSH TABLE t1 FOR EXPORT;
+# Connection default
+COMMIT;
+# Connection con2
+# Reaping ALTER TABLE ...
+# Connection con1
+# Reaping FLUSH TABLE t1 FOR EXPORT
+UNLOCK TABLES;
+# Connection default
+FLUSH TABLE t1 FOR EXPORT;
+# Connection con2
+# Should be blocked
+DROP TABLE t1;
+# Connection default
+UNLOCK TABLES;
+# Connection con2
+# Reaping DROP TABLE t1
+# Connection default
+DROP TABLE t2;
+# Test 5: Compatibilty with FLUSH TABLES WITH READ LOCK
+#
+CREATE TABLE t1(a INT) engine= InnoDB;
+FLUSH TABLES WITH READ LOCK;
+# Connection con1
+# This should not block
+FLUSH TABLE t1 FOR EXPORT;
+UNLOCK TABLES;
+# Connection default
+UNLOCK TABLES;
+DROP TABLE t1;
+# Test 6: Unsupported storage engines.
+#
+CREATE TABLE t1(a INT) engine= MyISAM;
+FLUSH TABLE t1 FOR EXPORT;
+ERROR HY000: Table storage engine for 't1' doesn't have this option
+DROP TABLE t1;
+# Connection con1
+# Connection defalt
+# Test 7: Check privileges required.
+#
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (a INT) engine= InnoDB;
+GRANT RELOAD, SELECT, LOCK TABLES ON *.* TO user1@localhost;
+GRANT CREATE, DROP ON *.* TO user2@localhost;
+GRANT RELOAD, SELECT ON *.* TO user3@localhost;
+GRANT SELECT, LOCK TABLES ON *.* TO user4@localhost;
+GRANT RELOAD, LOCK TABLES ON *.* TO user5@localhost;
+# Connection con1 as user1
+FLUSH TABLE db1.t1 FOR EXPORT;
+UNLOCK TABLES;
+# Connection default
+# Connection con1 as user2
+FLUSH TABLE db1.t1 FOR EXPORT;
+ERROR 42000: Access denied; you need (at least one of) the RELOAD privilege(s) for this operation
+# Connection default
+# Connection con1 as user3
+FLUSH TABLE db1.t1 FOR EXPORT;
+ERROR 42000: Access denied for user 'user3'@'localhost' to database 'db1'
+# Connection default
+# Connection con1 as user4
+FLUSH TABLE db1.t1 FOR EXPORT;
+ERROR 42000: Access denied; you need (at least one of) the RELOAD privilege(s) for this operation
+# Connection default
+# Connection con1 as user5
+FLUSH TABLE db1.t1 FOR EXPORT;
+ERROR 42000: SELECT command denied to user 'user5'@'localhost' for table 't1'
+# Connection default
+DROP USER user1@localhost, user2@localhost, user3@localhost,
+user4@localhost, user5@localhost;
+DROP TABLE db1.t1;
+DROP DATABASE db1;
# End of 5.6 tests
=== modified file 'mysql-test/t/flush_table.test'
--- a/mysql-test/t/flush_table.test 2012-04-12 06:38:47 +0000
+++ b/mysql-test/t/flush_table.test 2012-05-03 08:10:14 +0000
@@ -163,7 +163,7 @@ DROP PROCEDURE export;
--error ER_PARSE_ERROR
FLUSH TABLES FOR EXPORT;
-CREATE TABLE t1 (i INT);
+CREATE TABLE t1 (i INT) engine=InnoDB;
CREATE TABLE t2 LIKE t1;
FLUSH TABLES t1, t2 FOR EXPORT;
@@ -173,7 +173,7 @@ DROP TABLES t1, t2;
--echo # new "EXPORT" keyword is a valid table name:
-CREATE TABLE export (i INT);
+CREATE TABLE export (i INT) engine=InnoDB;
--echo # it's ok to lock the "export" table for export:
@@ -182,5 +182,269 @@ UNLOCK TABLES;
DROP TABLE export;
+
+--echo #
+--echo # WL#6169 FLUSH TABLES ... FOR EXPORT -- runtime
+--echo #
+
+--echo # Test 1: Views, temporary tables, non-existent tables
+--echo #
+
+CREATE VIEW v1 AS SELECT 1;
+CREATE TEMPORARY TABLE t1 (a INT);
+
+--error ER_WRONG_OBJECT
+FLUSH TABLES v1 FOR EXPORT;
+--error ER_NO_SUCH_TABLE
+FLUSH TABLES t1 FOR EXPORT;
+--error ER_NO_SUCH_TABLE
+FLUSH TABLES non_existent FOR EXPORT;
+
+DROP TEMPORARY TABLE t1;
+DROP VIEW v1;
+
+--echo # Test 2: Blocked by update transactions, blocks updates.
+--echo #
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT) engine= InnoDB;
+CREATE TABLE t2 (a INT) engine= InnoDB;
+
+--echo # Connection con1
+--connect (con1, localhost, root)
+START TRANSACTION;
+INSERT INTO t1 VALUES (1, 1);
+
+--echo # Connection default
+--connection default
+--echo # Should be blocked
+--echo # Sending:
+--send FLUSH TABLES t1 FOR EXPORT
+
+--echo # Connection con1
+--connection con1
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE state = "Waiting for table metadata lock" AND
+ info = "FLUSH TABLES t1 FOR EXPORT";
+--source include/wait_condition.inc
+COMMIT;
+
+--echo # Connection default
+--connection default
+--echo # Reaping: FLUSH TABLES t1 FOR EXPORT
+--reap
+
+--echo # Connection con1
+--connection con1
+--echo # Should not be blocked
+INSERT INTO t2 VALUES (1);
+--echo # Should be blocked
+--echo # Sending:
+--send INSERT INTO t1 VALUES (2, 2)
+
+--echo # Connection default
+--connection default
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE state = "Waiting for table metadata lock" AND
+ info = "INSERT INTO t1 VALUES (2, 2)";
+--source include/wait_condition.inc
+UNLOCK TABLES;
+
+--echo # Connection con1
+--connection con1
+--echo # Reaping: INSERT INTO t1 VALUES (2, 2);
+--reap
+
+--echo # Test 3: Read operations should not be affected.
+--echo #
+
+START TRANSACTION;
+SELECT * FROM t1;
+
+--echo # Connection default
+--connection default
+--echo # Should not be blocked
+FLUSH TABLES t1 FOR EXPORT;
+
+--echo # Connection con1
+--connection con1
+COMMIT;
+--echo # Should not be blocked
+SELECT * FROM t1;
+
+--echo # Connection default
+--connection default
+UNLOCK TABLES;
+
+--echo # Test 4: Blocked by DDL, blocks DDL.
+--echo #
+
+START TRANSACTION;
+SELECT * FROM t1;
+
+--echo # Connection con2
+--connect (con2, localhost, root)
+--echo # Sending:
+--send ALTER TABLE t1 ADD INDEX i1(b)
+
+--echo # Connection con1
+--connection con1
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE state = "Waiting for table metadata lock" AND
+ info = "ALTER TABLE t1 ADD INDEX i1(b)";
+--source include/wait_condition.inc
+--echo # Should be blocked
+--send FLUSH TABLE t1 FOR EXPORT
+
+--echo # Connection default
+--connection default
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE state = "Waiting for table metadata lock" AND
+ info = "FLUSH TABLE t1 FOR EXPORT";
+--source include/wait_condition.inc
+COMMIT;
+
+--echo # Connection con2
+--connection con2
+--echo # Reaping ALTER TABLE ...
+--reap
+
+--echo # Connection con1
+--connection con1
+--echo # Reaping FLUSH TABLE t1 FOR EXPORT
+--reap
+UNLOCK TABLES;
+
+--echo # Connection default
+--connection default
+FLUSH TABLE t1 FOR EXPORT;
+
+--echo # Connection con2
+--connection con2
+--echo # Should be blocked
+--send DROP TABLE t1
+
+--echo # Connection default
+--connection default
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE state = "Waiting for table metadata lock" AND
+ info = "DROP TABLE t1";
+--source include/wait_condition.inc
+UNLOCK TABLES;
+
+--echo # Connection con2
+--connection con2
+--echo # Reaping DROP TABLE t1
+--reap
+--disconnect con2
+--source include/wait_until_disconnected.inc
+
+--echo # Connection default
+--connection default
+DROP TABLE t2;
+
+--echo # Test 5: Compatibilty with FLUSH TABLES WITH READ LOCK
+--echo #
+
+CREATE TABLE t1(a INT) engine= InnoDB;
+FLUSH TABLES WITH READ LOCK;
+
+--echo # Connection con1
+--connection con1
+--echo # This should not block
+FLUSH TABLE t1 FOR EXPORT;
+UNLOCK TABLES;
+
+--echo # Connection default
+--connection default
+UNLOCK TABLES;
+DROP TABLE t1;
+
+--echo # Test 6: Unsupported storage engines.
+--echo #
+
+CREATE TABLE t1(a INT) engine= MyISAM;
+--error ER_ILLEGAL_HA
+FLUSH TABLE t1 FOR EXPORT;
+DROP TABLE t1;
+
+--echo # Connection con1
+--connection con1
+--disconnect con1
+--source include/wait_until_disconnected.inc
+
+--echo # Connection defalt
+--connection default
+
+--echo # Test 7: Check privileges required.
+--echo #
+
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (a INT) engine= InnoDB;
+GRANT RELOAD, SELECT, LOCK TABLES ON *.* TO user1@localhost;
+GRANT CREATE, DROP ON *.* TO user2@localhost;
+GRANT RELOAD, SELECT ON *.* TO user3@localhost;
+GRANT SELECT, LOCK TABLES ON *.* TO user4@localhost;
+GRANT RELOAD, LOCK TABLES ON *.* TO user5@localhost;
+
+--echo # Connection con1 as user1
+--connect(con1, localhost, user1)
+FLUSH TABLE db1.t1 FOR EXPORT;
+UNLOCK TABLES;
+--disconnect con1
+--source include/wait_until_disconnected.inc
+
+--echo # Connection default
+--connection default
+
+--echo # Connection con1 as user2
+--connect(con1, localhost, user2)
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+FLUSH TABLE db1.t1 FOR EXPORT;
+--disconnect con1
+--source include/wait_until_disconnected.inc
+
+--echo # Connection default
+--connection default
+
+--echo # Connection con1 as user3
+--connect(con1, localhost, user3)
+--error ER_DBACCESS_DENIED_ERROR
+FLUSH TABLE db1.t1 FOR EXPORT;
+--disconnect con1
+--source include/wait_until_disconnected.inc
+
+--echo # Connection default
+--connection default
+
+--echo # Connection con1 as user4
+--connect(con1, localhost, user4)
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+FLUSH TABLE db1.t1 FOR EXPORT;
+--disconnect con1
+--source include/wait_until_disconnected.inc
+
+--echo # Connection default
+--connection default
+
+--echo # Connection con1 as user5
+--connect(con1, localhost, user5)
+--error ER_TABLEACCESS_DENIED_ERROR
+FLUSH TABLE db1.t1 FOR EXPORT;
+--disconnect con1
+--source include/wait_until_disconnected.inc
+
+--echo # Connection default
+--connection default
+DROP USER user1@localhost, user2@localhost, user3@localhost,
+ user4@localhost, user5@localhost;
+DROP TABLE db1.t1;
+DROP DATABASE db1;
+
+
--echo # End of 5.6 tests
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2012-05-02 12:04:42 +0000
+++ b/sql/handler.h 2012-05-03 08:10:14 +0000
@@ -202,6 +202,12 @@ enum enum_alter_inplace_result {
*/
#define HA_READ_OUT_OF_SYNC (LL(1) << 40)
+/*
+ Storage engine supports table export using the
+ FLUSH TABLE <table_list> FOR EXPORT statement.
+*/
+#define HA_CAN_EXPORT (LL(1) << 41)
+
/* bits in index_flags(index_number) for what you can do with index */
#define HA_READ_NEXT 1 /* TODO really use this flag */
#define HA_READ_PREV 2 /* supports ::index_prev */
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2012-04-30 07:13:31 +0000
+++ b/sql/sql_parse.cc 2012-05-03 08:10:14 +0000
@@ -4033,6 +4033,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
=== modified file 'sql/sql_reload.cc'
--- a/sql/sql_reload.cc 2012-04-13 12:00:39 +0000
+++ b/sql/sql_reload.cc 2012-05-03 08:10:14 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -454,7 +454,7 @@ bool flush_tables_with_read_lock(THD *th
/*
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
@@ -484,4 +484,79 @@ 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_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;
+}
=== modified file 'sql/sql_reload.h'
--- a/sql/sql_reload.h 2010-12-07 16:11:13 +0000
+++ b/sql/sql_reload.h 2012-05-03 08:10:14 +0000
@@ -1,6 +1,6 @@
#ifndef SQL_RELOAD_INCLUDED
#define SQL_RELOAD_INCLUDED
-/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,4 +23,6 @@ bool reload_acl_and_cache(THD *thd, unsi
bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables);
+bool flush_tables_for_export(THD *thd, TABLE_LIST *all_tables);
+
#endif
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2012-05-02 12:48:08 +0000
+++ b/sql/sql_yacc.yy 2012-05-03 08:10:14 +0000
@@ -12346,13 +12346,8 @@ opt_flush_lock:
}
EXPORT_SYM
{
- /*
- Following code is a temporary copy of the "WITH READ LOCK" logic
- from the previous rule.
- TODO: Runtime: replace with the "FOR EXPORT" implementation.
- */
TABLE_LIST *tables= Lex->query_tables;
- Lex->type|= REFRESH_READ_LOCK;
+ Lex->type|= REFRESH_FOR_EXPORT;
for (; tables; tables= tables->next_global)
{
tables->mdl_request.set_type(MDL_SHARED_NO_WRITE);
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc 2012-04-30 13:39:52 +0000
+++ b/storage/innobase/handler/ha_innodb.cc 2012-05-03 08:10:14 +0000
@@ -2082,7 +2082,7 @@ ha_innobase::ha_innobase(
HA_BINLOG_ROW_CAPABLE |
HA_CAN_GEOMETRY | HA_PARTIAL_COLUMN_READ |
HA_TABLE_SCAN_ON_INDEX | HA_CAN_FULLTEXT |
- HA_CAN_FULLTEXT_EXT),
+ HA_CAN_FULLTEXT_EXT | HA_CAN_EXPORT),
start_of_scan(0),
num_write_row(0)
{}
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk-wl6168 branch (jon.hauglid:3870 to 3871) WL#6169 | Jon Olav Hauglid | 3 May |