-
Notifications
You must be signed in to change notification settings - Fork 75
Replace cursor RowLock with FOR SHARE NOWAIT #386
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 |
|---|---|---|
|
|
@@ -3,8 +3,10 @@ package ghostferry | |
| import ( | ||
| sqlorig "database/sql" | ||
| "fmt" | ||
| sql "github.com/Shopify/ghostferry/sqlwrapper" | ||
| "strings" | ||
| "time" | ||
|
|
||
| sql "github.com/Shopify/ghostferry/sqlwrapper" | ||
|
|
||
| "github.com/Masterminds/squirrel" | ||
| "github.com/go-mysql-org/go-mysql/schema" | ||
|
|
@@ -35,8 +37,8 @@ type CursorConfig struct { | |
| DB *sql.DB | ||
| Throttler Throttler | ||
|
|
||
| ColumnsToSelect []string | ||
| BuildSelect func([]string, *TableSchema, uint64, uint64) (squirrel.SelectBuilder, error) | ||
| ColumnsToSelect []string | ||
| BuildSelect func([]string, *TableSchema, uint64, uint64) (squirrel.SelectBuilder, error) | ||
| // BatchSize is a pointer to the BatchSize in Config.UpdatableConfig which can be independently updated from this code. | ||
| // Having it as a pointer allows the updated value to be read without needing additional code to copy the batch size value into the cursor config for each cursor we create. | ||
| BatchSize *uint64 | ||
|
|
@@ -99,7 +101,7 @@ func (c *Cursor) Each(f func(*RowBatch) error) error { | |
| var batch *RowBatch | ||
| var paginationKeypos uint64 | ||
|
|
||
| err := WithRetries(c.ReadRetries, 0, c.logger, "fetch rows", func() (err error) { | ||
| err := WithRetries(c.ReadRetries, 1*time.Second, c.logger, "fetch rows", func() (err error) { | ||
| if c.Throttler != nil { | ||
| WaitForThrottle(c.Throttler) | ||
| } | ||
|
|
@@ -172,7 +174,15 @@ func (c *Cursor) Fetch(db SqlPreparer) (batch *RowBatch, paginationKeypos uint64 | |
| } | ||
|
|
||
| if c.RowLock { | ||
| selectBuilder = selectBuilder.Suffix("FOR UPDATE") | ||
| mySqlVersion, err := c.DB.QueryMySQLVersion() | ||
|
Member
Author
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. Thought it's best to just ask the DB 🙃 |
||
| if err != nil { | ||
| return nil, 0, err | ||
| } | ||
| if strings.HasPrefix(mySqlVersion, "8.") { | ||
| selectBuilder = selectBuilder.Suffix("FOR SHARE NOWAIT") | ||
| } else { | ||
| selectBuilder = selectBuilder.Suffix("LOCK IN SHARE MODE") | ||
| } | ||
| } | ||
|
|
||
| query, args, err := selectBuilder.ToSql() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ import ( | |
| "fmt" | ||
| "math/rand" | ||
| "sync" | ||
| "time" | ||
|
|
||
| sq "github.com/Masterminds/squirrel" | ||
| sql "github.com/Shopify/ghostferry/sqlwrapper" | ||
|
|
@@ -175,6 +176,8 @@ func (this *MixedActionDataWriter) WriteData(i int) { | |
| if err != nil { | ||
| panic(err) | ||
| } | ||
|
|
||
| time.Sleep(10 * time.Millisecond) | ||
|
Member
Author
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. Added this to make the I'm wondering if this is a signal to consider just a
Contributor
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 mean, we haven't seen problems with ghostferry holding on to locks so far, AFAIK, so it wouldn't be the worst thing to keep doing it. However, if the goal is the minimize production impact than not holding on to locks would be better.
Contributor
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. We could also start with
Member
Author
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. Yep, I agree that Do you have any objections against shipping with
Contributor
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 think it's fine to go with |
||
| } | ||
| } | ||
|
|
||
|
|
||
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.
Implies
60 * 1sretry schedule. I thought it's a reasonable starting point, similarly to howgh-ostdoes it (60 and 1s)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.
And just double-checked that the config is currently @ default in core (
components/shop_mover/app/utils/podding/shop_mover/ghostferry/config.rb)