diff --git a/session/bootstrap.go b/session/bootstrap.go index fcd1aa001847f..2c8aab4f52dc6 100644 --- a/session/bootstrap.go +++ b/session/bootstrap.go @@ -637,11 +637,14 @@ const ( version95 = 95 // version96 converts server-memory-quota to a sysvar version96 = 96 + // version97 sets tidb_opt_range_max_size to 0 when a cluster upgrades from some version lower than v6.4.0 to v6.4.0+. + // It promises the compatibility of building ranges behavior. + version97 = 97 ) // currentBootstrapVersion is defined as a variable, so we can modify its value for testing. // please make sure this is the largest version -var currentBootstrapVersion int64 = version95 +var currentBootstrapVersion int64 = version97 // DDL owner key's expired time is ManagerSessionTTL seconds, we should wait the time and give more time to have a chance to finish it. var internalSQLTimeout = owner.ManagerSessionTTL + 15 @@ -743,6 +746,7 @@ var ( upgradeToVer94, upgradeToVer95, upgradeToVer96, + upgradeToVer97, } ) @@ -1953,6 +1957,27 @@ func upgradeToVer96(s Session, ver int64) { importConfigOption(s, "performance.server-memory-quota", variable.TiDBServerMemoryLimit, valStr) } +func upgradeToVer97(s Session, ver int64) { + if ver >= version97 { + return + } + // Check if tidb_opt_range_max_size exists in mysql.GLOBAL_VARIABLES. + // If not, insert "tidb_opt_range_max_size | 0" since this is the old behavior before we introduce this variable. + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnBootstrap) + rs, err := s.ExecuteInternal(ctx, "SELECT VARIABLE_VALUE FROM %n.%n WHERE VARIABLE_NAME=%?;", + mysql.SystemDB, mysql.GlobalVariablesTable, variable.TiDBOptRangeMaxSize) + terror.MustNil(err) + req := rs.NewChunk(nil) + err = rs.Next(ctx, req) + terror.MustNil(err) + if req.NumRows() != 0 { + return + } + + mustExecute(s, "INSERT HIGH_PRIORITY IGNORE INTO %n.%n VALUES (%?, %?);", + mysql.SystemDB, mysql.GlobalVariablesTable, variable.TiDBOptRangeMaxSize, 0) +} + func writeOOMAction(s Session) { comment := "oom-action is `log` by default in v3.0.x, `cancel` by default in v4.0.11+" mustExecute(s, `INSERT HIGH_PRIORITY INTO %n.%n VALUES (%?, %?, %?) ON DUPLICATE KEY UPDATE VARIABLE_VALUE= %?`, diff --git a/session/bootstrap_test.go b/session/bootstrap_test.go index 7989f5a520104..0093df302406f 100644 --- a/session/bootstrap_test.go +++ b/session/bootstrap_test.go @@ -1055,3 +1055,61 @@ func TestTiDBEnablePagingVariable(t *testing.T) { r.Close() } } + +func TestTiDBOptRangeMaxSizeWhenUpgrading(t *testing.T) { + ctx := context.Background() + store, dom := createStoreAndBootstrap(t) + defer func() { require.NoError(t, store.Close()) }() + + // Upgrade from v6.3.0 to v6.4.0+. + ver94 := 94 + seV630 := createSessionAndSetID(t, store) + txn, err := store.Begin() + require.NoError(t, err) + m := meta.NewMeta(txn) + err = m.FinishBootstrap(int64(ver94)) + require.NoError(t, err) + err = txn.Commit(context.Background()) + require.NoError(t, err) + mustExec(t, seV630, fmt.Sprintf("update mysql.tidb set variable_value=%d where variable_name='tidb_server_version'", ver94)) + mustExec(t, seV630, fmt.Sprintf("delete from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBOptRangeMaxSize)) + mustExec(t, seV630, "commit") + unsetStoreBootstrapped(store.UUID()) + ver, err := getBootstrapVersion(seV630) + require.NoError(t, err) + require.Equal(t, int64(ver94), ver) + + // We are now in 6.3.0, check tidb_opt_range_max_size should not exist. + res := mustExec(t, seV630, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBOptRangeMaxSize)) + chk := res.NewChunk(nil) + err = res.Next(ctx, chk) + require.NoError(t, err) + require.Equal(t, 0, chk.NumRows()) + dom.Close() + domCurVer, err := BootstrapSession(store) + require.NoError(t, err) + defer domCurVer.Close() + seCurVer := createSessionAndSetID(t, store) + ver, err = getBootstrapVersion(seCurVer) + require.NoError(t, err) + require.Equal(t, currentBootstrapVersion, ver) + + // We are now in version no lower than v6.4.0, tidb_opt_range_max_size should be 0. + res = mustExec(t, seCurVer, "select @@session.tidb_opt_range_max_size") + chk = res.NewChunk(nil) + err = res.Next(ctx, chk) + require.NoError(t, err) + require.Equal(t, 1, chk.NumRows()) + row := chk.GetRow(0) + require.Equal(t, 1, row.Len()) + require.Equal(t, "0", row.GetString(0)) + + res = mustExec(t, seCurVer, "select @@global.tidb_opt_range_max_size") + chk = res.NewChunk(nil) + err = res.Next(ctx, chk) + require.NoError(t, err) + require.Equal(t, 1, chk.NumRows()) + row = chk.GetRow(0) + require.Equal(t, 1, row.Len()) + require.Equal(t, "0", row.GetString(0)) +}