How does gh-ost guarantee no race between chunk copying & binlog processing
Hi folks,
Thank you all for writing this awesome tool! There's one scenario I don't quite understand. How do we avoid following situation:
- A row in the original table has value (foo, 1).
- A migration run starts: (foo, 1) is read by the chunk copying thread, but before it's written into the ghost table, 3) & 4) happened.
- A user of the table updates the row and changes its value to (bar, 2)
- Binlog of the update is processed, (bar, 2) is not written into the ghost table because of the query condition.
- the execution of 2) is now resumed, and (foo, 1) is written into the ghost table.
The issue of this scenario is that after 5), the row has incorrect value, and it's not fixable by future binlog entries (because it won't match the update query condition)
Best, Zhe
migrating data from origin table to ghost table uses insert-select statement, like this
insert /* gh-ost %s.%s */ ignore into %s.%s (%s)
(select %s from %s.%s force index (%s)
where (%s and %s) lock in share mode
)
the sql is executed atomic.
so no sql is executed between 2-5
Best, Zhanbing
@wangzhanbing Thanks for your reply! But I still have some questions about the ordering.
According to https://github.com/github/gh-ost/blob/8f361f6445c2fe1d830b053e315a70a69d60e73f/go/logic/migrator.go#L1267-L1293, the applyEventsQueue takes precedence over copyRowsQueue, so the update (foo, 2) could actually be processed earlier through the binlog applier, and then the problem will be as described by @wangzhe711.