From 3ff5176c535c649df96fb1bad982fe82f7137eda Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Wed, 17 Oct 2018 10:19:04 +0800 Subject: [PATCH] executor: add an variable to compatible with MySQL insert for OGG (#7863) --- executor/insert_common.go | 4 +++- executor/set_test.go | 5 +++++ executor/write_test.go | 14 ++++++++++++++ session/session.go | 1 + sessionctx/variable/session.go | 5 +++++ sessionctx/variable/sysvar.go | 1 + sessionctx/variable/tidb_vars.go | 5 +++++ sessionctx/variable/varsutil.go | 2 +- 8 files changed, 35 insertions(+), 2 deletions(-) diff --git a/executor/insert_common.go b/executor/insert_common.go index a5f72dff8cb33..3f419c33d9246 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -557,7 +557,9 @@ func (e *InsertValues) addRecord(row []types.Datum) (int64, error) { if err != nil { return 0, errors.Trace(err) } - txn.SetOption(kv.PresumeKeyNotExists, nil) + if !e.ctx.GetSessionVars().ConstraintCheckInPlace { + txn.SetOption(kv.PresumeKeyNotExists, nil) + } h, err := e.Table.AddRecord(e.ctx, row) txn.DelOption(kv.PresumeKeyNotExists) if err != nil { diff --git a/executor/set_test.go b/executor/set_test.go index e1b63cda8fbfb..4c34b807d9080 100644 --- a/executor/set_test.go +++ b/executor/set_test.go @@ -248,6 +248,11 @@ func (s *testSuite) TestSetVar(c *C) { tk.MustQuery("select @@session.tidb_query_log_max_len;").Check(testkit.Rows("20")) _, err = tk.Exec("set global tidb_query_log_max_len = 20") c.Assert(err, NotNil) + + tk.MustExec("set tidb_constraint_check_in_place = 1") + tk.MustQuery(`select @@session.tidb_constraint_check_in_place;`).Check(testkit.Rows("1")) + tk.MustExec("set global tidb_constraint_check_in_place = 0") + tk.MustQuery(`select @@global.tidb_constraint_check_in_place;`).Check(testkit.Rows("0")) } func (s *testSuite) TestSetCharset(c *C) { diff --git a/executor/write_test.go b/executor/write_test.go index 4f0aa412a4c44..05e3687732e03 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -2189,3 +2189,17 @@ func (s *testSuite) TestAutoIDInRetry(c *C) { tk.MustExec("insert into t values ()") tk.MustQuery(`select * from t`).Check(testkit.Rows("1", "2", "3", "4", "5")) } + +func (s *testSuite) TestDeferConstraintCheckForInsert(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec(`use test`) + tk.MustExec(`drop table if exists t;create table t (i int key);`) + tk.MustExec(`insert t values (1);`) + tk.MustExec(`set tidb_constraint_check_in_place = 1;`) + tk.MustExec(`begin;`) + _, err := tk.Exec(`insert t values (1);`) + c.Assert(err, NotNil) + tk.MustExec(`update t set i = 2 where i = 1;`) + tk.MustExec(`commit;`) + tk.MustQuery(`select * from t;`).Check(testkit.Rows("2")) +} diff --git a/session/session.go b/session/session.go index 9747920f33054..28ee027e43170 100644 --- a/session/session.go +++ b/session/session.go @@ -1353,6 +1353,7 @@ const loadCommonGlobalVarsSQL = "select HIGH_PRIORITY * from mysql.global_variab variable.TiDBHashAggPartialConcurrency + quoteCommaQuote + variable.TiDBHashAggFinalConcurrency + quoteCommaQuote + variable.TiDBBackoffLockFast + quoteCommaQuote + + variable.TiDBConstraintCheckInPlace + quoteCommaQuote + variable.TiDBOptInSubqUnFolding + quoteCommaQuote + variable.TiDBDistSQLScanConcurrency + quoteCommaQuote + variable.TiDBMaxChunkSize + quoteCommaQuote + diff --git a/sessionctx/variable/session.go b/sessionctx/variable/session.go index 6974be2a6fb93..f05db03cbf8da 100644 --- a/sessionctx/variable/session.go +++ b/sessionctx/variable/session.go @@ -305,6 +305,9 @@ type SessionVars struct { EnableStreaming bool writeStmtBufs WriteStmtBufs + + // ConstraintCheckInPlace indicates whether to check the constraint when the SQL executing. + ConstraintCheckInPlace bool } // NewSessionVars creates a session vars object. @@ -555,6 +558,8 @@ func (s *SessionVars) SetSystemVar(name string, val string) error { s.IndexSerialScanConcurrency = tidbOptPositiveInt32(val, DefIndexSerialScanConcurrency) case TiDBBackoffLockFast: s.KVVars.BackoffLockFast = tidbOptPositiveInt32(val, kv.DefBackoffLockFast) + case TiDBConstraintCheckInPlace: + s.ConstraintCheckInPlace = TiDBOptOn(val) case TiDBBatchInsert: s.BatchInsert = TiDBOptOn(val) case TiDBBatchDelete: diff --git a/sessionctx/variable/sysvar.go b/sessionctx/variable/sysvar.go index 3971b9aacebb0..9f794b3d2ce18 100644 --- a/sessionctx/variable/sysvar.go +++ b/sessionctx/variable/sysvar.go @@ -658,6 +658,7 @@ var defaultSysVars = []*SysVar{ {ScopeGlobal | ScopeSession, TiDBBackoffLockFast, strconv.Itoa(kv.DefBackoffLockFast)}, {ScopeGlobal | ScopeSession, TiDBRetryLimit, strconv.Itoa(DefTiDBRetryLimit)}, {ScopeGlobal | ScopeSession, TiDBDisableTxnAutoRetry, boolToIntStr(DefTiDBDisableTxnAutoRetry)}, + {ScopeGlobal | ScopeSession, TiDBConstraintCheckInPlace, boolToIntStr(DefTiDBConstraintCheckInPlace)}, {ScopeSession, TiDBOptimizerSelectivityLevel, strconv.Itoa(DefTiDBOptimizerSelectivityLevel)}, /* The following variable is defined as session scope but is actually server scope. */ {ScopeSession, TiDBGeneralLog, strconv.Itoa(DefTiDBGeneralLog)}, diff --git a/sessionctx/variable/tidb_vars.go b/sessionctx/variable/tidb_vars.go index f89e4ac141aae..4261d37c8007c 100644 --- a/sessionctx/variable/tidb_vars.go +++ b/sessionctx/variable/tidb_vars.go @@ -203,6 +203,10 @@ const ( // tidb_force_priority defines the operations priority of all statements. // It can be "NO_PRIORITY", "LOW_PRIORITY", "HIGH_PRIORITY", "DELAYED" TiDBForcePriority = "tidb_force_priority" + + // tidb_constraint_check_in_place indicates to check the constraint when the SQL executing. + // It could hurt the performance of bulking insert when it is ON. + TiDBConstraintCheckInPlace = "tidb_constraint_check_in_place" ) // Default TiDB system variable values. @@ -238,6 +242,7 @@ const ( DefTiDBGeneralLog = 0 DefTiDBRetryLimit = 10 DefTiDBDisableTxnAutoRetry = false + DefTiDBConstraintCheckInPlace = false DefTiDBHashJoinConcurrency = 5 DefTiDBProjectionConcurrency = 4 DefTiDBOptimizerSelectivityLevel = 0 diff --git a/sessionctx/variable/varsutil.go b/sessionctx/variable/varsutil.go index 8282334e851a6..d7a4dae103a40 100644 --- a/sessionctx/variable/varsutil.go +++ b/sessionctx/variable/varsutil.go @@ -306,7 +306,7 @@ func ValidateSetSystemVar(vars *SessionVars, name string, value string) (string, case WarningCount, ErrorCount: return value, ErrReadOnly.GenWithStackByArgs(name) case GeneralLog, TiDBGeneralLog, AvoidTemporalUpgrade, BigTables, CheckProxyUsers, CoreFile, EndMakersInJSON, SQLLogBin, OfflineMode, - PseudoSlaveMode, LowPriorityUpdates, SkipNameResolve, ForeignKeyChecks, SQLSafeUpdates: + PseudoSlaveMode, LowPriorityUpdates, SkipNameResolve, ForeignKeyChecks, SQLSafeUpdates, TiDBConstraintCheckInPlace: if strings.EqualFold(value, "ON") || value == "1" { return "1", nil } else if strings.EqualFold(value, "OFF") || value == "0" {