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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
a88babcb
Commit
a88babcb
authored
Nov 09, 2007
by
mats@capulet.net
Browse files
Options
Browse Files
Download
Plain Diff
Merge capulet.net:/home/bk/mysql-5.0-rpl
into capulet.net:/home/mats/devel/b31793-mysql-5.0-rpl
parents
a432d3de
d5ccec26
Changes
14
Show 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 @
a88babcb
...
@@ -9,4 +9,48 @@ insert into t2 values (null, null), (null, get_lock("a", 10));
...
@@ -9,4 +9,48 @@ insert into t2 values (null, null), (null, get_lock("a", 10));
select @result /* must be zero either way */;
select @result /* must be zero either way */;
@result
@result
0
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;
drop table t1,t2,t3;
end of the tests
mysql-test/r/binlog_killed_simulate.result
0 → 100644
View file @
a88babcb
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 @
a88babcb
...
@@ -55,194 +55,162 @@ enable_result_log;
...
@@ -55,194 +55,162 @@ enable_result_log;
select
@
result
/* must be zero either way */
;
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
# checking that killing inside of select loops is safe as before
connection
con1
;
# killing after the loop can be only simulated - another test
select
get_lock
(
"a"
,
20
);
connection
con2
;
delete
from
t1
;
let
$ID
=
`select connection_id()`
;
delete
from
t2
;
send
insert
into
t1
values
(
bug27563
(),
1
);
insert
into
t1
values
(
1
,
1
),(
2
,
2
);
#
# simple update
#
connection
con1
;
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
;
connection
con2
;
let
$ID
=
`select connection_id()`
;
let
$ID
=
`select connection_id()`
;
begin
;
begin
;
send
insert
into
t1
values
(
bug27563
(),
1
)
;
send
update
t1
set
b
=
b
+
10
;
connection
con1
;
connection
con1
;
--
replace_result
$ID
ID
eval
kill
query
$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
;
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
--
error
0
,
ER_QUERY_INTERRUPTED
reap
;
reap
;
--
disable_info
rollback
;
select
count
(
*
)
from
t1
/* must be zero unless Bug#27563 */
;
select
*
from
t1
order
by
a
/* must be the same as before (1,1),(2,2) */
;
commit
;
#
# 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
;
connection
con2
;
let
$ID
=
`select connection_id()`
;
let
$ID
=
`select connection_id()`
;
send
insert
into
t2
values
(
bug27563
(),
1
);
begin
;
send
delete
from
t1
where
a
=
2
;
connection
con1
;
connection
con1
;
--
replace_result
$ID
ID
eval
kill
query
$ID
;
eval
kill
query
$ID
;
rollback
;
connection
con2
;
connection
con2
;
# todo: remove 0 return after fixing Bug#27563
--
error
0
,
ER_QUERY_INTERRUPTED
--
error
0
,
ER_QUERY_INTERRUPTED
reap
;
reap
;
select
count
(
*
)
from
t2
/* must be one */
;
rollback
;
#show binlog events from 98 /* must have the insert on non-ta table */;
# todo1,2 above
show
master
status
/* must have the insert event more to FD */
;
select
*
from
t1
order
by
a
/* must be the same as before (1,1),(2,2) */
;
# 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
);
#
#
# Bug#27565
# multi delete
# test where KILL is propagated as error to the top level
# the same as for multi-update
# 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 con1;
# begin; delete from t1 where a=2;
connection
con2
;
let
$ID
=
`select connection_id()`
;
send
update
t2
set
b
=
bug27565
()
-
1
where
a
=
1
;
connection
con1
;
# connection con2;
eval
kill
query
$ID
;
# send delete t1 from t1 where t1.a=2;
commit
;
connection
con2
;
# connection con1;
# todo: fix Bug #27565 killed query of SF() is not reported correctly and
# --replace_result $ID ID
# remove 1105 (wrong)
# eval kill query $ID;
#--error ER_QUERY_INTERRUPTED
# rollback;
--
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) */
;
## 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
;
connection
con1
;
delete
from
t3
;
--
disable_warnings
reset
master
;
drop
table
if
exists
t4
;
begin
;
update
t1
set
b
=
0
where
a
=
1
;
--
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
;
connection
con2
;
let
$ID
=
`select connection_id()`
;
let
$ID
=
`select connection_id()`
;
# the query won't perform completely since the function gets interrupted
begin
;
send
insert
into
t
3
values
(
0
,
0
),(
1
,
bug27565
())
;
send
insert
into
t
1
select
*
from
t4
for
update
;
connection
con1
;
connection
con1
;
--
replace_result
$ID
ID
eval
kill
query
$ID
;
eval
kill
query
$ID
;
rollback
;
rollback
;
connection
con2
;
connection
con2
;
# todo: fix Bug #27565 killed query of SF() is not reported correctly and
--
error
0
,
ER_QUERY_INTERRUPTED
# remove 1105 (wrong)
reap
;
#--error ER_QUERY_INTERRUPTED
# todo 1,2 above
--
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
;
rollback
;
rollback
;
select
*
from
t1
/* must be the same as before (1,1),(2,2) */
;
connection
con2
;
drop
table
t4
;
# cleanup for the sub-case
# todo: fix Bug #27565 killed query of SF() is not reported correctly and
# remove 1105 (wrong)
###
#--error ER_QUERY_INTERRUPTED
## non-ta table case: killing must be recorded in binlog
--
error
1105
,
ER_QUERY_INTERRUPTED
###
reap
;
### pb: wrong error
select
count
(
*
)
from
t2
/* count must be one */
;
# In order to be deterministic the test needs INFORMATION_SCHEMA.PROCESSLIST
show
master
status
/* insert into non-ta must be in binlog */
;
# 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
;
drop
table
t1
,
t2
,
t3
;
--
echo
end
of
the
tests
mysql-test/t/binlog_killed_simulate-master.opt
0 → 100644
View file @
a88babcb
--loose-debug=d,simulate_kill_bug27571
mysql-test/t/binlog_killed_simulate.test
0 → 100644
View file @
a88babcb
--
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 @
a88babcb
...
@@ -106,9 +106,3 @@ connection slave;
...
@@ -106,9 +106,3 @@ connection slave;
sync_with_master
;
sync_with_master
;
# End of 4.1 tests
# 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 @
a88babcb
...
@@ -211,6 +211,8 @@ select * from t1;
...
@@ -211,6 +211,8 @@ select * from t1;
connection
master
;
connection
master
;
drop
table
t1
;
drop
table
t1
;
--
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
bug14157
.
sql
# Delete the anonymous users
# Delete the anonymous users
source
include
/
delete_anonymous_users
.
inc
;
source
include
/
delete_anonymous_users
.
inc
;
...
...
sql/log.cc
View file @
a88babcb
...
@@ -448,13 +448,10 @@ const char *MYSQL_LOG::generate_name(const char *log_name,
...
@@ -448,13 +448,10 @@ const char *MYSQL_LOG::generate_name(const char *log_name,
{
{
if
(
!
log_name
||
!
log_name
[
0
])
if
(
!
log_name
||
!
log_name
[
0
])
{
{
/*
strmake
(
buff
,
pidfile_name
,
FN_REFLEN
-
strlen
(
suffix
)
-
1
);
TODO: The following should be using fn_format(); We just need to
return
(
const
char
*
)
first change fn_format() to cut the file name if it's too long.
fn_format
(
buff
,
buff
,
""
,
suffix
,
MYF
(
MY_REPLACE_EXT
|
MY_REPLACE_DIR
));
*/
strmake
(
buff
,
pidfile_name
,
FN_REFLEN
-
5
);
strmov
(
fn_ext
(
buff
),
suffix
);
return
(
const
char
*
)
buff
;
}
}
// get rid of extension if the log is binary to avoid problems
// get rid of extension if the log is binary to avoid problems
if
(
strip_ext
)
if
(
strip_ext
)
...
...
sql/log_event.cc
View file @
a88babcb
...
@@ -5070,9 +5070,10 @@ Execute_load_query_log_event(THD* thd_arg, const char* query_arg,
...
@@ -5070,9 +5070,10 @@ Execute_load_query_log_event(THD* thd_arg, const char* query_arg,
ulong
query_length_arg
,
uint
fn_pos_start_arg
,
ulong
query_length_arg
,
uint
fn_pos_start_arg
,
uint
fn_pos_end_arg
,
uint
fn_pos_end_arg
,
enum_load_dup_handling
dup_handling_arg
,
enum_load_dup_handling
dup_handling_arg
,
bool
using_trans
,
bool
suppress_use
)
:
bool
using_trans
,
bool
suppress_use
,
THD
::
killed_state
killed_err_arg
)
:
Query_log_event
(
thd_arg
,
query_arg
,
query_length_arg
,
using_trans
,
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
),
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
)
fn_pos_end
(
fn_pos_end_arg
),
dup_handling
(
dup_handling_arg
)
{
{
...
...
sql/log_event.h
View file @
a88babcb
...
@@ -1622,7 +1622,9 @@ public:
...
@@ -1622,7 +1622,9 @@ public:
ulong
query_length
,
uint
fn_pos_start_arg
,
ulong
query_length
,
uint
fn_pos_start_arg
,
uint
fn_pos_end_arg
,
uint
fn_pos_end_arg
,
enum_load_dup_handling
dup_handling_arg
,
enum_load_dup_handling
dup_handling_arg
,
bool
using_trans
,
bool
suppress_use
);
bool
using_trans
,
bool
suppress_use
,
THD
::
killed_state
killed_err_arg
=
THD
::
KILLED_NO_VALUE
);
#ifdef HAVE_REPLICATION
#ifdef HAVE_REPLICATION
void
pack_info
(
Protocol
*
protocol
);
void
pack_info
(
Protocol
*
protocol
);
int
exec_event
(
struct
st_relay_log_info
*
rli
);
int
exec_event
(
struct
st_relay_log_info
*
rli
);
...
...
sql/sql_delete.cc
View file @
a88babcb
...
@@ -38,6 +38,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
...
@@ -38,6 +38,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
ha_rows
deleted
;
ha_rows
deleted
;
uint
usable_index
=
MAX_KEY
;
uint
usable_index
=
MAX_KEY
;
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
THD
::
killed_state
killed_status
=
THD
::
NOT_KILLED
;
DBUG_ENTER
(
"mysql_delete"
);
DBUG_ENTER
(
"mysql_delete"
);
if
(
open_and_lock_tables
(
thd
,
table_list
))
if
(
open_and_lock_tables
(
thd
,
table_list
))
...
@@ -280,8 +281,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
...
@@ -280,8 +281,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
else
else
table
->
file
->
unlock_row
();
// Row failed selection, release lock on it
table
->
file
->
unlock_row
();
// Row failed selection, release lock on it
}
}
if
(
thd
->
killed
&&
!
error
)
killed_status
=
thd
->
killed
;
error
=
1
;
// Aborted
error
=
(
killed_status
==
THD
::
NOT_KILLED
)
?
error
:
1
;
thd
->
proc_info
=
"end"
;
thd
->
proc_info
=
"end"
;
end_read_record
(
&
info
);
end_read_record
(
&
info
);
free_io_cache
(
table
);
// Will not do any harm
free_io_cache
(
table
);
// Will not do any harm
...
@@ -326,7 +327,7 @@ cleanup:
...
@@ -326,7 +327,7 @@ cleanup:
if
(
error
<
0
)
if
(
error
<
0
)
thd
->
clear_error
();
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
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
)
if
(
mysql_bin_log
.
write
(
&
qinfo
)
&&
transactional_table
)
error
=
1
;
error
=
1
;
}
}
...
@@ -729,7 +730,8 @@ void multi_delete::send_error(uint errcode,const char *err)
...
@@ -729,7 +730,8 @@ void multi_delete::send_error(uint errcode,const char *err)
}
}
thd
->
transaction
.
all
.
modified_non_trans_table
=
true
;
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
;
DBUG_VOID_RETURN
;
}
}
...
@@ -817,6 +819,7 @@ int multi_delete::do_deletes()
...
@@ -817,6 +819,7 @@ int multi_delete::do_deletes()
bool
multi_delete
::
send_eof
()
bool
multi_delete
::
send_eof
()
{
{
THD
::
killed_state
killed_status
=
THD
::
NOT_KILLED
;
thd
->
proc_info
=
"deleting from reference tables"
;
thd
->
proc_info
=
"deleting from reference tables"
;
/* Does deletes for the last n - 1 tables, returns 0 if ok */
/* Does deletes for the last n - 1 tables, returns 0 if ok */
...
@@ -824,7 +827,7 @@ bool multi_delete::send_eof()
...
@@ -824,7 +827,7 @@ bool multi_delete::send_eof()
/* compute a total error to know if something failed */
/* compute a total error to know if something failed */
local_error
=
local_error
||
error
;
local_error
=
local_error
||
error
;
killed_status
=
(
local_error
==
0
)
?
THD
::
NOT_KILLED
:
thd
->
killed
;
/* reset used flags */
/* reset used flags */
thd
->
proc_info
=
"end"
;
thd
->
proc_info
=
"end"
;
...
@@ -836,7 +839,8 @@ bool multi_delete::send_eof()
...
@@ -836,7 +839,8 @@ bool multi_delete::send_eof()
{
{
query_cache_invalidate3
(
thd
,
delete_tables
,
1
);
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
((
local_error
==
0
)
||
thd
->
transaction
.
stmt
.
modified_non_trans_table
)
{
{
if
(
mysql_bin_log
.
is_open
())
if
(
mysql_bin_log
.
is_open
())
...
@@ -844,7 +848,7 @@ bool multi_delete::send_eof()
...
@@ -844,7 +848,7 @@ bool multi_delete::send_eof()
if
(
local_error
==
0
)
if
(
local_error
==
0
)
thd
->
clear_error
();
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
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
)
if
(
mysql_bin_log
.
write
(
&
qinfo
)
&&
!
normal_tables
)
local_error
=
1
;
// Log write failed: roll back the SQL statement
local_error
=
1
;
// Log write failed: roll back the SQL statement
}
}
...
...
sql/sql_insert.cc
View file @
a88babcb
...
@@ -2938,6 +2938,7 @@ bool select_insert::send_eof()
...
@@ -2938,6 +2938,7 @@ bool select_insert::send_eof()
{
{
int
error
,
error2
;
int
error
,
error2
;
bool
changed
,
transactional_table
=
table
->
file
->
has_transactions
();
bool
changed
,
transactional_table
=
table
->
file
->
has_transactions
();
THD
::
killed_state
killed_status
=
thd
->
killed
;
DBUG_ENTER
(
"select_insert::send_eof"
);
DBUG_ENTER
(
"select_insert::send_eof"
);
error
=
(
!
thd
->
prelocked_mode
)
?
table
->
file
->
end_bulk_insert
()
:
0
;
error
=
(
!
thd
->
prelocked_mode
)
?
table
->
file
->
end_bulk_insert
()
:
0
;
...
@@ -2967,7 +2968,7 @@ bool select_insert::send_eof()
...
@@ -2967,7 +2968,7 @@ bool select_insert::send_eof()
if
(
!
error
)
if
(
!
error
)
thd
->
clear_error
();
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
transactional_table
,
FALSE
);
transactional_table
,
FALSE
,
killed_status
);
mysql_bin_log
.
write
(
&
qinfo
);
mysql_bin_log
.
write
(
&
qinfo
);
}
}
if
((
error2
=
ha_autocommit_or_rollback
(
thd
,
error
))
&&
!
error
)
if
((
error2
=
ha_autocommit_or_rollback
(
thd
,
error
))
&&
!
error
)
...
...
sql/sql_load.cc
View file @
a88babcb
...
@@ -85,7 +85,8 @@ static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
...
@@ -85,7 +85,8 @@ static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY
static
bool
write_execute_load_query_log_event
(
THD
*
thd
,
static
bool
write_execute_load_query_log_event
(
THD
*
thd
,
bool
duplicates
,
bool
ignore
,
bool
duplicates
,
bool
ignore
,
bool
transactional_table
);
bool
transactional_table
,
THD
::
killed_state
killed_status
);
#endif
/* EMBEDDED_LIBRARY */
#endif
/* EMBEDDED_LIBRARY */
/*
/*
...
@@ -135,6 +136,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
...
@@ -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
char
*
tdb
=
thd
->
db
?
thd
->
db
:
db
;
// Result is never null
ulong
skip_lines
=
ex
->
skip_lines
;
ulong
skip_lines
=
ex
->
skip_lines
;
bool
transactional_table
;
bool
transactional_table
;
THD
::
killed_state
killed_status
=
THD
::
NOT_KILLED
;
DBUG_ENTER
(
"mysql_load"
);
DBUG_ENTER
(
"mysql_load"
);
#ifdef EMBEDDED_LIBRARY
#ifdef EMBEDDED_LIBRARY
...
@@ -404,7 +406,16 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
...
@@ -404,7 +406,16 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
free_blobs
(
table
);
/* if pack_blob was used */
free_blobs
(
table
);
/* if pack_blob was used */
table
->
copy_blobs
=
0
;
table
->
copy_blobs
=
0
;
thd
->
count_cuted_fields
=
CHECK_FIELD_IGNORE
;
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
We must invalidate the table in query cache before binlog writing and
ha_autocommit_...
ha_autocommit_...
...
@@ -446,7 +457,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
...
@@ -446,7 +457,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
{
{
if
(
thd
->
transaction
.
stmt
.
modified_non_trans_table
)
if
(
thd
->
transaction
.
stmt
.
modified_non_trans_table
)
write_execute_load_query_log_event
(
thd
,
handle_duplicates
,
write_execute_load_query_log_event
(
thd
,
handle_duplicates
,
ignore
,
transactional_table
);
ignore
,
transactional_table
,
killed_status
);
else
else
{
{
Delete_file_log_event
d
(
thd
,
db
,
transactional_table
);
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,
...
@@ -477,7 +489,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
read_info
.
end_io_cache
();
read_info
.
end_io_cache
();
if
(
lf_info
.
wrote_create_file
)
if
(
lf_info
.
wrote_create_file
)
write_execute_load_query_log_event
(
thd
,
handle_duplicates
,
write_execute_load_query_log_event
(
thd
,
handle_duplicates
,
ignore
,
transactional_table
);
ignore
,
transactional_table
,
killed_status
);
}
}
#endif
/*!EMBEDDED_LIBRARY*/
#endif
/*!EMBEDDED_LIBRARY*/
if
(
transactional_table
)
if
(
transactional_table
)
...
@@ -504,7 +517,8 @@ err:
...
@@ -504,7 +517,8 @@ err:
/* Not a very useful function; just to avoid duplication of code */
/* Not a very useful function; just to avoid duplication of code */
static
bool
write_execute_load_query_log_event
(
THD
*
thd
,
static
bool
write_execute_load_query_log_event
(
THD
*
thd
,
bool
duplicates
,
bool
ignore
,
bool
duplicates
,
bool
ignore
,
bool
transactional_table
)
bool
transactional_table
,
THD
::
killed_state
killed_err_arg
)
{
{
Execute_load_query_log_event
Execute_load_query_log_event
e
(
thd
,
thd
->
query
,
thd
->
query_length
,
e
(
thd
,
thd
->
query
,
thd
->
query_length
,
...
@@ -512,7 +526,7 @@ static bool write_execute_load_query_log_event(THD *thd,
...
@@ -512,7 +526,7 @@ static bool write_execute_load_query_log_event(THD *thd,
(
char
*
)
thd
->
lex
->
fname_end
-
(
char
*
)
thd
->
query
,
(
char
*
)
thd
->
lex
->
fname_end
-
(
char
*
)
thd
->
query
,
(
duplicates
==
DUP_REPLACE
)
?
LOAD_DUP_REPLACE
:
(
duplicates
==
DUP_REPLACE
)
?
LOAD_DUP_REPLACE
:
(
ignore
?
LOAD_DUP_IGNORE
:
LOAD_DUP_ERROR
),
(
ignore
?
LOAD_DUP_IGNORE
:
LOAD_DUP_ERROR
),
transactional_table
,
FALSE
);
transactional_table
,
FALSE
,
killed_err_arg
);
return
mysql_bin_log
.
write
(
&
e
);
return
mysql_bin_log
.
write
(
&
e
);
}
}
...
...
sql/sql_update.cc
View file @
a88babcb
...
@@ -134,6 +134,7 @@ int mysql_update(THD *thd,
...
@@ -134,6 +134,7 @@ int mysql_update(THD *thd,
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
bool
need_reopen
;
bool
need_reopen
;
List
<
Item
>
all_fields
;
List
<
Item
>
all_fields
;
THD
::
killed_state
killed_status
=
THD
::
NOT_KILLED
;
DBUG_ENTER
(
"mysql_update"
);
DBUG_ENTER
(
"mysql_update"
);
LINT_INIT
(
timestamp_query_id
);
LINT_INIT
(
timestamp_query_id
);
...
@@ -519,43 +520,26 @@ int mysql_update(THD *thd,
...
@@ -519,43 +520,26 @@ int mysql_update(THD *thd,
table
->
file
->
unlock_row
();
table
->
file
->
unlock_row
();
thd
->
row_count
++
;
thd
->
row_count
++
;
}
}
if
(
!
transactional_table
&&
updated
>
0
)
thd
->
transaction
.
stmt
.
modified_non_trans_table
=
TRUE
;
/*
/*
todo bug#27571: to avoid asynchronization of `error' and
Caching the killed status to pass as the arg to query event constuctor;
`error_code' of binlog event constructor
The cached value can not change whereas the killed status can
(externally) since this point and change of the latter won't affect
The concept, which is a bit different for insert(!), is to
binlogging.
replace `error' assignment with the following lines
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
killed_status
=
thd
->
killed
;
// get the status of the volatile
// simulated killing after the loop must be ineffective for binlogging
Notice: thd->killed is type of "state" whereas the lhs has
DBUG_EXECUTE_IF
(
"simulate_kill_bug27571"
,
"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
thd
->
killed
=
THD
::
KILL_QUERY
;
our case. Binlogging ops are conducted with the status.
};);
error
=
(
killed_status
==
THD
::
NOT_KILLED
)
?
error
:
1
;
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 -
if
(
!
transactional_table
&&
updated
>
0
)
and then KILLED was caught later still within the loop - we shall
thd
->
transaction
.
stmt
.
modified_non_trans_table
=
TRUE
;
do something to avoid binlogging of incorrect ER_SERVER_SHUTDOWN
error_code.
*/
if
(
thd
->
killed
&&
!
error
)
error
=
1
;
// Aborted
end_read_record
(
&
info
);
end_read_record
(
&
info
);
free_io_cache
(
table
);
// If ORDER BY
free_io_cache
(
table
);
// If ORDER BY
delete
select
;
delete
select
;
...
@@ -587,7 +571,7 @@ int mysql_update(THD *thd,
...
@@ -587,7 +571,7 @@ int mysql_update(THD *thd,
if
(
error
<
0
)
if
(
error
<
0
)
thd
->
clear_error
();
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
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
)
if
(
mysql_bin_log
.
write
(
&
qinfo
)
&&
transactional_table
)
error
=
1
;
// Rollback update
error
=
1
;
// Rollback update
}
}
...
@@ -1522,6 +1506,11 @@ void multi_update::send_error(uint errcode,const char *err)
...
@@ -1522,6 +1506,11 @@ void multi_update::send_error(uint errcode,const char *err)
*/
*/
if
(
mysql_bin_log
.
is_open
())
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
,
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
transactional_tables
,
FALSE
);
transactional_tables
,
FALSE
);
mysql_bin_log
.
write
(
&
qinfo
);
mysql_bin_log
.
write
(
&
qinfo
);
...
@@ -1709,10 +1698,19 @@ err2:
...
@@ -1709,10 +1698,19 @@ err2:
bool
multi_update
::
send_eof
()
bool
multi_update
::
send_eof
()
{
{
char
buff
[
STRING_BUFFER_USUAL_SIZE
];
char
buff
[
STRING_BUFFER_USUAL_SIZE
];
THD
::
killed_state
killed_status
=
THD
::
NOT_KILLED
;
thd
->
proc_info
=
"updating reference tables"
;
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
;
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"
;
thd
->
proc_info
=
"end"
;
/* We must invalidate the query cache before binlog writing and
/* We must invalidate the query cache before binlog writing and
...
@@ -1740,7 +1738,7 @@ bool multi_update::send_eof()
...
@@ -1740,7 +1738,7 @@ bool multi_update::send_eof()
if
(
local_error
==
0
)
if
(
local_error
==
0
)
thd
->
clear_error
();
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
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
)
if
(
mysql_bin_log
.
write
(
&
qinfo
)
&&
trans_safe
)
local_error
=
1
;
// Rollback update
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