diff --git a/ddl/db_test.go b/ddl/db_test.go index 6177151cdd434..8b11eeaead13e 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -3331,6 +3331,38 @@ func (s *testDBSuite4) TestAlterShardRowIDBits(c *C) { c.Assert(err.Error(), Equals, "[autoid:1467]Failed to read auto-increment value from storage engine") } +func (s *testDBSuite2) TestSkipSchemaChecker(c *C) { + s.tk = testkit.NewTestKit(c, s.store) + tk := s.tk + tk.MustExec("use test") + tk.MustExec("drop table if exists t1") + defer tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1 (a int)") + tk2 := testkit.NewTestKit(c, s.store) + tk2.MustExec("use test") + + // Test skip schema checker for ActionSetTiFlashReplica. + tk.MustExec("begin") + tk.MustExec("insert into t1 set a=1;") + tk2.MustExec("alter table t1 set tiflash replica 2 location labels 'a','b';") + tk.MustExec("commit") + + // Test skip schema checker for ActionUpdateTiFlashReplicaStatus. + tk.MustExec("begin") + tk.MustExec("insert into t1 set a=1;") + tb := testGetTableByName(c, s.tk.Se, "test", "t1") + err := domain.GetDomain(s.tk.Se).DDL().UpdateTableReplicaInfo(s.tk.Se, tb.Meta().ID, true) + c.Assert(err, IsNil) + tk.MustExec("commit") + + // Test can't skip schema checker. + tk.MustExec("begin") + tk.MustExec("insert into t1 set a=1;") + tk2.MustExec("alter table t1 add column b int;") + _, err = tk.Exec("commit") + c.Assert(terror.ErrorEqual(domain.ErrInfoSchemaChanged, err), IsTrue) +} + func (s *testDBSuite2) TestLockTables(c *C) { s.tk = testkit.NewTestKit(c, s.store) tk := s.tk diff --git a/domain/domain.go b/domain/domain.go index 696a5bd22f5d3..07bcbfe1b6fdb 100644 --- a/domain/domain.go +++ b/domain/domain.go @@ -254,12 +254,23 @@ func (do *Domain) tryLoadSchemaDiffs(m *meta.Meta, usedVersion, newVersion int64 if err != nil { return false, nil, err } + if canSkipSchemaCheckerDDL(diff.Type) { + continue + } tblIDs = append(tblIDs, ids...) } builder.Build() return true, tblIDs, nil } +func canSkipSchemaCheckerDDL(tp model.ActionType) bool { + switch tp { + case model.ActionUpdateTiFlashReplicaStatus, model.ActionSetTiFlashReplica: + return true + } + return false +} + // InfoSchema gets information schema from domain. func (do *Domain) InfoSchema() infoschema.InfoSchema { return do.infoHandle.Get() diff --git a/store/mockstore/mocktikv/cluster.go b/store/mockstore/mocktikv/cluster.go index 672e88f14bb28..f941e749145f0 100644 --- a/store/mockstore/mocktikv/cluster.go +++ b/store/mockstore/mocktikv/cluster.go @@ -371,13 +371,15 @@ func (c *Cluster) Split(regionID, newRegionID uint64, key []byte, peerIDs []uint } // SplitRaw splits a Region at the key (not encoded) and creates new Region. -func (c *Cluster) SplitRaw(regionID, newRegionID uint64, rawKey []byte, peerIDs []uint64, leaderPeerID uint64) *Region { +func (c *Cluster) SplitRaw(regionID, newRegionID uint64, rawKey []byte, peerIDs []uint64, leaderPeerID uint64) *metapb.Region { c.Lock() defer c.Unlock() newRegion := c.regions[regionID].split(newRegionID, rawKey, peerIDs, leaderPeerID) c.regions[newRegionID] = newRegion - return newRegion + // The mocktikv should return a deep copy of meta info to avoid data race + meta := proto.Clone(newRegion.Meta) + return meta.(*metapb.Region) } // Merge merges 2 regions, their key ranges should be adjacent. diff --git a/store/mockstore/mocktikv/rpc.go b/store/mockstore/mocktikv/rpc.go index 32dff89fd0427..09e3c6b8d057f 100755 --- a/store/mockstore/mocktikv/rpc.go +++ b/store/mockstore/mocktikv/rpc.go @@ -624,9 +624,7 @@ func (h *rpcHandler) handleSplitRegion(req *kvrpcpb.SplitRegionRequest) *kvrpcpb } newRegionID, newPeerIDs := h.cluster.AllocID(), h.cluster.AllocIDs(len(region.Peers)) newRegion := h.cluster.SplitRaw(region.GetId(), newRegionID, k, newPeerIDs, newPeerIDs[0]) - // The mocktikv should return a deep copy of meta info to avoid data race - metaCloned := proto.Clone(newRegion.Meta) - resp.Regions = append(resp.Regions, metaCloned.(*metapb.Region)) + resp.Regions = append(resp.Regions, newRegion) } return resp }