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

     1  #!/bin/bash
     2  
     3  # [DISCRIPTION]:
     4  #   This test is related to https://github.com/pingcap/tiflow/issues/658.
     5  #   It will record the syncpoint map of upstream and downstream to a table to achieve snapshot level consistency replication
     6  # [STEP]:
     7  #   1. Create changefeed with --sync-point --sync-interval=10s
     8  #   2. After test, get all syncpoints from tidb_cdc.syncpoint_v1
     9  #   3. Get all ddl history from Upstream TiDB
    10  #   4. Check if the syncpoint is in the process of a ddl, if not, using syncpoint to check data diff of upstream and downstream
    11  
    12  set -eu
    13  
    14  CUR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
    15  source $CUR/../_utils/test_prepare
    16  WORK_DIR=$OUT_DIR/$TEST_NAME
    17  CDC_BINARY=cdc.test
    18  SINK_TYPE=$1
    19  
    20  CDC_COUNT=3
    21  DB_COUNT=4
    22  
    23  # The follow `sleep 2` make sure the ddl and dml operation can always execute during the test.
    24  # So every syncpoint will have different data and the diff tool can judge the syncpoint's validity.
    25  function ddl() {
    26  	run_sql "DROP table IF EXISTS testSync.simple1"
    27  	sleep 2
    28  	run_sql "DROP table IF EXISTS testSync.simple2"
    29  	sleep 2
    30  	run_sql "CREATE table testSync.simple1(id int primary key, val int);"
    31  	sleep 2
    32  	run_sql "INSERT INTO testSync.simple1(id, val) VALUES (1, 1);"
    33  	sleep 2
    34  	run_sql "INSERT INTO testSync.simple1(id, val) VALUES (2, 2);"
    35  	sleep 2
    36  	run_sql "INSERT INTO testSync.simple1(id, val) VALUES (3, 3);"
    37  	sleep 2
    38  	run_sql "INSERT INTO testSync.simple1(id, val) VALUES (4, 4);"
    39  	sleep 2
    40  	run_sql "INSERT INTO testSync.simple1(id, val) VALUES (5, 5);"
    41  	sleep 2
    42  	run_sql "INSERT INTO testSync.simple1(id, val) VALUES (6, 6);"
    43  	sleep 2
    44  	run_sql "CREATE table testSync.simple2(id int primary key, val int);"
    45  	sleep 2
    46  	run_sql "INSERT INTO testSync.simple2(id, val) VALUES (1, 1);"
    47  	sleep 2
    48  	run_sql "INSERT INTO testSync.simple2(id, val) VALUES (2, 2);"
    49  	sleep 2
    50  	run_sql "INSERT INTO testSync.simple2(id, val) VALUES (3, 3);"
    51  	sleep 2
    52  	run_sql "INSERT INTO testSync.simple2(id, val) VALUES (4, 4);"
    53  	sleep 2
    54  	run_sql "INSERT INTO testSync.simple2(id, val) VALUES (5, 5);"
    55  	sleep 2
    56  	run_sql "INSERT INTO testSync.simple2(id, val) VALUES (6, 6);"
    57  	sleep 2
    58  	run_sql "CREATE index simple1_val ON testSync.simple1(val);"
    59  	sleep 2
    60  	run_sql "CREATE index simple2_val ON testSync.simple2(val);"
    61  	sleep 2
    62  	run_sql "DELETE FROM testSync.simple1 where id=1;"
    63  	sleep 2
    64  	run_sql "DELETE FROM testSync.simple2 where id=1;"
    65  	sleep 2
    66  	run_sql "DELETE FROM testSync.simple1 where id=2;"
    67  	sleep 2
    68  	run_sql "DELETE FROM testSync.simple2 where id=2;"
    69  	sleep 2
    70  	run_sql "DROP index simple1_val ON testSync.simple1;"
    71  	sleep 2
    72  	run_sql "DROP index simple2_val ON testSync.simple2;"
    73  	sleep 2
    74  }
    75  
    76  function goSql() {
    77  	for i in {1..3}; do
    78  		go-ycsb load mysql -P $CUR/conf/workload -p mysql.host=${UP_TIDB_HOST} -p mysql.port=${UP_TIDB_PORT} -p mysql.user=root -p mysql.db=testSync
    79  		sleep 2
    80  		ddl
    81  		sleep 2
    82  	done
    83  }
    84  
    85  function deployConfig() {
    86  	cat $CUR/conf/diff_config_part1.toml >$CUR/conf/diff_config.toml
    87  	echo "snapshot = \"$1\"" >>$CUR/conf/diff_config.toml
    88  	cat $CUR/conf/diff_config_part2.toml >>$CUR/conf/diff_config.toml
    89  	echo "snapshot = \"$2\"" >>$CUR/conf/diff_config.toml
    90  }
    91  
    92  # check whether the given tso happens in a DDL job, if true returns the start_ts
    93  # and commit_ts of the DDL job
    94  function checkPrimaryTsNotInDDL() {
    95  	primary_ts=$1
    96  	tsos=$2
    97  	count=$((${#tsos[@]} / 2))
    98  	for i in $(seq 1 $count); do
    99  		start_ts=${tsos[((2 * $i - 2))]}
   100  		commit_ts=${tsos[((2 * $i - 1))]}
   101  		if [[ ($primary_ts > $start_ts) && ($primary_ts < $commit_ts) ]]; then
   102  			echo "$start_ts $commit_ts"
   103  			return
   104  		fi
   105  	done
   106  }
   107  
   108  # check whether the synpoint happens after test ddl to avoid `no table need to be compared` of sync_diff_inspector
   109  # we need to make sure that the syncpoint we check is after the `CREATE table`
   110  function checkValidSyncPointTs() {
   111  	primary_ts=$1
   112  	first_ddl_ts=$2
   113  	if [[ ($primary_ts < $first_ddl_ts) ]]; then
   114  		echo 0
   115  		return
   116  	fi
   117  	echo 1
   118  }
   119  
   120  function checkDiff() {
   121  	primaryArr=($(grep primary_ts $OUT_DIR/sql_res.$TEST_NAME.txt | awk -F ": " '{print $2}'))
   122  	secondaryArr=($(grep secondary_ts $OUT_DIR/sql_res.$TEST_NAME.txt | awk -F ": " '{print $2}'))
   123  	tsos=($(curl -s http://$UP_TIDB_HOST:$UP_TIDB_STATUS/ddl/history | grep -E "real_start_ts|FinishedTS" | grep -oE "[0-9]*"))
   124  	firstDDLTs=($(curl -s http://$UP_TIDB_HOST:$UP_TIDB_STATUS/ddl/history | grep -B 3 "CREATE table testSync" | grep "real_start_ts" | grep -oE "[0-9]*"))
   125  	num=${#primaryArr[*]}
   126  	for ((i = 0; i < $num; i++)); do
   127  		if [[ 1 != $(checkValidSyncPointTs ${primaryArr[$i]} $firstDDLTs) ]]; then
   128  			echo "skip invalid syncpoint primary_ts: ${primaryArr[$i]}, first_ddl_ts: $firstDDLTs"
   129  			continue
   130  		fi
   131  
   132  		check_in_ddl=$(checkPrimaryTsNotInDDL ${primaryArr[$i]} $tsos)
   133  		if [[ ! -z $check_in_ddl ]]; then
   134  			echo "syncpoint ${primaryArr[$i]} ${secondaryArr[$i]} " \
   135  				"is recorded in a DDL event(${check_in_ddl[0]}), skip the check of it"
   136  			continue
   137  		fi
   138  		deployConfig ${primaryArr[$i]} ${secondaryArr[$i]}
   139  		check_sync_diff $WORK_DIR $CUR/conf/diff_config.toml
   140  	done
   141  	rm $CUR/conf/diff_config.toml
   142  }
   143  
   144  function run() {
   145  	if [ "$SINK_TYPE" != "mysql" ]; then
   146  		echo "kafka downstream isn't support syncpoint record"
   147  		return
   148  	fi
   149  
   150  	rm -rf $WORK_DIR && mkdir -p $WORK_DIR
   151  
   152  	start_tidb_cluster --workdir $WORK_DIR
   153  
   154  	cd $WORK_DIR
   155  	run_sql "SET GLOBAL tidb_enable_external_ts_read = on;" ${DOWN_TIDB_HOST} ${DOWN_TIDB_PORT}
   156  	run_sql "CREATE DATABASE testSync;"
   157  	run_sql "CREATE DATABASE testSync;" ${DOWN_TIDB_HOST} ${DOWN_TIDB_PORT}
   158  
   159  	# make suer no panic happen when the syncpoint enable and the ddl sink initializing slowly
   160  	export GO_FAILPOINTS='github.com/pingcap/tiflow/cdc/owner/DDLSinkInitializeSlowly=return(true)'
   161  	start_ts=$(run_cdc_cli_tso_query ${UP_PD_HOST_1} ${UP_PD_PORT_1})
   162  	run_cdc_server --workdir $WORK_DIR --binary $CDC_BINARY
   163  
   164  	# this test contains `set global tidb_external_ts = ?` , which requires super privilege, so we
   165  	# can't use the normal user
   166  	SINK_URI="mysql://root@127.0.0.1:3306/?max-txn-row=1"
   167  	run_cdc_cli changefeed create --start-ts=$start_ts --sink-uri="$SINK_URI" --config="$CUR/conf/changefeed.toml"
   168  
   169  	goSql
   170  
   171  	check_table_exists "testSync.usertable" ${DOWN_TIDB_HOST} ${DOWN_TIDB_PORT}
   172  	check_table_exists "testSync.simple1" ${DOWN_TIDB_HOST} ${DOWN_TIDB_PORT}
   173  	check_table_exists "testSync.simple2" ${DOWN_TIDB_HOST} ${DOWN_TIDB_PORT}
   174  
   175  	run_sql "SET GLOBAL tidb_enable_external_ts_read = off;" ${DOWN_TIDB_HOST} ${DOWN_TIDB_PORT}
   176  	sleep 60
   177  
   178  	run_sql "SELECT primary_ts, secondary_ts FROM tidb_cdc.syncpoint_v1;" ${DOWN_TIDB_HOST} ${DOWN_TIDB_PORT}
   179  	echo "____________________________________"
   180  	cat "$OUT_DIR/sql_res.$TEST_NAME.txt"
   181  	checkDiff
   182  	check_sync_diff $WORK_DIR $CUR/conf/diff_config_final.toml
   183  
   184  	cleanup_process $CDC_BINARY
   185  }
   186  
   187  trap stop_tidb_cluster EXIT
   188  run $*
   189  check_logs $WORK_DIR
   190  echo "[$(date)] <<<<<< run test case $TEST_NAME success! >>>>>>"