Bug #47442 | RBR breaks on CREATE TABLE IF EXISTS <existing VIEW> AS SELECT | ||
---|---|---|---|
Submitted: | 18 Sep 2009 14:06 | Modified: | 2 Sep 2010 14:12 |
Reporter: | Matthias Leich | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Row Based Replication ( RBR ) | Severity: | S3 (Non-critical) |
Version: | 5.1,5.4 | OS: | Any |
Assigned to: | Libing Song | CPU Architecture: | Any |
Tags: | RBR |
[18 Sep 2009 14:06]
Matthias Leich
[29 Oct 2009 8:26]
Libing Song
Duplicate of Bug#47418
[5 Nov 2009 7:24]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/89414 3649 Li-Bing.Song@sun.com 2009-11-05 BUG#47442 BR breaks on CREATE TABLE IF EXISTS <existing VIEW> AS SELECT 'CREATE TABLE IF NOT EXIST ... SELECT' statement is binlogged as 'CREATE TEMPORARY TABLE ...' with a wrong table name when a view exists with the same name. Base table is in the same name space with view. when excuting open_and_lock_tables_derived, create_table is initialized as the existing view. and create_table->table is now a temporary table for the view. This cause the bug to happen. In this patch, create_table->table will be masqueraded as a base table with the correct table name and db name if it is exists as a view.
[5 Jan 2010 9:38]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/95937 3798 Li-Bing.Song@sun.com 2010-01-05 BUG#47442 BR breaks on CREATE TABLE IF EXISTS <existing VIEW> AS SELECT 'CREATE TABLE IF NOT EXIST ... SELECT' statement is binlogged as 'CREATE TEMPORARY TABLE ...' with a wrong table name when a view exists with the same name. Base table is in the same name space with view. when excuting open_and_lock_tables_derived, create_table is initialized as the existing view. and create_table->table is now a temporary table or base table which the view is derived. This cause a wrong binlog query which leads slave crash. After a long time of discussion, we ultimately decided to do the following in this patch. about 'CREATE TABLE IF EXISTS <existing VIEW>(COLUMNS) AS SELECT ...' and 'CREATE TABLE IF EXISTS <<existing VIEW> LIKE ...', the {COLUMNS and SELECT | LIKE} part are binlogged when a view exists with the same name. In another words, the binlog query is same as the binlog query which was binlogged when the table does not exist and it is created succefully. To implement the resolution, source table is used to binlog the query of 'CREATE TABLE IF EXISTS <<existing VIEW> LIKE ...'. A temporary table which is created by using the same query of 'CREATE TABLE IF EXISTS <existing VIEW> (COLUMNS) AS SELECT ...' is used to binlog 'CREATE TABLE IF EXISTS <existing VIEW> (COLUMNS) AS SELECT ...' statement.
[21 Jan 2010 15:01]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/97735 3798 Li-Bing.Song@sun.com 2010-01-21 BUG#47442 BR breaks on CREATE TABLE IF EXISTS <existing VIEW> AS SELECT 'CREATE TABLE IF NOT EXIST ... SELECT' statement is binlogged as 'CREATE TEMPORARY TABLE ...' with a wrong table name when a view exists with the same name. Base table is in the same name space with view. when excuting open_and_lock_tables_derived, create_table is initialized as the existing view. and create_table->table is now a temporary table or base table which the view is derived. This cause a wrong binlog query which leads slave crash. After a long time of discussion, we ultimately decided to do the following in this patch. about 'CREATE TABLE IF EXISTS <existing VIEW>(COLUMNS) AS SELECT ...' and 'CREATE TABLE IF EXISTS <<existing VIEW> LIKE ...', the {COLUMNS and SELECT | LIKE} part are binlogged when a view exists with the same name. In another words, the binlog query is same as the binlog query which was binlogged when the table does not exist and it is created succefully. To implement the resolution, source table is used to binlog the query of 'CREATE TABLE IF EXISTS <<existing VIEW> LIKE ...'. A temporary table which is created by using the same query of 'CREATE TABLE IF EXISTS <existing VIEW> (COLUMNS) AS SELECT ...' is used to binlog 'CREATE TABLE IF EXISTS <existing VIEW> (COLUMNS) AS SELECT ...' statement.
[6 Jul 2010 3:37]
Libing Song
It will be fixed by bug#47132. After the patch for bug#47132, 'CREATE TABLE IF NOT EXISTS ... SELECT' will do nothing and binlog nothing if the table exists.
[6 Jul 2010 5:15]
Konstantin Osipov
Please only close after a test case is in.
[16 Aug 2010 6:34]
Libing Song
It will be fixed by WL#5370. After WL#5370, 'CREATE TABLE IF NOT EXISTS ... SELECT' will insert nothing with a warning that 'table already exits.' if a view of the same name already exists.
[18 Aug 2010 9:26]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/116060 3184 Li-Bing.Song@sun.com 2010-08-18 WL#5370 Keep forward-compatibility when changing 'CREATE TABLE IF NOT EXISTS ... SELECT' behaviour BUG#47132, BUG#47442, BUG49494, BUG#23992 and BUG#48814 will disappear automatically after the this patch. BUG#55617 is fixed by this patch too. This is the 5.5 part. It implements: - 'CREATE TABLE IF NOT EXISTS ... SELECT' statement will not insert anything and binlog anything if the table already exists. It only generate a warning that table already exists. - A couple of test cases for the behavior changing.
[18 Aug 2010 9:38]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/116062 3186 Li-Bing.Song@sun.com 2010-08-18 WL#5370 Keep forward-compatibility when changing 'CREATE TABLE IF NOT EXISTS ... SELECT' behaviour BUG#47132, BUG#47442, BUG49494, BUG#23992 and BUG#48814 will disappear automatically after the this patch. BUG#55617 is fixed by this patch too. This is the 5.5 part. It implements: - 'CREATE TABLE IF NOT EXISTS ... SELECT' statement will not insert anything and binlog anything if the table already exists. It only generate a warning that table already exists. - A couple of test cases for the behavior changing.
[19 Aug 2010 7:39]
Libing Song
It disappears after the patch for WL#5370. As behavior of CREATE TABLE IF NOT EXISTS SELECT has changed. It will never insert anything and not be binlogged after the worklog.
[25 Aug 2010 9:24]
Bugs System
Pushed into mysql-5.5 5.5.6-m3 (revid:alik@ibmvm-20100825092002-2yvkb3iwu43ycpnm) (version source revid:alik@ibmvm-20100825092002-2yvkb3iwu43ycpnm) (merge vers: 5.5.6-m3) (pib:20)
[26 Aug 2010 10:01]
Jon Stephens
Thank you for your bug report. This issue has been committed to our source repository of that product and will be incorporated into the next release. If necessary, you can access the source repository and build the latest available version, including the bug fix. More information about accessing the source trees is available at http://dev.mysql.com/doc/en/installing-source.html
[26 Aug 2010 10:02]
Jon Stephens
Documentation of the fix for the current issue is being handled with documentation of WL#5370, so closed bug report without further action.
[30 Aug 2010 8:32]
Bugs System
Pushed into mysql-trunk 5.6.1-m4 (revid:alik@sun.com-20100830082732-n2eyijnv86exc5ci) (version source revid:alik@sun.com-20100830082732-n2eyijnv86exc5ci) (merge vers: 5.6.1-m4) (pib:21)
[30 Aug 2010 8:35]
Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100830082745-n6sh01wlwh3itasv) (version source revid:alik@sun.com-20100830082745-n6sh01wlwh3itasv) (pib:21)
[30 Aug 2010 10:51]
Jon Stephens
Setting back to Closed state per my comment of 26 August.
[2 Sep 2010 14:12]
Jon Stephens
Setting back to Closed. See previous comments.
[9 Sep 2010 17:43]
Paul DuBois
Noted in 5.1.51, 5.5.6, 5.6.1 changelogs. As of MySQL 5.5.6, handling of CREATE TABLE IF NOT EXISTS ... SELECT statements has been changed for the case that the destination table already exists: * Previously, for CREATE TABLE IF NOT EXISTS ... SELECT, MySQL produced a warning that the table exists, but inserted the rows and wrote the statement to the binary log anyway. By contrast, CREATE TABLE ... SELECT (without IF NOT EXISTS) failed with an error, but MySQL inserted no rows and did not write the statement to the binary log. * MySQL now handles both statements the same way when the destination table exists, in that neither statement inserts rows or is written to the binary log. The difference between them is that MySQL produces a warning when IF NOT EXISTS is present and an error when it is not. This change in handling of IF NOT EXISTS results in an incompatibility for statement-based replication from a MySQL 5.1 master with the original behavior and a MySQL 5.5 slave with the new behavior. Suppose that CREATE TABLE IF NOT EXISTS ... SELECT is executed on the master and the destination table exists. The result is that rows are inserted on the master but not on the slave. (Row-based replication does not have this problem.) To address this issue, statement-based binary logging for CREATE TABLE IF NOT EXISTS ... SELECT is changed in MySQL 5.1 as of 5.1.51: * If the destination table does not exist, there is no change: The statement is logged as is. * If the destination table does exist, the statement is logged as the equivalent pair of CREATE TABLE IF NOT EXISTS and INSERT ... SELECT statements. (If the SELECT in the original statement is preceded by IGNORE or REPLACE, the INSERT becomes INSERT IGNORE or REPLACE, respectively.) This change provides forward compatibility for statement-based replication from MySQL 5.1 to 5.5 because when the destination table exists, the rows will be inserted on both the master and slave. To take advantage of this compatibility measure, the 5.1 server must be at least 5.1.51 and the 5.5 server must be at least 5.5.6. To upgrade an existing 5.1-to-5.5 replication scenario, upgrade the master first to 5.1.51 or higher. Note that this differs from the usual replication upgrade advice of upgrading the slave first. A workaround for applications that wish to achieve the original effect (rows inserted regardless of whether the destination table exists) is to use CREATE TABLE IF NOT EXISTS and INSERT ... SELECT statements rather than CREATE TABLE IF NOT EXISTS ... SELECT statements. Along with the change just described, the following related change was made: Previously, if an existing updatable view was named as the destination table for CREATE TABLE IF NOT EXISTS ... SELECT, rows were inserted into the underlying base table and the statement was written to the binary log. As of MySQL 5.1.51 and 5.5.6, nothing is inserted or logged.