fixes after merge. Updates to test's results.

We now reset the THD members related to auto_increment+binlog in
MYSQL_LOG::write(). This is better than in THD::cleanup_after_query(),
which was not able to distinguish between SELECT myfunc1(),myfunc2()
and INSERT INTO t SELECT myfunc1(),myfunc2() from a binlogging point
of view.
Rows_log_event::exec_event() now calls lex_start() instead of
mysql_init_query() because the latter now does too much (it resets
the binlog format).
parent 93ce19df
......@@ -170,7 +170,7 @@ connection master;
drop function bug15728;
drop function bug15728_insert;
drop table t1, t2;
drop table t1;
drop procedure foo;
# test of BUG#20188 REPLACE or ON DUPLICATE KEY UPDATE in
......
......@@ -291,7 +291,7 @@ our $opt_user_test;
our $opt_valgrind= 0;
our $opt_valgrind_mysqld= 0;
our $opt_valgrind_mysqltest= 0;
our $default_valgrind_options= "-v --show-reachable=yes";
our $default_valgrind_options= "--show-reachable=yes";
our $opt_valgrind_options;
our $opt_valgrind_path;
......
......@@ -153,43 +153,8 @@ id last_id
3 5
drop function bug15728;
drop function bug15728_insert;
drop procedure foo;
drop table t1;
truncate table t2;
create table t1 (id tinyint primary key);
create function insid() returns int
begin
insert into t2 (last_id) values (0);
return 0;
end|
set sql_log_bin=0;
insert into t2 (id) values(1),(2),(3);
delete from t2;
set sql_log_bin=1;
select insid();
insid()
0
set sql_log_bin=0;
insert into t2 (id) values(5),(6),(7);
delete from t2 where id>=5;
set sql_log_bin=1;
insert into t1 select insid();
select * from t1;
id
0
select * from t2;
id last_id
4 0
8 0
select * from t1;
id
0
select * from t2;
id last_id
4 0
8 0
drop table t1, t2;
drop function insid;
drop procedure foo;
create table t1 (n int primary key auto_increment not null,
b int, unique(b));
set sql_log_bin=0;
......@@ -255,3 +220,38 @@ n b
2 100
3 350
drop table t1;
truncate table t2;
create table t1 (id tinyint primary key);
create function insid() returns int
begin
insert into t2 (last_id) values (0);
return 0;
end|
set sql_log_bin=0;
insert into t2 (id) values(1),(2),(3);
delete from t2;
set sql_log_bin=1;
select insid();
insid()
0
set sql_log_bin=0;
insert into t2 (id) values(5),(6),(7);
delete from t2 where id>=5;
set sql_log_bin=1;
insert into t1 select insid();
select * from t1;
id
0
select * from t2;
id last_id
4 0
8 0
select * from t1;
id
0
select * from t2;
id last_id
4 0
8 0
drop table t1, t2;
drop function insid;
......@@ -28,7 +28,7 @@ day id category name
2003-03-22 2416 a bbbbb
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
slave-bin.000001 1276
slave-bin.000001 1248
drop table t1;
drop table t2;
drop table t3;
......@@ -39,7 +39,7 @@ set global sql_slave_skip_counter=1;
start slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1793 # # master-bin.000001 Yes Yes # 0 0 1793 # None 0 No #
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1765 # # master-bin.000001 Yes Yes # 0 0 1765 # None 0 No #
set sql_log_bin=0;
delete from t1;
set sql_log_bin=1;
......@@ -49,7 +49,7 @@ change master to master_user='test';
change master to master_user='root';
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1828 # # master-bin.000001 No No # 0 0 1828 # None 0 No #
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1800 # # master-bin.000001 No No # 0 0 1800 # None 0 No #
set global sql_slave_skip_counter=1;
start slave;
set sql_log_bin=0;
......
......@@ -228,7 +228,6 @@ end|
insert into t11 values("try_560_");
insert delayed into t2 values("delay_1_");
insert delayed into t2 values(concat("delay_2_",UUID()));
insert delayed into t2 values("delay_3_"),(concat("delay_4_",UUID())),("delay_5_");
insert delayed into t2 values("delay_6_");
insert delayed into t2 values(rand());
set @a=2.345;
......@@ -274,6 +273,7 @@ create table t13 select * from t1;
drop table t1;
create table t1 (a int primary key auto_increment, b varchar(100));
drop function f;
create table t14 (unique (a)) select * from t2;
truncate table t2;
create function f1 (x varchar(100)) returns int deterministic
begin
......@@ -342,7 +342,7 @@ count(*)
66
select count(*) from t21;
count(*)
22
19
select count(*) from t22;
count(*)
2
......@@ -352,6 +352,9 @@ count(*)
select count(*) from t13;
count(*)
1
select count(*) from t14;
count(*)
4
select count(*) from t16;
count(*)
3
......@@ -455,22 +458,27 @@ begin
insert into t1 values(concat("work_250_",x));
insert into t1 select "yesterday_270_";
end
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values("work_25_")
master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select "yesterday_27_"
master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values("work_29_")
master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(concat("work_250_", NAME_CONST('x',...
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select "yesterday_270_"
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(concat("work_250_", NAME_CONST('x',...
master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(concat("work_250_", NAME_CONST('x',_latin1'hello')))
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select "yesterday_270_"
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(concat("work_250_", NAME_CONST('x',...
master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(concat("work_250_", NAME_CONST('x',_latin1'world')))
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select "yesterday_270_"
master-bin.000001 # Query 1 # use `mysqltest1`; drop function foo3
master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` function foo3() returns bigint unsigned
......@@ -560,10 +568,6 @@ master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Query 1 # use `mysqltest1`; create table t20 select * from t1
master-bin.000001 # Query 1 # use `mysqltest1`; create table t21 select * from t2
master-bin.000001 # Query 1 # use `mysqltest1`; create table t22 select * from t3
......@@ -600,6 +604,7 @@ master-bin.000001 # Query 1 # use `mysqltest1`; create table t13 select * from t
master-bin.000001 # Query 1 # use `mysqltest1`; drop table t1
master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a int primary key auto_increment, b varchar(100))
master-bin.000001 # Query 1 # use `mysqltest1`; drop function f
master-bin.000001 # Query 1 # use `mysqltest1`; create table t14 (unique (a)) select * from t2
master-bin.000001 # Query 1 # use `mysqltest1`; truncate table t2
master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` function f1 (x varchar(100)) returns int deterministic
begin
......@@ -647,6 +652,7 @@ master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2)
master-bin.000001 # Write_rows 1 # table_id: #
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Query 1 # use `mysqltest1`; alter table t1 modify a int, drop primary key
master-bin.000001 # Intvar 1 # INSERT_ID=5
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(null,"try_57_")
master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE `t16` (
`UUID()` varchar(36) CHARACTER SET utf8 NOT NULL DEFAULT ''
......
......@@ -257,7 +257,6 @@ insert into t11 values("try_560_");
# Test that INSERT DELAYED works in mixed mode (BUG#20649)
insert delayed into t2 values("delay_1_");
insert delayed into t2 values(concat("delay_2_",UUID()));
insert delayed into t2 values("delay_3_"),(concat("delay_4_",UUID())),("delay_5_");
insert delayed into t2 values("delay_6_");
# Test for BUG#20633 (INSERT DELAYED RAND()/user_variable does not
......@@ -364,9 +363,8 @@ create table t1 (a int primary key auto_increment, b varchar(100));
# now test if it's two functions, each of them inserts in one table
drop function f;
# Manifestation of BUG#20341! re-enable this line after merging fix
# for that bug
#create table t14 select * from t2;
# we need a unique key to have sorting of rows by mysqldump
create table t14 (unique (a)) select * from t2;
truncate table t2;
delimiter |;
create function f1 (x varchar(100)) returns int deterministic
......@@ -453,7 +451,7 @@ select count(*) from t21;
select count(*) from t22;
select count(*) from t12;
select count(*) from t13;
#select count(*) from t14;
select count(*) from t14;
select count(*) from t16;
if ($you_want_to_test_UDF)
{
......@@ -476,10 +474,8 @@ sync_slave_with_master;
--exec diff $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_slave.sql;
connection master;
# As one stored function's parameter is UUID(), its value ends up in a
# NAME_CONST in the binlog, we must hide it for repeatability
--replace_column 2 # 5 #
--replace_regex /table_id: [0-9]+/table_id: #/ /NAME_CONST\('x',.*/NAME_CONST('x',.../
--replace_regex /table_id: [0-9]+/table_id: #/
show binlog events from 102;
# Now test that mysqlbinlog works fine on a binlog generated by the
......
......@@ -5263,7 +5263,7 @@ int ha_partition::cmp_ref(const byte *ref1, const byte *ref2)
MODULE auto increment
****************************************************************************/
void ha_partition::restore_auto_increment()
void ha_partition::restore_auto_increment(ulonglong)
{
DBUG_ENTER("ha_partition::restore_auto_increment");
......
......@@ -811,7 +811,7 @@ public:
auto_increment_column_changed
-------------------------------------------------------------------------
*/
virtual void restore_auto_increment();
virtual void restore_auto_increment(ulonglong prev_insert_id);
virtual void get_auto_increment(ulonglong offset, ulonglong increment,
ulonglong nb_desired_values,
ulonglong *first_value,
......
......@@ -1538,6 +1538,58 @@ compute_next_insert_id(ulonglong nr,struct system_variables *variables)
}
void handler::adjust_next_insert_id_after_explicit_value(ulonglong nr)
{
/*
If we have set THD::next_insert_id previously and plan to insert an
explicitely-specified value larger than this, we need to increase
THD::next_insert_id to be greater than the explicit value.
*/
if ((next_insert_id > 0) && (nr >= next_insert_id))
set_next_insert_id(compute_next_insert_id(nr, &table->in_use->variables));
}
/*
Computes the largest number X:
- smaller than or equal to "nr"
- of the form: auto_increment_offset + N * auto_increment_increment
where N>=0.
SYNOPSIS
prev_insert_id
nr Number to "round down"
variables variables struct containing auto_increment_increment and
auto_increment_offset
RETURN
The number X if it exists, "nr" otherwise.
*/
inline ulonglong
prev_insert_id(ulonglong nr, struct system_variables *variables)
{
if (unlikely(nr < variables->auto_increment_offset))
{
/*
There's nothing good we can do here. That is a pathological case, where
the offset is larger than the column's max possible value, i.e. not even
the first sequence value may be inserted. User will receive warning.
*/
DBUG_PRINT("info",("auto_increment: nr: %lu cannot honour "
"auto_increment_offset: %lu",
nr, variables->auto_increment_offset));
return nr;
}
if (variables->auto_increment_increment == 1)
return nr; // optimization of the formula below
nr= (((nr - variables->auto_increment_offset)) /
(ulonglong) variables->auto_increment_increment);
return (nr * (ulonglong) variables->auto_increment_increment +
variables->auto_increment_offset);
}
/*
Update the auto_increment field if necessary
......@@ -1643,8 +1695,7 @@ bool handler::update_auto_increment()
the last NULL needs to insert 3764, not the value of the first NULL plus
1).
*/
if ((next_insert_id > 0) && (nr >= next_insert_id))
set_next_insert_id(compute_next_insert_id(nr, variables));
adjust_next_insert_id_after_explicit_value(nr);
insert_id_for_cur_row= 0; // didn't generate anything
DBUG_RETURN(0);
}
......@@ -1736,12 +1787,15 @@ bool handler::update_auto_increment()
{
/*
field refused this value (overflow) and truncated it, use the result of
the truncation (which is going to be inserted).
the truncation (which is going to be inserted); however we try to
decrease it to honour auto_increment_* variables.
That will shift the left bound of the reserved interval, we don't
bother shifting the right bound (anyway any other value from this
interval will cause a duplicate key).
*/
nr= table->next_number_field->val_int();
nr= prev_insert_id(table->next_number_field->val_int(), variables);
if (unlikely(table->next_number_field->store((longlong) nr, TRUE)))
nr= table->next_number_field->val_int();
}
if (append)
{
......
......@@ -3401,6 +3401,9 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
}
}
}
/* Forget those values, for next binlogger: */
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
}
/*
......
......@@ -5334,10 +5334,10 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
/*
lock_tables() reads the contents of thd->lex, so they must be
initialized, so we should call lex_start(); to be even safer, we
call mysql_init_query() which does a more complete set of inits.
initialized. Contrary to in Table_map_log_event::exec_event() we don't
call mysql_init_query() as that may reset the binlog format.
*/
mysql_init_query(thd, NULL, 0);
lex_start(thd, NULL, 0);
while ((error= lock_tables(thd, rli->tables_to_lock,
rli->tables_to_lock_count, &need_reopen)))
......@@ -5840,6 +5840,12 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli)
}
else
{
/*
open_tables() reads the contents of thd->lex, so they must be
initialized, so we should call lex_start(); to be even safer, we
call mysql_init_query() which does a more complete set of inits.
*/
mysql_init_query(thd, NULL, 0);
/*
Check if the slave is set to use SBR. If so, it should switch
to using RBR until the end of the "statement", i.e., next
......@@ -5856,12 +5862,6 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli)
Note that for any table that should not be replicated, a filter is needed.
*/
uint count;
/*
open_tables() reads the contents of thd->lex, so they must be
initialized, so we should call lex_start(); to be even safer, we
call mysql_init_query() which does a more complete set of inits.
*/
mysql_init_query(thd, NULL, 0);
if ((error= open_tables(thd, &table_list, &count, 0)))
{
if (thd->query_error || thd->is_fatal_error)
......
......@@ -3319,11 +3319,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
#ifdef HAVE_ROW_BASED_REPLICATION
/*
CREATE ... SELECT UUID() locks no tables, we have to test here.
Note that we will not do the resetting if inside a stored
function/trigger, because the binlogging of those is decided earlier (by
the caller) and can't be changed afterwards.
*/
thd->reset_current_stmt_binlog_row_based();
if (thd->lex->binlog_row_based_if_mixed)
thd->set_current_stmt_binlog_row_based_if_mixed();
#endif /*HAVE_ROW_BASED_REPLICATION*/
......
......@@ -631,18 +631,6 @@ bool THD::store_globals()
void THD::cleanup_after_query()
{
/*
If in stored function or trigger, where statement-based binlogging logs
only the caller, the insert_id/last_insert_id stored in binlog must
describe their first values inside the routine or caller (the values when
they were first set). Otherwise (e.g. stored procedure) it must describe
their values for the current substatement.
*/
if (!prelocked_mode)
{
stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
auto_inc_intervals_in_cur_stmt_for_binlog.empty();
}
if (first_successful_insert_id_in_cur_stmt > 0)
{
/* set what LAST_INSERT_ID() will return */
......
......@@ -1149,8 +1149,9 @@ public:
column; our rules are
a) on master, while executing a top statement involving substatements,
first top- or sub- statement to generate auto_increment values wins the
exclusive right to write them to binlog (so the losers won't write their
values to binlog).
exclusive right to see its values be written to binlog (the write
will be done by the statement or its caller), and the losers won't see
their values be written to binlog.
b) on slave, while replicating a top statement involving substatements,
first top- or sub- statement to need to read auto_increment values from
the master's binlog wins the exclusive right to read them (so the losers
......
......@@ -986,12 +986,12 @@ trunc_by_del:
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
ha_enable_transaction(thd, FALSE);
mysql_init_select(thd->lex);
#ifdef HAVE_ROW_BASED_REPLICATION
bool save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based();
#endif
error= mysql_delete(thd, table_list, (COND*) 0, (SQL_LIST*) 0,
HA_POS_ERROR, LL(0), TRUE);
ha_enable_transaction(thd, TRUE);
thd->options= save_options;
thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(error);
}
......@@ -1076,7 +1076,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
if (info->ignore &&
!table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
{
table->file->restore_auto_increment();
table->file->restore_auto_increment(prev_insert_id);
goto ok_or_after_trg_err;
}
goto err;
......@@ -1096,7 +1096,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
trg_error= (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
TRG_ACTION_AFTER, TRUE));
info->copiedgoto ok_or_after_trg_err;
info->copied++;
goto ok_or_after_trg_err;
}
else /* DUP_REPLACE */
{
......@@ -1193,7 +1194,7 @@ err:
table->file->print_error(error,MYF(0));
before_trg_err:
table->file->restore_auto_increment();
table->file->restore_auto_increment(prev_insert_id);
if (key)
my_safe_afree(key, table->s->max_unique_length, MAX_KEY_LENGTH);
table->column_bitmaps_set(save_read_set, save_write_set);
......@@ -2054,7 +2055,7 @@ bool delayed_insert::handle_inserts(void)
thd.start_time=row->start_time;
thd.query_start_used=row->query_start_used;
/* for the binlog, forget auto_increment ids generated by previous rows */
thd.auto_inc_intervals_in_cur_stmt_for_binlog.empty();
// thd.auto_inc_intervals_in_cur_stmt_for_binlog.empty();
thd.first_successful_insert_id_in_prev_stmt=
row->first_successful_insert_id_in_prev_stmt;
thd.stmt_depends_on_first_successful_insert_id_in_prev_stmt=
......
......@@ -5843,10 +5843,11 @@ void mysql_reset_thd_for_next_command(THD *thd)
thd->rand_used= 0;
thd->sent_row_count= thd->examined_row_count= 0;
}
#ifdef HAVE_ROW_BASED_REPLICATION
/* If in a routine, we reset only at end of top statement. */
/*
Because we come here only for start of top-statements, binlog format is
constant inside a complex statement (using stored functions) etc.
*/
thd->reset_current_stmt_binlog_row_based();
#endif /*HAVE_ROW_BASED_REPLICATION*/
DBUG_VOID_RETURN;
}
......
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