--source include/have_debug.inc --source include/have_binlog_format_row.inc --source include/master-slave.inc --source ../include/have_xengine.inc --disable_ps_protocol CALL mtr.add_suppression("Fail TO recycle table"); CALL mtr.add_suppression("Incorrect key file"); connection master; CREATE DATABASE db_recycle; CREATE DATABASE db_recycle_dummy; CREATE USER super_1@'%' IDENTIFIED BY 'pass'; CREATE USER super_2@'%' IDENTIFIED BY 'pass'; CREATE USER normal_1@'%' IDENTIFIED BY 'pass'; CREATE USER normal_2@'%' IDENTIFIED BY 'pass'; CREATE USER normal_3@'%' IDENTIFIED BY 'pass'; CREATE USER normal_4@'%' IDENTIFIED BY 'pass'; CREATE USER normal_5@'%' IDENTIFIED BY 'pass'; GRANT ALL ON *.* TO super_1@'%'; GRANT ALL ON *.* TO super_2@'%'; GRANT ALL ON db_recycle.* TO normal_1@'%' ; GRANT ALL ON __recycle_bin__.* TO normal_1@'%' ; GRANT CREATE TABLESPACE ON *.* TO normal_1@'%' ; GRANT SYSTEM_VARIABLES_ADMIN on *.* TO normal_1@'%'; GRANT ALL ON db_recycle_dummy.* TO normal_2@'%' ; GRANT ALL ON db_recycle.* TO normal_3@'%' ; GRANT ALL ON __recycle_bin__.* TO normal_3@'%' ; GRANT ALL ON db_recycle_dummy.* TO normal_4@'%' ; GRANT ALL ON __recycle_bin__.* TO normal_5@'%' ; --sync_slave_with_master connect(m_super_1, 127.0.0.1, super_1, pass, db_recycle, $MASTER_MYPORT); connect(s_super_2, 127.0.0.1, super_1, pass, db_recycle, $SLAVE_MYPORT); connect(m_normal_1, 127.0.0.1, normal_1, pass, db_recycle, $MASTER_MYPORT); connect(m_normal_2, 127.0.0.1, normal_2, pass, test, $MASTER_MYPORT); connect(m_normal_5, 127.0.0.1, normal_5, pass, , $MASTER_MYPORT); connect(s_normal_3, 127.0.0.1, normal_3, pass, db_recycle, $SLAVE_MYPORT); connect(s_normal_4, 127.0.0.1, normal_4, pass, test, $SLAVE_MYPORT); connection slave; SET @start_read_only = @@global.read_only; SET GLOBAL read_only = true; --echo ------------------------------------------------------ --echo 1. Privileges --echo -- Still require related privileges if want to --echo show recycle bin db; --echo -- No one can alter db except super_acl user; --echo ------------------------------------------------------ connection m_normal_1; SHOW DATABASES; connection s_normal_3; SHOW DATABASES; connection m_normal_2; SHOW DATABASES; connection s_normal_4; SHOW DATABASES; connection m_normal_1; USE __recycle_bin__; --error ER_DBACCESS_DENIED_ERROR CREATE TABLE t1 (id int); SHOW TABLES; --echo ------------------------------------------------------ --echo 1.1 dbms_recycle.purge_table still require db.table privileges; --echo ------------------------------------------------------ connection m_super_1; SET GLOBAL recycle_scheduler=off; connection m_normal_1; USE db_recycle; CREATE TABLE t1(id INT); DROP TABLE t1; --replace_column 5 # 6 # CALL dbms_recycle.show_tables(); connection m_normal_2; let $table_name=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 1); --error ER_TABLEACCESS_DENIED_ERROR eval CALL dbms_recycle.purge_table("$table_name"); connection m_normal_5; let $table_name=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 1); --error ER_TABLEACCESS_DENIED_ERROR eval CALL dbms_recycle.purge_table("$table_name"); connection m_super_1; --let $pos_before= query_get_value(show master status,Position,1) connection m_normal_1; show grants; let $table_name=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 1); eval CALL dbms_recycle.purge_table("$table_name"); connection m_super_1; --let $assert_text= assert that the purge has not been added TO binlog --let $assert_cond= [SHOW MASTER STATUS, Position,1] = $pos_before --source include/assert.inc connection m_super_1; SET GLOBAL recycle_scheduler=on; --echo ------------------------------------------------------ --echo 2. Drop table --echo -- Related object: --echo Foreign key(XEngine doesn't support): --echo Trigger: --echo View: --echo Constraint: --echo ------------------------------------------------------ connection m_super_1; SET GLOBAL recycle_scheduler=off; connection m_normal_1; use db_recycle; CREATE TABLE p1 ( id INT NOT NULL, PRIMARY KEY (id) ); # XEngine doesn't support foreign key #CREATE TABLE c1 ( # id INT, # parent_id INT, # INDEX par_ind (parent_id), # FOREIGN KEY (parent_id) # REFERENCES p1(id) # ON DELETE CASCADE #); CREATE TABLE l1(id INT); delimiter //; CREATE TRIGGER tri_1 BEFORE INSERT ON p1 FOR EACH ROW BEGIN INSERT INTO l1 value(1); END// delimiter ;// CREATE VIEW v1 AS SELECT * FROM p1; --echo 1.1 confirm the trigger, view DROP TABLE p1; let $table_name=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 1); eval SHOW CREATE TABLE __recycle_bin__.$table_name; --error ER_TRG_DOES_NOT_EXIST SHOW CREATE TRIGGER tri_1; SHOW CREATE VIEW v1; --error ER_VIEW_INVALID SELECT * FROM v1; DROP TABLE l1; DROP VIEW v1; connection m_super_1; SET GLOBAL recycle_scheduler=on; --sleep 3 --echo ------------------------------------------------------ --echo 3. Drop parent table(XEngine doesn't support foreign key) --echo ------------------------------------------------------ #connection m_super_1; #SET GLOBAL recycle_scheduler=off; # #connection m_normal_1; #use db_recycle; # # XEngine doesn't support foreign key #CREATE TABLE p1 ( # id INT NOT NULL, # PRIMARY KEY (id) #); # #CREATE TABLE c1 ( # id INT, # parent_id INT, # INDEX par_ind (parent_id), # FOREIGN KEY (parent_id) # REFERENCES p1(id) # ON DELETE CASCADE #); # #--echo 1.1 foreign key. #--error ER_FK_CANNOT_DROP_PARENT #DROP TABLE p1; # #SET foreign_key_checks=off; #DROP TABLE p1; #INSERT INTO c1 VALUES(1, 2); #COMMIT; #SHOW CREATE TABLE c1; #SET foreign_key_checks=on; # #--replace_column 5 # 6 # #CALL dbms_recycle.show_tables(); #let $table_name=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 1); # #eval SHOW CREATE TABLE __recycle_bin__.$table_name; # #DROP TABLE c1; #connection m_super_1; #SET GLOBAL recycle_scheduler=on; # #--sleep 3 --echo ------------------------------------------------------ --echo 4. Drop in procedure --echo ------------------------------------------------------ connection m_super_1; SET GLOBAL recycle_scheduler=off; connection m_normal_1; USE db_recycle; CREATE TABLE p1 ( id INT NOT NULL, PRIMARY KEY (id) ); delimiter //; CREATE PROCEDURE proc_1() BEGIN DROP TABLE p1; END// delimiter ;// CALL proc_1(); --replace_column 5 # 6 # CALL dbms_recycle.show_tables(); let $table_name=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 1); eval SHOW CREATE TABLE __recycle_bin__.$table_name; DROP procedure proc_1; connection m_super_1; SET GLOBAL recycle_scheduler=on; --sleep 3 --echo ------------------------------------------------------ --echo 5. Drop database --echo ------------------------------------------------------ connection m_super_1; SET GLOBAL recycle_scheduler=off; connection m_normal_1; USE db_recycle; CREATE TABLE p2 ( id INT NOT NULL, PRIMARY KEY (id) ); # XEngine doesn't support foreign key #CREATE TABLE c2 ( # id INT, # parent_id INT, # self_id INT, # INDEX id_ind (id), # INDEX par_ind (parent_id), # INDEX sel_ind (self_id), # FOREIGN KEY (self_id) # REFERENCES c2(id), # FOREIGN KEY (parent_id) # REFERENCES p2(id) # ON DELETE CASCADE #); CREATE TABLE l2(id int); delimiter //; CREATE TRIGGER tri_1 BEFORE INSERT ON p2 FOR EACH ROW BEGIN INSERT INTO l2 value(1); END// delimiter ;// CREATE VIEW v2 AS SELECT * FROM p2; DROP DATABASE db_recycle; --replace_column 5 # 6 # CALL dbms_recycle.show_tables(); let $table_name1=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 1); let $table_name2=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 2); eval SHOW CREATE TABLE __recycle_bin__.$table_name1; eval SHOW CREATE TABLE __recycle_bin__.$table_name2; connection m_super_1; CREATE DATABASE db_recycle; SET GLOBAL recycle_scheduler=on; --sleep 3 --echo ------------------------------------------------------ --echo 6. read only --echo ------------------------------------------------------ connection m_super_1; SET GLOBAL recycle_scheduler=off; connection m_normal_1; USE db_recycle; CREATE TABLE t2 (id int); DROP TABLE t2; --replace_column 5 # 6 # CALL dbms_recycle.show_tables(); connection m_super_1; SET GLOBAL read_only = on; connection m_normal_1; let $table_name=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 1); --error ER_OPTION_PREVENTS_STATEMENT eval CALL dbms_recycle.purge_table("$table_name"); connection m_super_1; SET GLOBAL read_only = off; connection m_normal_1; let $table_name=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 1); eval CALL dbms_recycle.purge_table("$table_name"); connection m_super_1; SET GLOBAL recycle_scheduler=on; --echo ------------------------------------------------------ --echo 7. partition table or general tablespace --echo (XEngine doesn't support partitioned table and tablespace) --echo ------------------------------------------------------ #connection m_super_1; #SET GLOBAL recycle_scheduler=off; # #connection m_normal_1; #use db_recycle; # #CREATE TABLE t3 ( # firstname VARCHAR(25) NOT NULL, # lastname VARCHAR(25) NOT NULL, # username VARCHAR(16) NOT NULL, # email VARCHAR(35), # joined DATE NOT NULL #) #PARTITION BY RANGE( YEAR(joined) ) ( # PARTITION p0 VALUES LESS THAN (1960), # PARTITION p1 VALUES LESS THAN (1970), # PARTITION p2 VALUES LESS THAN (1980), # PARTITION p3 VALUES LESS THAN (1990), # PARTITION p4 VALUES LESS THAN MAXVALUE #); # #DROP TABLE t3; # #--replace_column 5 # 6 # #CALL dbms_recycle.show_tables(); # #let $table_name=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 1); #eval SHOW CREATE TABLE __recycle_bin__.$table_name; #eval CALL dbms_recycle.purge_table("$table_name"); #CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB; #CREATE TABLE t4(id int) tablespace ts1; #DROP TABLE t4; # #--replace_column 5 # 6 # #CALL dbms_recycle.show_tables(); # #let $table_name=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 1); #eval SHOW CREATE TABLE __recycle_bin__.$table_name; #eval CALL dbms_recycle.purge_table("$table_name"); # #connection m_super_1; #SET GLOBAL recycle_scheduler=on; # #--sleep 3 #connection master; #--sync_slave_with_master # #connection m_normal_1; #DROP TABLEspace ts1; --echo ------------------------------------------------------ --echo 8. recycle_bin table exists error --echo ------------------------------------------------------ connection m_super_1; SET GLOBAL recycle_scheduler=off; connection m_normal_1; use db_recycle; CREATE TABLE t5(id int); DROP TABLE t5; CREATE TABLE t5(id int); DROP TABLE t5; --replace_column 5 # 6 # CALL dbms_recycle.show_tables(); let $table_name=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 1); eval CALL dbms_recycle.purge_table("$table_name"); connection m_super_1; SET GLOBAL recycle_scheduler=on; --echo ------------------------------------------------------ --echo 9 fts table didn't support to be recycled --echo (XEngine doesn't support FULLTEXT index) --echo ------------------------------------------------------ #connection m_super_1; #SET GLOBAL recycle_scheduler=off; # #connection m_normal_1; #use db_recycle; # #CREATE TABLE t1 ( # id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, # title VARCHAR(200), # content TEXT, # FULLTEXT INDEX ft_content (content) #) ENGINE=InnoDB DEFAULT CHARACTER SET gb2312 COLLATE gb2312_chinese_ci; # #DROP TABLE t1; # #CALL dbms_recycle.show_tables(); # #connection m_super_1; #SET GLOBAL recycle_scheduler=on; --echo ------------------------------------------------------ --echo 10. purge normal table or nonexist table --echo ------------------------------------------------------ connection m_super_1; SET GLOBAL recycle_scheduler=off; connection m_normal_1; use db_recycle; connection m_super_1; CREATE TABLE __recycle_bin__.x5(id INT); connection m_normal_1; --error ER_PREPARE_RECYCLE_TABLE_ERROR CALL dbms_recycle.purge_table("x5"); --error ER_PREPARE_RECYCLE_TABLE_ERROR CALL dbms_recycle.purge_table("x6"); --replace_column 5 # 6 # CALL dbms_recycle.show_tables(); connection m_super_1; DROP TABLE __recycle_bin__.x5; SET GLOBAL recycle_scheduler=on; --echo ------------------------------------------------------ --echo 11. simulate handler rename failed. --echo ------------------------------------------------------ connection m_super_1; SET GLOBAL recycle_scheduler=off; connection m_normal_1; USE db_recycle; CREATE TABLE t6(id INT); INSERT INTO t6 VALUES(1); COMMIT; SET @@SESSION.debug = "+d,simulate_crashed_table_error"; --error 126 DROP TABLE t6; SET @@SESSION.debug = "-d,simulate_crashed_table_error"; SHOW CREATE TABLE t6; SELECT * FROM t6; DROP TABLE t6; --replace_column 5 # 6 # CALL dbms_recycle.show_tables(); let $table_name=query_get_value(CALL dbms_recycle.show_tables(), TABLE, 1); eval CALL dbms_recycle.purge_table("$table_name"); --echo ------------------------------------------------------ --echo 12. with lock mode --echo ------------------------------------------------------ connection m_super_1; CREATE TABLE test.t1(id INT); SET SESSION recycle_bin=on; LOCK TABLES test.t1 write; DROP TABLE test.t1; --error ER_NO_SUCH_TABLE show create table t1; --replace_column 5 # 6 # CALL dbms_recycle.show_tables(); UNLOCK tables; connection m_super_1; SET GLOBAL recycle_scheduler=on; connection master; drop database db_recycle; drop database db_recycle_dummy; drop user super_1@'%'; drop user super_2@'%'; drop user normal_1@'%'; drop user normal_2@'%'; drop user normal_3@'%'; drop user normal_4@'%'; drop user normal_5@'%'; connection slave; SET GLOBAL read_only = @start_read_only; connection master; --sync_slave_with_master --source include/rpl_end.inc --enable_ps_protocol --source suite/xengine/include/check_xengine_log_error.inc