Commit f71dc02e authored by Michael Widenius's avatar Michael Widenius

Automatic merge

parents d51ee6d4 c4bb7cd6
include/master-slave.inc
[connection master]
drop table if exists t1;
SET @old_debug= @@session.debug;
CREATE TABLE t1 (i INT, KEY(i)) ENGINE=InnoDB;
CREATE OR REPLACE TEMPORARY TABLE tmp (a int, b int, key(a)) engine=myisam;
set debug_dbug='+d,send_kill_after_delete';
CREATE OR REPLACE TABLE t1 LIKE tmp;
set debug_dbug=@old_debug;
SHOW TABLES;
Tables_in_test
t1
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
KEY `a` (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SHOW TABLES;
Tables_in_test
t1
drop temporary table if exists tmp;
drop table t1;
include/rpl_end.inc
...@@ -67,6 +67,9 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY' ...@@ -67,6 +67,9 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
create table t1 (a int); create table t1 (a int);
create or replace table t1 (a int primary key) select a from t2; create or replace table t1 (a int primary key) select a from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY' ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
create temporary table t9 (a int);
create or replace temporary table t9 (a int primary key) select a from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
binlog from server 1 binlog from server 1
include/show_binlog_events.inc include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
...@@ -79,20 +82,27 @@ master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated ...@@ -79,20 +82,27 @@ master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated
master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (a int) master-bin.000001 # Query # # use `test`; create table t1 (a int)
master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` ( master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */
`a` int(11) NOT NULL, master-bin.000001 # Query # # ROLLBACK
PRIMARY KEY (`a`) master-bin.000001 # Gtid # # BEGIN GTID #-#-#
) master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t9`/* Generated to handle failed CREATE OR REPLACE */
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # ROLLBACK master-bin.000001 # Query # # ROLLBACK
show tables; show tables;
Tables_in_test Tables_in_test
t1
t2 t2
create table t1 (a int);
create or replace table t1 (a int, a int) select * from t2;
ERROR 42S21: Duplicate column name 'a'
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (a int)
drop table if exists t1,t2; drop table if exists t1,t2;
Warnings: Warnings:
Note 1051 Unknown table 'test.t1' Note 1051 Unknown table 'test.t1'
drop temporary table if exists t9;
Warnings:
Note 1051 Unknown table 'test.t9'
# #
# Ensure that CREATE are run as CREATE OR REPLACE on slave # Ensure that CREATE are run as CREATE OR REPLACE on slave
# #
...@@ -158,5 +168,39 @@ slave-bin.000001 # Table_map # # table_id: # (test.t2) ...@@ -158,5 +168,39 @@ slave-bin.000001 # Table_map # # table_id: # (test.t2)
slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
slave-bin.000001 # Xid # # COMMIT /* XID */ slave-bin.000001 # Xid # # COMMIT /* XID */
drop table t1; drop table t1;
drop table t2,t3; #
# Check logging of drop temporary table
#
drop temporary table t3;
set @org_binlog_format=@@binlog_format;
set binlog_format="STATEMENT";
create temporary table t5 (a int);
drop temporary table t5;
set binlog_format="ROW";
create temporary table t6 (a int);
drop temporary table t6;
set binlog_format="STATEMENT";
create temporary table t7 (a int);
set binlog_format="ROW";
drop temporary table t7;
create temporary table t8 (a int);
set binlog_format="STATEMENT";
ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables
drop temporary table t8;
set @@binlog_format=@org_binlog_format;
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create temporary table t5 (a int)
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE `t5` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t6` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create temporary table t7 (a int)
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t7` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t8` /* generated by server */
drop table t2;
include/rpl_end.inc include/rpl_end.inc
...@@ -89,6 +89,9 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY' ...@@ -89,6 +89,9 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
create table t1 (a int); create table t1 (a int);
create or replace table t1 (a int primary key) select a from t2; create or replace table t1 (a int primary key) select a from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY' ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
create temporary table t9 (a int);
create or replace temporary table t9 (a int primary key) select a from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
binlog from server 1 binlog from server 1
include/show_binlog_events.inc include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
...@@ -101,20 +104,27 @@ master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated ...@@ -101,20 +104,27 @@ master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated
master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (a int) master-bin.000001 # Query # # use `test`; create table t1 (a int)
master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` ( master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */
`a` int(11) NOT NULL, master-bin.000001 # Query # # ROLLBACK
PRIMARY KEY (`a`) master-bin.000001 # Gtid # # BEGIN GTID #-#-#
) master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t9`/* Generated to handle failed CREATE OR REPLACE */
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # ROLLBACK master-bin.000001 # Query # # ROLLBACK
show tables; show tables;
Tables_in_test Tables_in_test
t1
t2 t2
create table t1 (a int);
create or replace table t1 (a int, a int) select * from t2;
ERROR 42S21: Duplicate column name 'a'
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (a int)
drop table if exists t1,t2; drop table if exists t1,t2;
Warnings: Warnings:
Note 1051 Unknown table 'test.t1' Note 1051 Unknown table 'test.t1'
drop temporary table if exists t9;
Warnings:
Note 1051 Unknown table 'test.t9'
# #
# Ensure that CREATE are run as CREATE OR REPLACE on slave # Ensure that CREATE are run as CREATE OR REPLACE on slave
# #
...@@ -180,5 +190,39 @@ slave-bin.000001 # Table_map # # table_id: # (test.t2) ...@@ -180,5 +190,39 @@ slave-bin.000001 # Table_map # # table_id: # (test.t2)
slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
slave-bin.000001 # Xid # # COMMIT /* XID */ slave-bin.000001 # Xid # # COMMIT /* XID */
drop table t1; drop table t1;
drop table t2,t3; #
# Check logging of drop temporary table
#
drop temporary table t3;
set @org_binlog_format=@@binlog_format;
set binlog_format="STATEMENT";
create temporary table t5 (a int);
drop temporary table t5;
set binlog_format="ROW";
create temporary table t6 (a int);
drop temporary table t6;
set binlog_format="STATEMENT";
create temporary table t7 (a int);
set binlog_format="ROW";
drop temporary table t7;
create temporary table t8 (a int);
set binlog_format="STATEMENT";
ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables
drop temporary table t8;
set @@binlog_format=@org_binlog_format;
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create temporary table t5 (a int)
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE `t5` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t6` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create temporary table t7 (a int)
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t7` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t8` /* generated by server */
drop table t2;
include/rpl_end.inc include/rpl_end.inc
...@@ -67,6 +67,9 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY' ...@@ -67,6 +67,9 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
create table t1 (a int); create table t1 (a int);
create or replace table t1 (a int primary key) select a from t2; create or replace table t1 (a int primary key) select a from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY' ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
create temporary table t9 (a int);
create or replace temporary table t9 (a int primary key) select a from t2;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
binlog from server 1 binlog from server 1
include/show_binlog_events.inc include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
...@@ -79,13 +82,27 @@ master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated ...@@ -79,13 +82,27 @@ master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated
master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (a int) master-bin.000001 # Query # # use `test`; create table t1 (a int)
master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create or replace table t1 (a int primary key) select a from t2 master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `test`.`t1`/* Generated to handle failed CREATE OR REPLACE */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create temporary table t9 (a int)
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t9`/* Generated to handle failed CREATE OR REPLACE */
show tables; show tables;
Tables_in_test Tables_in_test
t2 t2
create table t1 (a int);
create or replace table t1 (a int, a int) select * from t2;
ERROR 42S21: Duplicate column name 'a'
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (a int)
drop table if exists t1,t2; drop table if exists t1,t2;
Warnings: Warnings:
Note 1051 Unknown table 'test.t1' Note 1051 Unknown table 'test.t1'
drop temporary table if exists t9;
Warnings:
Note 1051 Unknown table 'test.t9'
# #
# Ensure that CREATE are run as CREATE OR REPLACE on slave # Ensure that CREATE are run as CREATE OR REPLACE on slave
# #
...@@ -140,5 +157,39 @@ slave-bin.000001 # Query # # use `test`; create table t2 engine=myisam select * ...@@ -140,5 +157,39 @@ slave-bin.000001 # Query # # use `test`; create table t2 engine=myisam select *
slave-bin.000001 # Gtid # # GTID #-#-# slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `test`; create or replace table t2 engine=innodb select * from t1 slave-bin.000001 # Query # # use `test`; create or replace table t2 engine=innodb select * from t1
drop table t1; drop table t1;
drop table t2,t3; #
# Check logging of drop temporary table
#
drop temporary table t3;
set @org_binlog_format=@@binlog_format;
set binlog_format="STATEMENT";
create temporary table t5 (a int);
drop temporary table t5;
set binlog_format="ROW";
create temporary table t6 (a int);
drop temporary table t6;
set binlog_format="STATEMENT";
create temporary table t7 (a int);
set binlog_format="ROW";
drop temporary table t7;
create temporary table t8 (a int);
set binlog_format="STATEMENT";
ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables
drop temporary table t8;
set @@binlog_format=@org_binlog_format;
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create temporary table t5 (a int)
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE `t5` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t6` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create temporary table t7 (a int)
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t7` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t8` /* generated by server */
drop table t2;
include/rpl_end.inc include/rpl_end.inc
...@@ -50,10 +50,15 @@ drop table if exists t1; ...@@ -50,10 +50,15 @@ drop table if exists t1;
create or replace table t1 (a int primary key) select a from t2; create or replace table t1 (a int primary key) select a from t2;
create table t1 (a int); create table t1 (a int);
# This should be logged as we will delete t1 # This should as a delete as we will delete t1
--error ER_DUP_ENTRY --error ER_DUP_ENTRY
create or replace table t1 (a int primary key) select a from t2; create or replace table t1 (a int primary key) select a from t2;
# Same with temporary table
create temporary table t9 (a int);
--error ER_DUP_ENTRY
create or replace temporary table t9 (a int primary key) select a from t2;
--echo binlog from server 1 --echo binlog from server 1
--source include/show_binlog_events.inc --source include/show_binlog_events.inc
save_master_pos; save_master_pos;
...@@ -62,7 +67,14 @@ sync_with_master; ...@@ -62,7 +67,14 @@ sync_with_master;
show tables; show tables;
connection server_1; connection server_1;
--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1)
create table t1 (a int);
--error ER_DUP_FIELDNAME
create or replace table t1 (a int, a int) select * from t2;
--source include/show_binlog_events.inc
drop table if exists t1,t2; drop table if exists t1,t2;
drop temporary table if exists t9;
--echo # --echo #
--echo # Ensure that CREATE are run as CREATE OR REPLACE on slave --echo # Ensure that CREATE are run as CREATE OR REPLACE on slave
...@@ -131,7 +143,34 @@ sync_with_master; ...@@ -131,7 +143,34 @@ sync_with_master;
connection server_1; connection server_1;
drop table t1; drop table t1;
--echo #
--echo # Check logging of drop temporary table
--echo #
drop temporary table t3;
--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1)
set @org_binlog_format=@@binlog_format;
set binlog_format="STATEMENT";
create temporary table t5 (a int);
drop temporary table t5;
set binlog_format="ROW";
create temporary table t6 (a int);
drop temporary table t6;
set binlog_format="STATEMENT";
create temporary table t7 (a int);
set binlog_format="ROW";
drop temporary table t7;
create temporary table t8 (a int);
--error ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
set binlog_format="STATEMENT";
drop temporary table t8;
set @@binlog_format=@org_binlog_format;
--source include/show_binlog_events.inc
# Clean up # Clean up
drop table t2,t3; drop table t2;
--source include/rpl_end.inc --source include/rpl_end.inc
# #
# Check CREATE OR REPLACE ALTER TABLE # Check CREATE OR REPLACE TABLE
# #
--source include/have_innodb.inc --source include/have_innodb.inc
......
#
# Check CREATE OR REPLACE TABLE for test that requires DEBUG
#
--source include/have_debug.inc
--source include/master-slave.inc
--source include/have_binlog_format_row.inc
--source include/have_xtradb.inc
--disable_warnings
drop table if exists t1;
--enable_warnings
SET @old_debug= @@session.debug;
#
# MDEV-5854
# Interrupted CREATE OR REPLACE is written into binlog, and in a wrong format
#
CREATE TABLE t1 (i INT, KEY(i)) ENGINE=InnoDB;
CREATE OR REPLACE TEMPORARY TABLE tmp (a int, b int, key(a)) engine=myisam;
set debug_dbug='+d,send_kill_after_delete';
CREATE OR REPLACE TABLE t1 LIKE tmp;
set debug_dbug=@old_debug;
SHOW TABLES;
show create table t1;
--sync_slave_with_master
SHOW TABLES;
--connection master
--disable_warnings
drop temporary table if exists tmp;
--enable_warnings
drop table t1;
--source include/rpl_end.inc
...@@ -2052,6 +2052,19 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) ...@@ -2052,6 +2052,19 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
void binlog_reset_cache(THD *thd)
{
binlog_cache_mngr *const cache_mngr=
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
DBUG_ENTER("binlog_reset_cache");
thd->binlog_remove_pending_rows_event(TRUE, TRUE);
cache_mngr->reset(true, true);
thd->clear_binlog_table_maps();
DBUG_VOID_RETURN;
}
void MYSQL_BIN_LOG::set_write_error(THD *thd, bool is_transactional) void MYSQL_BIN_LOG::set_write_error(THD *thd, bool is_transactional)
{ {
DBUG_ENTER("MYSQL_BIN_LOG::set_write_error"); DBUG_ENTER("MYSQL_BIN_LOG::set_write_error");
......
...@@ -1012,6 +1012,7 @@ File open_binlog(IO_CACHE *log, const char *log_file_name, ...@@ -1012,6 +1012,7 @@ File open_binlog(IO_CACHE *log, const char *log_file_name,
const char **errmsg); const char **errmsg);
void make_default_log_name(char **out, const char* log_ext, bool once); void make_default_log_name(char **out, const char* log_ext, bool once);
void binlog_reset_cache(THD *thd);
extern MYSQL_PLUGIN_IMPORT MYSQL_BIN_LOG mysql_bin_log; extern MYSQL_PLUGIN_IMPORT MYSQL_BIN_LOG mysql_bin_log;
extern LOGGER logger; extern LOGGER logger;
......
...@@ -656,6 +656,12 @@ static void mark_temp_tables_as_free_for_reuse(THD *thd) ...@@ -656,6 +656,12 @@ static void mark_temp_tables_as_free_for_reuse(THD *thd)
{ {
DBUG_ENTER("mark_temp_tables_as_free_for_reuse"); DBUG_ENTER("mark_temp_tables_as_free_for_reuse");
if (thd->query_id == 0)
{
/* Thread has not executed any statement and has not used any tmp tables */
DBUG_VOID_RETURN;
}
thd->lock_temporary_tables(); thd->lock_temporary_tables();
for (TABLE *table= thd->temporary_tables ; table ; table= table->next) for (TABLE *table= thd->temporary_tables ; table ; table= table->next)
{ {
......
...@@ -3960,6 +3960,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, ...@@ -3960,6 +3960,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
*/ */
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
DBUG_ASSERT(create_table->table == create_info->table);
} }
} }
else else
...@@ -4247,6 +4248,8 @@ bool select_create::send_eof() ...@@ -4247,6 +4248,8 @@ bool select_create::send_eof()
if (!(thd->variables.option_bits & OPTION_GTID_BEGIN)) if (!(thd->variables.option_bits & OPTION_GTID_BEGIN))
trans_commit_implicit(thd); trans_commit_implicit(thd);
} }
else if (!thd->is_current_stmt_binlog_format_row())
table->s->table_creation_was_logged= 1;
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
...@@ -4310,7 +4313,6 @@ void select_create::abort_result_set() ...@@ -4310,7 +4313,6 @@ void select_create::abort_result_set()
*/ */
save_option_bits= thd->variables.option_bits; save_option_bits= thd->variables.option_bits;
if (!(thd->log_current_statement))
thd->variables.option_bits&= ~OPTION_BIN_LOG; thd->variables.option_bits&= ~OPTION_BIN_LOG;
select_insert::abort_result_set(); select_insert::abort_result_set();
thd->transaction.stmt.modified_non_trans_table= FALSE; thd->transaction.stmt.modified_non_trans_table= FALSE;
...@@ -4334,11 +4336,21 @@ void select_create::abort_result_set() ...@@ -4334,11 +4336,21 @@ void select_create::abort_result_set()
if (table) if (table)
{ {
bool tmp_table= table->s->tmp_table;
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
table->auto_increment_field_not_null= FALSE; table->auto_increment_field_not_null= FALSE;
drop_open_table(thd, table, create_table->db, create_table->table_name); drop_open_table(thd, table, create_table->db, create_table->table_name);
table=0; // Safety table=0; // Safety
if (thd->log_current_statement)
{
/* Remove logging of drop, create + insert rows */
binlog_reset_cache(thd);
/* Original table was deleted. We have to log it */
log_drop_table(thd, create_table->db, create_table->db_length,
create_table->table_name, create_table->table_name_length,
tmp_table);
}
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -2288,6 +2288,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, ...@@ -2288,6 +2288,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
for (table= tables; table; table= table->next_local) for (table= tables; table; table= table->next_local)
{ {
bool is_trans= 0; bool is_trans= 0;
bool table_creation_was_logged= 1;
char *db=table->db; char *db=table->db;
size_t db_length= table->db_length; size_t db_length= table->db_length;
handlerton *table_type= 0; handlerton *table_type= 0;
...@@ -2316,6 +2317,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, ...@@ -2316,6 +2317,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
error= 1; error= 1;
else else
{ {
table_creation_was_logged= table->table->s->table_creation_was_logged;
if ((error= drop_temporary_table(thd, table->table, &is_trans)) == -1) if ((error= drop_temporary_table(thd, table->table, &is_trans)) == -1)
{ {
DBUG_ASSERT(thd->in_sub_stmt); DBUG_ASSERT(thd->in_sub_stmt);
...@@ -2336,7 +2338,10 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, ...@@ -2336,7 +2338,10 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
. "DROP" was executed but a temporary table was affected (.i.e . "DROP" was executed but a temporary table was affected (.i.e
!error). !error).
*/ */
if (!dont_log_query) #ifndef DONT_LOG_DROP_OF_TEMPORARY_TABLES
table_creation_was_logged= 1;
#endif
if (!dont_log_query && table_creation_was_logged)
{ {
/* /*
If there is an error, we don't know the type of the engine If there is an error, we don't know the type of the engine
...@@ -2560,6 +2565,18 @@ err: ...@@ -2560,6 +2565,18 @@ err:
error= 1; error= 1;
} }
/*
We are always logging drop of temporary tables.
The reason is to handle the following case:
- Use statement based replication
- CREATE TEMPORARY TABLE foo (logged)
- set row based replication
- DROP TEMPORAY TABLE foo (needs to be logged)
This should be fixed so that we remember if creation of the
temporary table was logged and only log it if the creation was
logged.
*/
if (non_trans_tmp_table_deleted || if (non_trans_tmp_table_deleted ||
trans_tmp_table_deleted || non_tmp_table_deleted) trans_tmp_table_deleted || non_tmp_table_deleted)
{ {
...@@ -2648,6 +2665,43 @@ end: ...@@ -2648,6 +2665,43 @@ end:
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/**
Log the drop of a table.
@param thd Thread handler
@param db_name Database name
@param table_name Table name
@param temporary_table 1 if table was a temporary table
This code is only used in the case of failed CREATE OR REPLACE TABLE
when the original table was dropped but we could not create the new one.
*/
bool log_drop_table(THD *thd, const char *db_name, size_t db_name_length,
const char *table_name, size_t table_name_length,
bool temporary_table)
{
char buff[NAME_LEN*2 + 80];
String query(buff, sizeof(buff), system_charset_info);
bool error;
DBUG_ENTER("log_drop_table");
query.length(0);
query.append(STRING_WITH_LEN("DROP "));
if (temporary_table)
query.append(STRING_WITH_LEN("TEMPORARY "));
query.append(STRING_WITH_LEN("TABLE IF EXISTS "));
append_identifier(thd, &query, db_name, db_name_length);
query.append(".");
append_identifier(thd, &query, table_name, table_name_length);
query.append(STRING_WITH_LEN("/* Generated to handle "
"failed CREATE OR REPLACE */"));
error= thd->binlog_query(THD::STMT_QUERY_TYPE,
query.ptr(), query.length(),
FALSE, FALSE, temporary_table, 0);
DBUG_RETURN(error);
}
/** /**
Quickly remove a table. Quickly remove a table.
...@@ -4578,6 +4632,7 @@ int create_table_impl(THD *thd, ...@@ -4578,6 +4632,7 @@ int create_table_impl(THD *thd,
TABLE *tmp_table; TABLE *tmp_table;
if ((tmp_table= find_temporary_table(thd, db, table_name))) if ((tmp_table= find_temporary_table(thd, db, table_name)))
{ {
bool table_creation_was_logged= tmp_table->s->table_creation_was_logged;
if (create_info->options & HA_LEX_CREATE_REPLACE) if (create_info->options & HA_LEX_CREATE_REPLACE)
{ {
bool is_trans; bool is_trans;
...@@ -4595,6 +4650,19 @@ int create_table_impl(THD *thd, ...@@ -4595,6 +4650,19 @@ int create_table_impl(THD *thd,
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
goto err; goto err;
} }
/*
We have to log this query, even if it failed later to ensure the
drop is done.
*/
#ifndef DONT_LOG_DROP_OF_TEMPORARY_TABLES
table_creation_was_logged= 1;
#endif
if (table_creation_was_logged)
{
thd->variables.option_bits|= OPTION_KEEP_LOG;
thd->log_current_statement= 1;
create_info->table_was_deleted= 1;
}
} }
} }
else else
...@@ -4628,6 +4696,7 @@ int create_table_impl(THD *thd, ...@@ -4628,6 +4696,7 @@ int create_table_impl(THD *thd,
thd->variables.option_bits|= OPTION_KEEP_LOG; thd->variables.option_bits|= OPTION_KEEP_LOG;
thd->log_current_statement= 1; thd->log_current_statement= 1;
create_info->table_was_deleted= 1; create_info->table_was_deleted= 1;
DBUG_EXECUTE_IF("send_kill_after_delete", thd->killed= KILL_QUERY; );
/* /*
The test of query_tables is to ensure we have any tables in the The test of query_tables is to ensure we have any tables in the
...@@ -4707,6 +4776,7 @@ int create_table_impl(THD *thd, ...@@ -4707,6 +4776,7 @@ int create_table_impl(THD *thd,
goto err; goto err;
} }
create_info->table= 0;
if (!frm_only && create_info->tmp_table()) if (!frm_only && create_info->tmp_table())
{ {
/* /*
...@@ -4727,6 +4797,7 @@ int create_table_impl(THD *thd, ...@@ -4727,6 +4797,7 @@ int create_table_impl(THD *thd,
*is_trans= table->file->has_transactions(); *is_trans= table->file->has_transactions();
thd->thread_specific_used= TRUE; thd->thread_specific_used= TRUE;
create_info->table= table; // Store pointer to table
} }
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
else if (thd->work_part_info && frm_only) else if (thd->work_part_info && frm_only)
...@@ -4769,6 +4840,7 @@ int create_table_impl(THD *thd, ...@@ -4769,6 +4840,7 @@ int create_table_impl(THD *thd,
err: err:
THD_STAGE_INFO(thd, stage_after_create); THD_STAGE_INFO(thd, stage_after_create);
delete file; delete file;
DBUG_PRINT("exit", ("return: %d", error));
DBUG_RETURN(error); DBUG_RETURN(error);
warn: warn:
...@@ -4898,6 +4970,7 @@ err: ...@@ -4898,6 +4970,7 @@ err:
/* In RBR we don't need to log CREATE TEMPORARY TABLE */ /* In RBR we don't need to log CREATE TEMPORARY TABLE */
if (thd->is_current_stmt_binlog_format_row() && create_info->tmp_table()) if (thd->is_current_stmt_binlog_format_row() && create_info->tmp_table())
DBUG_RETURN(result); DBUG_RETURN(result);
/* Write log if no error or if we already deleted a table */ /* Write log if no error or if we already deleted a table */
if (!result || thd->log_current_statement) if (!result || thd->log_current_statement)
{ {
...@@ -4909,6 +4982,14 @@ err: ...@@ -4909,6 +4982,14 @@ err:
*/ */
thd->locked_tables_list.unlock_locked_table(thd, mdl_ticket); thd->locked_tables_list.unlock_locked_table(thd, mdl_ticket);
} }
else if (!result && create_info->tmp_table() && create_info->table)
{
/*
Remember that tmp table creation was logged so that we know if
we should log a delete of it.
*/
create_info->table->s->table_creation_was_logged= 1;
}
if (write_bin_log(thd, result ? FALSE : TRUE, thd->query(), if (write_bin_log(thd, result ? FALSE : TRUE, thd->query(),
thd->query_length(), is_trans)) thd->query_length(), is_trans))
result= 1; result= 1;
...@@ -5262,7 +5343,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, ...@@ -5262,7 +5343,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
char buf[2048]; char buf[2048];
String query(buf, sizeof(buf), system_charset_info); String query(buf, sizeof(buf), system_charset_info);
query.length(0); // Have to zero it since constructor doesn't query.length(0); // Have to zero it since constructor doesn't
Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN); Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN |
MYSQL_OPEN_IGNORE_KILLED);
bool new_table= FALSE; // Whether newly created table is open. bool new_table= FALSE; // Whether newly created table is open.
if (create_res != 0) if (create_res != 0)
...@@ -5271,6 +5353,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, ...@@ -5271,6 +5353,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
Table or view with same name already existed and we where using Table or view with same name already existed and we where using
IF EXISTS. Continue without logging anything. IF EXISTS. Continue without logging anything.
*/ */
do_logging= 0;
goto err; goto err;
} }
if (!table->table) if (!table->table)
...@@ -5316,6 +5399,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, ...@@ -5316,6 +5399,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
if (write_bin_log(thd, TRUE, query.ptr(), query.length())) if (write_bin_log(thd, TRUE, query.ptr(), query.length()))
{ {
res= 1; res= 1;
do_logging= 0;
goto err; goto err;
} }
...@@ -5339,13 +5423,38 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, ...@@ -5339,13 +5423,38 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
*/ */
} }
else else
{
DBUG_PRINT("info",
("res: %d tmp_table: %d create_info->table: %p",
res, create_info->tmp_table(), local_create_info.table));
if (!res && create_info->tmp_table() && local_create_info.table)
{
/*
Remember that tmp table creation was logged so that we know if
we should log a delete of it.
*/
local_create_info.table->s->table_creation_was_logged= 1;
}
do_logging= TRUE; do_logging= TRUE;
}
err: err:
if (do_logging && if (do_logging)
write_bin_log(thd, res ? FALSE : TRUE, thd->query(), {
if (res && create_info->table_was_deleted)
{
/*
Table was not deleted. Original table was deleted.
We have to log it.
*/
log_drop_table(thd, table->db, table->db_length,
table->table_name, table->table_name_length,
create_info->tmp_table());
}
else if (write_bin_log(thd, res ? FALSE : TRUE, thd->query(),
thd->query_length(), is_trans)) thd->query_length(), is_trans))
res= 1; res= 1;
}
DBUG_RETURN(res); DBUG_RETURN(res);
} }
...@@ -8701,6 +8810,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -8701,6 +8810,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
mysql_lock_remove(thd, thd->lock, table); mysql_lock_remove(thd, thd->lock, table);
} }
} }
new_table->s->table_creation_was_logged=
table->s->table_creation_was_logged;
/* Remove link to old table and rename the new one */ /* Remove link to old table and rename the new one */
close_temporary_table(thd, table, true, true); close_temporary_table(thd, table, true, true);
/* Should pass the 'new_name' as we store table name in the cache */ /* Should pass the 'new_name' as we store table name in the cache */
......
...@@ -240,6 +240,9 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, ...@@ -240,6 +240,9 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
bool drop_temporary, bool drop_view, bool drop_temporary, bool drop_view,
bool log_query, bool dont_free_locks); bool log_query, bool dont_free_locks);
bool log_drop_table(THD *thd, const char *db_name, size_t db_name_length,
const char *table_name, size_t table_name_length,
bool temporary_table);
bool quick_rm_table(THD *thd, handlerton *base, const char *db, bool quick_rm_table(THD *thd, handlerton *base, const char *db,
const char *table_name, uint flags); const char *table_name, uint flags);
void close_cached_table(THD *thd, TABLE *table); void close_cached_table(THD *thd, TABLE *table);
......
...@@ -256,6 +256,7 @@ static bool recreate_temporary_table(THD *thd, TABLE *table) ...@@ -256,6 +256,7 @@ static bool recreate_temporary_table(THD *thd, TABLE *table)
bool error= TRUE; bool error= TRUE;
TABLE_SHARE *share= table->s; TABLE_SHARE *share= table->s;
handlerton *table_type= table->s->db_type(); handlerton *table_type= table->s->db_type();
TABLE *new_table;
DBUG_ENTER("recreate_temporary_table"); DBUG_ENTER("recreate_temporary_table");
table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
...@@ -266,11 +267,13 @@ static bool recreate_temporary_table(THD *thd, TABLE *table) ...@@ -266,11 +267,13 @@ static bool recreate_temporary_table(THD *thd, TABLE *table)
dd_recreate_table(thd, share->db.str, share->table_name.str, dd_recreate_table(thd, share->db.str, share->table_name.str,
share->normalized_path.str); share->normalized_path.str);
if (open_table_uncached(thd, table_type, share->path.str, share->db.str, if ((new_table= open_table_uncached(thd, table_type, share->path.str,
share->table_name.str, true, true)) share->db.str,
share->table_name.str, true, true)))
{ {
error= FALSE; error= FALSE;
thd->thread_specific_used= TRUE; thd->thread_specific_used= TRUE;
new_table->s->table_creation_was_logged= share->table_creation_was_logged;
} }
else else
rm_temporary_table(table_type, share->path.str); rm_temporary_table(table_type, share->path.str);
......
...@@ -742,6 +742,7 @@ struct TABLE_SHARE ...@@ -742,6 +742,7 @@ struct TABLE_SHARE
bool is_view; bool is_view;
bool deleting; /* going to delete this table */ bool deleting; /* going to delete this table */
bool can_cmp_whole_record; bool can_cmp_whole_record;
bool table_creation_was_logged;
ulong table_map_id; /* for row-based replication */ ulong table_map_id; /* for row-based replication */
/* /*
......
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