Bug #37011 | creating temporary table inside a transaction may result in incorrect binlog | ||
---|---|---|---|
Submitted: | 27 May 2008 15:43 | Modified: | 4 Aug 2008 7:36 |
Reporter: | Gregory Haase | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: Replication | Severity: | S2 (Serious) |
Version: | 5.0.27, 5.1.24-rc | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | temporary table, transaction |
[27 May 2008 15:43]
Gregory Haase
[9 Jun 2008 20:55]
Sveta Smirnova
Thank you for the report. According to http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html: CREATE TABLE and DROP TABLE do not commit a transaction if the TEMPORARY keyword is used. (This does not apply to other operations on temporary tables such as CREATE INDEX, which do cause a commit.) However, although no implicit commit occurs, neither can the statement be rolled back. Therefore, use of such statements will violate transaction atomicity: For example, if you use CREATE TEMPORARY TABLE and then roll back the transaction, the table remains in existence. current behavior is correct. So I close the report as "Not a Bug". Since version 5.1 you can use binary log format ROW to prevent errors like "tmp table does not exist"
[9 Jun 2008 21:06]
Gregory Haase
No! This is incorrect. The documentation you refer to discusses when a commit occurs. And it states that a temporary table does NOT cause in implicit commit. This documentation has nothing to do with how or when a transaction is started. This bug occurs with respect to when a transaction is started. Consider this outline: 1.) Start a Transaction 2a.) Create a Temporary Table 2b.) Per documentation you cited, creation of temporary table DOES NOT CAUSE A COMMIT 3.) Do some work 4.) Manually issue a COMMIT. This bug needs to be reopened. It needs to be fixed.
[2 Aug 2008 21:29]
Sveta Smirnova
Thank you for the feedback. Assuming following scenario. For first case (only temporary table used): 1. Transaction started. 2. Temporary table created. 3. Transaction rolled back -> not written to binary log. So if write CREATE TEMPORARY TABLE after BEGIN master will have and can use temporary table, but slave would not. For second case (with regular table) transaction can be rolled back before temporary table is created. So having CREATE TEMPORARY TABLE after INSERT is logical.
[4 Aug 2008 1:35]
Gregory Haase
Do not get caught up on the fact that the first action in my example is an INSERT. The begin statement can be triggered by almost anything. If, for example, you try the following sequence: 1.) START TRANSACTION 2.) DROP TEMPORARY TABLE IF EXISTS `tablename` 3.) CREATE TEMPORARY TABLE `tablename` Then your 'BEGIN' statement occurs in your binlog *after* the DROP TABLE but *before* the CREATE TEMPORARY TABLE. The case you suggest where temporary table can become available on MASTER and not SLAVE is indeed possible, but there are also a lot of other reasons you can get into this same state (e.g. slave is stopped and restarted for cold backup). Whether or not this bug is fixed - people still have to code with these sorts of scenarios in mind. Consider the scenario I mentioned above. The code wraps temporary tables inside of transactions. The slave gets shut down for a cold backup in the middle of the transcation. It gets restarted. Normally, your replication will crash because the temporary table no longer exists. If this bug is properly fixed, then the transaction is rolled back and when the slave restarts, it simply creates the temporary table again and replication proceeds. So what I'm saying here: that the very error condition you presented above that can result from this fixing this bug... that error condition can also be prevented from happening many other ways as a result of fixing this bug. Most importantly, I believe that the current behavior outlined in the bug report shows there are several levels of inconsistency here. First of all, from a developer standpoint, if I START TRANSACTION, I expect everything after that to be in the transaction. If I didn't want the temp table to be in the transaction, I would have built the temp table first, then I would have started the transaction. The documentation you referenced above is already warning me about the temp table violating atomicity - I'm choosing to heed that warning and build controls into my code to check that the temp table exists before using it, and doing "DROP IF EXISTS" before trying to create it. The documentation, however, is NOT clear - until this bug is fixed there are cases where creating a temporary table inside of a transaction doesn't violate atomicity. Fix the bug or expand on the documentation. I'd prefer you fix the bug.
[4 Aug 2008 7:36]
Susanne Ebrecht
Many thanks for writing a bug report. When I understand you right, this is not a bug it is an expected behaviour. Consider, transactions are only for DML not for DDL. That some other RDBMS have DDL transactions is a feature of them but the SQL standard only have rules for DML transactions and not for DDL which means MySQL and some other RDBMS with same behaviour are standard conform here. Also the following statements commit a transaction by automatism: http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html Consider also that temporary tables are session only and are not made for replication originally. Also it is recommend not to use stored routines for replication. Please also read here: http://dev.mysql.com/doc/refman/5.1/en/stored-procedure-logging.html http://dev.mysql.com/doc/refman/5.1/en/replication-formats.html http://dev.mysql.com/doc/refman/5.1/en/replication-features-temptables.html