Bug #88891 | Filtered replication leaves GTID holes with create database if not exists | ||
---|---|---|---|
Submitted: | 13 Dec 2017 6:50 | Modified: | 26 Apr 2018 14:38 |
Reporter: | Simon Mudd (OCA) | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Replication | Severity: | S3 (Non-critical) |
Version: | 5.7.19/20 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | filtering, GTID, holes, replication |
[13 Dec 2017 6:50]
Simon Mudd
[22 Dec 2017 10:45]
MySQL Verification Team
Hi Simon, I can verify that this is how it behaves, I can't say for sure if it's a bug or not. It behaves the way I expect it to behave but maybe my mind is corrupted that way. Also, in order to preserve gtid's if you filter some out there has to be a hole don't you agree? Filtering server could rearrange them but then the gtids would change between boxes and I'm sure there are cases where that would be a problem. Anyhow I'm setting this to "verified" and will let GR engineers decide :) thanks for the report Bogdan
[24 Dec 2017 8:48]
Simon Mudd
I must admit that I would first have expected, if using filtered replication, to get a large number of gaps representing the transactions which were NOT processed (the filtered ones). The problem with this is that for many filter type operations that will leave a GTID_EXECUTED set with a huge size, a large number of holes and I'd expect that if I ran such a setup for months or years MySQL would eventually break if it couldn't actually store the huge GTID_EXECUTED set in memory. Checking for each transaction prior to executing it would likely be very slow too. This behaviour is not explicitly documented. (or not as clearly as I'd expect). So I'm assuming that to avoid these troubles the behaviour has been modified to replace the transaction upstream of the filter with an empty transaction downstream of the filter. That is the GTID_EXECUTED remains the _same_ even though the actual transaction has not been applied. What's been applied is a _filtered_ (empty) transaction. This behaviour matches what is currently seen. * the rewrite rules I show earlier correctly filter the statements for the specific tables I wanted to keep data for. That worked fine. The upstream server had more databases and more tables and all transactions relating to those other tables seemed to be filtered out, though clearly I saw that the GTID_EXECUTED value on the downstream slaves was unchanged from upstream. This behaviour works fine. * it also works fine if you do 'CREATE TABLE IF NOT EXISTS for a table that's in one of the filtered databases but not the one of the requested tables to be passed through. * what does not work is the CREATE DATABASE IF NOT EXISTS of the database that's being filtered. This statement is _ignored_ and the GTID value of the statement is not added with an empty event to the downstream server. Feel free to contact the replication developers on this. I'd be delighted to understand their thinking but I think in this case it's a statement type that they've missed. I do have, if I make a bit of effort, ways to talk to the devs directly but it struck me for something like this that the bug report was the correct way to report the issue I saw. Personally I think the filtering with empty transactions should possibly have a couple of extra things attached: * a counter of how many of this type of event are actually filtered as "empty events" * maybe this behaviour should be optional, if it is it should be good to explain the limitations that this will provoke due to the GTID implementation in MySQL * more documentation on the filtering and the limitations would be good. Clearly this is a complex topic and the filtering was designed long before MySQL had GTID so many of the concepts make sense outside of the GTID environment and are harder to apply when GTID is enabled. * I suspect that the issues described here are due to lack of "in the field" experience. With any complex bit of software like MySQL sometimes it gets used (often for quite valid reasons) in ways the original developers never anticipated. I think it's hard if you're a developer and don't get "in field experience" to understand some of these edge cases, yet for those of us out here we have problems to solve and use the tooling provided, or ask for such tooling. This seems to be something that goes along those lines. So any feedback on this would be good.
[25 Dec 2017 10:22]
MySQL Verification Team
Hi Simon, Of course you can :D talk directly to the devs :) now as for the bug reported, as I already verified it the devs are informed and will decide if/how they will proceed. We also know how to contact you directly if need be so that's covered too. take care, happy holidays Bogdan
[26 Apr 2018 14:38]
Margaret Fisher
Posted by developer: Thanks for the report. Changelog entry added for MySQL 8.0.12, 5.7.23, and 5.6.41: When GTIDs are in use for replication, replicated transactions that are filtered out on the slave are persisted. If binary logging is enabled on the slave, the filtered-out transaction is written to the binary log as a Gtid_log_event followed by an empty transaction containing only BEGIN and COMMIT statements. If binary logging is disabled, the GTID of the filtered-out transaction is written to the mysql.gtid_executed table. This process ensures that there are no gaps in the set of executed GTIDs, and that the filtered-out transactions are not retrieved again if the slave reconnects to the master. Previously, this process was not done for CREATE DATABASE, ALTER DATABASE, and DROP DATABASE statements, but it is now carried out for those statements as well as for others. - The GTIDs documentation for MySQL 8.0 was recently updated to cover this area better. Please see https://dev.mysql.com/doc/refman/8.0/en/replication-gtids.html and the first three subtopics.
[31 May 2018 7:01]
MySQL Verification Team
Bug #91086 marked as duplicate of this one.