mirror of
https://github.com/MariaDB/server.git
synced 2025-01-24 07:44:22 +01:00
4dc7be62a9
Problem: When RAND() is binlogged in statement mode, the seed is binlogged too, so the replication slave generates the same sequence of random numbers. This makes replication work in many cases, but not in all cases: the order of rows is not guaranteed for, e.g., UPDATE or INSERT...SELECT statements, so the row data will be different if master and slave retrieve the rows in different orders. Fix: Mark RAND() as unsafe. It will generate a warning if binlog_format=STATEMENT and switch to row-logging if binlog_format=ROW. mysql-test/extra/rpl_tests/rpl_row_func003.test: updated test case to ignore new warnings mysql-test/suite/binlog/r/binlog_unsafe.result: updated result file mysql-test/suite/binlog/t/binlog_unsafe.test: Added test for RAND(). Also clarified some old comments. mysql-test/suite/rpl/r/rpl_misc_functions.result: updated result file mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result: updated test case to ignore new warnings mysql-test/suite/rpl/r/rpl_optimize.result: updated result file mysql-test/suite/rpl/r/rpl_row_func003.result: updated result file mysql-test/suite/rpl/t/rpl_misc_functions.test: updated test case to ignore new warnings mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test: updated test case to ignore new warnings mysql-test/suite/rpl/t/rpl_optimize.test: updated test case to ignore new warnings mysql-test/suite/rpl/t/rpl_trigger.test: updated test case to ignore new warnings mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result: updated result file sql/item_create.cc: Mark RAND() unsafe.
97 lines
3.4 KiB
Text
97 lines
3.4 KiB
Text
#############################################################################
|
|
# Original Author: JBM #
|
|
# Original Date: Aug/15/2005 #
|
|
# Update: 08/29/2005 Comment out sleep. Only needed for debugging #
|
|
#############################################################################
|
|
# Note: Many lines are commented out in this test case. These were used for #
|
|
# creating the test case and debugging and are being left for #
|
|
# debugging, but they can not be used for the regular testing as the #
|
|
# Time changes and is not deteministic, so instead we dump both the #
|
|
# master and slave and diff the dumps. If the dumps differ then the #
|
|
# test case will fail. To run during diff failuers, comment out the #
|
|
# diff. #
|
|
# Test: Tests MySQL stored function using RAND() and a flow control. The #
|
|
# test inserts rows into a givin table with the function used in #
|
|
# the insert statement. Depending on the RAND() value returned #
|
|
# inside the function one set of text is returned. In addition, #
|
|
# it uses a transaction to see the effect a rollback has on master #
|
|
# Vs slave. #
|
|
#############################################################################
|
|
|
|
CALL mtr.add_suppression('Statement may not be safe to log in statement format.');
|
|
|
|
# Begin clean up test section
|
|
connection master;
|
|
--disable_warnings
|
|
DROP FUNCTION IF EXISTS test.f1;
|
|
DROP TABLE IF EXISTS test.t1;
|
|
|
|
--enable_warnings
|
|
|
|
|
|
eval CREATE TABLE test.t1 (a INT NOT NULL AUTO_INCREMENT, c CHAR(16),PRIMARY KEY(a))ENGINE=$engine_type;
|
|
|
|
delimiter |;
|
|
create function test.f1() RETURNS CHAR(16)
|
|
BEGIN
|
|
DECLARE tmp CHAR(16);
|
|
DECLARE var_name FLOAT;
|
|
SET var_name = RAND();
|
|
IF var_name > .6
|
|
THEN SET tmp = 'Texas';
|
|
ELSE SET tmp = 'MySQL';
|
|
END IF;
|
|
RETURN tmp;
|
|
END|
|
|
delimiter ;|
|
|
|
|
--disable_warnings
|
|
INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1());
|
|
sleep 6;
|
|
INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1());
|
|
sleep 6;
|
|
--enable_warnings
|
|
|
|
#Select in this test are used for debugging
|
|
#select * from test.t1;
|
|
#connection slave;
|
|
#select * from test.t1;
|
|
|
|
connection master;
|
|
SET AUTOCOMMIT=0;
|
|
START TRANSACTION;
|
|
--disable_warnings
|
|
INSERT INTO test.t1 VALUES (null,test.f1());
|
|
--enable_warnings
|
|
ROLLBACK;
|
|
SET AUTOCOMMIT=1;
|
|
#select * from test.t1;
|
|
#sleep 6;
|
|
|
|
#connection slave;
|
|
#select * from test.t1;
|
|
|
|
#connection master;
|
|
|
|
#used for debugging
|
|
#show binlog events;
|
|
|
|
# time to dump the databases and so we can see if they match
|
|
|
|
--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/func003_master.sql
|
|
--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/func003_slave.sql
|
|
|
|
# First lets cleanup
|
|
DROP FUNCTION test.f1;
|
|
DROP TABLE test.t1;
|
|
|
|
|
|
# the test will show that the diff statement failed and no reject file
|
|
# will be created. You will need to go to the mysql-test dir and diff
|
|
# the files yourself to see what is not matching :-) File are located
|
|
# in $MYSQLTEST_VARDIR/tmp
|
|
|
|
diff_files $MYSQLTEST_VARDIR/tmp/func003_master.sql $MYSQLTEST_VARDIR/tmp/func003_slave.sql;
|
|
|
|
|
|
# End of 5.0 test case
|