Skip to content

Commit c8be855

Browse files
author
Sujatha Sivakumar
committed
Merge branch 'mysql-5.5' into mysql-5.6
2 parents c4fc2a5 + 818b3a9 commit c8be855

6 files changed

Lines changed: 155 additions & 7 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
DROP TABLE IF EXISTS t1 ;
2+
# READ_ONLY does nothing to SUPER users
3+
# so we use a non-SUPER one:
4+
GRANT CREATE, SELECT, DROP ON *.* TO test@localhost;
5+
connect con1,localhost,test,,test;
6+
connection default;
7+
SET GLOBAL READ_ONLY=1;
8+
connection con1;
9+
CREATE TEMPORARY TABLE t1 (a INT) ENGINE=INNODB;
10+
# Test INSERTS with autocommit being off and on.
11+
BEGIN;
12+
INSERT INTO t1 VALUES (10);
13+
COMMIT;
14+
INSERT INTO t1 VALUES (20);
15+
# Test UPDATES with autocommit being off and on.
16+
BEGIN;
17+
UPDATE t1 SET a=30 WHERE a=10;
18+
COMMIT;
19+
UPDATE t1 SET a=40 WHERE a=20;
20+
connection default;
21+
SET GLOBAL READ_ONLY=0;
22+
# Test scenario where global read_only is enabled in the middle of transaction.
23+
# Test INSERT operations on temporary tables, INSERTs should be successful even
24+
# when global read_only is enabled.
25+
connection con1;
26+
BEGIN;
27+
INSERT INTO t1 VALUES(50);
28+
connection default;
29+
SET GLOBAL READ_ONLY=1;
30+
connection con1;
31+
SELECT @@GLOBAL.READ_ONLY;
32+
@@GLOBAL.READ_ONLY
33+
1
34+
COMMIT;
35+
connection default;
36+
SET GLOBAL READ_ONLY=0;
37+
# Test UPDATE operations on temporary tables, UPDATEs should be successful even
38+
# when global read_only is enabled.
39+
connection con1;
40+
BEGIN;
41+
UPDATE t1 SET a=60 WHERE a=50;
42+
connection default;
43+
SET GLOBAL READ_ONLY=1;
44+
connection con1;
45+
SELECT @@GLOBAL.READ_ONLY;
46+
@@GLOBAL.READ_ONLY
47+
1
48+
COMMIT;
49+
SELECT * FROM t1;
50+
a
51+
30
52+
40
53+
60
54+
# Clean up
55+
connection default;
56+
SET GLOBAL READ_ONLY=0;
57+
disconnect con1;
58+
DROP USER test@localhost;
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# ==== Purpose ====
2+
#
3+
# Check that DMLs are allowed on temporary tables, when server is in read only
4+
# mode and binary log is enabled with binlog-format being stmt/mixed mode.
5+
#
6+
# ==== Implementation ====
7+
#
8+
# Start the server with binary log being enabled. Mark the server as read only.
9+
# Create a non-SUPER user and let the user to create a temporary table and
10+
# perform DML operations on that temporary table. DMLs should not be blocked
11+
# with a 'server read-only mode' error.
12+
#
13+
# ==== References ====
14+
#
15+
# Bug#12818255: READ-ONLY OPTION DOES NOT ALLOW INSERTS/UPDATES ON TEMPORARY
16+
# TABLES
17+
# Bug#14294223: CHANGES NOT ALLOWED TO TEMPORARY TABLES ON READ-ONLY SERVERS
18+
###############################################################################
19+
--source include/have_log_bin.inc
20+
--disable_warnings
21+
DROP TABLE IF EXISTS t1 ;
22+
--enable_warnings
23+
24+
--enable_connect_log
25+
--echo # READ_ONLY does nothing to SUPER users
26+
--echo # so we use a non-SUPER one:
27+
GRANT CREATE, SELECT, DROP ON *.* TO test@localhost;
28+
29+
connect (con1,localhost,test,,test);
30+
31+
connection default;
32+
SET GLOBAL READ_ONLY=1;
33+
34+
connection con1;
35+
CREATE TEMPORARY TABLE t1 (a INT) ENGINE=INNODB;
36+
37+
--echo # Test INSERTS with autocommit being off and on.
38+
BEGIN;
39+
INSERT INTO t1 VALUES (10);
40+
COMMIT;
41+
INSERT INTO t1 VALUES (20);
42+
43+
--echo # Test UPDATES with autocommit being off and on.
44+
BEGIN;
45+
UPDATE t1 SET a=30 WHERE a=10;
46+
COMMIT;
47+
UPDATE t1 SET a=40 WHERE a=20;
48+
49+
connection default;
50+
SET GLOBAL READ_ONLY=0;
51+
52+
--echo # Test scenario where global read_only is enabled in the middle of transaction.
53+
--echo # Test INSERT operations on temporary tables, INSERTs should be successful even
54+
--echo # when global read_only is enabled.
55+
connection con1;
56+
BEGIN;
57+
INSERT INTO t1 VALUES(50);
58+
59+
connection default;
60+
SET GLOBAL READ_ONLY=1;
61+
62+
connection con1;
63+
SELECT @@GLOBAL.READ_ONLY;
64+
COMMIT;
65+
66+
connection default;
67+
SET GLOBAL READ_ONLY=0;
68+
69+
--echo # Test UPDATE operations on temporary tables, UPDATEs should be successful even
70+
--echo # when global read_only is enabled.
71+
connection con1;
72+
BEGIN;
73+
UPDATE t1 SET a=60 WHERE a=50;
74+
75+
connection default;
76+
SET GLOBAL READ_ONLY=1;
77+
78+
connection con1;
79+
SELECT @@GLOBAL.READ_ONLY;
80+
COMMIT;
81+
82+
SELECT * FROM t1;
83+
84+
--echo # Clean up
85+
connection default;
86+
SET GLOBAL READ_ONLY=0;
87+
88+
disconnect con1;
89+
DROP USER test@localhost;
90+
--disable_connect_log

