Skip to content

Commit a44b1bd

Browse files
committed
fix(cdc): skip foreign key tables in scanner
1 parent b3fe1ba commit a44b1bd

3 files changed

Lines changed: 289 additions & 23 deletions

File tree

pkg/cdc/sql_builder.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -248,19 +248,20 @@ const (
248248
"table_name = '%s'"
249249

250250
CDCCollectTableInfoSqlTemplate = "SELECT " +
251-
" rel_id, " +
252-
" relname, " +
253-
" reldatabase_id, " +
254-
" reldatabase, " +
255-
" rel_createsql, " +
256-
" account_id " +
257-
"FROM `mo_catalog`.`mo_tables` " +
251+
" tbl.rel_id, " +
252+
" tbl.relname, " +
253+
" tbl.reldatabase_id, " +
254+
" tbl.reldatabase, " +
255+
" tbl.rel_createsql, " +
256+
" tbl.account_id, " +
257+
" tbl.constraint " +
258+
"FROM `mo_catalog`.`mo_tables` tbl " +
258259
"WHERE " +
259-
" account_id IN (%s) " +
260+
" tbl.account_id IN (%s) " +
260261
"%s" +
261262
"%s" +
262-
" AND relkind = '%s' " +
263-
" AND reldatabase NOT IN (%s)"
263+
" AND tbl.relkind = '%s' " +
264+
" AND tbl.reldatabase NOT IN (%s)"
264265
CDCInsertMOISCPLogSqlTemplate = `REPLACE INTO mo_catalog.mo_iscp_log (` +
265266
`account_id,` +
266267
`table_id,` +
@@ -475,6 +476,7 @@ var CDCSQLTemplates = [CDCSqlTemplateCount]struct {
475476
"reldatabase",
476477
"rel_createsql",
477478
"account_id",
479+
"constraint",
478480
},
479481
},
480482
CDCGetWatermarkWhereSqlTemplate_Idx: {
@@ -1071,13 +1073,13 @@ func (b cdcSQLBuilder) CollectTableInfoSQL(accountIDs string, dbNames string, ta
10711073
if dbNames == "*" {
10721074
return ""
10731075
}
1074-
return " AND reldatabase IN (" + dbNames + ") "
1076+
return " AND tbl.reldatabase IN (" + dbNames + ") "
10751077
}(),
10761078
func() string {
10771079
if tableNames == "*" {
10781080
return ""
10791081
}
1080-
return " AND relname IN (" + tableNames + ") "
1082+
return " AND tbl.relname IN (" + tableNames + ") "
10811083
}(),
10821084
catalog.SystemOrdinaryRel,
10831085
AddSingleQuotesJoin(catalog.SystemDatabases),

pkg/cdc/table_scanner.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"fmt"
2020
"runtime/debug"
2121
"slices"
22-
"strings"
2322
"sync"
2423
"sync/atomic"
2524
"time"
@@ -37,6 +36,7 @@ import (
3736
"github.com/matrixorigin/matrixone/pkg/defines"
3837
"github.com/matrixorigin/matrixone/pkg/logutil"
3938
"github.com/matrixorigin/matrixone/pkg/util/executor"
39+
"github.com/matrixorigin/matrixone/pkg/vm/engine"
4040
)
4141

4242
const (
@@ -752,9 +752,20 @@ func (s *TableDetector) scanTable() error {
752752
dbName := cols[3].GetStringAt(i)
753753
createSql := cols[4].GetStringAt(i)
754754
accountId := vector.MustFixedColWithTypeCheck[uint32](cols[5])[i]
755+
hasForeignKey, err := tableHasForeignKeyConstraint(cols[6].GetBytesAt(i))
756+
if err != nil {
757+
logutil.Warn(
758+
"cdc.table_detector.scan_constraint_failed",
759+
zap.Uint32("account-id", accountId),
760+
zap.String("db", dbName),
761+
zap.String("table", tblName),
762+
zap.Error(err),
763+
)
764+
return false
765+
}
755766

756767
// skip table with foreign key
757-
if strings.Contains(strings.ToLower("createSql"), "foreign key") {
768+
if hasForeignKey {
758769
continue
759770
}
760771

@@ -787,10 +798,36 @@ func (s *TableDetector) scanTable() error {
787798
}
788799
return true
789800
})
801+
if err != nil {
802+
return err
803+
}
790804

791805
// replace the old table map
792806
s.mu.Lock()
793807
s.Mp = mp
794808
s.mu.Unlock()
795809
return nil
796810
}
811+
812+
func tableHasForeignKeyConstraint(data []byte) (hasForeignKey bool, err error) {
813+
if len(data) == 0 {
814+
return false, nil
815+
}
816+
817+
defer func() {
818+
if r := recover(); r != nil {
819+
err = moerr.NewInternalErrorNoCtxf("unmarshal table constraint failed: %v", r)
820+
}
821+
}()
822+
823+
constraintDef := &engine.ConstraintDef{}
824+
if err := constraintDef.UnmarshalBinary(data); err != nil {
825+
return false, err
826+
}
827+
for _, constraint := range constraintDef.Cts {
828+
if foreignKeyDef, ok := constraint.(*engine.ForeignKeyDef); ok && len(foreignKeyDef.Fkeys) > 0 {
829+
return true, nil
830+
}
831+
}
832+
return false, nil
833+
}

0 commit comments

Comments
 (0)