[MDEV-17863] DROP TEMPORARY TABLE creates a transaction in binary log on read only server Created: 2018-11-28 Updated: 2020-02-11 Resolved: 2019-10-20 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Replication |
| Affects Version/s: | 10.2, 10.3 |
| Fix Version/s: | 10.3.19, 10.4.9 |
| Type: | Bug | Priority: | Critical |
| Reporter: | Muhammad Irfan | Assignee: | Michael Widenius |
| Resolution: | Fixed | Votes: | 1 |
| Labels: | upstream-fix | ||
| Issue Links: |
|
||||||||||||||||||||||||
| Description |
|
If "DROP TEMPORARY TABLE..." gets executed on server with GTID enabled and read_only mode enabled, then 'DROP /* TEMPORARY */ TABLE IF EXISTS `sometablename`' gets inserted in server binary log. This creates errant extra transaction on slave and breaks replication.
Upstream https://bugs.mysql.com/bug.php?id=85258 |
| Comments |
| Comment by Elena Stepanova [ 2018-11-28 ] | |||||||||||||||||||||||||||||||||||||||||
|
According to the last comment on the upstream bug, the bugfix is not quite about the same. It only fixes the situation when the table (temporary table in this case) does not exist. In your case, it does. As I remember, temporary tables are a painful subject in regard to binary logging format, and it's not as simple at all as "just don't write it in the RBR". The binary logging format might change dynamically (and even automatically), so it's entirely possible that at the time when the table was created, it was SBR and thus the statement was written. I'll leave it to Elkin to handle it further. | |||||||||||||||||||||||||||||||||||||||||
| Comment by Muhammad Irfan [ 2018-11-28 ] | |||||||||||||||||||||||||||||||||||||||||
|
elenst It creates errant transaction regardless temporary table exists or not.
| |||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2018-11-28 ] | |||||||||||||||||||||||||||||||||||||||||
Yes, I know. My point is, even if we use the upstream fix, it won't solve the problem you are describing. And I don't think with the current implementation it is possible just not to write DROP for temporary tables as you suggested. Maybe Elkin will think of a different solution. | |||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2019-01-17 ] | |||||||||||||||||||||||||||||||||||||||||
|
> valerii: it should be as simple as "no new GTID written to the binary log on slave, ever" Right. But at the same time we need to pay attention to The two goals may actually clash as #23911 witnesses. A. B. If this one does not suffice (to the customer / MXS ) we can go with C. Now I need serg to assess especially B, C one of the two I think we should pick out. The support alerts our action. | |||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2019-01-28 ] | |||||||||||||||||||||||||||||||||||||||||
|
There's also D. mark temporary tables created or dropped during read-only. And if later, read-only was turned off, they're needed for replication, switch to row-based (in mixed) or error out (in statement). It'll avoid logging a lot of (almost always useless) events in THD binlog cache (as in C) and won't require any user actions (as in B). | |||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2019-02-01 ] | |||||||||||||||||||||||||||||||||||||||||
|
serg, I like D. idea. Indeed we can refine logging rules for table drop/create at read-only. A question comes anyway to pre (set ro=1) existing temp tables. | |||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2019-02-01 ] | |||||||||||||||||||||||||||||||||||||||||
|
Sergei, could you please follow my latest refinement for D. Thanks, Andrei. | |||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2019-02-05 ] | |||||||||||||||||||||||||||||||||||||||||
|
Elkin, yes to handle tables created before but dropped during read-only, I would suggest not to drop them | |||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2019-02-05 ] | |||||||||||||||||||||||||||||||||||||||||
|
A much simpler fix would be to remember per THD whether it has created or dropped temporary tables during read-only, and refuse to change binlog format away from ROW. This will practically work for most of the users. And it will help to avoid implementing a fairly complex solution for a use case that nobody has. | |||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2019-03-20 ] | |||||||||||||||||||||||||||||||||||||||||
|
The requested change in read-only mode binlogging is motivated by a user running into
being logged into the binary log of the slave apparently by the Executive summary: However along discussion we've came across a related issue of how to At time of @@global.read_only = ON
is allowed only when @@session.binlog_format= ROW or MIXED. Otherwise
is allowed always and it's not binlogged regardless whether it was OTHER binloggable DML and DDL operation on the temp table Summary: Effectively no temporary table replication event gets created in | |||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2019-03-20 ] | |||||||||||||||||||||||||||||||||||||||||
|
serg, could you please run through a summary of proposed changes. Also notice the most probable immediate issue that the user faced which stands somewhat separately from the read-only policy we have been discussing. Thank you for your time! Andrei | |||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2019-03-25 ] | |||||||||||||||||||||||||||||||||||||||||
|
I suggested a simpler fix above:
Practically, it's done by remembering just one flag per THD: temp_tables_existed_when_read_only_was_enabled When read_only is disabled in a connection and this flag was set or a temporary table exists, then forever (until disconnect) log everything done in this connection using RBR. This solves all practical cases with minimal run-time overhead and without tracking per table when it was created. As a drawback, it will force RBR more than strictly necessary in some corner cases. | |||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2019-03-26 ] | |||||||||||||||||||||||||||||||||||||||||
|
serg, When read_only is disabled in a connection and this flag was set or a temporary table exists, then forever (until disconnect) log everything done in this connection using RBR this also stays in my sketch. temp_tables_existed_when_read_only_was_enabled is to govern post-read_only term binlogging behavour. And as I am fine to associate it with the connection rather than with a table. Let me make myself clear on two points. Firstly, due to post read-only RBR-forever principle there's a use case of a DROP not to be logged which I suggested we would tackle with a warning. Secondly, the immediately reported case is (may be) irrelevant for the read-only discussion at all as the unexpected DROP TEMP table event is just wrong to turn out into binlog when the connection runs binlog_format ROW which must've been the case in the reporter's case (no CREATE was spotted plus @@global.binlog_format=ROW hints to that). | |||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2019-03-26 ] | |||||||||||||||||||||||||||||||||||||||||
|
okay, an addition:
and, sure, in that approach that we both seem to agree on there will be no temp-table related writes into binlog in read_only mode. At all. So it'll naturally solve the latter case. | |||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2019-07-17 ] | |||||||||||||||||||||||||||||||||||||||||
|
serg, when I agreed on the above proposals from you, I still was not certain of a solution to the support case which I initially believed was caused by connection close. If fact the customer case must be rooted by a new Yet I have to prioritize now | |||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2019-07-18 ] | |||||||||||||||||||||||||||||||||||||||||
|
serg, to earlier comment of yours, incl My question has been (was in removed/edited comments) how/if logging should be implemented for a case like
We are not going to log such otherwise must-do-log DROP into binlog until (if ever)
But at this point the connection user has gone. So practically we would have to create a list of deferred-to-log-DROP temp tables which the connection admin would attend as a pre-hook to its main read-write opening action. It's worth to mention DROP /regular/ TABLE IF EXISTS as a second object to handle if we are going to pursue Footnotes: | |||||||||||||||||||||||||||||||||||||||||
| Comment by Michael Widenius [ 2019-10-15 ] | |||||||||||||||||||||||||||||||||||||||||
|
Work in bb-10.3-monty, f49f37eb2dff02dba19f8b3a4e5b55d65e13c131 Will add the MDEV's this fixed in the final commit before pushing | |||||||||||||||||||||||||||||||||||||||||
| Comment by Michael Widenius [ 2019-10-20 ] | |||||||||||||||||||||||||||||||||||||||||
|
Coding, documentation and testing Temporary tables will not be logged in read-only mode. Temporary tables created while the server is in read-only mode will not be logged even after the server has disabled the read-only mode. |