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
9397cbb8
Commit
9397cbb8
authored
May 16, 2008
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge mkindahl@bk-internal.mysql.com:/home/bk/mysql-5.1-bugteam
into mats-laptop.(none):/home/bkroot/mysql-5.1-bugteam
parents
19e1bc76
439cbe54
Changes
7
Show 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 @
19e1bc76
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 @
19e1bc76
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 @
19e1bc76
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 @
19e1bc76
--
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 @
9397cbb8
...
@@ -6425,15 +6425,29 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
...
@@ -6425,15 +6425,29 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
*/
*/
if (!thd->lock)
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
Lock_tables() reads the contents of thd->lex, so they must be
initialized. Contrary to in
initialized.
Table_map_log_event::do_apply_event() we don't call
mysql_init_query() as that may reset the binlog format.
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);
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.
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)
...
@@ -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 */
/* A small test to verify that objects have consistent types */
DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
if (simple_open_n_lock_tables(thd, rli->tables_to_lock))
while
((
error
=
lock_tables
(
thd
,
rli
->
tables_to_lock
,
rli
->
tables_to_lock_count
,
&
need_reopen
)))
{
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();
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
)))
{
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
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
simplifications (we don't honour --slave-skip-errors)
*/
*/
uint
actual_error
=
thd
->
main_da
.
sql_errno
();
rli->report(ERROR_LEVEL, actual_error,
rli->report(ERROR_LEVEL, actual_error,
"Error '%s' on re
opening tables"
,
"Error '%s' on
opening tables",
(actual_error ? thd->main_da.message() :
(actual_error ? thd->main_da.message() :
"unexpected success or fatal error"));
"unexpected success or fatal error"));
thd->is_slave_error= 1;
thd->is_slave_error= 1;
}
}
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
DBUG_RETURN
(
error
);
DBUG_RETURN(actual_error);
}
}
}
/*
/*
...
@@ -6570,6 +6535,8 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
...
@@ -6570,6 +6535,8 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
table=
table=
m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
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)
if (table)
{
{
/*
/*
...
@@ -7293,71 +7260,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
...
@@ -7293,71 +7260,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
}
}
else
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);
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
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)
...
@@ -7383,10 +7286,6 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
}
}
DBUG_RETURN(error);
DBUG_RETURN(error);
err:
my_free
(
memory
,
MYF
(
MY_WME
));
DBUG_RETURN
(
error
);
}
}
Log_event::enum_skip_reason
Log_event::enum_skip_reason
...
...
sql/log_event_old.cc
View file @
9397cbb8
...
@@ -53,81 +53,46 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
...
@@ -53,81 +53,46 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
*/
*/
if
(
!
thd
->
lock
)
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
Lock_tables() reads the contents of thd->lex, so they must be
initialized. Contrary to in
initialized.
Table_map_log_event::do_apply_event() we don't call
mysql_init_query() as that may reset the binlog format.
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
);
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
)))
{
if
(
!
need_reopen
)
{
if
(
thd
->
is_slave_error
||
thd
->
is_fatal_error
)
{
/*
/*
Error reporting borrowed from Query_log_event with many excessive
Check if the slave is set to use SBR. If so, it should switch
simplifications (we don't honour --slave-skip-errors)
to using RBR until the end of the "statement", i.e., next
STMT_END_F or next error.
*/
*/
uint
actual_error
=
thd
->
main_da
.
sql_errno
();
if
(
!
thd
->
current_stmt_binlog_row_based
&&
rli
->
report
(
ERROR_LEVEL
,
actual_error
,
mysql_bin_log
.
is_open
()
&&
(
thd
->
options
&
OPTION_BIN_LOG
))
"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
,
thd
->
set_current_stmt_binlog_row_based
();
"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
);
uint
tables_count
=
rli
->
tables_to_lock_count
;
if
(
simple_open_n_lock_tables
(
thd
,
rli
->
tables_to_lock
))
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
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
simplifications (we don't honour --slave-skip-errors)
*/
*/
uint
actual_error
=
thd
->
main_da
.
sql_errno
();
rli
->
report
(
ERROR_LEVEL
,
actual_error
,
rli
->
report
(
ERROR_LEVEL
,
actual_error
,
"Error '%s' on re
opening tables"
,
"Error '%s' on
opening tables"
,
(
actual_error
?
thd
->
main_da
.
message
()
:
(
actual_error
?
thd
->
main_da
.
message
()
:
"unexpected success or fatal error"
));
"unexpected success or fatal error"
));
thd
->
is_slave_error
=
1
;
thd
->
is_slave_error
=
1
;
}
}
const_cast
<
Relay_log_info
*>
(
rli
)
->
clear_tables_to_lock
();
const_cast
<
Relay_log_info
*>
(
rli
)
->
clear_tables_to_lock
();
DBUG_RETURN
(
error
);
DBUG_RETURN
(
actual_error
);
}
}
}
/*
/*
...
...
sql/sql_base.cc
View file @
9397cbb8
...
@@ -4367,6 +4367,11 @@ bool fix_merge_after_open(TABLE_LIST *old_child_list, TABLE_LIST **old_last,
...
@@ -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
prelocking it won't do such precaching and will simply reuse table list
which is already built.
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
RETURN
0 - OK
0 - OK
-1 - error
-1 - error
...
@@ -4579,7 +4584,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
...
@@ -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.
process its triggers since they never will be activated.
*/
*/
if
(
!
thd
->
prelocked_mode
&&
!
thd
->
lex
->
requires_prelocking
()
&&
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
)
tables
->
lock_type
>=
TL_WRITE_ALLOW_WRITE
)
{
{
if
(
!
query_tables_last_own
)
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