-
Notifications
You must be signed in to change notification settings - Fork 95
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
Resume issue with big row events #85
Comments
Let's imagine there a big transaction in database (e.g. large INSERT affected 10kk rows). Then you will receive multiple ROW_EVENT with inserted rows (one or more, depends on binlog_row_event_max_size, If I remember correctly) If your script fails in the middle of the processing row event, then, when you start from such position you will not have TABLE_MAP event and will have no structure for the table - php-mysql-replication will just skip such events untill it gets new TABLE_MAP. There is no possibility to ask master for TABLE_MAP in the middle of event. |
Hello there,
We have a running application which:
MySQLReplication\Event\DTO\RowsDTO
events (inserts, updates, deletes)RowsDTO::getValues()
to process themforeach ($rows->getValues())
, stores the binlog position of the event:$event->getEventInfo()->getBinLogCurrent()->getBinFileName() / $event->getEventInfo()->getBinLogCurrent()->getBinLogPosition()
.When the app starts, it starts from the previously stored filename / position.
In most of the times, this works well. However, we found a typical case when it doesn't.
Consider you have an INSERT containing several thousands rows (i.e.
INSERT INTO [table] SELECT * FROM [some_other_table]
). As opposed to what we expected, this doesn't fire a singleRowsDTO
event with a hugegetValues()
array, but severalRowsDTO
events with just a few dozens items ingetValues()
in each.We didn't understood why, until we discovered the
binlog_row_event_max_size
option on the replica server, but that's not the point.To reproduce:
RowsDTO::getValues()
eventExpected Result:
RowsDTO
events.Actual Result:
RowsDTO
events of that INSERT query are simply dismissed and apps resumes to the next query in the binlog.The only solution we have right now is to pray that the application is not shut down (or doesn't crash) while processing that kind of big statements. We could increase
binlog_row_event_max_size
on the replica server but this won't guaranteeRowsDTO
won't be split and OTOH having a huge array inRowsDTO::getValues()
might lead to memory issues.As a quick fix, we now temporarily store filename / position on
QueryDTO
that are fired before and after theRowsDTO
events, so that if not allRowsDTO
can be processed, they can be replayed with the former position (00001 in our example). This leads to duplicate processing, but we prefer this instead of missing events.Thank you,
Ben
The text was updated successfully, but these errors were encountered: