Commit 13649d90 authored by jimw@mysql.com's avatar jimw@mysql.com

Prevent adding 'CREATE TABLE .. SELECT' query to the binary log when the

insertion of new records partially failed. It would get logged because of the
logic to log a partially-failed 'INSERT ... SELECT' (which can't be rolled back
in non-transactional tables), but 'CREATE TABLE ... SELECT' is always rolled
back on failure, even for non-transactional tables. (Bug #6682)
(Original fix reimplemented after review by Serg and Guilhem.)
parent 7ed27533
...@@ -64,6 +64,7 @@ jcole@main.burghcom.com ...@@ -64,6 +64,7 @@ jcole@main.burghcom.com
jcole@mugatu.spaceapes.com jcole@mugatu.spaceapes.com
jcole@sarvik.tfr.cafe.ee jcole@sarvik.tfr.cafe.ee
jcole@tetra.spaceapes.com jcole@tetra.spaceapes.com
jimw@mysql.com
joerg@mysql.com joerg@mysql.com
jorge@linux.jorge.mysql.com jorge@linux.jorge.mysql.com
kaj@work.mysql.com kaj@work.mysql.com
......
...@@ -78,6 +78,15 @@ master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3 ...@@ -78,6 +78,15 @@ master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3
master-bin.001 79 Query 1 79 use `test`; insert into t1 select * from t2 master-bin.001 79 Query 1 79 use `test`; insert into t1 select * from t2
drop table t1, t2; drop table t1, t2;
drop table if exists t1, t2; drop table if exists t1, t2;
create table t1(a int);
insert into t1 values(1),(1);
reset master;
create table t2(unique(a)) select a from t1;
Duplicate entry '1' for key 1
show binlog events;
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3
drop table t1;
create table t1 (a int not null); create table t1 (a int not null);
create table t2 (a int not null); create table t2 (a int not null);
insert into t1 values (1); insert into t1 values (1);
......
...@@ -86,6 +86,19 @@ show binlog events; ...@@ -86,6 +86,19 @@ show binlog events;
drop table t1, t2; drop table t1, t2;
drop table if exists t1, t2; drop table if exists t1, t2;
# Verify that a partly-completed CREATE TABLE .. SELECT does not
# get into the binlog (Bug #6682)
create table t1(a int);
insert into t1 values(1),(1);
reset master;
--error 1062
create table t2(unique(a)) select a from t1;
# The above should produce an error, *and* not appear in the binlog
let $VERSION=`select version()`;
--replace_result $VERSION VERSION
show binlog events;
drop table t1;
# #
# Test of insert ... select from same table # Test of insert ... select from same table
# #
......
...@@ -637,6 +637,15 @@ public: ...@@ -637,6 +637,15 @@ public:
#endif #endif
}; };
# define tmp_disable_binlog(A) \
ulong save_options= (A)->options, save_master_access= (A)->master_access; \
(A)->options&= ~OPTION_BIN_LOG; \
(A)->master_access|= SUPER_ACL; /* unneeded in 4.1 */
#define reenable_binlog(A) \
(A)->options= save_options; \
(A)->master_access= save_master_access;
/* Flags for the THD::system_thread (bitmap) variable */ /* Flags for the THD::system_thread (bitmap) variable */
#define SYSTEM_THREAD_DELAYED_INSERT 1 #define SYSTEM_THREAD_DELAYED_INSERT 1
#define SYSTEM_THREAD_SLAVE_IO 2 #define SYSTEM_THREAD_SLAVE_IO 2
...@@ -781,6 +790,7 @@ public: ...@@ -781,6 +790,7 @@ public:
{} {}
int prepare(List<Item> &list); int prepare(List<Item> &list);
bool send_data(List<Item> &values); bool send_data(List<Item> &values);
void send_error(uint errcode,const char *err);
bool send_eof(); bool send_eof();
void abort(); void abort();
}; };
......
...@@ -1505,6 +1505,19 @@ bool select_create::send_data(List<Item> &values) ...@@ -1505,6 +1505,19 @@ bool select_create::send_data(List<Item> &values)
return 0; return 0;
} }
void select_create::send_error(uint errcode,const char *err)
{
/*
Disable binlog, because we "roll back" partial inserts in ::abort
by removing the table, even for non-transactional tables.
*/
tmp_disable_binlog(thd);
select_insert::send_error(errcode, err);
reenable_binlog(thd);
}
extern HASH open_cache; extern HASH open_cache;
......
...@@ -31,14 +31,6 @@ ...@@ -31,14 +31,6 @@
#endif #endif
#include "sql_acl.h" // for SUPER_ACL #include "sql_acl.h" // for SUPER_ACL
# define tmp_disable_binlog(A) \
ulong save_options= (A)->options, save_master_access= (A)->master_access; \
(A)->options&= ~OPTION_BIN_LOG; \
(A)->master_access|= SUPER_ACL; /* unneeded in 4.1 */
#define reenable_binlog(A) \
(A)->options= save_options; \
(A)->master_access= save_master_access;
extern HASH open_cache; extern HASH open_cache;
static const char *primary_key_name="PRIMARY"; static const char *primary_key_name="PRIMARY";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment