Skip to content

Commit 85c160d

Browse files
authored
br: make table existence check unified on different br client (#58211) (#58245)
close #58168
1 parent dc56ee8 commit 85c160d

File tree

6 files changed

+174
-7
lines changed

6 files changed

+174
-7
lines changed

br/pkg/task/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ go_library(
4545
"//br/pkg/utils",
4646
"//br/pkg/version",
4747
"//pkg/config",
48+
"//pkg/infoschema",
4849
"//pkg/kv",
4950
"//pkg/parser/model",
5051
"//pkg/parser/mysql",

br/pkg/task/restore.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/pingcap/tidb/br/pkg/utils"
3030
"github.com/pingcap/tidb/br/pkg/version"
3131
"github.com/pingcap/tidb/pkg/config"
32+
"github.com/pingcap/tidb/pkg/infoschema"
3233
"github.com/pingcap/tidb/pkg/util"
3334
"github.com/pingcap/tidb/pkg/util/mathutil"
3435
"github.com/spf13/cobra"
@@ -787,6 +788,11 @@ func runRestore(c context.Context, g glue.Glue, cmdName string, cfg *RestoreConf
787788
if cfg.WithSysTable {
788789
client.InitFullClusterRestore(cfg.ExplicitFilter)
789790
}
791+
} else if client.IsFull() && checkpointFirstRun && cfg.CheckRequirements {
792+
if err := checkTableExistence(ctx, mgr, tables, g); err != nil {
793+
schedulersRemovable = true
794+
return errors.Trace(err)
795+
}
790796
}
791797

792798
if client.IsFullClusterRestore() && client.HasBackedUpSysDB() {
@@ -1069,6 +1075,24 @@ func runRestore(c context.Context, g glue.Glue, cmdName string, cfg *RestoreConf
10691075
return nil
10701076
}
10711077

1078+
func checkTableExistence(ctx context.Context, mgr *conn.Mgr, tables []*metautil.Table, g glue.Glue) error {
1079+
message := "table already exists: "
1080+
allUnique := true
1081+
for _, table := range tables {
1082+
_, err := mgr.GetDomain().InfoSchema().TableByName(table.DB.Name, table.Info.Name)
1083+
if err == nil {
1084+
message += fmt.Sprintf("%s.%s ", table.DB.Name, table.Info.Name)
1085+
allUnique = false
1086+
} else if !infoschema.ErrTableNotExists.Equal(err) {
1087+
return errors.Trace(err)
1088+
}
1089+
}
1090+
if !allUnique {
1091+
return errors.Errorf("Target tables already existed: %s", message)
1092+
}
1093+
return nil
1094+
}
1095+
10721096
// dropToBlackhole drop all incoming tables into black hole,
10731097
// i.e. don't execute checksum, just increase the process anyhow.
10741098
func dropToBlackhole(

br/tests/br_300_small_tables/run.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,15 @@ else
7373
fi
7474

7575
# truncate every table
76-
# (FIXME: drop instead of truncate. if we drop then create-table will still be executed and wastes time executing DDLs)
7776
i=1
7877
while [ $i -le $TABLES_COUNT ]; do
79-
run_sql "truncate $DB.sbtest$i;"
78+
run_sql "drop table $DB.sbtest$i;"
8079
i=$(($i+1))
8180
done
8281

8382
rm -rf $RESTORE_LOG
8483
echo "restore 1/300 of the table start..."
85-
run_br restore table --db $DB --table "sbtest100" --log-file $RESTORE_LOG -s "local://$TEST_DIR/$DB" --pd $PD_ADDR --no-schema
84+
run_br restore table --db $DB --table "sbtest100" --log-file $RESTORE_LOG -s "local://$TEST_DIR/$DB" --pd $PD_ADDR
8685
restore_size=`grep "restore-data-size" "${RESTORE_LOG}" | grep -oP '\[\K[^\]]+' | grep "restore-data-size" | awk -F '=' '{print $2}' | grep -oP '\d*\.?\d+'`
8786
echo "restore data size is ${restore_size}"
8887

@@ -98,9 +97,10 @@ else
9897
exit 1
9998
fi
10099

100+
run_sql "drop table $DB.sbtest100;"
101+
101102
# restore db
102-
# (FIXME: shouldn't need --no-schema to be fast, currently the alter-auto-id DDL slows things down)
103103
echo "restore start..."
104-
run_br restore db --db $DB -s "local://$TEST_DIR/$DB" --pd $PD_ADDR --no-schema
104+
run_br restore db --db $DB -s "local://$TEST_DIR/$DB" --pd $PD_ADDR
105105

106106
run_sql "DROP DATABASE $DB;"

br/tests/br_check_dup_table/run.sh

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/bin/sh
2+
#
3+
# Copyright 2024 PingCAP, Inc.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -eu
18+
DB="$TEST_NAME"
19+
20+
run_sql "CREATE DATABASE $DB;"
21+
22+
run_sql "CREATE TABLE $DB.usertable1 ( \
23+
YCSB_KEY varchar(64) NOT NULL, \
24+
FIELD0 varchar(1) DEFAULT NULL, \
25+
PRIMARY KEY (YCSB_KEY) \
26+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;"
27+
28+
run_sql "INSERT INTO $DB.usertable1 VALUES (\"a\", \"b\");"
29+
run_sql "INSERT INTO $DB.usertable1 VALUES (\"aa\", \"b\");"
30+
31+
run_sql "CREATE TABLE $DB.usertable2 ( \
32+
YCSB_KEY varchar(64) NOT NULL, \
33+
FIELD0 varchar(1) DEFAULT NULL, \
34+
PRIMARY KEY (YCSB_KEY) \
35+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;"
36+
37+
run_sql "INSERT INTO $DB.usertable2 VALUES (\"c\", \"d\");"
38+
# backup db
39+
echo "backup start..."
40+
run_br --pd $PD_ADDR backup db --db "$DB" -s "local://$TEST_DIR/$DB"
41+
42+
run_sql "DROP DATABASE $DB;"
43+
44+
# restore db
45+
echo "restore start..."
46+
run_br restore db --db $DB -s "local://$TEST_DIR/$DB" --pd $PD_ADDR
47+
48+
table_count=$(run_sql "use $DB; show tables;" | grep "Tables_in" | wc -l)
49+
if [ "$table_count" -ne "2" ];then
50+
echo "TEST: [$TEST_NAME] failed!"
51+
exit 1
52+
fi
53+
54+
# restore db again
55+
echo "restore start..."
56+
LOG_OUTPUT=$(run_br restore db --db "$DB" -s "local://$TEST_DIR/$DB" --pd "$PD_ADDR" 2>&1 || true)
57+
58+
# Check if the log contains 'ErrTableAlreadyExisted'
59+
if ! echo "$LOG_OUTPUT" | grep -q "BR:Restore:ErrTablesAlreadyExisted"; then
60+
echo "Error: 'ErrTableAlreadyExisted' not found in logs."
61+
echo "Log output:"
62+
echo "$LOG_OUTPUT"
63+
exit 1
64+
else
65+
echo "restore failed as expect"
66+
fi
67+
68+
run_sql "DROP DATABASE $DB;"

br/tests/br_incompatible_tidb_config/run.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,14 @@ run_br --pd $PD_ADDR backup db --db "$DB" -s "local://$TEST_DIR/$DB$INCREMENTAL_
5454
run_sql "drop schema $DB;"
5555
# restore with ddl(create table) job one by one
5656
run_br --pd $PD_ADDR restore db --db "$DB" -s "local://$TEST_DIR/$DB$TABLE" --ddl-batch-size=1
57-
57+
run_sql "drop schema $DB;"
5858
run_br --pd $PD_ADDR restore db --db "$DB" -s "local://$TEST_DIR/$DB$INCREMENTAL_TABLE" --ddl-batch-size=1
5959

6060
# restore
6161
run_sql "drop schema $DB;"
6262
# restore with batch create table
6363
run_br --pd $PD_ADDR restore db --db "$DB" -s "local://$TEST_DIR/$DB$TABLE" --ddl-batch-size=128
64-
64+
run_sql "drop schema $DB;"
6565
run_br --pd $PD_ADDR restore db --db "$DB" -s "local://$TEST_DIR/$DB$INCREMENTAL_TABLE" --ddl-batch-size=128
6666

6767
run_sql "drop schema $DB;"

br/tests/run_group_br_tests.sh

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env bash
2+
3+
# This script split the integration tests into 9 groups to support parallel group tests execution.
4+
# all the integration tests are located in br/tests directory. only the directories
5+
# containing run.sh will be considered as valid br integration tests. the script will print the total case number
6+
7+
set -eo pipefail
8+
9+
# Step 1
10+
CUR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
11+
group=$1
12+
export COV_DIR="/tmp/group_cover"
13+
rm -rf $COV_DIR
14+
mkdir -p $COV_DIR
15+
16+
# Define groups
17+
# Note: If new group is added, the group name must also be added to CI
18+
# * https://github.com/PingCAP-QE/ci/blob/main/pipelines/pingcap/tidb/latest/pull_br_integration_test.groovy
19+
# Each group of tests consumes as much time as possible, thus reducing CI waiting time.
20+
# Putting multiple light tests together and heavy tests in a separate group.
21+
declare -A groups
22+
groups=(
23+
["G00"]="br_300_small_tables br_backup_empty br_backup_version br_cache_table br_case_sensitive br_charset_gbk br_check_new_collocation_enable br_history br_gcs br_rawkv br_tidb_placement_policy"
24+
["G01"]="br_autoid br_crypter2 br_db br_check_dup_table br_db_online br_db_online_newkv br_db_skip br_debug_meta br_ebs br_foreign_key br_full br_table_partition br_full_ddl br_tiflash"
25+
["G02"]="br_full_cluster_restore br_full_index br_incremental_ddl br_pitr_failpoint br_pitr_gc_safepoint br_other br_pitr_long_running_schema_loading"
26+
["G03"]='br_incompatible_tidb_config br_incremental br_incremental_index br_incremental_only_ddl br_incremental_same_table br_insert_after_restore br_key_locked br_log_test br_move_backup br_mv_index'
27+
["G04"]='br_range br_replica_read br_restore_TDE_enable br_restore_log_task_enable br_s3 br_shuffle_leader br_shuffle_region br_single_table '
28+
["G05"]='br_skip_checksum br_split_region_fail br_systables br_table_filter br_txn br_stats br_clustered_index br_crypter br_partition_add_index'
29+
["G06"]='br_tikv_outage br_tikv_outage3 br_restore_checkpoint br_encryption'
30+
["G07"]='br_pitr'
31+
["G08"]='br_tikv_outage2 br_ttl br_views_and_sequences br_z_gc_safepoint br_autorandom br_file_corruption br_tiflash_conflict'
32+
)
33+
34+
# Get other cases not in groups, to avoid missing any case
35+
others=()
36+
for script in "$CUR"/*/run.sh; do
37+
test_name="$(basename "$(dirname "$script")")"
38+
if [[ $test_name != br* ]]; then
39+
continue
40+
fi
41+
# shellcheck disable=SC2076
42+
if [[ ! " ${groups[*]} " =~ " ${test_name} " ]]; then
43+
others=("${others[@]} ${test_name}")
44+
fi
45+
done
46+
47+
# enable local encryption for all tests
48+
ENABLE_ENCRYPTION=true
49+
export ENABLE_ENCRYPTION
50+
51+
if [[ "$group" == "others" ]]; then
52+
if [[ -z $others ]]; then
53+
echo "All br integration test cases have been added to groups"
54+
exit 0
55+
fi
56+
echo "Error: "$others" is not added to any group in br/tests/run_group_br_tests.sh"
57+
exit 1
58+
elif [[ " ${!groups[*]} " =~ " ${group} " ]]; then
59+
test_names="${groups[${group}]}"
60+
# Run test cases
61+
if [[ -n $test_names ]]; then
62+
echo ""
63+
echo "Run cases: ${test_names}"
64+
for case_name in $test_names; do
65+
echo "Run cases: ${case_name}"
66+
rm -rf /tmp/backup_restore_test
67+
mkdir -p /tmp/backup_restore_test
68+
TEST_NAME=${case_name} ${CUR}/run.sh
69+
done
70+
fi
71+
else
72+
echo "Error: invalid group name: ${group}"
73+
exit 1
74+
fi

0 commit comments

Comments
 (0)