github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/tests/validator_basic/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 9 db_name=$TEST_NAME 10 11 function get_gtid_executed() { 12 gtid_executed=$(echo "show master status;" | MYSQL_PWD=123456 mysql -uroot -h$1 -P$2 | awk 'FNR == 2 {print $3}') 13 echo $gtid_executed 14 } 15 16 function prepare_dm_and_source() { 17 cleanup_process $* 18 cleanup_data $db_name 19 cleanup_data_upstream $db_name 20 21 run_sql_file $cur/data/db1.prepare.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1 22 23 run_dm_master $WORK_DIR/master $MASTER_PORT $cur/conf/dm-master.toml 24 check_rpc_alive $cur/../bin/check_master_online 127.0.0.1:$MASTER_PORT 25 26 run_dm_worker $WORK_DIR/worker1 $WORKER1_PORT $cur/conf/dm-worker1.toml 27 check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER1_PORT 28 # source 1 should be bound to worker 1 29 dmctl_operate_source create $cur/conf/source1.yaml $SOURCE_ID1 30 31 run_dm_worker $WORK_DIR/worker2 $WORKER2_PORT $cur/conf/dm-worker2.toml 32 check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT 33 } 34 35 function prepare_for_standalone_test() { 36 prepare_dm_and_source 37 dmctl_start_task_standalone $cur/conf/dm-task-standalone.yaml --remove-meta 38 39 # sync-diff seems cannot handle float/double well, will skip it here 40 } 41 42 function trigger_checkpoint_flush() { 43 sleep 1.5 44 run_sql_source1 "alter table $db_name.t1 comment 'a';" # force flush checkpoint 45 } 46 47 function restore_timezone() { 48 echo "restore time_zone" 49 run_sql_source1 "set global time_zone = SYSTEM" 50 run_sql_tidb "set global time_zone = SYSTEM" 51 } 52 53 function restore_on_case_exit() { 54 echo "restore config" 55 mv $cur/conf/dm-task-standalone.yaml.bak $cur/conf/dm-task-standalone.yaml 56 mv $cur/conf/source1.yaml.bak $cur/conf/source1.yaml 57 58 restore_timezone 59 } 60 61 function test_validator_together_with_task() { 62 enable_gtid=$1 63 enable_relay=$2 64 # clear fail point 65 export GO_FAILPOINTS="" 66 echo "--> full mode, check we validate different data types(gtid=$enable_gtid, relay=$enable_relay)" 67 cp $cur/conf/dm-task-standalone.yaml.bak $cur/conf/dm-task-standalone.yaml 68 cp $cur/conf/source1.yaml.bak $cur/conf/source1.yaml 69 sed -i 's/enable-gtid: false/enable-gtid: '$enable_gtid'/g' $cur/conf/source1.yaml 70 sed -i 's/enable-relay: false/enable-relay: '$enable_relay'/g' $cur/conf/source1.yaml 71 prepare_for_standalone_test 72 # key=6, mysql store as 1.2345679e+17, but in tidb it's 1.23457e17 73 # so will fail in current compare rule 74 # note: key=1 has the same condition, but it's not validated, since it's migrated in full phase. 75 run_sql_file $cur/data/db1.increment.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1 76 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 77 "config source $SOURCE_ID1" \ 78 "enable-gtid: $enable_gtid" 1 \ 79 "enable-relay: $enable_relay" 1 80 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 81 "validation status test" \ 82 "\"processedRowsStatus\": \"insert\/update\/delete: 6\/1\/1\"" 1 \ 83 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 84 "new\/ignored\/resolved: 1\/0\/0" 1 85 run_sql_tidb "SELECT count(*) from $db_name.t1_down" 86 check_contains "count(*): 6" 87 } 88 89 function test_start_validator_on_the_fly_prepare() { 90 enable_gtid=$1 91 enable_relay=$2 92 # clear fail point 93 export GO_FAILPOINTS="" 94 cp $cur/conf/dm-task-standalone.yaml.bak $cur/conf/dm-task-standalone.yaml 95 cp $cur/conf/source1.yaml.bak $cur/conf/source1.yaml 96 sed -i 's/enable-gtid: false/enable-gtid: '$enable_gtid'/g' $cur/conf/source1.yaml 97 sed -i 's/enable-relay: false/enable-relay: '$enable_relay'/g' $cur/conf/source1.yaml 98 run_sql_source1 "flush binary logs" 99 sleep 1 100 run_sql_source1 "purge binary logs before now()" 101 prepare_dm_and_source 102 dmctl_start_task_standalone $cur/conf/dm-task-standalone-no-validator.yaml --remove-meta 103 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 104 "config source $SOURCE_ID1" \ 105 "enable-gtid: $enable_gtid" 1 \ 106 "enable-relay: $enable_relay" 1 107 run_sql_source1 "insert into $db_name.t1(id, name) values(2,'b'), (3, 'c')" 108 run_sql_source1 "delete from $db_name.t1 where id=1" 109 trigger_checkpoint_flush 110 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 111 "query-status test" \ 112 "\"synced\": true" 1 113 check_sync_diff $WORK_DIR $cur/conf/diff_config.toml 114 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 115 "validation status test" \ 116 "validator not found for task" 1 117 } 118 119 function test_start_validator_on_the_fly() { 120 enable_gtid=$1 121 enable_relay=$2 122 echo "--> start validator on the fly, validate from current syncer progress(gtid=$enable_gtid, relay=$enable_relay)" 123 test_start_validator_on_the_fly_prepare $enable_gtid $enable_relay 124 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 125 "validation start test" \ 126 "\"result\": true" 1 127 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 128 "validation status test" \ 129 "\"processedRowsStatus\": \"insert\/update\/delete: 0\/0\/0\"" 1 130 run_sql_source1 "insert into $db_name.t1(id, name) values(4,'d'), (5, 'e')" 131 run_sql_source1 "update $db_name.t1 set name='bb' where id=2" 132 run_sql_source1 "delete from $db_name.t1 where id=3" 133 trigger_checkpoint_flush 134 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 135 "validation status test" \ 136 "\"processedRowsStatus\": \"insert\/update\/delete: 2\/1\/1\"" 1 \ 137 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 138 "new\/ignored\/resolved: 0\/0\/0" 1 139 check_sync_diff $WORK_DIR $cur/conf/diff_config.toml 140 } 141 142 function test_start_validator_with_time_smaller_than_min_binlog_pos() { 143 enable_gtid=$1 144 echo "--> start validator from time < min mysql binlog pos(gtid=$enable_gtid)" 145 test_start_validator_on_the_fly_prepare $enable_gtid false 146 run_sql_source1 "insert into $db_name.t1(id, name) values(4,'d'), (5, 'e')" 147 run_sql_source1 "update $db_name.t1 set name='bb' where id=2" 148 run_sql_source1 "delete from $db_name.t1 where id=3" 149 trigger_checkpoint_flush 150 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 151 "query-status test" \ 152 "\"synced\": true" 1 153 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 154 "validation start --start-time '$(($(date "+%Y") - 2))-01-01 00:00:00' test" \ 155 "\"result\": true" 1 156 trigger_checkpoint_flush 157 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 158 "validation status test" \ 159 "\"processedRowsStatus\": \"insert\/update\/delete: 5\/1\/2\"" 1 \ 160 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 161 "new\/ignored\/resolved: 0\/0\/0" 1 162 check_sync_diff $WORK_DIR $cur/conf/diff_config.toml 163 } 164 165 function test_start_validator_with_time_in_range_of_binlog_pos() { 166 enable_gtid=$1 167 echo "--> start validator from time which is in range of mysql binlog(gtid=$enable_gtid)" 168 test_start_validator_on_the_fly_prepare $enable_gtid false 169 run_sql_source1 "insert into $db_name.t1(id, name) values(4,'d'), (5, 'e')" 170 run_sql_source1 "update $db_name.t1 set name='bb' where id=2" 171 run_sql_source1 "delete from $db_name.t1 where id=3" 172 run_sql_source1 "insert into $db_name.t1(id, name) values(100,'d'), (101, 'e')" 173 sleep 2 174 start_time="$(TZ='UTC-2' date '+%Y-%m-%d %T')" # TZ=UTC-2 means +02:00 175 run_sql_source1 "insert into $db_name.t1(id, name) values(200,'d'), (201, 'e')" 176 run_sql_source1 "delete from $db_name.t1 where id=200" 177 run_sql_source1 "update $db_name.t1 set name='dd' where id=100" 178 run_sql_source1 "insert into $db_name.t1(id, name) values(300,'d')" 179 run_sql_source1 "update $db_name.t1 set name='ee' where id=101" 180 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 181 "validation start --start-time '$start_time' test" \ 182 "\"result\": true" 1 183 trigger_checkpoint_flush 184 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 185 "validation status test" \ 186 "\"processedRowsStatus\": \"insert\/update\/delete: 3\/2\/1\"" 1 \ 187 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 188 "new\/ignored\/resolved: 0\/0\/0" 1 189 check_sync_diff $WORK_DIR $cur/conf/diff_config.toml 190 } 191 192 function run_standalone() { 193 # 194 # we have set row-error-delay and meta-flush-interval small enough for cases below, 195 # but it maybe unstable if validator reached progress of syncer before the last ddl, 196 # and then validator start to mark failed rows as error. So we may have more errors 197 # than expected. 198 # 199 200 # backup it, will change it in the following case 201 cp $cur/conf/dm-task-standalone.yaml $cur/conf/dm-task-standalone.yaml.bak 202 cp $cur/conf/source1.yaml $cur/conf/source1.yaml.bak 203 204 trap restore_on_case_exit EXIT 205 206 # use different timezone for upstream and tidb 207 run_sql_source1 "set global time_zone = '+02:00'" 208 run_sql_source1 "SELECT cast(TIMEDIFF(NOW(6), UTC_TIMESTAMP(6)) as time) time" 209 check_contains "time: 02:00:00" 210 run_sql_tidb "set global time_zone = '+06:00'" 211 run_sql_tidb "SELECT cast(TIMEDIFF(NOW(6), UTC_TIMESTAMP(6)) as time) time" 212 check_contains "time: 06:00:00" 213 214 # validator is started together with task 215 test_validator_together_with_task false false 216 test_validator_together_with_task false true 217 test_validator_together_with_task true false 218 test_validator_together_with_task true true 219 220 echo "--> fast mode, check we validate different data types" 221 cp $cur/conf/dm-task-standalone.yaml.bak $cur/conf/dm-task-standalone.yaml 222 sed -i 's/ mode: full/ mode: fast/' $cur/conf/dm-task-standalone.yaml 223 prepare_for_standalone_test 224 # in fast mode we don't check col by col, so key=6 will pass 225 run_sql_file $cur/data/db1.increment.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1 226 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 227 "validation status test" \ 228 "\"processedRowsStatus\": \"insert\/update\/delete: 6\/1\/1\"" 1 \ 229 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 230 "new\/ignored\/resolved: 0\/0\/0" 1 231 run_sql_tidb "SELECT count(*) from $db_name.t1_down" 232 check_contains "count(*): 6" 233 234 echo "--> check we can catch inconsistent rows: full mode" 235 # skip incremental rows with id <= 5 236 export GO_FAILPOINTS='github.com/pingcap/tiflow/dm/syncer/SkipDML=return(5)' 237 cp $cur/conf/dm-task-standalone.yaml.bak $cur/conf/dm-task-standalone.yaml 238 prepare_for_standalone_test 239 run_sql_file $cur/data/db1.increment.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1 240 # 6 inconsistent rows: 241 # insert of id = 3, 4, 5 are skipped. 242 # insert & update of id = 2 are merged and skipped 243 # delete of id = 1 are skipped 244 # id = 6, float precision problem, so inconsistent 245 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 246 "validation status test" \ 247 "\"processedRowsStatus\": \"insert\/update\/delete: 6\/1\/1\"" 1 \ 248 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 249 "new\/ignored\/resolved: 6\/0\/0" 1 250 run_sql_tidb "SELECT count(*) from $db_name.t1_down" 251 check_contains "count(*): 3" 252 253 echo "--> check we can catch inconsistent rows: fast mode" 254 # skip incremental rows with id <= 5 255 export GO_FAILPOINTS='github.com/pingcap/tiflow/dm/syncer/SkipDML=return(5)' 256 cp $cur/conf/dm-task-standalone.yaml.bak $cur/conf/dm-task-standalone.yaml 257 sed -i 's/ mode: full/ mode: fast/' $cur/conf/dm-task-standalone.yaml 258 prepare_for_standalone_test 259 run_sql_file $cur/data/db1.increment.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1 260 # 5 inconsistent rows, nearly same as previous test, but id = 6 success in fast mode 261 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 262 "validation status test" \ 263 "\"processedRowsStatus\": \"insert\/update\/delete: 6\/1\/1\"" 1 \ 264 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 265 "new\/ignored\/resolved: 5\/0\/0" 1 266 run_sql_tidb "SELECT count(*) from $db_name.t1_down" 267 check_contains "count(*): 3" 268 269 echo "--> check update pk(split into insert and delete)" 270 run_sql_source1 "update $db_name.t1 set id=100 where id=7" 271 trigger_checkpoint_flush 272 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 273 "validation status test" \ 274 "\"processedRowsStatus\": \"insert\/update\/delete: 7\/1\/2\"" 1 \ 275 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 276 "new\/ignored\/resolved: 5\/0\/0" 1 277 run_sql_tidb "SELECT count(*) from $db_name.t1_down" 278 check_contains "count(*): 3" 279 280 echo "--> check validator panic and we can catch it" 281 export GO_FAILPOINTS='github.com/pingcap/tiflow/dm/syncer/ValidatorPanic=panic("validator panic")' 282 cp $cur/conf/dm-task-standalone.yaml.bak $cur/conf/dm-task-standalone.yaml 283 prepare_for_standalone_test 284 run_sql_file $cur/data/db1.increment.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1 285 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 286 "validation status test" \ 287 "validator panic" 1 288 289 echo "--> check validator worker panic and we can catch it" 290 # panic 1 times 291 export GO_FAILPOINTS='github.com/pingcap/tiflow/dm/syncer/ValidatorWorkerPanic=1*panic("validator worker panic")' 292 cp $cur/conf/dm-task-standalone.yaml.bak $cur/conf/dm-task-standalone.yaml 293 prepare_for_standalone_test 294 run_sql_file $cur/data/db1.increment.sql $MYSQL_HOST1 $MYSQL_PORT1 $MYSQL_PASSWORD1 295 sleep 5 296 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 297 "validation status test" \ 298 "validator worker panic" 1 299 300 # in real world panic, we cannot restart just like this, this case only makes sure worker panic doesn't 301 # mess status of validator up 302 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 303 "validation start test" \ 304 "\"result\": true" 1 305 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 306 "validation status test" \ 307 "\"processedRowsStatus\": \"insert\/update\/delete: 6\/1\/1\"" 1 \ 308 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 309 "new\/ignored\/resolved: 1\/0\/0" 1 310 run_sql_tidb "SELECT count(*) from $db_name.t1_down" 311 check_contains "count(*): 6" 312 313 echo "--> check validator stop when pending row size too large" 314 # skip incremental rows with id <= 5 315 export GO_FAILPOINTS='github.com/pingcap/tiflow/dm/syncer/SkipDML=return(5)' 316 cp $cur/conf/dm-task-standalone.yaml.bak $cur/conf/dm-task-standalone.yaml 317 sed -i 's/row-error-delay: .*$/row-error-delay: 30m/' $cur/conf/dm-task-standalone.yaml 318 sed -i 's/max-pending-row-size: .*$/max-pending-row-size: 20/' $cur/conf/dm-task-standalone.yaml 319 prepare_for_standalone_test 320 run_sql_source1 "create table $db_name.t1_large_col(id int primary key, c varchar(100))" 321 run_sql_source1 "insert into $db_name.t1_large_col values(1, 'this-text-is-more-than-20-bytes')" 322 trigger_checkpoint_flush 323 # since multiple worker may send this error, there should be at least one "too much pending data" error 324 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 325 "validation status test" \ 326 "\"stage\": \"Stopped\"" 1 \ 327 "too much pending data, stop validator" 1+ \ 328 "\"processedRowsStatus\": \"insert\/update\/delete: 1\/0\/0\"" 1 \ 329 "pendingRowsStatus\": \"insert\/update\/delete: 1\/0\/0" 1 \ 330 "new\/ignored\/resolved: 0\/0\/0" 1 331 332 echo "--> check validator stop when pending row count too many" 333 # skip incremental rows with id <= 5 334 export GO_FAILPOINTS='github.com/pingcap/tiflow/dm/syncer/SkipDML=return(5)' 335 cp $cur/conf/dm-task-standalone.yaml.bak $cur/conf/dm-task-standalone.yaml 336 sed -i 's/row-error-delay: .*$/row-error-delay: 30m/' $cur/conf/dm-task-standalone.yaml 337 sed -i 's/max-pending-row-count: .*$/max-pending-row-count: 2/' $cur/conf/dm-task-standalone.yaml 338 prepare_for_standalone_test 339 run_sql_source1 "create table $db_name.t1_large_col(id int primary key)" 340 run_sql_source1 "insert into $db_name.t1_large_col values(1)" 341 run_sql_source1 "insert into $db_name.t1_large_col values(2)" 342 run_sql_source1 "insert into $db_name.t1_large_col values(3)" 343 trigger_checkpoint_flush 344 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 345 "validation status test" \ 346 "\"stage\": \"Stopped\"" 1 \ 347 "too much pending data, stop validator" 1+ \ 348 "\"processedRowsStatus\": \"insert\/update\/delete: 3\/0\/0\"" 1 \ 349 "pendingRowsStatus\": \"insert\/update\/delete: 3\/0\/0" 1 \ 350 "new\/ignored\/resolved: 0\/0\/0" 1 351 352 test_start_validator_on_the_fly false false 353 test_start_validator_on_the_fly false true 354 test_start_validator_on_the_fly true false 355 test_start_validator_on_the_fly true true 356 357 test_start_validator_with_time_smaller_than_min_binlog_pos false 358 test_start_validator_with_time_smaller_than_min_binlog_pos true 359 360 test_start_validator_with_time_in_range_of_binlog_pos false 361 test_start_validator_with_time_in_range_of_binlog_pos true 362 363 echo "--> start validator from time > max mysql binlog pos" 364 test_start_validator_on_the_fly_prepare false false 365 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 366 "validation start --start-time '$(($(date "+%Y") + 2))-01-01 00:00:00' test" \ 367 "\"result\": true" 1 368 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 369 "validation status test" \ 370 "is too late, no binlog location matches it" 1 \ 371 "\"stage\": \"Stopped\"" 1 \ 372 "\"processedRowsStatus\": \"insert\/update\/delete: 0\/0\/0\"" 1 \ 373 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 374 "new\/ignored\/resolved: 0\/0\/0" 1 375 } 376 377 function validate_table_with_different_pk() { 378 export GO_FAILPOINTS="" 379 380 # int type uk already tested in run_standalone, so not test it here 381 echo "--> single varchar col pk" 382 prepare_for_standalone_test 383 run_sql_source1 "create table $db_name.t2(c1 varchar(10) primary key, c2 varchar(10))" 384 run_sql_source1 "insert into $db_name.t2 values('a', NULL), ('b', 'b'), ('c', 'c')" 385 run_sql_source1 "update $db_name.t2 set c2='bb' where c1='b'" 386 run_sql_source1 "update $db_name.t2 set c2='cc' where c1='c'" 387 run_sql_source1 "delete from $db_name.t2 where c1='a'" 388 trigger_checkpoint_flush 389 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 390 "validation status test" \ 391 "\"processedRowsStatus\": \"insert\/update\/delete: 3\/2\/1\"" 1 \ 392 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 393 "new\/ignored\/resolved: 0\/0\/0" 1 394 run_sql_tidb "SELECT count(*) from $db_name.t2" 395 check_contains "count(*): 2" 396 397 echo "--> single datetime col pk" 398 prepare_for_standalone_test 399 run_sql_source1 "create table $db_name.t2(c1 datetime primary key, c2 varchar(10))" 400 run_sql_source1 "insert into $db_name.t2 values('2022-01-01 00:00:00', NULL), ('2022-01-01 00:00:01', 'b'), ('2022-01-01 00:00:02', 'c')" 401 run_sql_source1 "update $db_name.t2 set c2='bb' where c1='2022-01-01 00:00:01'" 402 run_sql_source1 "update $db_name.t2 set c2='cc' where c1='2022-01-01 00:00:02'" 403 run_sql_source1 "delete from $db_name.t2 where c1='2022-01-01 00:00:00'" 404 trigger_checkpoint_flush 405 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 406 "validation status test" \ 407 "\"processedRowsStatus\": \"insert\/update\/delete: 3\/2\/1\"" 1 \ 408 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 409 "new\/ignored\/resolved: 0\/0\/0" 1 410 run_sql_tidb "SELECT count(*) from $db_name.t2" 411 check_contains "count(*): 2" 412 413 echo "--> compound pk (datetime, timestamp, int, varchar)" 414 prepare_for_standalone_test 415 run_sql_source1 "create table $db_name.t2(c1 datetime, c2 timestamp DEFAULT CURRENT_TIMESTAMP, c3 int, c4 varchar(10), c5 int, primary key(c1, c2, c3, c4))" 416 run_sql_source1 "insert into $db_name.t2 values('2022-01-01 00:00:00', '2022-01-01 00:00:00', 1, 'a', 1)" 417 run_sql_source1 "insert into $db_name.t2 values('2022-01-01 00:00:00', '2022-01-01 00:00:00', 1, 'b', 2)" 418 run_sql_source1 "insert into $db_name.t2 values('2022-01-01 00:00:00', '2012-12-01 00:00:00', 1, 'a', 3)" 419 run_sql_source1 "insert into $db_name.t2 values('2012-12-01 00:00:00', '2022-01-01 00:00:00', 1, 'a', 4)" 420 run_sql_source1 "update $db_name.t2 set c5=11 where c1='2022-01-01 00:00:00'" # update 3 rows 421 run_sql_source1 "update $db_name.t2 set c5=22 where c2='2012-12-01 00:00:00'" # update 1 row 422 run_sql_source1 "delete from $db_name.t2 where c4='a'" # delete 3 row 423 trigger_checkpoint_flush 424 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 425 "validation status test" \ 426 "\"processedRowsStatus\": \"insert\/update\/delete: 4\/4\/3\"" 1 \ 427 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 428 "new\/ignored\/resolved: 0\/0\/0" 1 429 run_sql_tidb "SELECT count(*) from $db_name.t2" 430 check_contains "count(*): 1" 431 } 432 433 function test_unsupported_table_status() { 434 export GO_FAILPOINTS="" 435 436 echo "--> table without primary key" 437 prepare_for_standalone_test 438 run_sql_source1 "create table $db_name.t2(c1 int)" 439 run_sql_source1 "insert into $db_name.t2 values(1)" 440 trigger_checkpoint_flush 441 # skipped row is not add to processed rows 442 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 443 "validation status test" \ 444 "\"processedRowsStatus\": \"insert\/update\/delete: 0\/0\/0\"" 1 \ 445 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 446 "new\/ignored\/resolved: 0\/0\/0" 1 \ 447 "\"stage\": \"Running\"" 1 \ 448 "\"stage\": \"Stopped\"" 1 \ 449 "no primary key" 1 450 run_sql_tidb "SELECT count(*) from $db_name.t2" 451 check_contains "count(*): 1" 452 453 echo "--> table is deleted on downstream" 454 prepare_dm_and_source 455 run_sql_source1 "reset master" 456 dmctl_start_task_standalone $cur/conf/dm-task-standalone-no-validator.yaml --remove-meta 457 run_sql_source1 "create table $db_name.t2(c1 int primary key, c2 int, c3 int)" 458 run_sql_source1 "insert into $db_name.t2 values(1, 1, 1)" 459 run_sql_source1 "insert into $db_name.t2 values(2, 2, 2)" 460 run_sql_source1 "drop table $db_name.t2" 461 trigger_checkpoint_flush 462 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 463 "query-status test" \ 464 "\"synced\": true" 1 465 run_sql_tidb "select count(*) from information_schema.tables where TABLE_SCHEMA='${db_name}' and TABLE_NAME = 't2'" 466 check_contains "count(*): 0" 467 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 468 "validation start --start-time '$(($(date "+%Y") - 2))-01-01 00:00:00' test" \ 469 "\"result\": true" 1 470 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 471 "validation status test" \ 472 "\"processedRowsStatus\": \"insert\/update\/delete: 0\/0\/0\"" 1 \ 473 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 474 "new\/ignored\/resolved: 0\/0\/0" 1 \ 475 "\"stage\": \"Running\"" 1 \ 476 "\"stage\": \"Stopped\"" 1 \ 477 "table is not synced or dropped" 1 478 479 echo "--> table in schema-tracker has less column than binlog" 480 prepare_dm_and_source 481 run_sql_source1 "reset master" 482 dmctl_start_task_standalone $cur/conf/dm-task-standalone-no-validator.yaml --remove-meta 483 run_sql_source1 "create table $db_name.t2(c1 int primary key, c2 int, c3 int)" 484 run_sql_source1 "insert into $db_name.t2 values(1, 1, 1)" 485 run_sql_source1 "alter table $db_name.t2 drop column c3" 486 run_sql_source1 "insert into $db_name.t2 values(2, 2)" 487 trigger_checkpoint_flush 488 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 489 "query-status test" \ 490 "\"synced\": true" 1 491 run_sql_tidb "SELECT count(*) from $db_name.t2" 492 check_contains "count(*): 2" 493 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 494 "validation start --start-time '$(($(date "+%Y") - 2))-01-01 00:00:00' test" \ 495 "\"result\": true" 1 496 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 497 "validation status test" \ 498 "\"processedRowsStatus\": \"insert\/update\/delete: 0\/0\/0\"" 1 \ 499 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 500 "new\/ignored\/resolved: 0\/0\/0" 1 \ 501 "\"stage\": \"Running\"" 1 \ 502 "\"stage\": \"Stopped\"" 1 \ 503 "binlog has more columns than current table" 1 504 505 echo "--> pk column of downstream table not in range of binlog column" 506 prepare_dm_and_source 507 run_sql_source1 "reset master" 508 dmctl_start_task_standalone $cur/conf/dm-task-standalone-no-validator.yaml --remove-meta 509 run_sql_source1 "create table $db_name.t2(c1 int)" 510 run_sql_source1 "insert into $db_name.t2 values(1)" 511 run_sql_source1 "alter table $db_name.t2 add column c2 int default 1" 512 run_sql_source1 "alter table $db_name.t2 add primary key(c2)" 513 run_sql_source1 "insert into $db_name.t2 values(2, 2)" 514 trigger_checkpoint_flush 515 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 516 "query-status test" \ 517 "\"synced\": true" 1 518 run_sql_tidb "SELECT count(*) from $db_name.t2" 519 check_contains "count(*): 2" 520 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 521 "validation start --start-time '$(($(date "+%Y") - 2))-01-01 00:00:00' test" \ 522 "\"result\": true" 1 523 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 524 "validation status test" \ 525 "\"processedRowsStatus\": \"insert\/update\/delete: 0\/0\/0\"" 1 \ 526 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 527 "new\/ignored\/resolved: 0\/0\/0" 1 \ 528 "\"stage\": \"Running\"" 1 \ 529 "\"stage\": \"Stopped\"" 1 \ 530 "primary key column of downstream table out of range of binlog event row" 1 531 } 532 533 function stopped_validator_fail_over() { 534 export GO_FAILPOINTS="" 535 536 echo "--> stopped validator fail over" 537 # skip incremental rows with c1 <= 1 538 export GO_FAILPOINTS='github.com/pingcap/tiflow/dm/syncer/SkipDML=return(1)' 539 prepare_for_standalone_test 540 run_sql_source1 "create table $db_name.t2(c1 int primary key, c2 int)" 541 run_sql_source1 "insert into $db_name.t2 values(1, 1), (2, 2), (3, 3)" 542 run_sql_source1 "update $db_name.t2 set c2=11 where c2=1" 543 run_sql_source1 "update $db_name.t2 set c2=22 where c2=2" 544 run_sql_source1 "delete from $db_name.t2 where c1=3" 545 trigger_checkpoint_flush 546 # skipped row is not add to processed rows 547 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 548 "validation status test" \ 549 "\"processedRowsStatus\": \"insert\/update\/delete: 3\/2\/1\"" 1 \ 550 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 551 "new\/ignored\/resolved: 1\/0\/0" 1 \ 552 "\"stage\": \"Running\"" 2 553 # make sure validator checkpoint is flushed 554 sleep 1 # wait for the min flush interval 555 trigger_checkpoint_flush 556 run_sql_tidb_with_retry "select concat_ws('/', procd_ins, procd_upd, procd_del) processed 557 from dm_meta.test_validator_checkpoint where source='mysql-replica-01'" \ 558 "processed: 3/2/1" 559 run_sql_tidb_with_retry "select count(1) cnt 560 from dm_meta.test_validator_error_change where source='mysql-replica-01'" \ 561 "cnt: 1" 562 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 563 "validation stop test" \ 564 "\"result\": true" 1 565 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 566 "validation status test" \ 567 "\"processedRowsStatus\": \"insert\/update\/delete: 3\/2\/1\"" 1 \ 568 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 569 "new\/ignored\/resolved: 1\/0\/0" 1 \ 570 "\"stage\": \"Running\"" 1 \ 571 "\"stage\": \"Stopped\"" 1 572 # source1 is bound to worker1, so source1 will be bound to worker2. see prepare_dm_and_source 573 kill_process worker1 574 # stopped task fail over, processed row status and table status is not loaded into memory, so they're zero 575 # but we can see errors, since it's loaded from db all the time 576 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 577 "validation status test" \ 578 "\"processedRowsStatus\": \"insert\/update\/delete: 0\/0\/0\"" 1 \ 579 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 580 "new\/ignored\/resolved: 1\/0\/0" 1 \ 581 "\"stage\": \"Running\"" 0 \ 582 "\"stage\": \"Stopped\"" 1 583 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 584 "validation show-error --error all test" \ 585 "\"result\": true" 1 \ 586 "\"id\": \"1\"" 1 587 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 588 "validation start test" \ 589 "\"result\": true" 1 590 run_sql_source1 "insert into $db_name.t2 values(4, 4), (5, 5), (6, 6)" 591 run_sql_source1 "update $db_name.t2 set c2=55 where c2=5" 592 trigger_checkpoint_flush 593 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 594 "validation status test" \ 595 "\"processedRowsStatus\": \"insert\/update\/delete: 6\/3\/1\"" 1 \ 596 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 597 "new\/ignored\/resolved: 1\/0\/0" 1 \ 598 "\"stage\": \"Running\"" 2 599 } 600 601 # some events are filtered in syncer, validator should filter them too. 602 # validator only support below 3 filter. 603 function test_data_filter() { 604 export GO_FAILPOINTS="" 605 606 echo "--> filter online ddl shadow table" 607 prepare_dm_and_source 608 dmctl_start_task_standalone $cur/conf/test-filter.yaml --remove-meta 609 run_sql_source1 "create table $db_name.t2(id int primary key)" 610 run_sql_source1 "insert into $db_name.t2 values(1), (2), (3)" 611 run_sql_source1 "create table $db_name._t_gho(id int primary key)" 612 run_sql_source1 "insert into $db_name._t_gho values(1), (2), (3)" 613 trigger_checkpoint_flush 614 # skipped table has no table status, so number of running = 2 615 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 616 "validation status test" \ 617 "\"processedRowsStatus\": \"insert\/update\/delete: 3\/0\/0\"" 1 \ 618 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 619 "new\/ignored\/resolved: 0\/0\/0" 1 \ 620 "\"stage\": \"Running\"" 2 621 622 echo "--> filter by ba list" 623 run_sql_source1 "create table $db_name.x1(id int primary key)" 624 run_sql_source1 "insert into $db_name.x1 values(1), (2), (3)" 625 trigger_checkpoint_flush 626 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 627 "query-status test" \ 628 "\"synced\": true" 1 629 # skipped table has no table status, so number of running is still 2 630 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 631 "validation status test" \ 632 "\"processedRowsStatus\": \"insert\/update\/delete: 3\/0\/0\"" 1 \ 633 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 634 "new\/ignored\/resolved: 0\/0\/0" 1 \ 635 "\"stage\": \"Running\"" 2 636 637 echo "--> filter by filter-rules" 638 run_sql_source1 "create table $db_name.t_filter_del(id int primary key, val int)" 639 run_sql_source1 "insert into $db_name.t_filter_del values(1, 1), (2, 2), (3, 3), (4, 4)" 640 run_sql_source1 "update $db_name.t_filter_del set val=11 where id=1" 641 run_sql_source1 "update $db_name.t_filter_del set val=22 where id=2" 642 run_sql_source1 "delete from $db_name.t_filter_del where id in (1, 2, 3)" 643 trigger_checkpoint_flush 644 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 645 "query-status test" \ 646 "\"synced\": true" 1 647 run_sql_tidb "SELECT count(*) from $db_name.t_filter_del" 648 check_contains "count(*): 4" 649 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 650 "validation status test" \ 651 "\"processedRowsStatus\": \"insert\/update\/delete: 7\/2\/0\"" 1 \ 652 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 653 "new\/ignored\/resolved: 0\/0\/0" 1 \ 654 "\"stage\": \"Running\"" 3 655 } 656 657 function test_validation_syncer_stopped() { 658 echo "--> validate when syncer is stopped" 659 insertCnt=5 660 export GO_FAILPOINTS="github.com/pingcap/tiflow/dm/syncer/mockValidatorDelay=return(2)" 661 prepare_for_standalone_test 662 run_sql_source1 "create table validator_basic.test(a int primary key, b int)" 663 run_sql_source1 "insert into validator_basic.test values(0, 0)" 664 trigger_checkpoint_flush 665 # wait syncer to start so that validator can start 666 sleep 4 667 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 668 "query-status test" \ 669 "\"synced\": true" 1 \ 670 "\"processedRowsStatus\": \"insert\/update\/delete: 1\/0\/0\"" 1 671 for ((k = 1; k <= $insertCnt; k++)); do 672 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 673 "pause-task test" \ 674 "\"result\": true" 2 675 trigger_checkpoint_flush 676 # catchup the last insert when the syncer is stopped 677 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 678 "query-status test" \ 679 "\"processedRowsStatus\": \"insert\/update\/delete: $k\/0\/0\"" 1 \ 680 "new\/ignored\/resolved: 0\/0\/0" 1 681 run_sql_source1 "insert into validator_basic.test values($k, $k)" 682 trigger_checkpoint_flush 683 run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 684 "resume-task test" \ 685 "\"result\": true" 2 686 # syncer synced but the validator delayed 687 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 688 "query-status test" \ 689 "\"synced\": true" 1 \ 690 "\"processedRowsStatus\": \"insert\/update\/delete: $k\/0\/0\"" 1 691 done 692 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 693 "query-status test" \ 694 "\"processedRowsStatus\": \"insert\/update\/delete: $(($insertCnt + 1))\/0\/0\"" 1 \ 695 "new\/ignored\/resolved: 0\/0\/0" 1 696 } 697 698 function test_dup_autopk() { 699 # successfully validate sharding tables 700 # though the downstream table deletes the primary key 701 # because not null unique key can identify a row accurately. 702 echo "--> test duplicate auto-incr pk" 703 export GO_FAILPOINTS="" 704 prepare_dm_and_source 705 dmctl_operate_source create $cur/conf/source2.yaml $SOURCE_ID2 706 # auto_incr pk in both tables 707 run_sql_source1 "create table validator_basic.shard1(id int primary key auto_increment, ukey int not null unique key)" 708 run_sql_file $cur/data/db1.prepare.sql $MYSQL_HOST2 $MYSQL_PORT2 $MYSQL_PASSWORD1 709 run_sql_source2 "create table validator_basic.shard1(id int primary key auto_increment, ukey int not null unique key)" 710 # delete pk in tidb 711 run_sql_tidb "create database if not exists validator_basic" 712 run_sql_tidb "create table validator_basic.shard(id int, ukey int not null unique key)" 713 dmctl_start_task "$cur/conf/sharding-task.yaml" "--remove-meta" 714 run_sql_source1 "insert into validator_basic.shard1(ukey) values(1),(2),(3)" 715 run_sql_source2 "insert into validator_basic.shard1(ukey) values(4),(5),(6)" 716 sleep 1.5 717 run_sql_source2 "alter table $db_name.t1 comment 'a';" # trigger source2 flush 718 trigger_checkpoint_flush # trigger source1 flush 719 # validate pass 720 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 721 "query-status test" \ 722 "\"processedRowsStatus\": \"insert\/update\/delete: 3\/0\/0\"" 2 \ 723 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 2 \ 724 "new\/ignored\/resolved: 0\/0\/0" 2 725 } 726 727 function test_update_validator() { 728 # backup it, will change it in the following case 729 cp $cur/conf/dm-task-standalone.yaml $cur/conf/dm-task-standalone.yaml.bak 730 cp $cur/conf/source1.yaml $cur/conf/source1.yaml.bak 731 732 trap restore_on_case_exit EXIT 733 # clear fail point 734 export GO_FAILPOINTS="" 735 cp $cur/conf/source1.yaml.bak $cur/conf/source1.yaml 736 sed -i 's/enable-gtid: false/enable-gtid: 'true'/g' $cur/conf/source1.yaml 737 sed -i 's/enable-relay: false/enable-relay: 'true'/g' $cur/conf/source1.yaml 738 run_sql_source1 "flush binary logs" 739 sleep 1 740 run_sql_source1 "purge binary logs before now()" 741 prepare_dm_and_source 742 dmctl_start_task_standalone $cur/conf/dm-task-standalone-long-interval.yaml --remove-meta 743 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 744 "config source $SOURCE_ID1" \ 745 "enable-gtid: true" 1 \ 746 "enable-relay: true" 1 747 run_sql_source1 "insert into $db_name.t1(id, name) values(2,'b'), (3, 'c')" 748 run_sql_source1 "delete from $db_name.t1 where id=1" 749 # check validator before start, should pass 750 # validate pass 751 trigger_checkpoint_flush 752 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 753 "query-status test" \ 754 "\"processedRowsStatus\": \"insert\/update\/delete: 2\/0\/1\"" 1 \ 755 "pendingRowsStatus\": \"insert\/update\/delete: 2\/0\/1" 1 \ 756 "new\/ignored\/resolved: 0\/0\/0" 1 \ 757 "\"cutoverBinlogGtid\": \"\"" 1 758 gtid_executed=($(get_gtid_executed $MYSQL_HOST1 $MYSQL_PORT1)) 759 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 760 "validation update test -s $SOURCE_ID1 --cutover-binlog-gtid $gtid_executed" \ 761 "\"result\": true" 2 762 sleep 3 763 # after 3 seconds, cutoverBinlogGtid should also not change 764 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 765 "query-status test" \ 766 "\"cutoverBinlogGtid\": \"$gtid_executed\"" 1 767 trigger_checkpoint_flush 768 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 769 "query-status test" \ 770 "\"synced\": true" 1 771 check_sync_diff $WORK_DIR $cur/conf/diff_config.toml 772 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 773 "query-status test" \ 774 "\"processedRowsStatus\": \"insert\/update\/delete: 2\/0\/1\"" 1 \ 775 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 776 "new\/ignored\/resolved: 0\/0\/0" 1 777 # set gtid_executed again, should be triggered by dml event 778 gtid_executed=($(get_gtid_executed $MYSQL_HOST1 $MYSQL_PORT1)) 779 extracted_number=$(echo "$gtid_executed" | grep -Eo '[0-9]+$') 780 incremented_number=$((extracted_number + 1)) 781 gtid_cutover=$(echo "$gtid_executed" | sed "s/${extracted_number}$/${incremented_number}/") 782 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 783 "validation update test -s $SOURCE_ID1 --cutover-binlog-gtid $gtid_cutover" \ 784 "\"result\": true" 2 785 run_sql_source1 "insert into $db_name.t1(id, name) values (4, 'c')" 786 # directly sleep without flush, can cutover by itself 787 sleep 1.5 788 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 789 "query-status test" \ 790 "\"synced\": true" 1 791 check_sync_diff $WORK_DIR $cur/conf/diff_config.toml 792 run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ 793 "query-status test" \ 794 "\"processedRowsStatus\": \"insert\/update\/delete: 3\/0\/1\"" 1 \ 795 "pendingRowsStatus\": \"insert\/update\/delete: 0\/0\/0" 1 \ 796 "new\/ignored\/resolved: 0\/0\/0" 1 \ 797 "\"cutoverBinlogGtid\": \"\"" 1 798 } 799 800 run_standalone $* 801 validate_table_with_different_pk 802 test_unsupported_table_status 803 stopped_validator_fail_over 804 test_data_filter 805 test_validation_syncer_stopped 806 test_dup_autopk 807 test_update_validator 808 cleanup_process $* 809 cleanup_data $db_name 810 cleanup_data_upstream $db_name 811 812 echo "[$(date)] <<<<<< test case $TEST_NAME success! >>>>>>"