sql/binlog.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,17 +1992,16 @@ trans_has_updated_trans_table(const THD* thd)
19921992
This function checks if a transactional table was updated by the
19931993
current statement.
19941994
1995-
@param thd The client thread that executed the current statement.
1995+
@param ha_list Registered storage engine handler list.
19961996
@return
19971997
@c true if a transactional table was updated, @c false otherwise.
19981998
*/
19991999
bool
2000-
stmt_has_updated_trans_table(const THD *thd)
2000+
stmt_has_updated_trans_table(Ha_trx_info* ha_list)
20012001
{
20022002
Ha_trx_info *ha_info;
20032003

2004-
for (ha_info= thd->transaction.stmt.ha_list; ha_info;
2005-
ha_info= ha_info->next())
2004+
for (ha_info= ha_list; ha_info; ha_info= ha_info->next())
20062005
{
20072006
if (ha_info->is_trx_read_write() && ha_info->ht() != binlog_hton)
20082007
return (TRUE);

sql/binlog.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ typedef struct st_load_file_info
690690
extern MYSQL_PLUGIN_IMPORT MYSQL_BIN_LOG mysql_bin_log;
691691

692692
bool trans_has_updated_trans_table(const THD* thd);
693-
bool stmt_has_updated_trans_table(const THD *thd);
693+
bool stmt_has_updated_trans_table(Ha_trx_info* ha_list);
694694
bool ending_trans(THD* thd, const bool all);
695695
bool ending_single_stmt_trans(THD* thd, const bool all);
696696
bool trans_cannot_safely_rollback(const THD* thd);

sql/handler.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1419,7 +1419,7 @@ int ha_commit_trans(THD *thd, bool all, bool ignore_global_read_lock)
14191419
DEBUG_SYNC(thd, "ha_commit_trans_after_acquire_commit_lock");
14201420
}
14211421

1422-
if (rw_trans &&
1422+
if (rw_trans && stmt_has_updated_trans_table(ha_info) &&
14231423
opt_readonly &&
14241424
!(thd->security_ctx->master_access & SUPER_ACL) &&
14251425
!thd->slave_thread)

sql/log_event.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3761,7 +3761,8 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
37613761
if (cmd_can_generate_row_events)
37623762
{
37633763
cmd_must_go_to_trx_cache= cmd_must_go_to_trx_cache || using_trans;
3764-
if (cmd_must_go_to_trx_cache || stmt_has_updated_trans_table(thd) ||
3764+
if (cmd_must_go_to_trx_cache ||
3765+
stmt_has_updated_trans_table(thd->transaction.stmt.ha_list) ||
37653766
thd->lex->is_mixed_stmt_unsafe(thd->in_multi_stmt_transaction_mode(),
37663767
thd->variables.binlog_direct_non_trans_update,
37673768
trans_has_updated_trans_table(thd),

0 commit comments

Comments
 (0)