-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Tablet Manager: Make WaitForPosition() accept either file:pos or GTID-based positions. #6374
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
Changes from all commits
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 |
|---|---|---|
|
|
@@ -204,32 +204,58 @@ func (mysqld *Mysqld) WaitMasterPos(ctx context.Context, targetPos mysql.Positio | |
| } | ||
| defer conn.Recycle() | ||
|
|
||
| // If we are the master, WaitUntilPositionCommand will fail. | ||
| // But position is most likely reached. So, check the position | ||
| // first. | ||
| mpos, err := conn.MasterPosition() | ||
| if err != nil { | ||
| return fmt.Errorf("WaitMasterPos: MasterPosition failed: %v", err) | ||
| } | ||
| if mpos.AtLeast(targetPos) { | ||
| return nil | ||
| } | ||
| // First check if filePos flavored Position was passed in. If so, we can't defer to the flavor in the connection, | ||
| // unless that flavor is also filePos. | ||
| waitCommandName := "WaitUntilPositionCommand" | ||
| var query string | ||
| if targetPos.MatchesFlavor(mysql.FilePosFlavorID) { | ||
| // If we are the master, WaitUntilFilePositionCommand will fail. | ||
| // But position is most likely reached. So, check the position | ||
| // first. | ||
| mpos, err := conn.MasterFilePosition() | ||
| if err != nil { | ||
| return fmt.Errorf("WaitMasterPos: MasterFilePosition failed: %v", err) | ||
| } | ||
| if mpos.AtLeast(targetPos) { | ||
| return nil | ||
| } | ||
|
|
||
| // Find the query to run, run it. | ||
| query, err := conn.WaitUntilPositionCommand(ctx, targetPos) | ||
| if err != nil { | ||
| return err | ||
| // Find the query to run, run it. | ||
| query, err = conn.WaitUntilFilePositionCommand(ctx, targetPos) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
||
| waitCommandName = "WaitUntilFilePositionCommand" | ||
| } else { | ||
| // If we are the master, WaitUntilPositionCommand will fail. | ||
| // But position is most likely reached. So, check the position | ||
| // first. | ||
| mpos, err := conn.MasterPosition() | ||
| if err != nil { | ||
| return fmt.Errorf("WaitMasterPos: MasterPosition failed: %v", err) | ||
| } | ||
| if mpos.AtLeast(targetPos) { | ||
| return nil | ||
| } | ||
|
|
||
| // Find the query to run, run it. | ||
| query, err = conn.WaitUntilPositionCommand(ctx, targetPos) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| } | ||
|
|
||
| qr, err := mysqld.FetchSuperQuery(ctx, query) | ||
| if err != nil { | ||
| return fmt.Errorf("WaitUntilPositionCommand(%v) failed: %v", query, err) | ||
| return fmt.Errorf("%v(%v) failed: %v", waitCommandName, query, err) | ||
| } | ||
|
|
||
| if len(qr.Rows) != 1 || len(qr.Rows[0]) != 1 { | ||
| return fmt.Errorf("unexpected result format from WaitUntilPositionCommand(%v): %#v", query, qr) | ||
| return fmt.Errorf("unexpected result format from %v(%v): %#v", waitCommandName, query, qr) | ||
| } | ||
| result := qr.Rows[0][0] | ||
| if result.IsNull() { | ||
| return fmt.Errorf("WaitUntilPositionCommand(%v) failed: replication is probably stopped", query) | ||
| return fmt.Errorf("%v(%v) failed: replication is probably stopped", waitCommandName, query) | ||
| } | ||
| if result.ToString() == "-1" { | ||
| return fmt.Errorf("timed out waiting for position %v", targetPos) | ||
|
|
||
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.
Merely a coding style comment, feel free to ignore. What I usually do is:
it's the caller's responsibility to check if
err != niland if so, to ignore theGTIDSetvalue.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.
I followed the pattern established in the rest of the codebase but you bring up a good point. I'm somewhat split on this. I agree with you that it's the caller's responsibility to check if
err != nilbut I'm also used to writing in languages where if a result is errorful, it's not even possible to access the successful result.In this case though if err is not nil, then gtidSet would be nil anyway, so I think your version would actually return the same result with less code - and I like that. I suppose it's a question of how others feel regarding established patterns that already exist in the Vitess codebase, and if we should follow those patterns or break them when it's sensible? @enisoc @deepthi @systay @sougou?
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.
I prefer the less compact version because it is easier to read.