mirror of
https://github.com/MariaDB/server.git
synced 2025-02-01 11:31:51 +01:00
070f5ad497
Bug#11733 (COMMITs should not happen if read-only is set) Bug#22009 (Can write to a read-only server under some circumstances) See the work log for details The change consist of a) acquiring the global read lock in SET GLOBAL READONLY b) honoring opt_readonly in ha_commit_trans(), c) honoring opt_readonly in mysql_lock_tables(). a) takes care of the server stability, b) makes the transactional tables safe (Bug 11733) c) makes the non transactional tables safe (Bug 22009)
214 lines
4.1 KiB
Text
214 lines
4.1 KiB
Text
# Test of the READ_ONLY global variable:
|
|
# check that it blocks updates unless they are only on temporary tables.
|
|
|
|
# should work with embedded server after mysqltest is fixed
|
|
-- source include/not_embedded.inc
|
|
|
|
--disable_warnings
|
|
DROP TABLE IF EXISTS t1,t2,t3;
|
|
--enable_warnings
|
|
|
|
# READ_ONLY does nothing to SUPER users
|
|
# so we use a non-SUPER one:
|
|
|
|
grant CREATE, SELECT, DROP on *.* to test@localhost;
|
|
|
|
connect (con1,localhost,test,,test);
|
|
|
|
connection default;
|
|
|
|
set global read_only=0;
|
|
|
|
connection con1;
|
|
|
|
create table t1 (a int);
|
|
|
|
insert into t1 values(1);
|
|
|
|
create table t2 select * from t1;
|
|
|
|
connection default;
|
|
|
|
set global read_only=1;
|
|
|
|
# We check that SUPER can:
|
|
|
|
create table t3 (a int);
|
|
drop table t3;
|
|
|
|
connection con1;
|
|
|
|
select @@global.read_only;
|
|
|
|
--error 1290
|
|
create table t3 (a int);
|
|
|
|
--error 1290
|
|
insert into t1 values(1);
|
|
|
|
# if a statement, after parse stage, looks like it will update a
|
|
# non-temp table, it will be rejected, even if at execution it would
|
|
# have turned out that 0 rows would be updated
|
|
--error 1290
|
|
update t1 set a=1 where 1=0;
|
|
|
|
# multi-update is special (see sql_parse.cc) so we test it
|
|
--error 1290
|
|
update t1,t2 set t1.a=t2.a+1 where t1.a=t2.a;
|
|
|
|
# check multi-delete to be sure
|
|
--error 1290
|
|
delete t1,t2 from t1,t2 where t1.a=t2.a;
|
|
|
|
# With temp tables updates should be accepted:
|
|
|
|
create temporary table t3 (a int);
|
|
|
|
create temporary table t4 (a int) select * from t3;
|
|
|
|
insert into t3 values(1);
|
|
|
|
insert into t4 select * from t3;
|
|
|
|
# a non-temp table updated:
|
|
--error 1290
|
|
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
|
|
|
|
# no non-temp table updated (just swapped):
|
|
update t1,t3 set t3.a=t1.a+1 where t1.a=t3.a;
|
|
|
|
update t4,t3 set t4.a=t3.a+1 where t4.a=t3.a;
|
|
|
|
--error 1290
|
|
delete t1 from t1,t3 where t1.a=t3.a;
|
|
|
|
delete t3 from t1,t3 where t1.a=t3.a;
|
|
|
|
delete t4 from t3,t4 where t4.a=t3.a;
|
|
|
|
# and even homonymous ones
|
|
|
|
create temporary table t1 (a int);
|
|
|
|
insert into t1 values(1);
|
|
|
|
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
|
|
|
|
delete t1 from t1,t3 where t1.a=t3.a;
|
|
|
|
drop table t1;
|
|
|
|
--error 1290
|
|
insert into t1 values(1);
|
|
|
|
#
|
|
# BUG#11733: COMMITs should not happen if read-only is set
|
|
#
|
|
|
|
# LOCK TABLE ... WRITE / READ_ONLY
|
|
# - is an error in the same connection
|
|
# - is ok in a different connection
|
|
|
|
connection default;
|
|
set global read_only=0;
|
|
lock table t1 write;
|
|
|
|
connection con1;
|
|
lock table t2 write;
|
|
|
|
connection default;
|
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION
|
|
set global read_only=1;
|
|
unlock tables ;
|
|
# The following call blocks until con1 releases the write lock.
|
|
# Blocking is expected.
|
|
send set global read_only=1;
|
|
|
|
connection con1;
|
|
--sleep 1
|
|
select @@global.read_only;
|
|
unlock tables ;
|
|
--sleep 1
|
|
select @@global.read_only;
|
|
|
|
connection default;
|
|
reap;
|
|
|
|
# LOCK TABLE ... READ / READ_ONLY
|
|
# - is an error in the same connection
|
|
# - is ok in a different connection
|
|
|
|
connection default;
|
|
set global read_only=0;
|
|
lock table t1 read;
|
|
|
|
connection con1;
|
|
lock table t2 read;
|
|
|
|
connection default;
|
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION
|
|
set global read_only=1;
|
|
unlock tables ;
|
|
# The following call blocks until con1 releases the read lock.
|
|
# Blocking is a limitation, and could be improved.
|
|
send set global read_only=1;
|
|
|
|
connection con1;
|
|
--sleep 1
|
|
select @@global.read_only;
|
|
unlock tables ;
|
|
--sleep 1
|
|
select @@global.read_only;
|
|
|
|
connection default;
|
|
reap;
|
|
|
|
# pending transaction / READ_ONLY
|
|
# - is an error in the same connection
|
|
# - is ok in a different connection
|
|
|
|
connection default;
|
|
set global read_only=0;
|
|
BEGIN;
|
|
|
|
connection con1;
|
|
BEGIN;
|
|
|
|
connection default;
|
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION
|
|
set global read_only=1;
|
|
ROLLBACK;
|
|
set global read_only=1;
|
|
|
|
connection con1;
|
|
select @@global.read_only;
|
|
ROLLBACK;
|
|
|
|
# Verify that FLUSH TABLES WITH READ LOCK do not block READ_ONLY
|
|
# - in the same SUPER connection
|
|
# - in another SUPER connection
|
|
|
|
connection default;
|
|
set global read_only=0;
|
|
flush tables with read lock;
|
|
set global read_only=1;
|
|
unlock tables;
|
|
|
|
connect (root2,localhost,root,,test);
|
|
|
|
connection default;
|
|
set global read_only=0;
|
|
flush tables with read lock;
|
|
|
|
connection root2;
|
|
set global read_only=1;
|
|
|
|
connection default;
|
|
select @@global.read_only;
|
|
unlock tables;
|
|
|
|
# Cleanup
|
|
connection default;
|
|
set global read_only=0;
|
|
drop table t1,t2;
|
|
drop user test@localhost;
|