1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

WL#2687 WL#5072 BUG#40278 BUG#47175

Non-transactional updates that take place inside a transaction present problems
for logging because they are visible to other clients before the transaction
is committed, and they are not rolled back even if the transaction is rolled
back. It is not always possible to log correctly in statement format when both
transactional and non-transactional tables are used in the same transaction.

In the current patch, we ensure that such scenario is completely safe under the
ROW and MIXED modes.
This commit is contained in:
Alfranio Correia
2009-11-03 19:02:56 +00:00
parent 97565b8d1a
commit 19c380aaff
149 changed files with 41957 additions and 3661 deletions

View File

@ -118,6 +118,7 @@ ERROR 23000: Duplicate entry '20' for key 'a'
show warnings;
Level Code Message
Error 1062 Duplicate entry '20' for key 'a'
Warning 1196 Some non-transactional changed tables couldn't be rolled back
select * from t2;
a
20
@ -270,6 +271,7 @@ end|
do fn1(100);
Warnings:
Error 1062 Duplicate entry '100' for key 'a'
Warning 1196 Some non-transactional changed tables couldn't be rolled back
select fn1(20);
ERROR 23000: Duplicate entry '20' for key 'a'
select * from t2;
@ -421,9 +423,15 @@ set b = 8;
insert into t1 values (b);
insert into t1 values (unix_timestamp());
end
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; insert into t1 values ( NAME_CONST('b',8))
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; insert into t1 values (unix_timestamp())
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; delete from t1
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `foo2`()
select * from mysqltest1.t1
master-bin.000001 # Query # # use `mysqltest1`; alter procedure foo2 contains sql
@ -442,13 +450,25 @@ begin
insert into t2 values(3);
insert into t1 values (5);
end
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; insert into t2 values(3)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; insert into t1 values (15)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; insert into t2 values(3)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `mysqltest1`; alter procedure foo4 sql security invoker
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; insert into t2 values(3)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; insert into t1 values (5)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; delete from t2
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `mysqltest1`; alter table t2 add unique (a)
master-bin.000001 # Query # # use `mysqltest1`; drop procedure foo4
master-bin.000001 # Query # # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `foo4`()
@ -456,7 +476,9 @@ master-bin.000001 # Query # # use `mysqltest1`; CREATE DEFINER=`root`@`localhost
begin
insert into t2 values(20),(20);
end
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; insert into t2 values(20),(20)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `mysqltest1`; drop procedure foo4
master-bin.000001 # Query # # use `mysqltest1`; drop procedure foo
master-bin.000001 # Query # # use `mysqltest1`; drop procedure foo2
@ -467,17 +489,27 @@ begin
insert into t1 values (x);
return x+2;
end
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; delete t1,t2 from t1,t2
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; SELECT `mysqltest1`.`fn1`(20)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; insert into t2 values(fn1(21))
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `mysqltest1`; drop function fn1
master-bin.000001 # Query # # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` FUNCTION `fn1`() RETURNS int(11)
NO SQL
begin
return unix_timestamp();
end
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; delete from t1
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; insert into t1 values(fn1())
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `mysqltest1`; CREATE DEFINER=`zedjzlcsjhd`@`127.0.0.1` FUNCTION `fn2`() RETURNS int(11)
NO SQL
begin
@ -488,7 +520,9 @@ master-bin.000001 # Query # # use `mysqltest1`; CREATE DEFINER=`root`@`localhost
begin
return 0;
end
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; delete from t2
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `mysqltest1`; alter table t2 add unique (a)
master-bin.000001 # Query # # use `mysqltest1`; drop function fn1
master-bin.000001 # Query # # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` FUNCTION `fn1`(x int) RETURNS int(11)
@ -496,14 +530,26 @@ begin
insert into t2 values(x),(x);
return 10;
end
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; SELECT `mysqltest1`.`fn1`(100)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; SELECT `mysqltest1`.`fn1`(20)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; delete from t1
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` trigger trg before insert on t1 for each row set new.a= 10
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; insert into t1 values (1)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; delete from t1
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `mysqltest1`; drop trigger trg
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest1`; insert into t1 values (1)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `foo`()
READS SQL DATA
select * from t1
@ -524,7 +570,9 @@ return var;
end
master-bin.000001 # Query # # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 as a
master-bin.000001 # Query # # use `test`; create table t1 (a int)
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; insert into t1 (a) values (f1())
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; drop view v1
master-bin.000001 # Query # # use `test`; drop function f1
master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS p1
@ -532,7 +580,9 @@ master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1(col VARCHAR(10))
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(arg VARCHAR(10))
INSERT INTO t1 VALUES(arg)
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES( NAME_CONST('arg',_latin1'test' COLLATE 'latin1_swedish_ci'))
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; DROP PROCEDURE p1
master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS p1
master-bin.000001 # Query # # use `test`; DROP FUNCTION IF EXISTS f1
@ -550,13 +600,17 @@ master-bin.000001 # Query # # create database mysqltest2
master-bin.000001 # Query # # use `mysqltest2`; create table t ( t integer )
master-bin.000001 # Query # # use `mysqltest2`; CREATE DEFINER=`root`@`localhost` PROCEDURE `mysqltest`.`test`()
begin end
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest2`; insert into t values ( 1 )
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `mysqltest2`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
begin
insert into t values (1);
return 0;
end
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `mysqltest`; SELECT `mysqltest2`.`f1`()
master-bin.000001 # Query # # COMMIT
set @@global.log_bin_trust_routine_creators= @old_log_bin_trust_routine_creators;
Warnings:
Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead
@ -645,15 +699,33 @@ insert into t1 values (unix_timestamp());
end
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t1 values ( NAME_CONST('b',8))
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t1 values (unix_timestamp())
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
delete from t1
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
CREATE DEFINER=`root`@`localhost` PROCEDURE `foo2`()
select * from mysqltest1.t1
/*!*/;
@ -692,27 +764,63 @@ insert into t1 values (5);
end
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t2 values(3)
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t1 values (15)
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t2 values(3)
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
alter procedure foo4 sql security invoker
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t2 values(3)
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t1 values (5)
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
delete from t2
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
alter table t2 add unique (a)
/*!*/;
SET TIMESTAMP=t/*!*/;
@ -726,9 +834,15 @@ insert into t2 values(20),(20);
end
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t2 values(20),(20)
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
drop procedure foo4
/*!*/;
SET TIMESTAMP=t/*!*/;
@ -749,15 +863,33 @@ return x+2;
end
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
delete t1,t2 from t1,t2
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
SELECT `mysqltest1`.`fn1`(20)
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t2 values(fn1(21))
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
drop function fn1
/*!*/;
SET TIMESTAMP=t/*!*/;
@ -768,12 +900,24 @@ return unix_timestamp();
end
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
delete from t1
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t1 values(fn1())
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
CREATE DEFINER=`zedjzlcsjhd`@`127.0.0.1` FUNCTION `fn2`() RETURNS int(11)
NO SQL
begin
@ -788,9 +932,15 @@ return 0;
end
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
delete from t2
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
alter table t2 add unique (a)
/*!*/;
SET TIMESTAMP=t/*!*/;
@ -804,30 +954,66 @@ return 10;
end
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
SELECT `mysqltest1`.`fn1`(100)
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
SELECT `mysqltest1`.`fn1`(20)
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
delete from t1
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
CREATE DEFINER=`root`@`localhost` trigger trg before insert on t1 for each row set new.a= 10
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t1 values (1)
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
delete from t1
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
drop trigger trg
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t1 values (1)
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
CREATE DEFINER=`root`@`localhost` PROCEDURE `foo`()
READS SQL DATA
select * from t1
@ -867,9 +1053,15 @@ SET TIMESTAMP=t/*!*/;
create table t1 (a int)
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t1 (a) values (f1())
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
drop view v1
/*!*/;
SET TIMESTAMP=t/*!*/;
@ -889,9 +1081,15 @@ CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(arg VARCHAR(10))
INSERT INTO t1 VALUES(arg)
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
INSERT INTO t1 VALUES( NAME_CONST('arg',_latin1'test' COLLATE 'latin1_swedish_ci'))
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
DROP PROCEDURE p1
/*!*/;
SET TIMESTAMP=t/*!*/;
@ -938,20 +1136,32 @@ CREATE DEFINER=`root`@`localhost` PROCEDURE `mysqltest`.`test`()
begin end
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=t/*!*/;
insert into t values ( 1 )
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
begin
insert into t values (1);
return 0;
end
/*!*/;
SET TIMESTAMP=t/*!*/;
BEGIN
/*!*/;
use mysqltest/*!*/;
SET TIMESTAMP=t/*!*/;
SELECT `mysqltest2`.`f1`()
/*!*/;
SET TIMESTAMP=t/*!*/;
COMMIT
/*!*/;
SET TIMESTAMP=t/*!*/;
drop database mysqltest
/*!*/;
SET TIMESTAMP=t/*!*/;