--source include/have_debug.inc --source include/have_binlog_format_row.inc --source include/master-slave.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__; create table t1 (id int); drop table t1; show tables; --echo 1.1 dbms_recycle.purge_table still require db.table privileges; 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; --error ER_TABLEACCESS_DENIED_ERROR call dbms_recycle.purge_table("__innodb_165"); connection m_normal_5; --error ER_TABLEACCESS_DENIED_ERROR call dbms_recycle.purge_table("__innodb_165"); connection m_super_1; --let $pos_before= query_get_value(show master status,Position,1) connection m_normal_1; show grants; call dbms_recycle.purge_table("__innodb_165"); 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 1. Drop table --echo -- Related object: --echo Foreign key: --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) ) ENGINE=INNODB; CREATE TABLE c1 ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES p1(id) ON DELETE CASCADE ) ENGINE=INNODB; create table l1(id int); delimiter //; CREATE TRIGGER tri_1 before INSERT ON c1 FOR EACH ROW BEGIN INSERT INTO l1 value(1); END// delimiter ;// create view v1 as select * from c1; --echo 1.1 confirm the trigger, view, foreign key. drop table c1; --replace_column 5 # 6 # call dbms_recycle.show_tables(); show create table __recycle_bin__.__innodb_148; --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; drop table p1; connection m_super_1; set global recycle_scheduler=on; --sleep 3 --echo ------------------------------------------------------ --echo 1. Drop parent table --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) ) ENGINE=INNODB; CREATE TABLE c1 ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES p1(id) ON DELETE CASCADE ) ENGINE=INNODB; --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(); show create table __recycle_bin__.__innodb_161; drop table c1; connection m_super_1; set global recycle_scheduler=on; --sleep 3 --echo ------------------------------------------------------ --echo 1. 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) ) ENGINE=INNODB; delimiter //; create procedure proc_1() begin drop table p1; end// delimiter ;// call proc_1(); --replace_column 5 # 6 # call dbms_recycle.show_tables(); show create table __recycle_bin__.__innodb_161; drop procedure proc_1; connection m_super_1; set global recycle_scheduler=on; --sleep 3 --echo ------------------------------------------------------ --echo 2. 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) ) ENGINE=INNODB; 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 ) ENGINE=INNODB; create table l2(id int); delimiter //; CREATE TRIGGER tri_1 before INSERT ON c2 FOR EACH ROW BEGIN INSERT INTO l2 value(1); END// delimiter ;// create view v2 as select * from c2; drop database db_recycle; --replace_column 5 # 6 # call dbms_recycle.show_tables(); show create table __recycle_bin__.__innodb_149; show create table __recycle_bin__.__innodb_158; show create table __recycle_bin__.__innodb_162; connection m_super_1; create database db_recycle; set global recycle_scheduler=on; --sleep 3 --echo ------------------------------------------------------ --echo 3. 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; --error ER_OPTION_PREVENTS_STATEMENT call dbms_recycle.purge_table("__innodb_166"); connection m_super_1; set global read_only = off; connection m_normal_1; call dbms_recycle.purge_table("__innodb_166"); connection m_super_1; set global recycle_scheduler=on; --echo ------------------------------------------------------ --echo 4. partition table or general 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(); show create table __recycle_bin__.__innodb_167; call dbms_recycle.purge_table("__innodb_167"); 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(); show create table __recycle_bin__.__innodb_168; call dbms_recycle.purge_table("__innodb_168"); 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 5. 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(); --error ER_NATIVE_PROC_PARAMETER_MISMATCH call dbms_recycle.purge_table(""); call dbms_recycle.purge_table("__innodb_169"); connection m_super_1; set global recycle_scheduler=on; --echo ------------------------------------------------------ --echo 5.1 fts table didn't support to be recycled --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 6. purge normal table or noexist 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 7. 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(); call dbms_recycle.purge_table("__innodb_170"); 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