Skip to content
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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

EtienneBerubeShopify
Copy link
Contributor

@EtienneBerubeShopify EtienneBerubeShopify commented Aug 17, 2021

Added TotalRows and TotalBytes to the /status api for Ghostferry for better time estimations when logging with Splunk.

This included getting the data from the information_schema and adding the data into the StateTracker so that it could be serialized later to be sent via HTTP.

DEBATE (DEPRECATED):
Should it fetch the data even when running from an interrupted state (reading from a serialized state) or should it only query the data when coming from a "clean" run?

Notes:
The Go compiler was complaining about a few things and would not allow me to run any commands before it was happy so I had to fix a few warnings. Here are the files with these "fixes":

  • config.go
  • iterative_verifier.go

@shuhaowu
Copy link
Contributor

This included getting the data from the information_schema and adding the data into the StateTracker so that it could be serialized later to be sent via HTTP.

StateTracker is used only for critical state that is needed to reconstruct Ghostferry after it is interrupted and resumed. Things that can be discovered should not be included in that struct. See the Progress struct.

@EtienneBerubeShopify EtienneBerubeShopify force-pushed the etienne-add-total-bytes-and-total-rows branch 3 times, most recently from d01fc2f to be58a07 Compare August 17, 2021 20:55
@EtienneBerubeShopify EtienneBerubeShopify force-pushed the etienne-add-total-bytes-and-total-rows branch from 3d990fa to 38b631c Compare August 17, 2021 21:41
@EtienneBerubeShopify EtienneBerubeShopify marked this pull request as ready for review August 17, 2021 21:49
@@ -116,7 +116,7 @@ func (c *DatabaseConfig) MySQLConfig() (*mysql.Config, error) {
return nil, fmt.Errorf("failed to build TLS config: %v", err)
}

cfgName := fmt.Sprintf("%s@%s:%s", c.User, c.Host, c.Port)
cfgName := fmt.Sprintf("%s@%s:%d", c.User, c.Host, c.Port)
Copy link
Contributor

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 ?

Copy link
Contributor Author

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

ferry.go Show resolved Hide resolved
@@ -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)}})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also is this change made purposefully ?

Copy link
Contributor Author

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

string(int) creates a rune with the ascii / UTF-8 int code

var totalBytes sqlorig.NullInt64

for rows.Next() {
if err = rows.Scan(&totalRows, &totalBytes); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The 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 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: Paired with Manan

@Manan007224
Copy link
Contributor

DEBATE:
Should it fetch the data even when running from an interrupted state (reading from a serialized state) or should it only query the data when coming from a "clean" run?

IMO fetching the stats via the /status endpoint should have nothing to do with the fact that ghostferry is running from an interrupted or clean run. So the /status should return these stats regardless.

@EtienneBerubeShopify
Copy link
Contributor Author

DEBATE:
Should it fetch the data even when running from an interrupted state (reading from a serialized state) or should it only query the data when coming from a "clean" run?

IMO fetching the stats via the /status endpoint should have nothing to do with the fact that ghostferry is running from an interrupted or clean run. So the /status should return these stats regardless.

This was an artifact from the first way of doing it, wanted to keep it for the documentation, but I guess it just brings more confusion.

totalRowsPerTable, totalBytesPerTable, err := f.GetTotalRowsAndBytesMap()

if err != nil {
f.logger.Error(err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this error occurs, won't line 996 below experience a nil pointer error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't as the maps are already initialized in GetTotalRowsAndBytesMap(). And uninitialized keys return zero values (for uint64 it returns 0). So if the error occurred you'll be getting zeroes for the TotalRows and TotalBytes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants