Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
d7bc28fc
Commit
d7bc28fc
authored
Nov 09, 2007
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge mkindahl@bk-internal.mysql.com:/home/bk/mysql-5.0-rpl
into capulet.net:/home/bk/mysql-5.0-rpl
parents
4e72c47f
6957e84e
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
335 additions
and
210 deletions
+335
-210
mysql-test/r/binlog_killed.result
mysql-test/r/binlog_killed.result
+44
-0
mysql-test/r/binlog_killed_simulate.result
mysql-test/r/binlog_killed_simulate.result
+33
-0
mysql-test/t/binlog_killed.test
mysql-test/t/binlog_killed.test
+106
-138
mysql-test/t/binlog_killed_simulate-master.opt
mysql-test/t/binlog_killed_simulate-master.opt
+1
-0
mysql-test/t/binlog_killed_simulate.test
mysql-test/t/binlog_killed_simulate.test
+66
-0
mysql-test/t/rpl_dual_pos_advance.test
mysql-test/t/rpl_dual_pos_advance.test
+0
-6
mysql-test/t/rpl_temporary.test
mysql-test/t/rpl_temporary.test
+2
-0
sql/log.cc
sql/log.cc
+4
-7
sql/log_event.cc
sql/log_event.cc
+6
-5
sql/log_event.h
sql/log_event.h
+6
-4
sql/sql_delete.cc
sql/sql_delete.cc
+11
-7
sql/sql_insert.cc
sql/sql_insert.cc
+2
-1
sql/sql_load.cc
sql/sql_load.cc
+20
-6
sql/sql_update.cc
sql/sql_update.cc
+34
-36
No files found.
mysql-test/r/binlog_killed.result
View file @
d7bc28fc
...
...
@@ -9,4 +9,48 @@ insert into t2 values (null, null), (null, get_lock("a", 10));
select @result /* must be zero either way */;
@result
0
select RELEASE_LOCK("a");
RELEASE_LOCK("a")
1
delete from t1;
delete from t2;
insert into t1 values (1,1),(2,2);
begin;
update t1 set b=11 where a=2;
begin;
update t1 set b=b+10;
kill query ID;
rollback;
rollback;
select * from t1 order by a /* must be the same as before (1,1),(2,2) */;
a b
1 1
2 2
begin;
delete from t1 where a=2;
begin;
delete from t1 where a=2;
kill query ID;
rollback;
rollback;
select * from t1 order by a /* must be the same as before (1,1),(2,2) */;
a b
1 1
2 2
drop table if exists t4;
create table t4 (a int, b int) engine=innodb;
insert into t4 values (3, 3);
begin;
insert into t1 values (3, 3);
begin;
insert into t1 select * from t4 for update;
kill query ID;
rollback;
rollback;
select * from t1 /* must be the same as before (1,1),(2,2) */;
a b
1 1
2 2
drop table t4;
drop table t1,t2,t3;
end of the tests
mysql-test/r/binlog_killed_simulate.result
0 → 100644
View file @
d7bc28fc
drop table if exists t1,t2;
create table t1 (a int) engine=MyISAM;
insert into t1 set a=1;
reset master;
update t1 set a=2 /* will be "killed" after work has been done */;
select
(@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
is not null;
(@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
is not null
1
select 1 /* must return 1 as query completed before got killed*/;
1
1
create table t2 (a int, b int) ENGINE=MyISAM;
reset master;
load data infile '../std_data_ln/rpl_loaddata.dat' into table t2 /* will be "killed" in the middle */;
ERROR 70100: Query execution was interrupted
show binlog events from 98;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 98 Begin_load_query 1 # ;file_id=1;block_len=12
master-bin.000001 133 Execute_load_query 1 # use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t2 /* will be "killed" in the middle */ ;file_id=1
select
(@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
is not null;
(@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
is not null
1
select 0 /* must return 0 to mean the killed query is in */;
0
0
drop table t1,t2;
end of the tests
mysql-test/t/binlog_killed.test
View file @
d7bc28fc
...
...
@@ -55,194 +55,162 @@ enable_result_log;
select
@
result
/* must be zero either way */
;
# the functions are either *insensitive* to killing or killing can cause
# strange problmes with the error propagation out of SF's stack
# Bug#27563, Bug#27565, BUG#24971
#
# TODO: use if's block as regression test for the bugs or remove
#
if
(
0
)
{
delimiter
|
;
create
function
bug27563
()
RETURNS
int
(
11
)
DETERMINISTIC
begin
select
get_lock
(
"a"
,
10
)
into
@
a
;
return
1
;
end
|
delimiter
;
|
# the function is sensitive to killing requiring innodb though with wrong client error
# TO FIX in BUG#27565; TODO: remove --error 1105 afterwards
delimiter
|
;
create
function
bug27565
()
RETURNS
int
(
11
)
DETERMINISTIC
begin
select
a
from
t1
where
a
=
1
into
@
a
for
update
;
return
1
;
end
|
delimiter
;
|
reset
master
;
--
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
kill_query_calling_sp
.
binlog
connection
con1
;
select
RELEASE_LOCK
(
"a"
);
### ta table case: killing causes rollback
#
# bug#27571 asynchronous setting mysql_`query`::error and Query_log_e::error_code
#
# A. autocommit ON
connection
con1
;
select
get_lock
(
"a"
,
20
);
# checking that killing inside of select loops is safe as before
# killing after the loop can be only simulated - another test
connection
con2
;
let
$ID
=
`select connection_id()`
;
send
insert
into
t1
values
(
bug27563
(),
1
);
delete
from
t1
;
delete
from
t2
;
insert
into
t1
values
(
1
,
1
),(
2
,
2
);
#
# simple update
#
connection
con1
;
eval
kill
query
$ID
;
begin
;
update
t1
set
b
=
11
where
a
=
2
;
connection
con2
;
# todo (re-record test): after bugs 27563,27565 got fixed affected rows will report zero
--
enable_info
# todo: remove 0 return after fixing Bug#27563
--
error
0
,
ER_QUERY_INTERRUPTED
reap
;
### pb: wrong error
--
disable_info
###--replace_column 2 # 5 #
### show binlog events from 98 /* nothing in binlog unless Bug#27563 */;
show
master
status
/* must be only FD event unless Bug#27563 */
;
select
count
(
*
)
from
t1
/* must be zero unless Bug#27563 */
;
# M. multi-statement-ta
connection
con2
;
let
$ID
=
`select connection_id()`
;
begin
;
send
insert
into
t1
values
(
bug27563
(),
1
)
;
send
update
t1
set
b
=
b
+
10
;
connection
con1
;
--
replace_result
$ID
ID
eval
kill
query
$ID
;
rollback
;
# Bug #32148 killi query may be ineffective
# forced to comment out the test's outcome
# and mask out ineffective ER_QUERY_INTERRUPTED
# todo1: revert back upon fixing bug#32148
# todo2: the tests need refining in that
# killing should wait till the victim requested
# its lock (wait_condition available in 5.1 tests)
connection
con2
;
# todo (re-record test): after bugs 27563,27565 got fixed affected rows will report zero
--
enable_info
# todo: remove 0 return after fixing Bug#27563
--
error
0
,
ER_QUERY_INTERRUPTED
reap
;
--
disable_info
select
count
(
*
)
from
t1
/* must be zero unless Bug#27563 */
;
commit
;
rollback
;
select
*
from
t1
order
by
a
/* must be the same as before (1,1),(2,2) */
;
#
# multi update
# commented out as Bug #31807 multi-update,delete killing does not report with ER_QUERY_INTERRUPTED
# in the way
#
# connection con1;
# begin; update t1 set b=b+10;
### non-ta table case: killing must be recorded in binlog
# connection con2;
# send update t1 as t_1,t1 as t_2 set t_1.b=11 where t_2.a=2;
reset
master
;
# connection con1;
# --replace_result $ID ID
# eval kill query $ID;
# rollback;
# disable_abort_on_error;
# connection con2;
# --error HY000,ER_QUERY_INTERRUPTED
# reap;
# select * from t1 /* must be the same as before (1,1),(2,2) */;
# enable_abort_on_error;
#
# simple delete
#
connection
con1
;
begin
;
delete
from
t1
where
a
=
2
;
connection
con2
;
let
$ID
=
`select connection_id()`
;
send
insert
into
t2
values
(
bug27563
(),
1
);
begin
;
send
delete
from
t1
where
a
=
2
;
connection
con1
;
--
replace_result
$ID
ID
eval
kill
query
$ID
;
rollback
;
connection
con2
;
# todo: remove 0 return after fixing Bug#27563
--
error
0
,
ER_QUERY_INTERRUPTED
reap
;
select
count
(
*
)
from
t2
/* must be one */
;
#show binlog events from 98 /* must have the insert on non-ta table */;
show
master
status
/* must have the insert event more to FD */
;
# the value of the error flag of KILLED_QUERY is tested further
connection
con1
;
select
RELEASE_LOCK
(
"a"
);
### test with effective killing of SF()
delete
from
t1
;
delete
from
t2
;
insert
into
t1
values
(
1
,
1
);
insert
into
t2
values
(
1
,
1
);
rollback
;
# todo1,2 above
select
*
from
t1
order
by
a
/* must be the same as before (1,1),(2,2) */
;
#
# Bug#27565
# test where KILL is propagated as error to the top level
# still another bug with the error message to the user
# todo: fix reexecute the result file after fixing
#
begin
;
update
t1
set
b
=
0
where
a
=
1
;
connection
con2
;
let
$ID
=
`select connection_id()`
;
send
update
t2
set
b
=
bug27565
()
-
1
where
a
=
1
;
#
# multi delete
# the same as for multi-update
#
# connection con1;
# begin; delete from t1 where a=2;
connection
con1
;
eval
kill
query
$ID
;
commit
;
# connection con2;
# send delete t1 from t1 where t1.a=2;
connection
con2
;
# todo: fix Bug #27565 killed query of SF() is not reported correctly and
# remove 1105 (wrong)
#--error ER_QUERY_INTERRUPTED
--
error
1105
,
ER_QUERY_INTERRUPTED
reap
;
### pb: wrong error
select
*
from
t1
/* must be: (1,0) */
;
select
*
from
t2
/* must be as before: (1,1) */
;
# connection con1;
# --replace_result $ID ID
# eval kill query $ID;
# rollback;
## bug#22725 with effective and propagating killing
# connection con2;
# --error 0,ER_QUERY_INTERRUPTED
# reap;
# select * from t1 /* must be the same as before (1,1),(2,2) */;
#
# insert select
#
# top-level ta-table
connection
con1
;
delete
from
t3
;
reset
master
;
begin
;
update
t1
set
b
=
0
where
a
=
1
;
--
disable_warnings
drop
table
if
exists
t4
;
--
enable_warnings
create
table
t4
(
a
int
,
b
int
)
engine
=
innodb
;
insert
into
t4
values
(
3
,
3
);
begin
;
insert
into
t1
values
(
3
,
3
);
connection
con2
;
let
$ID
=
`select connection_id()`
;
# the query won't perform completely since the function gets interrupted
send
insert
into
t
3
values
(
0
,
0
),(
1
,
bug27565
())
;
begin
;
send
insert
into
t
1
select
*
from
t4
for
update
;
connection
con1
;
--
replace_result
$ID
ID
eval
kill
query
$ID
;
rollback
;
connection
con2
;
# todo: fix Bug #27565 killed query of SF() is not reported correctly and
# remove 1105 (wrong)
#--error ER_QUERY_INTERRUPTED
--
error
1105
,
ER_QUERY_INTERRUPTED
reap
;
### pb: wrong error
select
count
(
*
)
from
t3
/* must be zero */
;
show
master
status
/* nothing in binlog */
;
# top-level non-ta-table
connection
con1
;
delete
from
t2
;
reset
master
;
begin
;
update
t1
set
b
=
0
where
a
=
1
;
connection
con2
;
let
$ID
=
`select connection_id()`
;
# the query won't perform completely since the function gets intrurrupted
send
insert
into
t2
values
(
0
,
0
),(
1
,
bug27565
())
/* non-ta t2 */
;
connection
con1
;
eval
kill
query
$ID
;
--
error
0
,
ER_QUERY_INTERRUPTED
reap
;
# todo 1,2 above
rollback
;
select
*
from
t1
/* must be the same as before (1,1),(2,2) */
;
connection
con2
;
# todo: fix Bug #27565 killed query of SF() is not reported correctly and
# remove 1105 (wrong)
#--error ER_QUERY_INTERRUPTED
--
error
1105
,
ER_QUERY_INTERRUPTED
reap
;
### pb: wrong error
drop
table
t4
;
# cleanup for the sub-case
###
## non-ta table case: killing must be recorded in binlog
###
select
count
(
*
)
from
t2
/* count must be one */
;
show
master
status
/* insert into non-ta must be in binlog */
;
# In order to be deterministic the test needs INFORMATION_SCHEMA.PROCESSLIST
# which is not available on 5.0 at this time.
# Therefore, skip this part on 5.0.
drop
function
bug27563
;
drop
function
bug27565
;
}
system
rm
$MYSQLTEST_VARDIR
/
tmp
/
kill_query_calling_sp
.
binlog
;
#
# common cleanup
#
drop
table
t1
,
t2
,
t3
;
--
echo
end
of
the
tests
mysql-test/t/binlog_killed_simulate-master.opt
0 → 100644
View file @
d7bc28fc
--loose-debug=d,simulate_kill_bug27571
mysql-test/t/binlog_killed_simulate.test
0 → 100644
View file @
d7bc28fc
--
source
include
/
have_debug
.
inc
#
# bug#27571 asynchronous setting mysql_$query()'s local error and
# Query_log_event::error_code
#
--
disable_warnings
drop
table
if
exists
t1
,
t2
;
--
enable_warnings
#
# Checking that killing upon successful row-loop does not affect binlogging
#
create
table
t1
(
a
int
)
engine
=
MyISAM
;
insert
into
t1
set
a
=
1
;
reset
master
;
update
t1
set
a
=
2
/* will be "killed" after work has been done */
;
# a proof the query is binlogged with no error
--
exec
$MYSQL_BINLOG
--
start
-
position
=
98
$MYSQLTEST_VARDIR
/
log
/
master
-
bin
.
000001
>
$MYSQLTEST_VARDIR
/
tmp
/
binlog_killed_bug27571
.
binlog
--
replace_result
$MYSQLTEST_VARDIR
MYSQLTEST_VARDIR
eval
select
(
@
a
:=
load_file
(
"
$MYSQLTEST_VARDIR
/tmp/binlog_killed_bug27571.binlog"
))
is
not
null
;
--
replace_result
$MYSQL_TEST_DIR
MYSQL_TEST_DIR
let
$error_code
=
`select @a like "%#%error_code=0%" /* must return 1 */`
;
eval
select
$error_code
/* must return 1 as query completed before got killed*/
;
# cleanup for the sub-case
system
rm
$MYSQLTEST_VARDIR
/
tmp
/
binlog_killed_bug27571
.
binlog
;
#
# Checking that killing inside of row-loop for LOAD DATA into
# non-transactional table affects binlogging
#
create
table
t2
(
a
int
,
b
int
)
ENGINE
=
MyISAM
;
reset
master
;
--
error
ER_QUERY_INTERRUPTED
load
data
infile
'../std_data_ln/rpl_loaddata.dat'
into
table
t2
/* will be "killed" in the middle */
;
# a proof the query is binlogged with an error
source
include
/
show_binlog_events
.
inc
;
--
exec
$MYSQL_BINLOG
--
start
-
position
=
98
$MYSQLTEST_VARDIR
/
log
/
master
-
bin
.
000001
>
$MYSQLTEST_VARDIR
/
tmp
/
binlog_killed_bug27571
.
binlog
--
replace_result
$MYSQLTEST_VARDIR
MYSQLTEST_VARDIR
eval
select
(
@
a
:=
load_file
(
"
$MYSQLTEST_VARDIR
/tmp/binlog_killed_bug27571.binlog"
))
is
not
null
;
--
replace_result
$MYSQL_TEST_DIR
MYSQL_TEST_DIR
let
$error_code
=
`select @a like "%#%error_code=0%" /* must return 0*/`
;
eval
select
$error_code
/* must return 0 to mean the killed query is in */
;
# cleanup for the sub-case
system
rm
$MYSQLTEST_VARDIR
/
tmp
/
binlog_killed_bug27571
.
binlog
;
drop
table
t1
,
t2
;
--
echo
end
of
the
tests
mysql-test/t/rpl_dual_pos_advance.test
View file @
d7bc28fc
...
...
@@ -106,9 +106,3 @@ connection slave;
sync_with_master
;
# End of 4.1 tests
# Cleanup
# The A->B->A replication causes the master to start writing relay logs
# in var/run, remove them
remove_file
$MYSQLTEST_VARDIR
/
run
/
master
-
relay
-
bin
.
000001
;
remove_file
$MYSQLTEST_VARDIR
/
run
/
master
-
relay
-
bin
.
index
;
mysql-test/t/rpl_temporary.test
View file @
d7bc28fc
...
...
@@ -211,6 +211,8 @@ select * from t1;
connection
master
;
drop
table
t1
;
--
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
bug14157
.
sql
# Delete the anonymous users
source
include
/
delete_anonymous_users
.
inc
;
...
...
sql/log.cc
View file @
d7bc28fc
...
...
@@ -448,13 +448,10 @@ const char *MYSQL_LOG::generate_name(const char *log_name,
{
if
(
!
log_name
||
!
log_name
[
0
])
{
/*
TODO: The following should be using fn_format(); We just need to
first change fn_format() to cut the file name if it's too long.
*/
strmake
(
buff
,
pidfile_name
,
FN_REFLEN
-
5
);
strmov
(
fn_ext
(
buff
),
suffix
);
return
(
const
char
*
)
buff
;
strmake
(
buff
,
pidfile_name
,
FN_REFLEN
-
strlen
(
suffix
)
-
1
);
return
(
const
char
*
)
fn_format
(
buff
,
buff
,
""
,
suffix
,
MYF
(
MY_REPLACE_EXT
|
MY_REPLACE_DIR
));
}
// get rid of extension if the log is binary to avoid problems
if
(
strip_ext
)
...
...
sql/log_event.cc
View file @
d7bc28fc
...
...
@@ -4994,12 +4994,13 @@ int Begin_load_query_log_event::get_create_or_append() const
#ifndef MYSQL_CLIENT
Execute_load_query_log_event
::
Execute_load_query_log_event
(
THD
*
thd_arg
,
const
char
*
query_arg
,
ulong
query_length_arg
,
uint
fn_pos_start_arg
,
uint
fn_pos_end_arg
,
enum_load_dup_handling
dup_handling_arg
,
bool
using_trans
,
bool
suppress_use
)
:
ulong
query_length_arg
,
uint
fn_pos_start_arg
,
uint
fn_pos_end_arg
,
enum_load_dup_handling
dup_handling_arg
,
bool
using_trans
,
bool
suppress_use
,
THD
::
killed_state
killed_err_arg
)
:
Query_log_event
(
thd_arg
,
query_arg
,
query_length_arg
,
using_trans
,
suppress_use
),
suppress_use
,
killed_err_arg
),
file_id
(
thd_arg
->
file_id
),
fn_pos_start
(
fn_pos_start_arg
),
fn_pos_end
(
fn_pos_end_arg
),
dup_handling
(
dup_handling_arg
)
{
...
...
sql/log_event.h
View file @
d7bc28fc
...
...
@@ -1619,10 +1619,12 @@ class Execute_load_query_log_event: public Query_log_event
#ifndef MYSQL_CLIENT
Execute_load_query_log_event
(
THD
*
thd
,
const
char
*
query_arg
,
ulong
query_length
,
uint
fn_pos_start_arg
,
uint
fn_pos_end_arg
,
enum_load_dup_handling
dup_handling_arg
,
bool
using_trans
,
bool
suppress_use
);
ulong
query_length
,
uint
fn_pos_start_arg
,
uint
fn_pos_end_arg
,
enum_load_dup_handling
dup_handling_arg
,
bool
using_trans
,
bool
suppress_use
,
THD
::
killed_state
killed_err_arg
=
THD
::
KILLED_NO_VALUE
);
#ifdef HAVE_REPLICATION
void
pack_info
(
Protocol
*
protocol
);
int
exec_event
(
struct
st_relay_log_info
*
rli
);
...
...
sql/sql_delete.cc
View file @
d7bc28fc
...
...
@@ -38,6 +38,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
ha_rows
deleted
;
uint
usable_index
=
MAX_KEY
;
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
THD
::
killed_state
killed_status
=
THD
::
NOT_KILLED
;
DBUG_ENTER
(
"mysql_delete"
);
if
(
open_and_lock_tables
(
thd
,
table_list
))
...
...
@@ -280,8 +281,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
else
table
->
file
->
unlock_row
();
// Row failed selection, release lock on it
}
if
(
thd
->
killed
&&
!
error
)
error
=
1
;
// Aborted
killed_status
=
thd
->
killed
;
error
=
(
killed_status
==
THD
::
NOT_KILLED
)
?
error
:
1
;
thd
->
proc_info
=
"end"
;
end_read_record
(
&
info
);
free_io_cache
(
table
);
// Will not do any harm
...
...
@@ -326,7 +327,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if
(
error
<
0
)
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
transactional_table
,
FALSE
);
transactional_table
,
FALSE
,
killed_status
);
if
(
mysql_bin_log
.
write
(
&
qinfo
)
&&
transactional_table
)
error
=
1
;
}
...
...
@@ -729,7 +730,8 @@ void multi_delete::send_error(uint errcode,const char *err)
}
thd
->
transaction
.
all
.
modified_non_trans_table
=
true
;
}
DBUG_ASSERT
(
!
normal_tables
||
!
deleted
||
thd
->
transaction
.
stmt
.
modified_non_trans_table
);
DBUG_ASSERT
(
!
normal_tables
||
!
deleted
||
thd
->
transaction
.
stmt
.
modified_non_trans_table
);
DBUG_VOID_RETURN
;
}
...
...
@@ -817,6 +819,7 @@ int multi_delete::do_deletes()
bool
multi_delete
::
send_eof
()
{
THD
::
killed_state
killed_status
=
THD
::
NOT_KILLED
;
thd
->
proc_info
=
"deleting from reference tables"
;
/* Does deletes for the last n - 1 tables, returns 0 if ok */
...
...
@@ -824,7 +827,7 @@ bool multi_delete::send_eof()
/* compute a total error to know if something failed */
local_error
=
local_error
||
error
;
killed_status
=
(
local_error
==
0
)
?
THD
::
NOT_KILLED
:
thd
->
killed
;
/* reset used flags */
thd
->
proc_info
=
"end"
;
...
...
@@ -836,7 +839,8 @@ bool multi_delete::send_eof()
{
query_cache_invalidate3
(
thd
,
delete_tables
,
1
);
}
DBUG_ASSERT
(
!
normal_tables
||
!
deleted
||
thd
->
transaction
.
stmt
.
modified_non_trans_table
);
DBUG_ASSERT
(
!
normal_tables
||
!
deleted
||
thd
->
transaction
.
stmt
.
modified_non_trans_table
);
if
((
local_error
==
0
)
||
thd
->
transaction
.
stmt
.
modified_non_trans_table
)
{
if
(
mysql_bin_log
.
is_open
())
...
...
@@ -844,7 +848,7 @@ bool multi_delete::send_eof()
if
(
local_error
==
0
)
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
transactional_tables
,
FALSE
);
transactional_tables
,
FALSE
,
killed_status
);
if
(
mysql_bin_log
.
write
(
&
qinfo
)
&&
!
normal_tables
)
local_error
=
1
;
// Log write failed: roll back the SQL statement
}
...
...
sql/sql_insert.cc
View file @
d7bc28fc
...
...
@@ -2938,6 +2938,7 @@ bool select_insert::send_eof()
{
int
error
,
error2
;
bool
changed
,
transactional_table
=
table
->
file
->
has_transactions
();
THD
::
killed_state
killed_status
=
thd
->
killed
;
DBUG_ENTER
(
"select_insert::send_eof"
);
error
=
(
!
thd
->
prelocked_mode
)
?
table
->
file
->
end_bulk_insert
()
:
0
;
...
...
@@ -2967,7 +2968,7 @@ bool select_insert::send_eof()
if
(
!
error
)
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
transactional_table
,
FALSE
);
transactional_table
,
FALSE
,
killed_status
);
mysql_bin_log
.
write
(
&
qinfo
);
}
if
((
error2
=
ha_autocommit_or_rollback
(
thd
,
error
))
&&
!
error
)
...
...
sql/sql_load.cc
View file @
d7bc28fc
...
...
@@ -85,7 +85,8 @@ static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
#ifndef EMBEDDED_LIBRARY
static
bool
write_execute_load_query_log_event
(
THD
*
thd
,
bool
duplicates
,
bool
ignore
,
bool
transactional_table
);
bool
transactional_table
,
THD
::
killed_state
killed_status
);
#endif
/* EMBEDDED_LIBRARY */
/*
...
...
@@ -135,6 +136,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
char
*
tdb
=
thd
->
db
?
thd
->
db
:
db
;
// Result is never null
ulong
skip_lines
=
ex
->
skip_lines
;
bool
transactional_table
;
THD
::
killed_state
killed_status
=
THD
::
NOT_KILLED
;
DBUG_ENTER
(
"mysql_load"
);
#ifdef EMBEDDED_LIBRARY
...
...
@@ -404,7 +406,16 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
free_blobs
(
table
);
/* if pack_blob was used */
table
->
copy_blobs
=
0
;
thd
->
count_cuted_fields
=
CHECK_FIELD_IGNORE
;
/*
simulated killing in the middle of per-row loop
must be effective for binlogging
*/
DBUG_EXECUTE_IF
(
"simulate_kill_bug27571"
,
{
error
=
1
;
thd
->
killed
=
THD
::
KILL_QUERY
;
};);
killed_status
=
(
error
==
0
)
?
THD
::
NOT_KILLED
:
thd
->
killed
;
/*
We must invalidate the table in query cache before binlog writing and
ha_autocommit_...
...
...
@@ -446,7 +457,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
{
if
(
thd
->
transaction
.
stmt
.
modified_non_trans_table
)
write_execute_load_query_log_event
(
thd
,
handle_duplicates
,
ignore
,
transactional_table
);
ignore
,
transactional_table
,
killed_status
);
else
{
Delete_file_log_event
d
(
thd
,
db
,
transactional_table
);
...
...
@@ -477,7 +489,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
read_info
.
end_io_cache
();
if
(
lf_info
.
wrote_create_file
)
write_execute_load_query_log_event
(
thd
,
handle_duplicates
,
ignore
,
transactional_table
);
ignore
,
transactional_table
,
killed_status
);
}
#endif
/*!EMBEDDED_LIBRARY*/
if
(
transactional_table
)
...
...
@@ -504,7 +517,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
/* Not a very useful function; just to avoid duplication of code */
static
bool
write_execute_load_query_log_event
(
THD
*
thd
,
bool
duplicates
,
bool
ignore
,
bool
transactional_table
)
bool
transactional_table
,
THD
::
killed_state
killed_err_arg
)
{
Execute_load_query_log_event
e
(
thd
,
thd
->
query
,
thd
->
query_length
,
...
...
@@ -512,7 +526,7 @@ static bool write_execute_load_query_log_event(THD *thd,
(
char
*
)
thd
->
lex
->
fname_end
-
(
char
*
)
thd
->
query
,
(
duplicates
==
DUP_REPLACE
)
?
LOAD_DUP_REPLACE
:
(
ignore
?
LOAD_DUP_IGNORE
:
LOAD_DUP_ERROR
),
transactional_table
,
FALSE
);
transactional_table
,
FALSE
,
killed_err_arg
);
return
mysql_bin_log
.
write
(
&
e
);
}
...
...
sql/sql_update.cc
View file @
d7bc28fc
...
...
@@ -134,6 +134,7 @@ int mysql_update(THD *thd,
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
bool
need_reopen
;
List
<
Item
>
all_fields
;
THD
::
killed_state
killed_status
=
THD
::
NOT_KILLED
;
DBUG_ENTER
(
"mysql_update"
);
LINT_INIT
(
timestamp_query_id
);
...
...
@@ -519,43 +520,26 @@ int mysql_update(THD *thd,
table
->
file
->
unlock_row
();
thd
->
row_count
++
;
}
/*
Caching the killed status to pass as the arg to query event constuctor;
The cached value can not change whereas the killed status can
(externally) since this point and change of the latter won't affect
binlogging.
It's assumed that if an error was set in combination with an effective
killed status then the error is due to killing.
*/
killed_status
=
thd
->
killed
;
// get the status of the volatile
// simulated killing after the loop must be ineffective for binlogging
DBUG_EXECUTE_IF
(
"simulate_kill_bug27571"
,
{
thd
->
killed
=
THD
::
KILL_QUERY
;
};);
error
=
(
killed_status
==
THD
::
NOT_KILLED
)
?
error
:
1
;
if
(
!
transactional_table
&&
updated
>
0
)
thd
->
transaction
.
stmt
.
modified_non_trans_table
=
TRUE
;
/*
todo bug#27571: to avoid asynchronization of `error' and
`error_code' of binlog event constructor
The concept, which is a bit different for insert(!), is to
replace `error' assignment with the following lines
killed_status= thd->killed; // get the status of the volatile
Notice: thd->killed is type of "state" whereas the lhs has
"status" the suffix which translates according to WordNet: a state
at a particular time - at the time of the end of per-row loop in
our case. Binlogging ops are conducted with the status.
error= (killed_status == THD::NOT_KILLED)? error : 1;
which applies to most mysql_$query functions.
Event's constructor will accept `killed_status' as an argument:
Query_log_event qinfo(..., killed_status);
thd->killed might be changed after killed_status had got cached and this
won't affect binlogging event but other effects remain.
Open issue: In a case the error happened not because of KILLED -
and then KILLED was caught later still within the loop - we shall
do something to avoid binlogging of incorrect ER_SERVER_SHUTDOWN
error_code.
*/
if
(
thd
->
killed
&&
!
error
)
error
=
1
;
// Aborted
end_read_record
(
&
info
);
free_io_cache
(
table
);
// If ORDER BY
delete
select
;
...
...
@@ -587,7 +571,7 @@ int mysql_update(THD *thd,
if
(
error
<
0
)
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
transactional_table
,
FALSE
);
transactional_table
,
FALSE
,
killed_status
);
if
(
mysql_bin_log
.
write
(
&
qinfo
)
&&
transactional_table
)
error
=
1
;
// Rollback update
}
...
...
@@ -1522,6 +1506,11 @@ void multi_update::send_error(uint errcode,const char *err)
*/
if
(
mysql_bin_log
.
is_open
())
{
/*
THD::killed status might not have been set ON at time of an error
got caught and if happens later the killed error is written
into repl event.
*/
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
transactional_tables
,
FALSE
);
mysql_bin_log
.
write
(
&
qinfo
);
...
...
@@ -1709,10 +1698,19 @@ int multi_update::do_updates(bool from_send_error)
bool
multi_update
::
send_eof
()
{
char
buff
[
STRING_BUFFER_USUAL_SIZE
];
THD
::
killed_state
killed_status
=
THD
::
NOT_KILLED
;
thd
->
proc_info
=
"updating reference tables"
;
/* Does updates for the last n - 1 tables, returns 0 if ok */
/*
Does updates for the last n - 1 tables, returns 0 if ok;
error takes into account killed status gained in do_updates()
*/
int
local_error
=
(
table_count
)
?
do_updates
(
0
)
:
0
;
/*
if local_error is not set ON until after do_updates() then
later carried out killing should not affect binlogging.
*/
killed_status
=
(
local_error
==
0
)
?
THD
::
NOT_KILLED
:
thd
->
killed
;
thd
->
proc_info
=
"end"
;
/* We must invalidate the query cache before binlog writing and
...
...
@@ -1740,7 +1738,7 @@ bool multi_update::send_eof()
if
(
local_error
==
0
)
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
transactional_tables
,
FALSE
);
transactional_tables
,
FALSE
,
killed_status
);
if
(
mysql_bin_log
.
write
(
&
qinfo
)
&&
trans_safe
)
local_error
=
1
;
// Rollback update
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment