mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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.)
This commit is contained in:
@ -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
|
|||||||
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;
|
|||||||
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:
|
|||||||
#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:
|
|||||||
{}
|
{}
|
||||||
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)
|
|||||||
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 @@
|
|||||||
#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";
|
||||||
|
Reference in New Issue
Block a user