Skip to content

Commit

Permalink
planner: fix tidb can point update data even if tidb_super_read_only …
Browse files Browse the repository at this point in the history
…is on (#32547)

close #32539
  • Loading branch information
ichn-hu committed Feb 23, 2022
1 parent 5bbd709 commit 221801b
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 14 deletions.
20 changes: 10 additions & 10 deletions planner/optimize.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ func matchSQLBinding(sctx sessionctx.Context, stmtNode ast.StmtNode) (bindRecord
func Optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is infoschema.InfoSchema) (plannercore.Plan, types.NameSlice, error) {
sessVars := sctx.GetSessionVars()

if !sctx.GetSessionVars().InRestrictedSQL && variable.RestrictedReadOnly.Load() || variable.VarTiDBSuperReadOnly.Load() {
allowed, err := allowInReadOnlyMode(sctx, node)
if err != nil {
return nil, nil, err
}
if !allowed {
return nil, nil, errors.Trace(core.ErrSQLInReadOnlyMode)
}
}

// Because for write stmt, TiFlash has a different results when lock the data in point get plan. We ban the TiFlash
// engine in not read only stmt.
if _, isolationReadContainTiFlash := sessVars.IsolationReadEngines[kv.TiFlash]; isolationReadContainTiFlash && !IsReadOnly(node, sessVars) {
Expand Down Expand Up @@ -351,16 +361,6 @@ func optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is in
return nil, nil, 0, err
}

if !sctx.GetSessionVars().InRestrictedSQL && variable.RestrictedReadOnly.Load() || variable.VarTiDBSuperReadOnly.Load() {
allowed, err := allowInReadOnlyMode(sctx, node)
if err != nil {
return nil, nil, 0, err
}
if !allowed {
return nil, nil, 0, errors.Trace(core.ErrSQLInReadOnlyMode)
}
}

// Handle the execute statement.
if execPlan, ok := p.(*plannercore.Execute); ok {
err := execPlan.OptimizePreparedPlan(ctx, sctx, is)
Expand Down
29 changes: 25 additions & 4 deletions tests/readonlytest/readonly_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import (

var (
tidbRootPassword = flag.String("passwd", "", "tidb root password")
tidbAPort = flag.Int("tidb_a_port", 4000, "first tidb server listening port")
tidbBPort = flag.Int("tidb_b_port", 4001, "second tidb server listening port")
tidbAPort = flag.Int("tidb_a_port", 4001, "first tidb server listening port")
tidbBPort = flag.Int("tidb_b_port", 4002, "second tidb server listening port")
ReadOnlyErrMsg = "Error 1836: Running in read-only mode"
ConflictErrMsg = "Error 1105: can't turn off tidb_super_read_only when tidb_restricted_read_only is on"
PriviledgedErrMsg = "Error 1227: Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation"
Expand Down Expand Up @@ -107,8 +107,18 @@ func createReadOnlySuite(t *testing.T) (s *ReadOnlySuite, clean func()) {
func TestRestriction(t *testing.T) {
s, clean := createReadOnlySuite(t)
defer clean()
setVariable(t, s.db, TiDBRestrictedReadOnly, 1)

var err error
_, err = s.db.Exec("drop table if exists t")
require.NoError(t, err)
_, err = s.udb.Exec("create table t (a int primary key, b int)")
require.NoError(t, err)
_, err = s.udb.Exec("insert into t values (1, 1)")
require.NoError(t, err)
_, err = s.udb.Exec("update t set b = 2 where a = 1")
require.NoError(t, err)

setVariable(t, s.db, TiDBRestrictedReadOnly, 1)
time.Sleep(1)

checkVariable(t, s.udb, TiDBRestrictedReadOnly, true)
Expand All @@ -117,7 +127,18 @@ func TestRestriction(t *testing.T) {
checkVariable(t, s.rdb, TiDBRestrictedReadOnly, true)
checkVariable(t, s.rdb, TiDBSuperReadOnly, true)

_, err := s.udb.Exec("create table t(a int)")
// can't create table
_, err = s.udb.Exec("create table t(a int)")
require.Error(t, err)
require.Equal(t, err.Error(), ReadOnlyErrMsg)

// can't do point update when tidb_restricted_read_only is on
_, err = s.udb.Exec("update t set b = 2 where a = 1")
require.Error(t, err)
require.Equal(t, err.Error(), ReadOnlyErrMsg)

// can't insert
_, err = s.udb.Exec("insert into t values (2, 3)")
require.Error(t, err)
require.Equal(t, err.Error(), ReadOnlyErrMsg)

Expand Down

0 comments on commit 221801b

Please sign in to comment.