github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/tests/shardddl2/run.sh (about)

     1  #!/bin/bash
     2  
     3  set -eu
     4  
     5  cur=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
     6  source $cur/../_utils/test_prepare
     7  WORK_DIR=$TEST_DIR/$TEST_NAME
     8  source $cur/../_utils/shardddl_lib.sh
     9  
    10  function DM_036_CASE() {
    11  	run_sql_source1 "alter table ${shardddl1}.${tb1} add column new_col1 int first;"
    12  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(1,1,'aaa');"
    13  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(2,'bbb');"
    14  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(3,'ccc');"
    15  	run_sql_source2 "alter table ${shardddl1}.${tb1} add column new_col1 int after a;"
    16  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(4,4,'ddd');"
    17  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(5,5,'eee');"
    18  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(6,'fff');"
    19  	run_sql_source2 "alter table ${shardddl1}.${tb2} add column new_col1 int after b;"
    20  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(7,7,'ggg');"
    21  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(8,8,'hhh');"
    22  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(9,'iii',9);"
    23  	run_sql_tidb_with_retry "select count(1) from ${shardddl}.${tb};" "count(1): 9"
    24  }
    25  
    26  function DM_036() {
    27  	# currently not support pessimistic
    28  	# run_case 036 "double-source-pessimistic" \
    29  	# "run_sql_source1 \"create table ${shardddl1}.${tb1} (a int primary key, b varchar(10));\"; \
    30  	#  run_sql_source2 \"create table ${shardddl1}.${tb1} (a int primary key, b varchar(10));\"; \
    31  	#  run_sql_source2 \"create table ${shardddl1}.${tb2} (a int primary key, b varchar(10));\";" \
    32  	# "clean_table" "pessimistic"
    33  
    34  	run_case 036 "double-source-optimistic" \
    35  		"run_sql_source1 \"create table ${shardddl1}.${tb1} (a int primary key, b varchar(10));\"; \
    36       run_sql_source2 \"create table ${shardddl1}.${tb1} (a int primary key, b varchar(10));\"; \
    37       run_sql_source2 \"create table ${shardddl1}.${tb2} (a int primary key, b varchar(10));\";" \
    38  		"clean_table" "optimistic"
    39  }
    40  
    41  function DM_037_CASE() {
    42  	run_sql_source1 "alter table ${shardddl1}.${tb1} add new_col1 int default 0;"
    43  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(1,1);"
    44  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(2);"
    45  	run_sql_source2 "alter table ${shardddl1}.${tb1} add new_col1 int default -1;"
    46  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(3,3);"
    47  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(4,4);"
    48  	run_sql_source2 "alter table ${shardddl1}.${tb2} add new_col1 int default -1;"
    49  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(5,5);"
    50  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(6,6);"
    51  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(7,7);"
    52  	if [[ "$1" = "pessimistic" ]]; then
    53  		check_log_contain_with_retry "is different with" $WORK_DIR/master/log/dm-master.log
    54  	else
    55  		run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
    56  			"query-status test" \
    57  			'ALTER TABLE `shardddl`.`tb` ADD COLUMN `new_col1` INT DEFAULT' 1 \
    58  			"\`${shardddl1}\`.\`${tb1}\`\"" 1
    59  	fi
    60  }
    61  
    62  function DM_037() {
    63  	run_case 037 "double-source-pessimistic" "init_table 111 211 212" "clean_table" "pessimistic"
    64  	run_case 037 "double-source-optimistic" "init_table 111 211 212" "clean_table" "optimistic"
    65  }
    66  
    67  function DM_038_CASE() {
    68  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(1);"
    69  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(2);"
    70  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(3);"
    71  
    72  	# TODO: remove sleep after we support detect ASAP in optimistic mode
    73  	sleep 1
    74  	run_sql_source1 "alter table ${shardddl1}.${tb1} add column col1 datetime default now();"
    75  	run_sql_source1 "insert into ${shardddl1}.${tb1} (id) values (4);"
    76  	sleep 1
    77  	run_sql_source2 "alter table ${shardddl1}.${tb1} add column col1 datetime default now();"
    78  	run_sql_source2 "insert into ${shardddl1}.${tb1} (id) values (5);"
    79  	sleep 1
    80  	run_sql_source2 "alter table ${shardddl1}.${tb2} add column col1 datetime default now();"
    81  	run_sql_source2 "insert into ${shardddl1}.${tb2} (id) values (6);"
    82  	check_sync_diff $WORK_DIR $cur/conf/diff_config.toml 3 'fail'
    83  }
    84  
    85  function DM_038() {
    86  	run_case 038 "double-source-pessimistic" "init_table 111 211 212" "clean_table" "pessimistic"
    87  	run_case 038 "double-source-optimistic" "init_table 111 211 212" "clean_table" "optimistic"
    88  }
    89  
    90  function DM_039_CASE() {
    91  	run_sql_source1 "alter table ${shardddl1}.${tb1} add column col1 varchar(10) character set utf8 collate utf8_bin;"
    92  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(1,'aaa');"
    93  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(2);"
    94  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(3);"
    95  	run_sql_source2 "alter table ${shardddl1}.${tb1} add column col1 varchar(10) character set utf8 collate utf8_bin;"
    96  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(4,'bbb');"
    97  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(5,'ccc');"
    98  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(6);"
    99  	run_sql_source2 "alter table ${shardddl1}.${tb2} add column col1 varchar(10) character set utf8 collate utf8_bin;"
   100  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(7,'ddd');"
   101  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(8,'eee');"
   102  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(9,'fff');"
   103  	check_sync_diff $WORK_DIR $cur/conf/diff_config.toml
   104  }
   105  
   106  function DM_039() {
   107  	run_case 039 "double-source-pessimistic" "init_table 111 211 212" "clean_table" "pessimistic"
   108  	run_case 039 "double-source-optimistic" "init_table 111 211 212" "clean_table" "optimistic"
   109  }
   110  
   111  function DM_040_CASE() {
   112  	run_sql_source1 "alter table ${shardddl1}.${tb1} add column col1 varchar(10) character set utf8 collate utf8_bin;"
   113  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(1,'aaa');"
   114  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(2);"
   115  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(3);"
   116  	run_sql_source2 "alter table ${shardddl1}.${tb1} add column col1 varchar(10) character set utf8mb4 collate utf8mb4_bin;"
   117  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(4,'bbb');"
   118  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(5,'ccc');"
   119  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(6);"
   120  	run_sql_source2 "alter table ${shardddl1}.${tb2} add column col1 varchar(10) character set utf8mb4 collate utf8mb4_bin;"
   121  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(7,'ddd');"
   122  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(8,'eee');"
   123  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(9,'fff');"
   124  	if [[ "$1" = "pessimistic" ]]; then
   125  		check_log_contain_with_retry "is different with" $WORK_DIR/master/log/dm-master.log
   126  	else
   127  		run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   128  			"query-status test" \
   129  			'ALTER TABLE `shardddl`.`tb` ADD COLUMN `col1` VARCHAR(10) CHARACTER SET UTF8' 1 \
   130  			"\`${shardddl1}\`.\`${tb1}\`\"" 1
   131  	fi
   132  }
   133  
   134  function DM_040() {
   135  	run_case 040 "double-source-pessimistic" "init_table 111 211 212" "clean_table" "pessimistic"
   136  	run_case 040 "double-source-optimistic" "init_table 111 211 212" "clean_table" "optimistic"
   137  }
   138  
   139  function DM_041_CASE() {
   140  	run_sql_source1 "alter table ${shardddl1}.${tb1} add column new_col1 int as (id+1);"
   141  	run_sql_source1 "insert into ${shardddl1}.${tb1} (id) values(1);"
   142  	run_sql_source2 "insert into ${shardddl1}.${tb1} (id) values(2);"
   143  	run_sql_source2 "insert into ${shardddl1}.${tb2} (id) values(3);"
   144  	run_sql_source2 "alter table ${shardddl1}.${tb1} add column new_col1 int as (id+1);"
   145  	run_sql_source1 "insert into ${shardddl1}.${tb1} (id) values(4);"
   146  	run_sql_source2 "insert into ${shardddl1}.${tb1} (id) values(5);"
   147  	run_sql_source2 "insert into ${shardddl1}.${tb2} (id) values(6);"
   148  	run_sql_source2 "alter table ${shardddl1}.${tb2} add column new_col1 int as (id+1);"
   149  	run_sql_source1 "insert into ${shardddl1}.${tb1} (id) values(7);"
   150  	run_sql_source2 "insert into ${shardddl1}.${tb1} (id) values(8);"
   151  	run_sql_source2 "insert into ${shardddl1}.${tb2} (id) values(9);"
   152  	check_sync_diff $WORK_DIR $cur/conf/diff_config.toml
   153  }
   154  
   155  function DM_041() {
   156  	run_case 041 "double-source-pessimistic" "init_table 111 211 212" "clean_table" "pessimistic"
   157  	run_case 041 "double-source-optimistic" "init_table 111 211 212" "clean_table" "optimistic"
   158  }
   159  
   160  function DM_043_CASE() {
   161  	run_sql_source1 "alter table ${shardddl1}.${tb1} add column new_col1 int as (id+1);"
   162  	run_sql_source1 "insert into ${shardddl1}.${tb1} (id) values(1);"
   163  	run_sql_source2 "insert into ${shardddl1}.${tb1} (id) values(2);"
   164  	run_sql_source2 "insert into ${shardddl1}.${tb2} (id) values(3);"
   165  	run_sql_source2 "alter table ${shardddl1}.${tb1} add column new_col1 int as (id+2);"
   166  	run_sql_source1 "insert into ${shardddl1}.${tb1} (id) values(4);"
   167  	run_sql_source2 "insert into ${shardddl1}.${tb1} (id) values(5);"
   168  	run_sql_source2 "insert into ${shardddl1}.${tb2} (id) values(6);"
   169  	run_sql_source2 "alter table ${shardddl1}.${tb2} add column new_col1 int as (id+2);"
   170  	run_sql_source1 "insert into ${shardddl1}.${tb1} (id) values(7);"
   171  	run_sql_source2 "insert into ${shardddl1}.${tb1} (id) values(8);"
   172  	run_sql_source2 "insert into ${shardddl1}.${tb2} (id) values(9);"
   173  	if [[ "$1" = "pessimistic" ]]; then
   174  		check_log_contain_with_retry "is different with" $WORK_DIR/master/log/dm-master.log
   175  	else
   176  		# can't make sure which MySQL comes first
   177  		run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   178  			"query-status test" \
   179  			'ALTER TABLE `shardddl`.`tb` ADD COLUMN `new_col1` INT GENERATED ALWAYS AS' 1
   180  	fi
   181  }
   182  
   183  function DM_043() {
   184  	run_case 043 "double-source-pessimistic" "init_table 111 211 212" "clean_table" "pessimistic"
   185  	run_case 043 "double-source-optimistic" "init_table 111 211 212" "clean_table" "optimistic"
   186  }
   187  
   188  function DM_INIT_SCHEMA_CASE() {
   189  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(1);"
   190  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(2);"
   191  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(3);"
   192  
   193  	run_sql_source1 "alter table ${shardddl1}.${tb1} add new_col1 int;"
   194  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(4,4);"
   195  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(5);"
   196  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(6);"
   197  	run_sql_source1 "alter table ${shardddl1}.${tb1} drop new_col1;"
   198  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(7);"
   199  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(8);"
   200  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(9);"
   201  
   202  	check_log_contain_with_retry 'finish to handle ddls in optimistic shard mode.*DROP COLUMN' \
   203  		$WORK_DIR/worker1/log/dm-worker.log $WORK_DIR/worker2/log/dm-worker.log
   204  
   205  	restart_master
   206  
   207  	run_sql_source1 "alter table ${shardddl1}.${tb1} add new_col1 int;"
   208  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(10,10);"
   209  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(11);"
   210  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(12);"
   211  	run_sql_source1 "alter table ${shardddl1}.${tb1} drop new_col1;"
   212  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(13);"
   213  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(14);"
   214  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(15);"
   215  
   216  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   217  		"query-status test" \
   218  		"\"result\": true" 3
   219  	check_sync_diff $WORK_DIR $cur/conf/diff_config.toml
   220  }
   221  
   222  function DM_INIT_SCHEMA() {
   223  	run_case INIT_SCHEMA "double-source-optimistic" "init_table 111 211 212" "clean_table" "optimistic"
   224  }
   225  
   226  function restart_worker() {
   227  	echo "restart dm-worker" $1
   228  	if [[ "$1" = "1" ]]; then
   229  		kill_process dm-worker1
   230  		check_port_offline $WORKER1_PORT 20
   231  	else
   232  		kill_process dm-worker2
   233  		check_port_offline $WORKER2_PORT 20
   234  	fi
   235  	export GO_FAILPOINTS=$2
   236  
   237  	if [[ "$1" = "1" ]]; then
   238  		run_dm_worker $WORK_DIR/worker1 $WORKER1_PORT $cur/conf/dm-worker1.toml
   239  		check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER1_PORT
   240  	else
   241  		run_dm_worker $WORK_DIR/worker2 $WORKER2_PORT $cur/conf/dm-worker2.toml
   242  		check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT
   243  	fi
   244  }
   245  
   246  function DM_DROP_COLUMN_EXEC_ERROR_CASE() {
   247  	# get worker of source1
   248  	w="1"
   249  	got=$(grep -a "mysql-replica-01" $WORK_DIR/worker1/log/dm-worker.log | wc -l)
   250  	if [[ "$got" -eq 0 ]]; then
   251  		w="2"
   252  	fi
   253  
   254  	restart_worker $w "github.com/pingcap/tiflow/dm/syncer/ExecDDLError=return()"
   255  
   256  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(1,'aaa');"
   257  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(2,'bbb');"
   258  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(3,'ccc');"
   259  
   260  	run_sql_source2 "alter table ${shardddl1}.${tb1} drop column b;"
   261  	run_sql_source2 "alter table ${shardddl1}.${tb2} drop column b;"
   262  
   263  	check_log_contain_with_retry 'finish to handle ddls in optimistic shard mode.*tb1 drop column' \
   264  		$WORK_DIR/worker1/log/dm-worker.log $WORK_DIR/worker2/log/dm-worker.log
   265  	check_log_contain_with_retry 'finish to handle ddls in optimistic shard mode.*tb2 drop column' \
   266  		$WORK_DIR/worker1/log/dm-worker.log $WORK_DIR/worker2/log/dm-worker.log
   267  
   268  	run_sql_source1 "alter table ${shardddl1}.${tb1} drop column b;"
   269  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   270  		"query-status test" \
   271  		"execute .* error" 1
   272  
   273  	restart_master
   274  
   275  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(4);"
   276  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(5);"
   277  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(6);"
   278  
   279  	run_sql_source2 "alter table ${shardddl1}.${tb1} add column b varchar(10);"
   280  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   281  		"query-status test" \
   282  		"because schema conflict detected" 1 \
   283  		"add column b that wasn't fully dropped in downstream" 1
   284  
   285  	restart_worker $w ""
   286  
   287  	run_sql_source2 "alter table ${shardddl1}.${tb2} add column b varchar(10);"
   288  	run_sql_source1 "alter table ${shardddl1}.${tb1} add column b varchar(10);"
   289  
   290  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(7,'ddd');"
   291  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(8,'eee');"
   292  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(9,'fff');"
   293  
   294  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   295  		"query-status test" \
   296  		"\"result\": true" 3
   297  	check_sync_diff $WORK_DIR $cur/conf/diff_config.toml
   298  }
   299  
   300  function DM_DROP_COLUMN_EXEC_ERROR() {
   301  	run_case DROP_COLUMN_EXEC_ERROR "double-source-optimistic" \
   302  		"run_sql_source1 \"create table ${shardddl1}.${tb1} (a int primary key, b varchar(10));\"; \
   303       run_sql_source2 \"create table ${shardddl1}.${tb1} (a int primary key, b varchar(10));\"; \
   304       run_sql_source2 \"create table ${shardddl1}.${tb2} (a int primary key, b varchar(10));\"" \
   305  		"clean_table" "optimistic"
   306  }
   307  
   308  function DM_DROP_COLUMN_ALL_DONE_CASE() {
   309  	# get worker of source2
   310  	w="1"
   311  	got=$(grep -a "mysql-replica-02" $WORK_DIR/worker1/log/dm-worker.log | wc -l)
   312  	if [[ "$got" -eq 0 ]]; then
   313  		w="2"
   314  	fi
   315  
   316  	restart_worker $w "github.com/pingcap/tiflow/dm/syncer/ExecDDLError=return()"
   317  
   318  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(1,'aaa');"
   319  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(2,'bbb');"
   320  
   321  	run_sql_source1 "alter table ${shardddl1}.${tb1} drop column b;"
   322  	check_log_contain_with_retry 'finish to handle ddls in optimistic shard mode.*tb1 drop column' \
   323  		$WORK_DIR/worker1/log/dm-worker.log $WORK_DIR/worker2/log/dm-worker.log
   324  
   325  	run_sql_source2 "alter table ${shardddl1}.${tb1} drop column b;"
   326  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   327  		"query-status test" \
   328  		"execute .* error" 1
   329  
   330  	restart_master
   331  
   332  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(4);"
   333  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(5);"
   334  
   335  	run_sql_source1 "alter table ${shardddl1}.${tb1} add column b varchar(10);"
   336  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   337  		"query-status test" \
   338  		"because schema conflict detected" 1 \
   339  		"add column b that wasn't fully dropped in downstream" 1
   340  
   341  	restart_worker $w ""
   342  	run_sql_source2 "alter table ${shardddl1}.${tb1} add column b varchar(10);"
   343  
   344  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(7,'ddd');"
   345  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(8,'eee');"
   346  
   347  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   348  		"query-status test" \
   349  		"\"result\": true" 3
   350  	check_sync_diff $WORK_DIR $cur/conf/diff_config.toml
   351  }
   352  
   353  function DM_DROP_COLUMN_ALL_DONE() {
   354  	run_case DROP_COLUMN_ALL_DONE "double-source-optimistic" \
   355  		"run_sql_source1 \"create table ${shardddl1}.${tb1} (a int primary key, b varchar(10));\"; \
   356       run_sql_source2 \"create table ${shardddl1}.${tb1} (a int primary key, b varchar(10));\"" \
   357  		"clean_table" "optimistic"
   358  }
   359  
   360  function DM_RECOVER_LOCK_CASE() {
   361  	# tb1(a,b) tb2(a,b)
   362  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(1,1);"
   363  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(2,2);"
   364  
   365  	# tb1(a,b,c); tb2(a,b)
   366  	run_sql_source1 "alter table ${shardddl1}.${tb1} add column c varchar(10);"
   367  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(3,3,'aaa');"
   368  	check_log_contain_with_retry "putted a shard DDL.*tb1.*ALTER TABLE .* ADD COLUMN" $WORK_DIR/worker1/log/dm-worker.log $WORK_DIR/worker2/log/dm-worker.log
   369  
   370  	# tb1(a,b,c); tb2(a)
   371  	run_sql_source2 "alter table ${shardddl1}.${tb2} drop column b;"
   372  	check_log_contain_with_retry "putted a shard DDL.*tb2.*ALTER TABLE .* DROP COLUMN" $WORK_DIR/worker1/log/dm-worker.log $WORK_DIR/worker2/log/dm-worker.log
   373  
   374  	restart_master
   375  
   376  	run_sql_source1 "alter table ${shardddl1}.${tb1} drop column b;"
   377  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(4,'bbb');"
   378  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(5);"
   379  	check_log_contain_with_retry "putted a shard DDL.*tb1.*ALTER TABLE .* DROP COLUMN" $WORK_DIR/worker1/log/dm-worker.log $WORK_DIR/worker2/log/dm-worker.log
   380  
   381  	# tb1(a,c); tb2(a,b)
   382  	run_sql_source2 "alter table ${shardddl1}.${tb2} add column b int;"
   383  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(6,'ccc');"
   384  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(7,7);"
   385  	check_log_contain_with_retry "putted a shard DDL.*tb2.*ALTER TABLE .* ADD COLUMN" $WORK_DIR/worker1/log/dm-worker.log $WORK_DIR/worker2/log/dm-worker.log
   386  
   387  	# recover lock, tb1's info: (a,b,c)->(a,c); tb2's info: (a)->(a,b)
   388  	# joined(a,b,c); tb1(a,b,c); tb2(a)
   389  	# TrySync tb1: joined(a,b,c); tb1(a,c); tb2(a)
   390  	# TrySync tb2: joined(a,c); tb1(a,c); tb2(a,b)
   391  	restart_master
   392  
   393  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(8,'eee');"
   394  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(9,9);"
   395  
   396  	run_sql_source1 "alter table ${shardddl1}.${tb1} add column b int;"
   397  	run_sql_source2 "alter table ${shardddl1}.${tb2} add column c varchar(10) after a;"
   398  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(10,'fff',10);"
   399  	run_sql_source2 "insert into ${shardddl1}.${tb2} values(11,'ggg',11);"
   400  
   401  	check_sync_diff $WORK_DIR $cur/conf/diff_config.toml
   402  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   403  		"shard-ddl-lock" \
   404  		"no DDL lock exists" 1
   405  }
   406  
   407  function DM_RECOVER_LOCK() {
   408  	run_case RECOVER_LOCK "double-source-optimistic" \
   409  		"run_sql_source1 \"create table ${shardddl1}.${tb1} (a int primary key, b int) DEFAULT CHARSET=latin1 COLLATE=latin1_bin;\"; \
   410       run_sql_source2 \"create table ${shardddl1}.${tb2} (a int primary key, b int) DEFAULT CHARSET=latin1 COLLATE=latin1_bin;\"" \
   411  		"clean_table" "optimistic"
   412  }
   413  
   414  function restart_master_on_pos() {
   415  	if [ "$1" = "$2" ]; then
   416  		restart_master
   417  	fi
   418  }
   419  
   420  function DM_DropAddColumn_CASE() {
   421  	reset=$2
   422  
   423  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(1,1,1);"
   424  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(2,2,2);"
   425  
   426  	check_sync_diff $WORK_DIR $cur/conf/diff_config.toml
   427  
   428  	run_sql_source1 "alter table ${shardddl1}.${tb1} drop column c;"
   429  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(3,3);"
   430  
   431  	restart_master_on_pos $reset "1"
   432  
   433  	run_sql_source2 "alter table ${shardddl1}.${tb1} drop column c;"
   434  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(4,4);"
   435  
   436  	restart_master_on_pos $reset "2"
   437  
   438  	# make sure column c is fully dropped in the downstream
   439  	check_log_contain_with_retry 'finish to handle ddls in optimistic shard mode' $WORK_DIR/worker1/log/dm-worker.log
   440  	check_log_contain_with_retry 'finish to handle ddls in optimistic shard mode' $WORK_DIR/worker2/log/dm-worker.log
   441  
   442  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   443  		"shard-ddl-lock" \
   444  		"no DDL lock exists" 1
   445  
   446  	run_sql_source1 "alter table ${shardddl1}.${tb1} drop column b;"
   447  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(5);"
   448  
   449  	restart_master_on_pos $reset "3"
   450  
   451  	run_sql_source1 "alter table ${shardddl1}.${tb1} add column c int;"
   452  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(6,6);"
   453  
   454  	restart_master_on_pos $reset "4"
   455  
   456  	# make sure task to step in "Sync" stage
   457  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   458  		"query-status test" \
   459  		"\"stage\": \"Running\"" 3 \
   460  		"\"unit\": \"Sync\"" 2
   461  	run_sql_source1 "alter table ${shardddl1}.${tb1} add column b int after a;"
   462  
   463  	restart_master_on_pos $reset "5"
   464  
   465  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   466  		"query-status test" \
   467  		"because schema conflict detected" 1 \
   468  		"add column b that wasn't fully dropped in downstream" 1
   469  
   470  	check_sync_diff $WORK_DIR $cur/conf/diff_config.toml 3 'fail'
   471  	# no ddl error but have un-synced ddl
   472  	check_metric_not_contains $MASTER_PORT "dm_master_shard_ddl_error" 3
   473  	# 9223372036854775807 is 2**63 -1
   474  	check_metric $MASTER_PORT 'dm_master_ddl_state_number{task="test",type="Un-synced"}' 3 0 9223372036854775807
   475  
   476  	# skip this error
   477  	run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   478  		"binlog skip test" \
   479  		"\"result\": true" 2 \
   480  		"\"source 'mysql-replica-02' has no error\"" 1
   481  
   482  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   483  		"pause-task test" \
   484  		"\"result\": true" 3
   485  
   486  	run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \
   487  		"resume-task test" \
   488  		"\"result\": true" 3
   489  
   490  	run_sql_source1 "update ${shardddl1}.${tb1} set b=1 where a=1;"
   491  	run_sql_source1 "update ${shardddl1}.${tb1} set b=3 where a=3;"
   492  	run_sql_source1 "update ${shardddl1}.${tb1} set b=4 where a=4;"
   493  	run_sql_source1 "update ${shardddl1}.${tb1} set b=6 where a=6;"
   494  	run_sql_source2 "alter table ${shardddl1}.${tb1} add column c int"
   495  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(7,7,7);"
   496  
   497  	check_sync_diff $WORK_DIR $cur/conf/diff_config.toml
   498  }
   499  
   500  function DM_DropAddColumn() {
   501  	for i in $(seq 0 5); do
   502  		echo "run DM_DropAddColumn case #${i}"
   503  		run_case DropAddColumn "double-source-optimistic" \
   504  			"run_sql_source1 \"create table ${shardddl1}.${tb1} (a int primary key, b int, c int);\"; \
   505              run_sql_source2 \"create table ${shardddl1}.${tb1} (a int primary key, b int, c int);\"" \
   506  			"clean_table" "optimistic" "$i"
   507  	done
   508  }
   509  
   510  function DM_ADD_DROP_PARTITIONS_CASE() {
   511  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(1);"
   512  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(2);"
   513  	run_sql_source1 "alter table ${shardddl1}.${tb1} add column new_col1 int;"
   514  	run_sql_source1 "insert into ${shardddl1}.${tb1} values(3,3);"
   515  	run_sql_source2 "insert into ${shardddl1}.${tb1} values(4);"
   516  
   517  	run_sql_source1 "ALTER TABLE ${shardddl1}.${tb1} ADD PARTITION (partition p1 VALUES LESS THAN (10000))"
   518  	run_sql_tidb_with_retry "SELECT count(1) FROM information_schema.partitions WHERE TABLE_SCHEMA='${shardddl}' AND TABLE_NAME = '${tb}' AND PARTITION_NAME IS NOT NULL;" "count(1): 2"
   519  
   520  	run_sql_source1 "ALTER TABLE ${shardddl1}.${tb1} DROP PARTITION p1;"
   521  	run_sql_tidb_with_retry "SELECT count(1) FROM information_schema.partitions WHERE TABLE_SCHEMA='${shardddl}' AND TABLE_NAME = '${tb}' AND PARTITION_NAME IS NOT NULL;" "count(1): 1"
   522  }
   523  
   524  function DM_ADD_DROP_PARTITIONS() {
   525  	run_case ADD_DROP_PARTITIONS "double-source-optimistic" \
   526  		"run_sql_source1 \"create table ${shardddl1}.${tb1} (a int) PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (100));\"; \
   527       run_sql_source2 \"create table ${shardddl1}.${tb1} (a int) PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (100));\";" \
   528  		"clean_table" "optimistic"
   529  }
   530  
   531  function run() {
   532  	init_cluster
   533  	init_database
   534  	DM_DROP_COLUMN_EXEC_ERROR
   535  	DM_INIT_SCHEMA
   536  	DM_DROP_COLUMN_ALL_DONE
   537  	DM_RECOVER_LOCK
   538  	DM_DropAddColumn
   539  	DM_ADD_DROP_PARTITIONS
   540  	start=36
   541  	end=45
   542  	except=(042 044 045)
   543  	for i in $(seq -f "%03g" ${start} ${end}); do
   544  		if [[ ${except[@]} =~ $i ]]; then
   545  			continue
   546  		fi
   547  		DM_${i}
   548  		sleep 1
   549  	done
   550  }
   551  
   552  cleanup_data $shardddl
   553  cleanup_data $shardddl1
   554  cleanup_data $shardddl2
   555  # also cleanup dm processes in case of last run failed
   556  cleanup_process $*
   557  run $*
   558  cleanup_process $*
   559  
   560  echo "[$(date)] <<<<<< test case $TEST_NAME success! >>>>>>"