-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added TotalRows and TotalBytes to the /status
api for Ghostferry
#303
base: main
Are you sure you want to change the base?
Changes from 4 commits
8722226
8061908
38b631c
b6b1ec9
dc51be9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ package ghostferry | |
|
||
import ( | ||
"context" | ||
sqlorig "database/sql" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
|
@@ -963,6 +964,7 @@ func (f *Ferry) Progress() *Progress { | |
} | ||
|
||
tables := f.Tables.AsSlice() | ||
totalRowsPerTable, totalBytesPerTable := f.GetTotalRowsAndBytesMap() | ||
|
||
for _, table := range tables { | ||
var currentAction string | ||
|
@@ -987,6 +989,8 @@ func (f *Ferry) Progress() *Progress { | |
BatchSize: f.DataIterator.CursorConfig.GetBatchSize(table.Schema, table.Name), | ||
RowsWritten: rowWrittenStats.NumRows, | ||
BytesWritten: rowWrittenStats.NumBytes, | ||
TotalBytes: totalBytesPerTable[tableName], | ||
TotalRows: totalRowsPerTable[tableName], | ||
} | ||
} | ||
|
||
|
@@ -1158,3 +1162,49 @@ func (f *Ferry) checkSourceForeignKeyConstraints() error { | |
|
||
return nil | ||
} | ||
|
||
func (f *Ferry) GetTotalRowsAndBytesMap() (totalRowsPerTable map[string]uint64, totalBytesPerTable map[string]uint64) { | ||
totalRowsPerTable = make(map[string]uint64) | ||
totalBytesPerTable = make(map[string]uint64) | ||
|
||
for _, table := range f.Tables { | ||
query := fmt.Sprintf(` | ||
SELECT table_rows, data_length | ||
FROM information_schema.tables | ||
WHERE table_schema='%s' | ||
AND table_name='%s' | ||
`, | ||
table.Schema, | ||
table.Name, | ||
) | ||
|
||
rows, err := f.SourceDB.Query(query) | ||
if err != nil { | ||
return | ||
} | ||
defer rows.Close() | ||
|
||
var totalRows sqlorig.NullInt64 | ||
var totalBytes sqlorig.NullInt64 | ||
|
||
EtienneBerubeShopify marked this conversation as resolved.
Show resolved
Hide resolved
|
||
for rows.Next() { | ||
if err = rows.Scan(&totalRows, &totalBytes); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason why you're not returning the error from here and making the stat values as 0 ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about what should happen when either a connection fails or there is an error with the row scanning, and in all cases, I don't want to stop the execution to report an error for one row. Even a level above, the only way of dealing with this would be to set it to zero regardless. The result could also be omitted, and the value in the map would still be zero. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Errors happened while scanning would have nothing to do with issues in connection. Although I get your reasoning on why you're not returning from the error, but just for the sake of consistency with codebase we should return the errors. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update: Paired with Manan |
||
totalRowsPerTable[table.String()] = 0 | ||
totalBytesPerTable[table.String()] = 0 | ||
continue | ||
} | ||
if totalRows.Valid { | ||
totalRowsPerTable[table.String()] = uint64(totalRows.Int64) | ||
} else { | ||
totalRowsPerTable[table.String()] = 0 | ||
} | ||
|
||
if totalBytes.Valid { | ||
totalBytesPerTable[table.String()] = uint64(totalBytes.Int64) | ||
} else { | ||
totalBytesPerTable[table.String()] = 0 | ||
} | ||
} | ||
} | ||
return totalRowsPerTable, totalBytesPerTable | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -337,7 +337,7 @@ func (v *IterativeVerifier) reverifyUntilStoreIsSmallEnough(maxIterations int) e | |
before := v.reverifyStore.RowCount | ||
start := time.Now() | ||
|
||
_, err := v.verifyStore("reverification_before_cutover", []MetricTag{{"iteration", string(iteration)}}) | ||
_, err := v.verifyStore("reverification_before_cutover", []MetricTag{{"iteration", fmt.Sprint(iteration)}}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also is this change made purposefully ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the compiler was complaining and wouldnt compile until this was fixed string(int) creates a rune with the ascii / UTF-8 int code |
||
if err != nil { | ||
return err | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this change made purposefully ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the compiler was complaining and wouldnt compile until this was fixed