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
439cbe54
Commit
439cbe54
authored
May 15, 2008
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge mats-laptop.(none):/home/bkroot/mysql-5.1-bugteam
into mats-laptop.(none):/home/bk/b36197-mysql-5.1-bugteam
parents
4f706f33
d2a75dc9
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
74 additions
and
812 deletions
+74
-812
mysql-test/suite/rpl/r/rpl_found_rows.result
mysql-test/suite/rpl/r/rpl_found_rows.result
+0
-233
mysql-test/suite/rpl/r/rpl_row_inexist_tbl.result
mysql-test/suite/rpl/r/rpl_row_inexist_tbl.result
+0
-59
mysql-test/suite/rpl/t/rpl_found_rows.test
mysql-test/suite/rpl/t/rpl_found_rows.test
+0
-256
mysql-test/suite/rpl/t/rpl_slave_status.test
mysql-test/suite/rpl/t/rpl_slave_status.test
+0
-59
sql/log_event.cc
sql/log_event.cc
+36
-137
sql/log_event_old.cc
sql/log_event_old.cc
+32
-67
sql/sql_base.cc
sql/sql_base.cc
+6
-1
No files found.
mysql-test/suite/rpl/r/rpl_found_rows.result
deleted
100644 → 0
View file @
4f706f33
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
==== 0. Setting it all up ====
SET BINLOG_FORMAT=STATEMENT;
**** On Master ****
CREATE TABLE t1 (a INT);
CREATE TABLE logtbl (sect INT, test INT, count INT);
INSERT INTO t1 VALUES (1),(2),(3);
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
#### 1. Using statement mode ####
==== 1.1. Simple test ====
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
SELECT FOUND_ROWS() INTO @a;
INSERT INTO logtbl VALUES(1,1,@a);
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1;
a
1
SELECT FOUND_ROWS() INTO @a;
INSERT INTO logtbl VALUES(1,2,@a);
SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
sect test count
1 1 183
1 2 3
**** On Slave ****
SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
sect test count
1 1 183
1 2 3
==== 1.2. Stored procedure ====
**** On Master ****
CREATE PROCEDURE calc_and_log(sect INT, test INT) BEGIN
DECLARE cnt INT;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO cnt;
INSERT INTO logtbl VALUES(sect,test,cnt);
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO cnt;
INSERT INTO logtbl VALUES(sect,test+1,cnt);
END $$
CALL calc_and_log(2,1);
a
1
a
7
CREATE PROCEDURE just_log(sect INT, test INT, found_rows INT) BEGIN
INSERT INTO logtbl VALUES (sect,test,found_rows);
END $$
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
SELECT FOUND_ROWS() INTO @found_rows;
CALL just_log(2,3,@found_rows);
SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test;
sect test count
2 1 3
2 2 183
2 3 183
**** On Slave ****
SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test;
sect test count
2 1 3
2 2 183
2 3 183
==== 1.3. Stored functions ====
**** On Master ****
CREATE FUNCTION log_rows(sect INT, test INT, found_rows INT)
RETURNS INT
BEGIN
INSERT INTO logtbl VALUES(sect,test,found_rows);
RETURN found_rows;
END $$
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
SELECT FOUND_ROWS() INTO @found_rows;
SELECT log_rows(3,1,@found_rows), log_rows(3,2,@found_rows);
log_rows(3,1,@found_rows) log_rows(3,2,@found_rows)
183 183
SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test;
sect test count
3 1 183
3 2 183
**** On Slave ****
SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test;
sect test count
3 1 183
3 2 183
==== 1.9. Cleanup ====
**** On Master ****
DELETE FROM logtbl;
DROP PROCEDURE just_log;
DROP PROCEDURE calc_and_log;
DROP FUNCTION log_rows;
**** Resetting master and slave ****
STOP SLAVE;
RESET SLAVE;
RESET MASTER;
START SLAVE;
#### 2. Using mixed mode ####
==== 2.1. Checking a procedure ====
**** On Master ****
SET BINLOG_FORMAT=MIXED;
CREATE PROCEDURE just_log(sect INT, test INT) BEGIN
INSERT INTO logtbl VALUES (sect,test,FOUND_ROWS());
END $$
**** On Master 1 ****
SET BINLOG_FORMAT=MIXED;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
CALL just_log(1,1);
**** On Master ****
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
CALL just_log(1,2);
**** On Master 1 ****
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1;
a
1
CALL just_log(1,3);
**** On Master ****
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
CALL just_log(1,4);
SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
sect test count
1 1 183
1 2 183
1 3 3
1 4 183
**** On Slave ****
SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
sect test count
1 1 183
1 2 183
1 3 3
1 4 183
==== 2.1. Checking a stored function ====
**** On Master ****
CREATE FUNCTION log_rows(sect INT, test INT)
RETURNS INT
BEGIN
DECLARE found_rows INT;
SELECT FOUND_ROWS() INTO found_rows;
INSERT INTO logtbl VALUES(sect,test,found_rows);
RETURN found_rows;
END $$
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1;
a
1
SELECT log_rows(2,1), log_rows(2,2);
log_rows(2,1) log_rows(2,2)
3 3
CREATE TABLE t2 (a INT, b INT);
CREATE TRIGGER t2_tr BEFORE INSERT ON t2 FOR EACH ROW
BEGIN
INSERT INTO logtbl VALUES (NEW.a, NEW.b, FOUND_ROWS());
END $$
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1;
a
1
INSERT INTO t2 VALUES (2,3), (2,4);
DROP TRIGGER t2_tr;
CREATE TRIGGER t2_tr BEFORE INSERT ON t2 FOR EACH ROW
BEGIN
DECLARE dummy INT;
SELECT log_rows(NEW.a, NEW.b) INTO dummy;
END $$
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
INSERT INTO t2 VALUES (2,5), (2,6);
DROP TRIGGER t2_tr;
CREATE PROCEDURE log_me_inner(sect INT, test INT)
BEGIN
DECLARE dummy INT;
SELECT log_rows(sect, test) INTO dummy;
SELECT log_rows(sect, test+1) INTO dummy;
END $$
CREATE PROCEDURE log_me(sect INT, test INT)
BEGIN
CALL log_me_inner(sect,test);
END $$
CREATE TRIGGER t2_tr BEFORE INSERT ON t2 FOR EACH ROW
BEGIN
CALL log_me(NEW.a, NEW.b);
END $$
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
INSERT INTO t2 VALUES (2,5), (2,6);
SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test;
sect test count
2 1 3
2 2 3
2 3 3
2 4 3
2 5 183
2 5 183
2 6 183
2 6 0
2 6 183
2 7 0
SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test;
sect test count
2 1 3
2 2 3
2 3 3
2 4 3
2 5 183
2 5 183
2 6 183
2 6 0
2 6 183
2 7 0
DROP TABLE t1, logtbl;
DROP PROCEDURE just_log;
DROP PROCEDURE log_me;
DROP PROCEDURE log_me_inner;
DROP FUNCTION log_rows;
mysql-test/suite/rpl/r/rpl_row_inexist_tbl.result
deleted
100644 → 0
View file @
4f706f33
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
create table t1 (a int not null primary key);
insert into t1 values (1);
create table t2 (a int);
insert into t2 values (1);
update t1, t2 set t1.a = 0 where t1.a = t2.a;
show tables;
Tables_in_test
t1
select * from t1;
a
0
drop table t1;
insert into t1 values (1);
SHOW SLAVE STATUS;
Slave_IO_State #
Master_Host 127.0.0.1
Master_User root
Master_Port MASTER_PORT
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos 1153
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1146
Last_Error Error 'Table 'test.t1' doesn't exist' on opening table `test`.`t1`
Skip_Counter 0
Exec_Master_Log_Pos 941
Relay_Log_Space #
Until_Condition None
Until_Log_File
Until_Log_Pos 0
Master_SSL_Allowed No
Master_SSL_CA_File
Master_SSL_CA_Path
Master_SSL_Cert
Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1146
Last_SQL_Error Error 'Table 'test.t1' doesn't exist' on opening table `test`.`t1`
drop table t1, t2;
mysql-test/suite/rpl/t/rpl_found_rows.test
deleted
100644 → 0
View file @
4f706f33
source
include
/
master
-
slave
.
inc
;
# It is not possible to replicate FOUND_ROWS() using statement-based
# replication, but there is a workaround that stores the result of
# FOUND_ROWS() into a user variable and then replicates this instead.
# The purpose of this test case is to test that the workaround
# function properly even when inside stored programs (i.e., stored
# routines and triggers).
--
echo
====
0.
Setting
it
all
up
====
SET
BINLOG_FORMAT
=
STATEMENT
;
--
echo
****
On
Master
****
connection
master
;
CREATE
TABLE
t1
(
a
INT
);
CREATE
TABLE
logtbl
(
sect
INT
,
test
INT
,
count
INT
);
INSERT
INTO
t1
VALUES
(
1
),(
2
),(
3
);
INSERT
INTO
t1
SELECT
2
*
a
+
3
FROM
t1
;
INSERT
INTO
t1
SELECT
2
*
a
+
3
FROM
t1
;
INSERT
INTO
t1
SELECT
2
*
a
+
3
FROM
t1
;
INSERT
INTO
t1
SELECT
2
*
a
+
3
FROM
t1
;
INSERT
INTO
t1
SELECT
2
*
a
+
3
FROM
t1
;
INSERT
INTO
t1
SELECT
2
*
a
+
3
FROM
t1
;
--
echo
#### 1. Using statement mode ####
--
echo
====
1.1
.
Simple
test
====
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
>
5
ORDER
BY
a
LIMIT
1
;
# Instead of
# INSERT INTO logtbl VALUES(1, 1, FOUND_ROWS());
# we write
SELECT
FOUND_ROWS
()
INTO
@
a
;
INSERT
INTO
logtbl
VALUES
(
1
,
1
,
@
a
);
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
<
5
ORDER
BY
a
LIMIT
1
;
# Instead of
# INSERT INTO logtbl VALUES(1, 2, FOUND_ROWS());
# we write
SELECT
FOUND_ROWS
()
INTO
@
a
;
INSERT
INTO
logtbl
VALUES
(
1
,
2
,
@
a
);
SELECT
*
FROM
logtbl
WHERE
sect
=
1
ORDER
BY
sect
,
test
;
--
echo
****
On
Slave
****
sync_slave_with_master
;
SELECT
*
FROM
logtbl
WHERE
sect
=
1
ORDER
BY
sect
,
test
;
--
echo
====
1.2
.
Stored
procedure
====
# Here we do both the calculation and the logging. We also do it twice
# to make sure that there are no limitations on how many times it can
# be used.
--
echo
****
On
Master
****
connection
master
;
--
delimiter
$$
CREATE
PROCEDURE
calc_and_log
(
sect
INT
,
test
INT
)
BEGIN
DECLARE
cnt
INT
;
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
<
5
ORDER
BY
a
LIMIT
1
;
SELECT
FOUND_ROWS
()
INTO
cnt
;
INSERT
INTO
logtbl
VALUES
(
sect
,
test
,
cnt
);
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
>
5
ORDER
BY
a
LIMIT
1
;
SELECT
FOUND_ROWS
()
INTO
cnt
;
INSERT
INTO
logtbl
VALUES
(
sect
,
test
+
1
,
cnt
);
END
$$
--
delimiter
;
CALL
calc_and_log
(
2
,
1
);
--
delimiter
$$
CREATE
PROCEDURE
just_log
(
sect
INT
,
test
INT
,
found_rows
INT
)
BEGIN
INSERT
INTO
logtbl
VALUES
(
sect
,
test
,
found_rows
);
END
$$
--
delimiter
;
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
>
5
ORDER
BY
a
LIMIT
1
;
SELECT
FOUND_ROWS
()
INTO
@
found_rows
;
CALL
just_log
(
2
,
3
,
@
found_rows
);
SELECT
*
FROM
logtbl
WHERE
sect
=
2
ORDER
BY
sect
,
test
;
--
echo
****
On
Slave
****
sync_slave_with_master
;
SELECT
*
FROM
logtbl
WHERE
sect
=
2
ORDER
BY
sect
,
test
;
--
echo
====
1.3
.
Stored
functions
====
--
echo
****
On
Master
****
connection
master
;
--
delimiter
$$
CREATE
FUNCTION
log_rows
(
sect
INT
,
test
INT
,
found_rows
INT
)
RETURNS
INT
BEGIN
INSERT
INTO
logtbl
VALUES
(
sect
,
test
,
found_rows
);
RETURN
found_rows
;
END
$$
--
delimiter
;
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
>
5
ORDER
BY
a
LIMIT
1
;
SELECT
FOUND_ROWS
()
INTO
@
found_rows
;
SELECT
log_rows
(
3
,
1
,
@
found_rows
),
log_rows
(
3
,
2
,
@
found_rows
);
SELECT
*
FROM
logtbl
WHERE
sect
=
3
ORDER
BY
sect
,
test
;
--
echo
****
On
Slave
****
sync_slave_with_master
;
SELECT
*
FROM
logtbl
WHERE
sect
=
3
ORDER
BY
sect
,
test
;
--
echo
====
1.9
.
Cleanup
====
--
echo
****
On
Master
****
connection
master
;
DELETE
FROM
logtbl
;
DROP
PROCEDURE
just_log
;
DROP
PROCEDURE
calc_and_log
;
DROP
FUNCTION
log_rows
;
sync_slave_with_master
;
source
include
/
reset_master_and_slave
.
inc
;
--
echo
#### 2. Using mixed mode ####
--
echo
====
2.1
.
Checking
a
procedure
====
--
echo
****
On
Master
****
connection
master
;
SET
BINLOG_FORMAT
=
MIXED
;
# We will now check some stuff that will not work in statement-based
# replication, but which should cause the binary log to switch to
# row-based logging.
--
delimiter
$$
CREATE
PROCEDURE
just_log
(
sect
INT
,
test
INT
)
BEGIN
INSERT
INTO
logtbl
VALUES
(
sect
,
test
,
FOUND_ROWS
());
END
$$
--
delimiter
;
sync_slave_with_master
;
--
echo
****
On
Master
1
****
connection
master1
;
SET
BINLOG_FORMAT
=
MIXED
;
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
>
5
ORDER
BY
a
LIMIT
1
;
CALL
just_log
(
1
,
1
);
--
echo
****
On
Master
****
connection
master
;
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
>
5
ORDER
BY
a
LIMIT
1
;
CALL
just_log
(
1
,
2
);
--
echo
****
On
Master
1
****
connection
master1
;
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
<
5
ORDER
BY
a
LIMIT
1
;
CALL
just_log
(
1
,
3
);
sync_slave_with_master
;
--
echo
****
On
Master
****
connection
master
;
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
>
5
ORDER
BY
a
LIMIT
1
;
CALL
just_log
(
1
,
4
);
sync_slave_with_master
;
connection
master
;
SELECT
*
FROM
logtbl
WHERE
sect
=
1
ORDER
BY
sect
,
test
;
--
echo
****
On
Slave
****
sync_slave_with_master
;
SELECT
*
FROM
logtbl
WHERE
sect
=
1
ORDER
BY
sect
,
test
;
--
echo
====
2.1
.
Checking
a
stored
function
====
--
echo
****
On
Master
****
connection
master
;
--
delimiter
$$
CREATE
FUNCTION
log_rows
(
sect
INT
,
test
INT
)
RETURNS
INT
BEGIN
DECLARE
found_rows
INT
;
SELECT
FOUND_ROWS
()
INTO
found_rows
;
INSERT
INTO
logtbl
VALUES
(
sect
,
test
,
found_rows
);
RETURN
found_rows
;
END
$$
--
delimiter
;
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
<
5
ORDER
BY
a
LIMIT
1
;
SELECT
log_rows
(
2
,
1
),
log_rows
(
2
,
2
);
CREATE
TABLE
t2
(
a
INT
,
b
INT
);
# Trying with referencing FOUND_ROWS() directly in the trigger.
--
delimiter
$$
CREATE
TRIGGER
t2_tr
BEFORE
INSERT
ON
t2
FOR
EACH
ROW
BEGIN
INSERT
INTO
logtbl
VALUES
(
NEW
.
a
,
NEW
.
b
,
FOUND_ROWS
());
END
$$
--
delimiter
;
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
<
5
ORDER
BY
a
LIMIT
1
;
INSERT
INTO
t2
VALUES
(
2
,
3
),
(
2
,
4
);
# Referencing FOUND_ROWS() indirectly.
DROP
TRIGGER
t2_tr
;
--
delimiter
$$
CREATE
TRIGGER
t2_tr
BEFORE
INSERT
ON
t2
FOR
EACH
ROW
BEGIN
DECLARE
dummy
INT
;
SELECT
log_rows
(
NEW
.
a
,
NEW
.
b
)
INTO
dummy
;
END
$$
--
delimiter
;
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
>
5
ORDER
BY
a
LIMIT
1
;
INSERT
INTO
t2
VALUES
(
2
,
5
),
(
2
,
6
);
# Putting FOUND_ROWS() even lower in the call chain.
connection
master
;
DROP
TRIGGER
t2_tr
;
--
delimiter
$$
CREATE
PROCEDURE
log_me_inner
(
sect
INT
,
test
INT
)
BEGIN
DECLARE
dummy
INT
;
SELECT
log_rows
(
sect
,
test
)
INTO
dummy
;
SELECT
log_rows
(
sect
,
test
+
1
)
INTO
dummy
;
END
$$
CREATE
PROCEDURE
log_me
(
sect
INT
,
test
INT
)
BEGIN
CALL
log_me_inner
(
sect
,
test
);
END
$$
--
delimiter
;
--
delimiter
$$
CREATE
TRIGGER
t2_tr
BEFORE
INSERT
ON
t2
FOR
EACH
ROW
BEGIN
CALL
log_me
(
NEW
.
a
,
NEW
.
b
);
END
$$
--
delimiter
;
SELECT
SQL_CALC_FOUND_ROWS
*
FROM
t1
WHERE
a
>
5
ORDER
BY
a
LIMIT
1
;
INSERT
INTO
t2
VALUES
(
2
,
5
),
(
2
,
6
);
SELECT
*
FROM
logtbl
WHERE
sect
=
2
ORDER
BY
sect
,
test
;
sync_slave_with_master
;
SELECT
*
FROM
logtbl
WHERE
sect
=
2
ORDER
BY
sect
,
test
;
connection
master
;
DROP
TABLE
t1
,
logtbl
;
DROP
PROCEDURE
just_log
;
DROP
PROCEDURE
log_me
;
DROP
PROCEDURE
log_me_inner
;
DROP
FUNCTION
log_rows
;
sync_slave_with_master
;
mysql-test/suite/rpl/t/rpl_slave_status.test
deleted
100644 → 0
View file @
4f706f33
--
source
include
/
master
-
slave
.
inc
############################################################################
# Test case for BUG#10780
#
# REQUIREMENT
# A slave without replication privileges should have Slave_IO_Running = No
# 1. Create new replication user
connection
master
;
grant
replication
slave
on
*.*
to
rpl
@
127.0
.
0.1
identified
by
'rpl'
;
connection
slave
;
stop
slave
;
change
master
to
master_user
=
'rpl'
,
master_password
=
'rpl'
;
start
slave
;
# 2. Do replication as new user
connection
master
;
--
disable_warnings
drop
table
if
exists
t1
;
--
enable_warnings
create
table
t1
(
n
int
);
insert
into
t1
values
(
1
);
save_master_pos
;
connection
slave
;
sync_with_master
;
select
*
from
t1
;
# 3. Delete new replication user
connection
master
;
delete
from
mysql
.
user
where
user
=
'rpl'
;
flush
privileges
;
connection
slave
;
# 4. Restart slave without privileges
# (slave.err will contain access denied error for this START SLAVE command)
stop
slave
;
start
slave
;
# 5. Make sure Slave_IO_Running = No
--
replace_result
$MASTER_MYPORT
MASTER_MYPORT
# Column 1 is replaced, since the output can be either
# "Connecting to master" or "Waiting for master update"
--
replace_column
1
# 7 # 8 # 9 # 22 # 23 # 35 # 36 #
--
vertical_results
show
slave
status
;
# Cleanup (Note that slave IO thread is not running)
connection
slave
;
drop
table
t1
;
delete
from
mysql
.
user
where
user
=
'rpl'
;
# cleanup: slave io thread has been stopped "irrecoverably"
# so we clean up mess manually
connection
master
;
drop
table
t1
;
# end of 4.1 tests
sql/log_event.cc
View file @
439cbe54
...
...
@@ -6425,15 +6425,29 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
*/
if
(
!
thd
->
lock
)
{
bool
need_reopen
=
1
;
/* To execute the first lap of the loop below */
/*
lock_tables() reads the contents of thd->lex, so they must be
initialized. Contrary to in
Table_map_log_event::do_apply_event() we don't call
mysql_init_query() as that may reset the binlog format.
Lock_tables() reads the contents of thd->lex, so they must be
initialized.
We also call the mysql_reset_thd_for_next_command(), since this
is the logical start of the next "statement". Note that this
call might reset the value of current_stmt_binlog_row_based, so
we need to do any changes to that value after this function.
*/
lex_start
(
thd
);
mysql_reset_thd_for_next_command
(
thd
);
/*
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
STMT_END_F or next error.
*/
if
(
!
thd
->
current_stmt_binlog_row_based
&&
mysql_bin_log
.
is_open
()
&&
(
thd
->
options
&
OPTION_BIN_LOG
))
{
thd
->
set_current_stmt_binlog_row_based
();
}
/*
There are a few flags that are replicated with each row event.
...
...
@@ -6452,72 +6466,23 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
/* A small test to verify that objects have consistent types */
DBUG_ASSERT
(
sizeof
(
thd
->
options
)
==
sizeof
(
OPTION_RELAXED_UNIQUE_CHECKS
));
while
((
error
=
lock_tables
(
thd
,
rli
->
tables_to_lock
,
rli
->
tables_to_lock_count
,
&
need_reopen
)))
if
(
simple_open_n_lock_tables
(
thd
,
rli
->
tables_to_lock
))
{
if
(
!
need_reopen
)
{
if
(
thd
->
is_slave_error
||
thd
->
is_fatal_error
)
{
/*
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
*/
uint
actual_error
=
thd
->
main_da
.
sql_errno
();
rli
->
report
(
ERROR_LEVEL
,
actual_error
,
"Error '%s' in %s event: when locking tables"
,
(
actual_error
?
thd
->
main_da
.
message
()
:
"unexpected success or fatal error"
),
get_type_str
());
thd
->
is_fatal_error
=
1
;
}
else
{
rli
->
report
(
ERROR_LEVEL
,
error
,
"Error in %s event: when locking tables"
,
get_type_str
());
}
const_cast
<
Relay_log_info
*>
(
rli
)
->
clear_tables_to_lock
();
DBUG_RETURN
(
error
);
}
/*
So we need to reopen the tables.
We need to flush the pending RBR event, since it keeps a
pointer to an open table.
ALTERNATIVE SOLUTION (not implemented): Extract a pointer to
the pending RBR event and reset the table pointer after the
tables has been reopened.
NOTE: For this new scheme there should be no pending event:
need to add code to assert that is the case.
*/
thd
->
binlog_flush_pending_rows_event
(
false
);
TABLE_LIST
*
tables
=
rli
->
tables_to_lock
;
close_tables_for_reopen
(
thd
,
&
tables
);
uint
tables_count
=
rli
->
tables_to_lock_count
;
if
((
error
=
open_tables
(
thd
,
&
tables
,
&
tables_count
,
0
)))
uint
actual_error
=
thd
->
main_da
.
sql_errno
();
if
(
thd
->
is_slave_error
||
thd
->
is_fatal_error
)
{
if
(
thd
->
is_slave_error
||
thd
->
is_fatal_error
)
{
/*
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
*/
uint
actual_error
=
thd
->
main_da
.
sql_errno
();
rli
->
report
(
ERROR_LEVEL
,
actual_error
,
"Error '%s' on reopening tables"
,
(
actual_error
?
thd
->
main_da
.
message
()
:
"unexpected success or fatal error"
));
thd
->
is_slave_error
=
1
;
}
const_cast
<
Relay_log_info
*>
(
rli
)
->
clear_tables_to_lock
();
DBUG_RETURN
(
error
);
/*
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
*/
rli
->
report
(
ERROR_LEVEL
,
actual_error
,
"Error '%s' on opening tables"
,
(
actual_error
?
thd
->
main_da
.
message
()
:
"unexpected success or fatal error"
));
thd
->
is_slave_error
=
1
;
}
const_cast
<
Relay_log_info
*>
(
rli
)
->
clear_tables_to_lock
();
DBUG_RETURN
(
actual_error
);
}
/*
...
...
@@ -6570,6 +6535,8 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
table
=
m_table
=
const_cast
<
Relay_log_info
*>
(
rli
)
->
m_table_map
.
get_table
(
m_table_id
);
DBUG_PRINT
(
"debug"
,
(
"m_table: 0x%lx, m_table_id: %lu"
,
(
ulong
)
m_table
,
m_table_id
));
if
(
table
)
{
/*
...
...
@@ -7293,71 +7260,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *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.
*/
lex_start
(
thd
);
mysql_reset_thd_for_next_command
(
thd
);
/*
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
STMT_END_F or next error.
*/
if
(
!
thd
->
current_stmt_binlog_row_based
&&
mysql_bin_log
.
is_open
()
&&
(
thd
->
options
&
OPTION_BIN_LOG
))
{
thd
->
set_current_stmt_binlog_row_based
();
}
/*
Open the table if it is not already open and add the table to
table map. Note that for any table that should not be
replicated, a filter is needed.
The creation of a new TABLE_LIST is used to up-cast the
table_list consisting of RPL_TABLE_LIST items. This will work
since the only case where the argument to open_tables() is
changed, is when thd->lex->query_tables == table_list, i.e.,
when the statement requires prelocking. Since this is not
executed when a statement is executed, this case will not occur.
As a precaution, an assertion is added to ensure that the bad
case is not a fact.
Either way, the memory in the list is *never* released
internally in the open_tables() function, hence we take a copy
of the pointer to make sure that it's not lost.
*/
uint
count
;
DBUG_ASSERT
(
thd
->
lex
->
query_tables
!=
table_list
);
TABLE_LIST
*
tmp_table_list
=
table_list
;
if
((
error
=
open_tables
(
thd
,
&
tmp_table_list
,
&
count
,
0
)))
{
if
(
thd
->
is_slave_error
||
thd
->
is_fatal_error
)
{
/*
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
*/
uint
actual_error
=
thd
->
main_da
.
sql_errno
();
rli
->
report
(
ERROR_LEVEL
,
actual_error
,
"Error '%s' on opening table `%s`.`%s`"
,
(
actual_error
?
thd
->
main_da
.
message
()
:
"unexpected success or fatal error"
),
table_list
->
db
,
table_list
->
table_name
);
thd
->
is_slave_error
=
1
;
}
goto
err
;
}
m_table
=
table_list
->
table
;
/*
This will fail later otherwise, the 'in_use' field should be
set to the current thread.
*/
DBUG_ASSERT
(
m_table
->
in_use
);
/*
Use placement new to construct the table_def instance in the
...
...
@@ -7383,10 +7286,6 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
}
DBUG_RETURN
(
error
);
err:
my_free
(
memory
,
MYF
(
MY_WME
));
DBUG_RETURN
(
error
);
}
Log_event
::
enum_skip_reason
...
...
sql/log_event_old.cc
View file @
439cbe54
...
...
@@ -53,81 +53,46 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
*/
if
(
!
thd
->
lock
)
{
bool
need_reopen
=
1
;
/* To execute the first lap of the loop below */
/*
lock_tables() reads the contents of thd->lex, so they must be
initialized. Contrary to in
Table_map_log_event::do_apply_event() we don't call
mysql_init_query() as that may reset the binlog format.
Lock_tables() reads the contents of thd->lex, so they must be
initialized.
We also call the mysql_reset_thd_for_next_command(), since this
is the logical start of the next "statement". Note that this
call might reset the value of current_stmt_binlog_row_based, so
we need to do any changes to that value after this function.
*/
lex_start
(
thd
);
mysql_reset_thd_for_next_command
(
thd
);
while
((
error
=
lock_tables
(
thd
,
rli
->
tables_to_lock
,
rli
->
tables_to_lock_count
,
&
need_reopen
)))
/*
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
STMT_END_F or next error.
*/
if
(
!
thd
->
current_stmt_binlog_row_based
&&
mysql_bin_log
.
is_open
()
&&
(
thd
->
options
&
OPTION_BIN_LOG
))
{
if
(
!
need_reopen
)
{
if
(
thd
->
is_slave_error
||
thd
->
is_fatal_error
)
{
/*
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
*/
uint
actual_error
=
thd
->
main_da
.
sql_errno
();
rli
->
report
(
ERROR_LEVEL
,
actual_error
,
"Error '%s' in %s event: when locking tables"
,
(
actual_error
?
thd
->
main_da
.
message
()
:
"unexpected success or fatal error"
),
ev
->
get_type_str
());
thd
->
is_fatal_error
=
1
;
}
else
{
rli
->
report
(
ERROR_LEVEL
,
error
,
"Error in %s event: when locking tables"
,
ev
->
get_type_str
());
}
const_cast
<
Relay_log_info
*>
(
rli
)
->
clear_tables_to_lock
();
DBUG_RETURN
(
error
);
}
/*
So we need to reopen the tables.
We need to flush the pending RBR event, since it keeps a
pointer to an open table.
ALTERNATIVE SOLUTION (not implemented): Extract a pointer to
the pending RBR event and reset the table pointer after the
tables has been reopened.
NOTE: For this new scheme there should be no pending event:
need to add code to assert that is the case.
*/
thd
->
binlog_flush_pending_rows_event
(
false
);
TABLE_LIST
*
tables
=
rli
->
tables_to_lock
;
close_tables_for_reopen
(
thd
,
&
tables
);
thd
->
set_current_stmt_binlog_row_based
();
}
uint
tables_count
=
rli
->
tables_to_lock_count
;
if
((
error
=
open_tables
(
thd
,
&
tables
,
&
tables_count
,
0
)))
if
(
simple_open_n_lock_tables
(
thd
,
rli
->
tables_to_lock
))
{
uint
actual_error
=
thd
->
main_da
.
sql_errno
();
if
(
thd
->
is_slave_error
||
thd
->
is_fatal_error
)
{
if
(
thd
->
is_slave_error
||
thd
->
is_fatal_error
)
{
/*
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
*/
uint
actual_error
=
thd
->
main_da
.
sql_errno
();
rli
->
report
(
ERROR_LEVEL
,
actual_error
,
"Error '%s' on reopening tables"
,
(
actual_error
?
thd
->
main_da
.
message
()
:
"unexpected success or fatal error"
));
thd
->
is_slave_error
=
1
;
}
const_cast
<
Relay_log_info
*>
(
rli
)
->
clear_tables_to_lock
();
DBUG_RETURN
(
error
);
/*
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
*/
rli
->
report
(
ERROR_LEVEL
,
actual_error
,
"Error '%s' on opening tables"
,
(
actual_error
?
thd
->
main_da
.
message
()
:
"unexpected success or fatal error"
));
thd
->
is_slave_error
=
1
;
}
const_cast
<
Relay_log_info
*>
(
rli
)
->
clear_tables_to_lock
();
DBUG_RETURN
(
actual_error
);
}
/*
...
...
sql/sql_base.cc
View file @
439cbe54
...
...
@@ -4367,6 +4367,11 @@ bool fix_merge_after_open(TABLE_LIST *old_child_list, TABLE_LIST **old_last,
prelocking it won't do such precaching and will simply reuse table list
which is already built.
If any table has a trigger and start->trg_event_map is non-zero
the final lock will end up in thd->locked_tables, otherwise, the
lock will be placed in thd->lock. See also comments in
st_lex::set_trg_event_type_for_tables().
RETURN
0 - OK
-1 - error
...
...
@@ -4579,7 +4584,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
process its triggers since they never will be activated.
*/
if
(
!
thd
->
prelocked_mode
&&
!
thd
->
lex
->
requires_prelocking
()
&&
tables
->
table
->
triggers
&&
tables
->
t
rg_event_map
&&
tables
->
t
able
->
triggers
&&
tables
->
lock_type
>=
TL_WRITE_ALLOW_WRITE
)
{
if
(
!
query_tables_last_own
)
...
...
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