mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 04:53:01 +01:00
Bug #57666 Unclear warning with broken text in error log on INSERT DELAYED
It is not necessary to support INSERT DELAYED for a single value insert, while we do not support that for multi-values insert when binlog is enabled in SBR. The lock_type is upgrade to TL_WRITE from TL_WRITE_DELAYED for INSERT DELAYED for single value insert as multi-values insert did when binlog is enabled. Then it's safe. And binlog it as INSERT without DELAYED.
This commit is contained in:
parent
30376d282d
commit
08db5f7eb6
6 changed files with 31 additions and 77 deletions
|
@ -34,11 +34,11 @@ create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
|
|||
let $table=t1;
|
||||
let $count=0;
|
||||
|
||||
insert delayed into t1 values (207);
|
||||
insert /* before delayed */ delayed /* after delayed */ into t1 values (207);
|
||||
inc $count;
|
||||
--source include/wait_until_rows_count.inc
|
||||
|
||||
insert delayed into t1 values (null);
|
||||
insert /*! delayed */ into t1 values (null);
|
||||
inc $count;
|
||||
--source include/wait_until_rows_count.inc
|
||||
|
||||
|
|
|
@ -1218,8 +1218,8 @@ master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F
|
|||
master-bin.000001 # Query # # COMMIT
|
||||
drop table t1,t2,t3,tt1;
|
||||
create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
|
||||
insert delayed into t1 values (207);
|
||||
insert delayed into t1 values (null);
|
||||
insert /* before delayed */ delayed /* after delayed */ into t1 values (207);
|
||||
insert /*! delayed */ into t1 values (null);
|
||||
insert delayed into t1 values (300);
|
||||
FLUSH TABLES;
|
||||
show binlog events from <binlog_start>;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
|
||||
insert delayed into t1 values (207);
|
||||
insert delayed into t1 values (null);
|
||||
insert /* before delayed */ delayed /* after delayed */ into t1 values (207);
|
||||
insert /*! delayed */ into t1 values (null);
|
||||
insert delayed into t1 values (300);
|
||||
FLUSH TABLES;
|
||||
show binlog events from <binlog_start>;
|
||||
|
@ -10,14 +10,14 @@ master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern)
|
|||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; insert delayed into t1 values (207)
|
||||
master-bin.000001 # Query # # use `test`; insert /* before delayed */ /* after delayed */ into t1 values (207)
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Intvar # # INSERT_ID=208
|
||||
master-bin.000001 # Query # # use `test`; insert delayed into t1 values (null)
|
||||
master-bin.000001 # Query # # use `test`; insert /*! */ into t1 values (null)
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; insert delayed into t1 values (300)
|
||||
master-bin.000001 # Query # # use `test`; insert into t1 values (300)
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # use `test`; FLUSH TABLES
|
||||
RESET MASTER;
|
||||
|
|
|
@ -717,8 +717,8 @@ master-bin.000001 # Query # # use `mysql`; DELETE FROM user WHERE host='localhos
|
|||
master-bin.000001 # Query # # COMMIT
|
||||
drop table t1,t2,t3,tt1;
|
||||
create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
|
||||
insert delayed into t1 values (207);
|
||||
insert delayed into t1 values (null);
|
||||
insert /* before delayed */ delayed /* after delayed */ into t1 values (207);
|
||||
insert /*! delayed */ into t1 values (null);
|
||||
insert delayed into t1 values (300);
|
||||
FLUSH TABLES;
|
||||
show binlog events from <binlog_start>;
|
||||
|
|
|
@ -51,8 +51,8 @@ CREATE TABLE t1(a int, UNIQUE(a));
|
|||
INSERT DELAYED IGNORE INTO t1 VALUES(1);
|
||||
INSERT DELAYED IGNORE INTO t1 VALUES(1);
|
||||
flush table t1;
|
||||
use `test`; INSERT DELAYED IGNORE INTO t1 VALUES(1)
|
||||
use `test`; INSERT DELAYED IGNORE INTO t1 VALUES(1)
|
||||
use `test`; INSERT IGNORE INTO t1 VALUES(1)
|
||||
use `test`; INSERT IGNORE INTO t1 VALUES(1)
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
|
@ -60,10 +60,10 @@ On slave
|
|||
show binlog events in 'slave-bin.000002' from <binlog_start> limit 1,6;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
slave-bin.000002 # Query # # BEGIN
|
||||
slave-bin.000002 # Query # # use `test`; INSERT DELAYED IGNORE INTO t1 VALUES(1)
|
||||
slave-bin.000002 # Query # # use `test`; INSERT IGNORE INTO t1 VALUES(1)
|
||||
slave-bin.000002 # Query # # COMMIT
|
||||
slave-bin.000002 # Query # # BEGIN
|
||||
slave-bin.000002 # Query # # use `test`; INSERT DELAYED IGNORE INTO t1 VALUES(1)
|
||||
slave-bin.000002 # Query # # use `test`; INSERT IGNORE INTO t1 VALUES(1)
|
||||
slave-bin.000002 # Query # # COMMIT
|
||||
select * from t1;
|
||||
a
|
||||
|
|
|
@ -420,8 +420,7 @@ void prepare_triggers_for_insert_stmt(TABLE *table)
|
|||
|
||||
static
|
||||
void upgrade_lock_type(THD *thd, thr_lock_type *lock_type,
|
||||
enum_duplicates duplic,
|
||||
bool is_multi_insert)
|
||||
enum_duplicates duplic)
|
||||
{
|
||||
if (duplic == DUP_UPDATE ||
|
||||
(duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT))
|
||||
|
@ -470,10 +469,9 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type,
|
|||
return;
|
||||
}
|
||||
|
||||
bool log_on= (thd->variables.option_bits & OPTION_BIN_LOG ||
|
||||
! (thd->security_ctx->master_access & SUPER_ACL));
|
||||
bool log_on= (thd->variables.option_bits & OPTION_BIN_LOG);
|
||||
if (global_system_variables.binlog_format == BINLOG_FORMAT_STMT &&
|
||||
log_on && mysql_bin_log.is_open() && is_multi_insert)
|
||||
log_on && mysql_bin_log.is_open())
|
||||
{
|
||||
/*
|
||||
Statement-based binary logging does not work in this case, because:
|
||||
|
@ -677,8 +675,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||
By default, both logs are enabled (this won't cause problems if the server
|
||||
runs without --log-bin).
|
||||
*/
|
||||
bool log_on= ((thd->variables.option_bits & OPTION_BIN_LOG) ||
|
||||
(!(thd->security_ctx->master_access & SUPER_ACL)));
|
||||
bool log_on= (thd->variables.option_bits & OPTION_BIN_LOG);
|
||||
#endif
|
||||
thr_lock_type lock_type;
|
||||
Item *unused_conds= 0;
|
||||
|
@ -688,8 +685,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||
Upgrade lock type if the requested lock is incompatible with
|
||||
the current connection mode or table operation.
|
||||
*/
|
||||
upgrade_lock_type(thd, &table_list->lock_type, duplic,
|
||||
values_list.elements > 1);
|
||||
upgrade_lock_type(thd, &table_list->lock_type, duplic);
|
||||
|
||||
/*
|
||||
We can't write-delayed into a table locked with LOCK TABLES:
|
||||
|
@ -1022,7 +1018,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||
DBUG_ASSERT(thd->killed != THD::KILL_BAD_DATA || error > 0);
|
||||
if (was_insert_delayed && table_list->lock_type == TL_WRITE)
|
||||
{
|
||||
/* Binlog multi INSERT DELAYED as INSERT without DELAYED. */
|
||||
/* Binlog INSERT DELAYED as INSERT without DELAYED. */
|
||||
String log_query;
|
||||
if (create_insert_stmt_from_insert_delayed(thd, &log_query))
|
||||
{
|
||||
|
@ -1905,22 +1901,6 @@ public:
|
|||
thd.command=COM_DELAYED_INSERT;
|
||||
thd.lex->current_select= 0; // for my_message_sql
|
||||
thd.lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock()
|
||||
/*
|
||||
Statement-based replication of INSERT DELAYED has problems with
|
||||
RAND() and user variables, so in mixed mode we go to row-based.
|
||||
For normal commands, the unsafe flag is set at parse time.
|
||||
However, since the flag is a member of the THD object, of which
|
||||
the delayed_insert thread has its own copy, we must set the
|
||||
statement to unsafe here and explicitly set row logging mode.
|
||||
|
||||
@todo set_current_stmt_binlog_format_row_if_mixed should not be
|
||||
called by anything else than thd->decide_logging_format(). When
|
||||
we call set_current_blah here, none of the checks in
|
||||
decide_logging_format is made. We should probably call
|
||||
thd->decide_logging_format() directly instead. /Sven
|
||||
*/
|
||||
thd.lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_DELAYED);
|
||||
thd.set_current_stmt_binlog_format_row_if_mixed();
|
||||
/*
|
||||
Prevent changes to global.lock_wait_timeout from affecting
|
||||
delayed insert threads as any timeouts in delayed inserts
|
||||
|
@ -2650,11 +2630,11 @@ pthread_handler_t handle_delayed_insert(void *arg)
|
|||
}
|
||||
|
||||
thd->lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock()
|
||||
|
||||
/*
|
||||
Statement-based replication of INSERT DELAYED has problems with RAND()
|
||||
and user vars, so in mixed mode we go to row-based.
|
||||
INSERT DELAYED has to go to row-based format because the time
|
||||
at which rows are inserted cannot be determined in mixed mode.
|
||||
*/
|
||||
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_DELAYED);
|
||||
thd->set_current_stmt_binlog_format_row_if_mixed();
|
||||
|
||||
/*
|
||||
|
@ -2921,6 +2901,13 @@ bool Delayed_insert::handle_inserts(void)
|
|||
(ulong) row->query.length));
|
||||
if (log_query)
|
||||
{
|
||||
/*
|
||||
Guaranteed that the INSERT DELAYED STMT will not be here
|
||||
in SBR when mysql binlog is enabled.
|
||||
*/
|
||||
DBUG_ASSERT(!(mysql_bin_log.is_open() &&
|
||||
!thd.is_current_stmt_binlog_format_row()));
|
||||
|
||||
/*
|
||||
This is the first value of an INSERT statement.
|
||||
It is the right place to clear a forced insert_id.
|
||||
|
@ -2988,39 +2975,6 @@ bool Delayed_insert::handle_inserts(void)
|
|||
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
|
||||
}
|
||||
|
||||
if (log_query && mysql_bin_log.is_open())
|
||||
{
|
||||
bool backup_time_zone_used = thd.time_zone_used;
|
||||
Time_zone *backup_time_zone = thd.variables.time_zone;
|
||||
if (row->time_zone != NULL)
|
||||
{
|
||||
thd.time_zone_used = true;
|
||||
thd.variables.time_zone = row->time_zone;
|
||||
}
|
||||
|
||||
/* if the delayed insert was killed, the killed status is
|
||||
ignored while binlogging */
|
||||
int errcode= 0;
|
||||
if (thd.killed == THD::NOT_KILLED)
|
||||
errcode= query_error_code(&thd, TRUE);
|
||||
|
||||
/*
|
||||
If the query has several rows to insert, only the first row will come
|
||||
here. In row-based binlogging, this means that the first row will be
|
||||
written to binlog as one Table_map event and one Rows event (due to an
|
||||
event flush done in binlog_query()), then all other rows of this query
|
||||
will be binlogged together as one single Table_map event and one
|
||||
single Rows event.
|
||||
*/
|
||||
if (thd.binlog_query(THD::ROW_QUERY_TYPE,
|
||||
row->query.str, row->query.length,
|
||||
FALSE, FALSE, FALSE, errcode))
|
||||
goto err;
|
||||
|
||||
thd.time_zone_used = backup_time_zone_used;
|
||||
thd.variables.time_zone = backup_time_zone;
|
||||
}
|
||||
|
||||
if (table->s->blob_fields)
|
||||
free_delayed_insert_blobs(table);
|
||||
thread_safe_decrement(delayed_rows_in_use,&LOCK_delayed_status);
|
||||
|
|
Loading…
Reference in a new issue