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
a1b260df
Commit
a1b260df
authored
Nov 30, 2006
by
malff/marcsql@weblab.(none)
Browse files
Options
Browse Files
Download
Plain Diff
Merge malff@bk-internal.mysql.com:/home/bk/mysql-5.1-runtime
into weblab.(none):/home/marcsql/TREE/mysql-5.1-11733_topdown
parents
2fbb40b9
e1bdc140
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
548 additions
and
4 deletions
+548
-4
mysql-test/r/read_only.result
mysql-test/r/read_only.result
+51
-1
mysql-test/r/read_only_innodb.result
mysql-test/r/read_only_innodb.result
+18
-0
mysql-test/r/rpl_read_only.result
mysql-test/r/rpl_read_only.result
+113
-0
mysql-test/t/read_only.test
mysql-test/t/read_only.test
+108
-2
mysql-test/t/read_only_innodb.test
mysql-test/t/read_only_innodb.test
+43
-0
mysql-test/t/rpl_read_only-slave.opt
mysql-test/t/rpl_read_only-slave.opt
+1
-0
mysql-test/t/rpl_read_only.test
mysql-test/t/rpl_read_only.test
+105
-0
sql/handler.cc
sql/handler.cc
+13
-0
sql/lock.cc
sql/lock.cc
+17
-0
sql/set_var.cc
sql/set_var.cc
+65
-1
sql/set_var.h
sql/set_var.h
+14
-0
No files found.
mysql-test/r/read_only.result
View file @
a1b260df
...
...
@@ -39,6 +39,56 @@ delete t1 from t1,t3 where t1.a=t3.a;
drop table t1;
insert into t1 values(1);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
set global read_only=0;
lock table t1 write;
lock table t2 write;
set global read_only=1;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
unlock tables ;
set global read_only=1;
select @@global.read_only;
@@global.read_only
0
unlock tables ;
select @@global.read_only;
@@global.read_only
1
set global read_only=0;
lock table t1 read;
lock table t2 read;
set global read_only=1;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
unlock tables ;
set global read_only=1;
select @@global.read_only;
@@global.read_only
0
unlock tables ;
select @@global.read_only;
@@global.read_only
1
set global read_only=0;
BEGIN;
BEGIN;
set global read_only=1;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
ROLLBACK;
set global read_only=1;
select @@global.read_only;
@@global.read_only
1
ROLLBACK;
set global read_only=0;
flush tables with read lock;
set global read_only=1;
unlock tables;
set global read_only=0;
flush tables with read lock;
set global read_only=1;
select @@global.read_only;
@@global.read_only
1
unlock tables;
set global read_only=0;
drop table t1,t2;
drop user test@localhost;
set global read_only=0;
mysql-test/r/read_only_innodb.result
0 → 100644
View file @
a1b260df
DROP TABLE IF EXISTS table_11733 ;
grant CREATE, SELECT, DROP on *.* to test@localhost;
set global read_only=0;
create table table_11733 (a int) engine=InnoDb;
BEGIN;
insert into table_11733 values(11733);
set global read_only=1;
select @@global.read_only;
@@global.read_only
1
select * from table_11733 ;
a
11733
COMMIT;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
set global read_only=0;
drop table table_11733 ;
drop user test@localhost;
mysql-test/r/rpl_read_only.result
0 → 100644
View file @
a1b260df
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) engine=InnoDB;
create table t2(a int) engine=MyISAM;
insert into t1 values(1001);
insert into t2 values(2001);
set global read_only=1;
select @@read_only;
@@read_only
1
select * from t1;
a
1001
select * from t2;
a
2001
select @@read_only;
@@read_only
0
select * from t1;
a
1001
select * from t2;
a
2001
set global read_only=0;
BEGIN;
insert into t1 values(1002);
insert into t2 values(2002);
BEGIN;
insert into t1 values(1003);
insert into t2 values(2003);
set global read_only=1;
COMMIT;
COMMIT;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
set global read_only=0;
insert into t1 values(1004);
insert into t2 values(2004);
select * from t1;
a
1001
1002
1004
select * from t2;
a
2001
2002
2003
2004
select * from t1;
a
1001
1002
1004
select * from t2;
a
2001
2002
2003
2004
set global read_only=1;
select @@read_only;
@@read_only
1
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values(1005);
insert into t2 values(2005);
select * from t1;
a
1001
1002
1004
1005
select * from t2;
a
2001
2002
2003
2004
2005
select * from t1;
a
1001
1002
1004
1005
select * from t2;
a
2001
2002
2003
2004
2005
insert into t1 values(1006);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
insert into t2 values(2006);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
drop table t1;
drop table t2;
mysql-test/t/read_only.test
View file @
a1b260df
...
...
@@ -101,8 +101,114 @@ 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
;
drop
table
t1
,
t2
;
drop
user
test
@
localhost
;
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
;
mysql-test/t/read_only_innodb.test
0 → 100644
View file @
a1b260df
# should work with embedded server after mysqltest is fixed
--
source
include
/
not_embedded
.
inc
--
source
include
/
have_innodb
.
inc
#
# BUG#11733: COMMITs should not happen if read-only is set
#
--
disable_warnings
DROP
TABLE
IF
EXISTS
table_11733
;
--
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
;
# Any transactional engine will do
create
table
table_11733
(
a
int
)
engine
=
InnoDb
;
connection
con1
;
BEGIN
;
insert
into
table_11733
values
(
11733
);
connection
default
;
set
global
read_only
=
1
;
connection
con1
;
select
@@
global
.
read_only
;
select
*
from
table_11733
;
--
error
ER_OPTION_PREVENTS_STATEMENT
COMMIT
;
connection
default
;
set
global
read_only
=
0
;
drop
table
table_11733
;
drop
user
test
@
localhost
;
mysql-test/t/rpl_read_only-slave.opt
0 → 100644
View file @
a1b260df
--innodb
mysql-test/t/rpl_read_only.test
0 → 100644
View file @
a1b260df
# Test case for BUG #11733
--
source
include
/
master
-
slave
.
inc
--
source
include
/
have_innodb
.
inc
# Setting the master readonly :
# - the variable @@readonly is not replicated on the slave
connect
(
master2
,
127.0
.
0.1
,
test
,,
test
,
$MASTER_MYPORT
,);
connect
(
slave2
,
127.0
.
0.1
,
test
,,
test
,
$SLAVE_MYPORT
,);
connection
master1
;
create
table
t1
(
a
int
)
engine
=
InnoDB
;
create
table
t2
(
a
int
)
engine
=
MyISAM
;
insert
into
t1
values
(
1001
);
insert
into
t2
values
(
2001
);
connection
master
;
set
global
read_only
=
1
;
connection
master1
;
select
@@
read_only
;
select
*
from
t1
;
select
*
from
t2
;
sync_slave_with_master
;
select
@@
read_only
;
select
*
from
t1
;
select
*
from
t2
;
# - replication of transactions
connection
master
;
set
global
read_only
=
0
;
connection
master1
;
BEGIN
;
insert
into
t1
values
(
1002
);
insert
into
t2
values
(
2002
);
connection
master2
;
BEGIN
;
insert
into
t1
values
(
1003
);
insert
into
t2
values
(
2003
);
connection
master
;
set
global
read_only
=
1
;
connection
master1
;
## works even with read_only=1, because master1 is root
COMMIT
;
connection
master2
;
--
error
ER_OPTION_PREVENTS_STATEMENT
COMMIT
;
connection
master
;
set
global
read_only
=
0
;
connection
master1
;
insert
into
t1
values
(
1004
);
insert
into
t2
values
(
2004
);
select
*
from
t1
;
select
*
from
t2
;
sync_slave_with_master
;
select
*
from
t1
;
select
*
from
t2
;
# Setting the slave readonly : replication will pass
#
connection
slave1
;
set
global
read_only
=
1
;
connection
slave
;
select
@@
read_only
;
# Make sure the replicated table is also transactional
show
create
table
t1
;
# Make sure the replicated table is not transactional
show
create
table
t2
;
connection
master
;
insert
into
t1
values
(
1005
);
insert
into
t2
values
(
2005
);
select
*
from
t1
;
select
*
from
t2
;
sync_slave_with_master
;
connection
slave
;
select
*
from
t1
;
select
*
from
t2
;
# Non root user can not write on the slave
connection
slave2
;
--
error
ER_OPTION_PREVENTS_STATEMENT
insert
into
t1
values
(
1006
);
--
error
ER_OPTION_PREVENTS_STATEMENT
insert
into
t2
values
(
2006
);
## Cleanup
connection
master
;
drop
table
t1
;
drop
table
t2
;
sync_slave_with_master
;
sql/handler.cc
View file @
a1b260df
...
...
@@ -692,6 +692,19 @@ int ha_commit_trans(THD *thd, bool all)
ha_rollback_trans
(
thd
,
all
);
DBUG_RETURN
(
1
);
}
if
(
is_real_trans
&&
opt_readonly
&&
!
(
thd
->
security_ctx
->
master_access
&
SUPER_ACL
)
&&
!
thd
->
slave_thread
)
{
my_error
(
ER_OPTION_PREVENTS_STATEMENT
,
MYF
(
0
),
"--read-only"
);
ha_rollback_trans
(
thd
,
all
);
error
=
1
;
goto
end
;
}
DBUG_EXECUTE_IF
(
"crash_commit_before"
,
abort
(););
/* Close all cursors that can not survive COMMIT */
...
...
sql/lock.cc
View file @
a1b260df
...
...
@@ -151,6 +151,23 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
}
}
if
(
write_lock_used
&&
opt_readonly
&&
!
(
thd
->
security_ctx
->
master_access
&
SUPER_ACL
)
&&
!
thd
->
slave_thread
)
{
/*
Someone has issued SET GLOBAL READ_ONLY=1 and we want a write lock.
We do not wait for READ_ONLY=0, and fail.
*/
reset_lock_data
(
sql_lock
);
my_free
((
gptr
)
sql_lock
,
MYF
(
0
));
sql_lock
=
0
;
my_error
(
ER_OPTION_PREVENTS_STATEMENT
,
MYF
(
0
),
"--read-only"
);
break
;
}
thd
->
proc_info
=
"System lock"
;
DBUG_PRINT
(
"info"
,
(
"thd->proc_info %s"
,
thd
->
proc_info
));
if
(
lock_external
(
thd
,
tables
,
count
))
...
...
sql/set_var.cc
View file @
a1b260df
...
...
@@ -369,7 +369,7 @@ sys_var_thd_ulong sys_preload_buff_size("preload_buffer_size",
&
SV
::
preload_buff_size
);
sys_var_thd_ulong
sys_read_buff_size
(
"read_buffer_size"
,
&
SV
::
read_buff_size
);
sys_var_
bool_ptr
sys_readonly
(
"read_only"
,
&
opt_readonly
);
sys_var_
opt_readonly
sys_readonly
(
"read_only"
,
&
opt_readonly
);
sys_var_thd_ulong
sys_read_rnd_buff_size
(
"read_rnd_buffer_size"
,
&
SV
::
read_rnd_buff_size
);
sys_var_thd_ulong
sys_div_precincrement
(
"div_precision_increment"
,
...
...
@@ -3854,6 +3854,70 @@ bool sys_var_trust_routine_creators::update(THD *thd, set_var *var)
return
sys_var_bool_ptr
::
update
(
thd
,
var
);
}
bool
sys_var_opt_readonly
::
update
(
THD
*
thd
,
set_var
*
var
)
{
bool
result
;
DBUG_ENTER
(
"sys_var_opt_readonly::update"
);
/* Prevent self dead-lock */
if
(
thd
->
locked_tables
||
thd
->
active_transaction
())
{
my_error
(
ER_LOCK_OR_ACTIVE_TRANSACTION
,
MYF
(
0
));
DBUG_RETURN
(
true
);
}
if
(
thd
->
global_read_lock
)
{
/*
This connection already holds the global read lock.
This can be the case with:
- FLUSH TABLES WITH READ LOCK
- SET GLOBAL READ_ONLY = 1
*/
result
=
sys_var_bool_ptr
::
update
(
thd
,
var
);
DBUG_RETURN
(
result
);
}
/*
Perform a 'FLUSH TABLES WITH READ LOCK'.
This is a 3 step process:
- [1] lock_global_read_lock()
- [2] close_cached_tables()
- [3] make_global_read_lock_block_commit()
[1] prevents new connections from obtaining tables locked for write.
[2] waits until all existing connections close their tables.
[3] prevents transactions from being committed.
*/
if
(
lock_global_read_lock
(
thd
))
DBUG_RETURN
(
true
);
/*
This call will be blocked by any connection holding a READ or WRITE lock.
Ideally, we want to wait only for pending WRITE locks, but since:
con 1> LOCK TABLE T FOR READ;
con 2> LOCK TABLE T FOR WRITE; (blocked by con 1)
con 3> SET GLOBAL READ ONLY=1; (blocked by con 2)
can cause to wait on a read lock, it's required for the client application
to unlock everything, and acceptable for the server to wait on all locks.
*/
if
(
close_cached_tables
(
thd
,
true
,
NULL
,
false
))
goto
end_with_read_lock
;
if
(
result
=
make_global_read_lock_block_commit
(
thd
))
goto
end_with_read_lock
;
/* Change the opt_readonly system variable, safe because the lock is held */
result
=
sys_var_bool_ptr
::
update
(
thd
,
var
);
end_with_read_lock:
/* Release the lock */
unlock_global_read_lock
(
thd
);
DBUG_RETURN
(
result
);
}
/* even session variable here requires SUPER, because of -#o,file */
bool
sys_var_thd_dbug
::
check
(
THD
*
thd
,
set_var
*
var
)
{
...
...
sql/set_var.h
View file @
a1b260df
...
...
@@ -905,6 +905,20 @@ class sys_var_trust_routine_creators :public sys_var_bool_ptr
};
/**
Handler for setting the system variable --read-only.
*/
class
sys_var_opt_readonly
:
public
sys_var_bool_ptr
{
public:
sys_var_opt_readonly
(
const
char
*
name_arg
,
my_bool
*
value_arg
)
:
sys_var_bool_ptr
(
name_arg
,
value_arg
)
{};
~
sys_var_opt_readonly
()
{};
bool
update
(
THD
*
thd
,
set_var
*
var
);
};
class
sys_var_thd_lc_time_names
:
public
sys_var_thd
{
public:
...
...
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