Skip to content

Commit e43a231

Browse files
author
ffffwh
committed
api: save dump progress on consul
extractor: send dump entry to applier anyway for row numbers
1 parent 1906d6e commit e43a231

File tree

4 files changed

+91
-54
lines changed

4 files changed

+91
-54
lines changed

api/handler/v2/job.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ func getTaskProgress(logger g.LoggerType, header http.Header, taskLogs []models.
754754
return nil, 0, ""
755755
}
756756

757-
execRowCount, totalRowCount, err := storeManager.GetFullProgress(jobId)
757+
execRowCount, totalRowCount, err := storeManager.GetDumpProgress(jobId)
758758
progress := &models.DumpProgress{
759759
ExecRowCount: execRowCount,
760760
TotalRowCount: totalRowCount,

driver/common/store.go

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -621,12 +621,6 @@ func (sm *StoreManager) WatchTree(dir string, stopCh <-chan struct{}) (<-chan []
621621
return sm.consulStore.WatchTree(dir, stopCh)
622622
}
623623

624-
// return: ExecRowCount, TotalRowCount
625-
func (sm *StoreManager) GetFullProgress(jobName string) (int64, int64, error) {
626-
// TODO
627-
return 42, 42, nil
628-
}
629-
630624
func (sm *StoreManager) PutJobStage(jobName string, stage string) error {
631625
key := fmt.Sprintf("dtle/%v/JobStage", jobName)
632626
return sm.consulStore.Put(key, []byte(stage), nil)
@@ -644,6 +638,37 @@ func (sm *StoreManager) GetJobStage(jobName string) (string, error) {
644638
return string(kv.Value), nil
645639
}
646640

641+
func (sm *StoreManager) PutDumpProgress(jobName string, exec int64, total int64) error {
642+
key := fmt.Sprintf("dtle/%v/DumpProgress", jobName)
643+
bs, err := json.Marshal([]int64{exec, total})
644+
if err != nil {
645+
return err
646+
}
647+
return sm.consulStore.Put(key, bs, nil)
648+
}
649+
650+
// return: ExecRowCount, TotalRowCount
651+
func (sm *StoreManager) GetDumpProgress(jobName string) (int64, int64, error) {
652+
key := fmt.Sprintf("dtle/%v/DumpProgress", jobName)
653+
kv, err:= sm.consulStore.Get(key)
654+
if err == store.ErrKeyNotFound {
655+
return 0, 0, nil
656+
} else if err != nil {
657+
return 0, 0, err
658+
}
659+
660+
var r []int64
661+
err = json.Unmarshal(kv.Value, &r)
662+
if err != nil {
663+
return 0, 0, err
664+
}
665+
if len(r) != 2 {
666+
return 0, 0, fmt.Errorf("unexpected len for %v. found %v", key, len(r))
667+
}
668+
669+
return r[0], r[1], nil
670+
}
671+
647672
// consul store item
648673

649674
func NewDefaultRole(tenant string) *Role {

driver/mysql/applier.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ func (a *Applier) Run() {
377377
}
378378
a.ai.OnError = a.onError
379379

380+
go a.updateDumpProgressLoop()
380381
if sourceType == "mysql" {
381382
go a.updateGtidLoop()
382383
}
@@ -1187,3 +1188,23 @@ func (a *Applier) enableForeignKeyChecks() error {
11871188
}
11881189
return nil
11891190
}
1191+
1192+
func (a *Applier) updateDumpProgressLoop() {
1193+
var err error
1194+
interval := 10
1195+
a.logger.Debug("updateDumpProgressLoop", "interval", interval)
1196+
1197+
for {
1198+
if a.shutdown {
1199+
return
1200+
}
1201+
1202+
err = a.storeManager.PutDumpProgress(a.subject, a.TotalRowsReplayed, a.mysqlContext.RowsEstimate)
1203+
if err != nil {
1204+
a.onError(common.TaskStateDead, err)
1205+
return
1206+
}
1207+
1208+
time.Sleep(time.Duration(interval) * time.Second)
1209+
}
1210+
}

driver/mysql/extractor.go

Lines changed: 38 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,51 +1303,48 @@ func (e *Extractor) mysqlDump() (retErr error) {
13031303

13041304
e.gotCoordinateCh <- struct{}{}
13051305

1306-
// Transform the current schema so that it reflects the *current* state of the MySQL server's contents.
1307-
// First, get the DROP TABLE and CREATE TABLE statement (with keys and constraint definitions) for our tables ...
1308-
if !e.mysqlContext.SkipCreateDbTable {
1309-
e.logger.Info("generating DROP and CREATE statements to reflect current database schemas",
1310-
"replicateDoDb", e.replicateDoDb)
1311-
1312-
for _, db := range e.replicateDoDb {
1313-
var dbSQL string
1314-
if strings.ToLower(db.TableSchema) != "mysql" {
1315-
if db.TableSchemaRename != "" {
1316-
dbSQL, err = base.RenameCreateSchemaAddINE(db.CreateSchemaString, db.TableSchemaRename)
1317-
if err != nil {
1318-
return errors.Wrap(err, "RenameCreateSchemaAddINE")
1319-
}
1320-
} else {
1321-
dbSQL = db.CreateSchemaString
1306+
// Go through all tables to get DDL and row numbers.
1307+
for _, db := range e.replicateDoDb {
1308+
if strings.ToLower(db.TableSchema) == "mysql" {
1309+
continue
1310+
}
1311+
1312+
// Create the schema.
1313+
entry := &common.DumpEntry{}
1314+
if !e.mysqlContext.SkipCreateDbTable {
1315+
if db.TableSchemaRename != "" {
1316+
entry.DbSQL, err = base.RenameCreateSchemaAddINE(db.CreateSchemaString, db.TableSchemaRename)
1317+
if err != nil {
1318+
return errors.Wrap(err, "RenameCreateSchemaAddINE")
13221319
}
1320+
} else {
1321+
entry.DbSQL = db.CreateSchemaString
1322+
}
1323+
}
1324+
if err := e.encodeAndSendDumpEntry(entry); err != nil {
1325+
return errors.Wrap(err, "encodeAndSendDumpEntry. create schema entry")
1326+
}
13231327

1328+
// Create the tables.
1329+
for _, tbCtx := range db.TableMap {
1330+
tb := tbCtx.Table
1331+
tb.Counter, err = e.CountTableRows(tb)
1332+
if err != nil {
1333+
return errors.Wrapf(err, "CountTableRows %v.%v", tb.TableSchema, tb.TableName)
13241334
}
1335+
e.logger.Info("count table", "schema", db.TableSchema, "table", tb.TableName, "rows", tb.Counter)
1336+
13251337
entry := &common.DumpEntry{
1326-
DbSQL: dbSQL,
1327-
}
1328-
atomic.AddInt64(&e.mysqlContext.RowsEstimate, 1)
1329-
atomic.AddInt64(&e.TotalRowsCopied, 1)
1330-
if err := e.encodeAndSendDumpEntry(entry); err != nil {
1331-
return errors.Wrap(err, "encodeAndSendDumpEntry. create schema entry")
1338+
TbSQL: []string{},
1339+
TotalCount: tb.Counter,
13321340
}
1333-
1334-
for _, tbCtx := range db.TableMap {
1335-
tb := tbCtx.Table
1336-
if tb.TableSchema != db.TableSchema {
1337-
continue
1338-
}
1339-
total, err := e.CountTableRows(tb)
1340-
if err != nil {
1341-
return errors.Wrapf(err, "CountTableRows %v.%v", tb.TableSchema, tb.TableName)
1342-
}
1343-
tb.Counter = total
1344-
var tbSQL []string
1341+
if !e.mysqlContext.SkipCreateDbTable {
13451342
if strings.ToLower(tb.TableType) == "view" {
13461343
/*tbSQL, err = base.ShowCreateView(e.singletonDB, tb.TableSchema, tb.TableName, e.mysqlContext.DropTableIfExists)
13471344
if err != nil {
13481345
return err
13491346
}*/
1350-
} else if strings.ToLower(tb.TableSchema) != "mysql" {
1347+
} else {
13511348
ctStmt, err := base.ShowCreateTable(e.singletonDB, tb.TableSchema, tb.TableName)
13521349
if err != nil {
13531350
return err
@@ -1362,23 +1359,17 @@ func (e *Extractor) mysqlDump() (retErr error) {
13621359
}
13631360

13641361
if e.mysqlContext.DropTableIfExists {
1365-
tbSQL = append(tbSQL, fmt.Sprintf("DROP TABLE IF EXISTS %s.%s",
1362+
entry.TbSQL = append(entry.TbSQL, fmt.Sprintf("DROP TABLE IF EXISTS %s.%s",
13661363
mysqlconfig.EscapeName(targetSchema), mysqlconfig.EscapeName(targetTable)))
13671364
}
1368-
tbSQL = append(tbSQL, ctStmt)
1369-
}
1370-
entry := &common.DumpEntry{
1371-
TbSQL: tbSQL,
1372-
TotalCount: tb.Counter,
1373-
}
1374-
atomic.AddInt64(&e.mysqlContext.RowsEstimate, 1)
1375-
atomic.AddInt64(&e.TotalRowsCopied, 1)
1376-
if err := e.encodeAndSendDumpEntry(entry); err != nil {
1377-
return errors.Wrap(err, "encodeAndSendDumpEntry. create table")
1365+
entry.TbSQL = append(entry.TbSQL, ctStmt)
13781366
}
13791367
}
1380-
e.tableCount += len(db.TableMap)
1368+
if err := e.encodeAndSendDumpEntry(entry); err != nil {
1369+
return errors.Wrap(err, "encodeAndSendDumpEntry. create table")
1370+
}
13811371
}
1372+
e.tableCount += len(db.TableMap)
13821373
}
13831374
step++
13841375

0 commit comments

Comments
 (0)