From 020f93660ace1f9b1ae6cca23406f55c7427dcf9 Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Wed, 29 Mar 2023 16:54:54 +0800 Subject: [PATCH] lightning: support auto_random column in composite primary key (#41463) (#41482) close pingcap/tidb#41454 --- br/pkg/lightning/backend/kv/sql2kv.go | 53 +++++++++---------- br/pkg/lightning/common/util.go | 20 +++++++ br/pkg/lightning/common/util_test.go | 27 ++++++++++ br/pkg/lightning/restore/check_info.go | 3 +- br/pkg/lightning/restore/restore.go | 4 +- br/pkg/lightning/restore/table_restore.go | 5 +- .../data2/auto_random.t.000000001.csv | 3 ++ br/tests/lightning_auto_random_default/run.sh | 27 ++++++++++ 8 files changed, 108 insertions(+), 34 deletions(-) create mode 100644 br/tests/lightning_auto_random_default/data2/auto_random.t.000000001.csv diff --git a/br/pkg/lightning/backend/kv/sql2kv.go b/br/pkg/lightning/backend/kv/sql2kv.go index 4dc80e0c17ce2..1a99b04c3e99e 100644 --- a/br/pkg/lightning/backend/kv/sql2kv.go +++ b/br/pkg/lightning/backend/kv/sql2kv.go @@ -57,10 +57,11 @@ type genCol struct { type autoIDConverter func(int64) int64 type tableKVEncoder struct { - tbl table.Table - se *session - recordCache []types.Datum - genCols []genCol + tbl table.Table + autoRandomColID int64 + se *session + recordCache []types.Datum + genCols []genCol // convert auto id for shard rowid or auto random id base on row id generated by lightning autoIDFn autoIDConverter } @@ -74,17 +75,15 @@ func NewTableKVEncoder(tbl table.Table, options *SessionOptions) (Encoder, error recordCtx := tables.NewCommonAddRecordCtx(len(cols)) tables.SetAddRecordCtx(se, recordCtx) + var autoRandomColID int64 autoIDFn := func(id int64) int64 { return id } - if meta.PKIsHandle && meta.ContainsAutoRandomBits() { - for _, col := range cols { - if mysql.HasPriKeyFlag(col.GetFlag()) { - incrementalBits := autoRandomIncrementBits(col, int(meta.AutoRandomBits)) - autoRandomBits := rand.New(rand.NewSource(options.AutoRandomSeed)).Int63n(1< 0 { rd := rand.New(rand.NewSource(options.AutoRandomSeed)) // nolint:gosec @@ -104,14 +103,15 @@ func NewTableKVEncoder(tbl table.Table, options *SessionOptions) (Encoder, error } return &tableKVEncoder{ - tbl: tbl, - se: se, - genCols: genCols, - autoIDFn: autoIDFn, + tbl: tbl, + autoRandomColID: autoRandomColID, + se: se, + genCols: genCols, + autoIDFn: autoIDFn, }, nil } -func autoRandomIncrementBits(col *table.Column, randomBits int) int { +func autoRandomIncrementBits(col *model.ColumnInfo, randomBits int) int { typeBitsLength := mysql.DefaultLengthOfMysqlTypes[col.GetType()] * 8 incrementalBits := typeBitsLength - randomBits hasSignBit := !mysql.HasUnsignedFlag(col.GetFlag()) @@ -369,8 +369,8 @@ func (kvcodec *tableKVEncoder) Encode( record = append(record, value) - if isTableAutoRandom(meta) && isPKCol(col.ToInfo()) { - incrementalBits := autoRandomIncrementBits(col, int(meta.AutoRandomBits)) + if kvcodec.isAutoRandomCol(col.ToInfo()) { + incrementalBits := autoRandomIncrementBits(col.ToInfo(), int(meta.AutoRandomBits)) alloc := kvcodec.tbl.Allocators(kvcodec.se).Get(autoid.AutoRandomType) if err := alloc.Rebase(context.Background(), value.GetInt64()&((1<= $NEXT_AUTO_RAND_VAL as ge FROM auto_random.t" check_contains 'ge: 1' done + +function run_for_auro_random_data2() { + create_table=$1 + run_sql 'DROP DATABASE IF EXISTS auto_random;' + run_sql 'CREATE DATABASE IF NOT EXISTS auto_random;' + run_sql "$create_table" + run_lightning --backend $backend -d "tests/$TEST_NAME/data2" + run_sql 'select count(*) as count from auto_random.t where c > 0' + check_contains "count: 2" + run_sql 'select count(*) as count from auto_random.t where a=1 and b=11' + check_contains "count: 1" + run_sql 'select count(*) as count from auto_random.t where a=2 and b=22' + check_contains "count: 1" +} + +for backend in tidb local; do + if [ "$backend" = 'local' ]; then + check_cluster_version 4 0 0 'local backend' || continue + fi + + run_for_auro_random_data2 'create table auto_random.t(c bigint auto_random primary key, a int, b int)' + run_for_auro_random_data2 'create table auto_random.t(a int, b int, c bigint auto_random primary key)' + # composite key and auto_random is the first column + run_for_auro_random_data2 'create table auto_random.t(c bigint auto_random, a int, b int, primary key(c, a) clustered)' + # composite key and auto_random is not the first column + run_for_auro_random_data2 'create table auto_random.t(a int, b int, c bigint auto_random, primary key(c, a) clustered)' +done