Merge lp:~laurynas-biveinis/percona-server/super-read-only into lp:percona-server/5.6

Proposed by Laurynas Biveinis
Status: Merged
Approved by: Sergei Glushchenko
Approved revision: 681
Merged at revision: 686
Proposed branch: lp:~laurynas-biveinis/percona-server/super-read-only
Merge into: lp:percona-server/5.6
Diff against target: 865 lines (+624/-19)
14 files modified
mysql-test/r/mysqld--help-notwin.result (+3/-0)
mysql-test/suite/rpl/r/rpl_ignore_super_read_only.result (+27/-0)
mysql-test/suite/rpl/t/rpl_ignore_super_read_only-slave.opt (+1/-0)
mysql-test/suite/rpl/t/rpl_ignore_super_read_only.test (+32/-0)
mysql-test/suite/sys_vars/r/super_read_only_basic.result (+263/-0)
mysql-test/suite/sys_vars/t/super_read_only_basic.test (+232/-0)
sql/handler.cc (+13/-2)
sql/lock.cc (+6/-4)
sql/mysqld.cc (+2/-0)
sql/mysqld.h (+1/-1)
sql/sql_parse.cc (+9/-5)
sql/sql_trigger.cc (+6/-3)
sql/sys_vars.cc (+23/-0)
sql/transaction.cc (+6/-4)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/super-read-only
Reviewer Review Type Date Requested Status
Sergei Glushchenko (community) g2 Approve
Review via email: mp+238747@code.launchpad.net

Description of the change

Port --super-read-only option from WebScaleSQL, implementing
https://blueprints.launchpad.net/percona-server/+spec/super-read-only.

It is based on the patch at
https://github.com/webscalesql/webscalesql-5.6/commit/73fe122dd4b7f1a0fa79f338a7a0c4e5809389e2
with the following differences:
- super read only is enforced for DROP TRIGGER too;
- added MTR tests for the implemented but untested cases in the
original patch: multi-table update, START TRANSACTION READ WRITE, and
CREATE TRIGGER.

http://jenkins.percona.com/job/percona-server-5.6-param/740/

To post a comment you must log in.
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

BT 46192

Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

Approve

review: Approve (g2)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'mysql-test/r/mysqld--help-notwin.result'
2--- mysql-test/r/mysqld--help-notwin.result 2014-10-01 13:08:27 +0000
3+++ mysql-test/r/mysqld--help-notwin.result 2014-10-17 16:06:20 +0000
4@@ -1008,6 +1008,8 @@
5 --stored-program-cache=#
6 The soft upper limit for number of cached stored routines
7 for one connection.
8+ --super-read-only Enable read_only, and also block writes by users with the
9+ SUPER privilege
10 -s, --symbolic-links
11 Enable symbolic link support.
12 --sync-binlog=# Synchronously flush binary log to disk after every #th
13@@ -1390,6 +1392,7 @@
14 sporadic-binlog-dump-fail FALSE
15 sql-mode NO_ENGINE_SUBSTITUTION
16 stored-program-cache 256
17+super-read-only FALSE
18 symbolic-links FALSE
19 sync-binlog 0
20 sync-frm TRUE
21
22=== added file 'mysql-test/suite/rpl/r/rpl_ignore_super_read_only.result'
23--- mysql-test/suite/rpl/r/rpl_ignore_super_read_only.result 1970-01-01 00:00:00 +0000
24+++ mysql-test/suite/rpl/r/rpl_ignore_super_read_only.result 2014-10-17 16:06:20 +0000
25@@ -0,0 +1,27 @@
26+# This unit test is only to test super_read_only=1 doesn't cause
27+# errors when executing "CHANGE MASTER".
28+#
29+# It is not intended to test general super_read_only functionality.
30+#
31+# Comprehensive super_read_only testing is in the
32+# sys_vars.super_read_only_basic test.
33+include/master-slave.inc
34+Warnings:
35+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
36+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
37+[connection master]
38+create table t1(a int);
39+insert into t1 values(1);
40+set @@global.super_read_only=1;
41+include/stop_slave.inc
42+change master to master_connect_retry=20;
43+include/start_slave.inc
44+insert into t1 values(2);
45+select * from t1;
46+a
47+1
48+2
49+set @@global.super_read_only=0;
50+set @@global.read_only=0;
51+drop table t1;
52+include/rpl_end.inc
53
54=== added file 'mysql-test/suite/rpl/t/rpl_ignore_super_read_only-slave.opt'
55--- mysql-test/suite/rpl/t/rpl_ignore_super_read_only-slave.opt 1970-01-01 00:00:00 +0000
56+++ mysql-test/suite/rpl/t/rpl_ignore_super_read_only-slave.opt 2014-10-17 16:06:20 +0000
57@@ -0,0 +1,1 @@
58+--relay_log_info_repository='TABLE'
59
60=== added file 'mysql-test/suite/rpl/t/rpl_ignore_super_read_only.test'
61--- mysql-test/suite/rpl/t/rpl_ignore_super_read_only.test 1970-01-01 00:00:00 +0000
62+++ mysql-test/suite/rpl/t/rpl_ignore_super_read_only.test 2014-10-17 16:06:20 +0000
63@@ -0,0 +1,32 @@
64+--echo # This unit test is only to test super_read_only=1 doesn't cause
65+--echo # errors when executing "CHANGE MASTER".
66+--echo #
67+--echo # It is not intended to test general super_read_only functionality.
68+--echo #
69+--echo # Comprehensive super_read_only testing is in the
70+--echo # sys_vars.super_read_only_basic test.
71+
72+source include/master-slave.inc;
73+
74+connection master;
75+create table t1(a int);
76+insert into t1 values(1);
77+sync_slave_with_master;
78+
79+set @@global.super_read_only=1;
80+source include/stop_slave.inc;
81+change master to master_connect_retry=20;
82+source include/start_slave.inc;
83+
84+connection master;
85+insert into t1 values(2);
86+sync_slave_with_master;
87+
88+select * from t1;
89+set @@global.super_read_only=0;
90+set @@global.read_only=0;
91+
92+connection master;
93+drop table t1;
94+
95+source include/rpl_end.inc;
96
97=== added file 'mysql-test/suite/sys_vars/r/super_read_only_basic.result'
98--- mysql-test/suite/sys_vars/r/super_read_only_basic.result 1970-01-01 00:00:00 +0000
99+++ mysql-test/suite/sys_vars/r/super_read_only_basic.result 2014-10-17 16:06:20 +0000
100@@ -0,0 +1,263 @@
101+#
102+# Setup
103+#
104+# Save original value
105+set @start_read_only= @@global.read_only;
106+set @start_super_read_only= @@global.super_read_only;
107+grant CREATE, SELECT, DROP on *.* to test@localhost;
108+# connect (con1,localhost,test,,test);
109+# connection default;
110+#
111+# Test combinations of settings and changes
112+#
113+# ro,sro: 0,0: set ro->0: 0,0
114+set global read_only=0;
115+set global super_read_only=0;
116+select @@global.read_only;
117+@@global.read_only
118+0
119+select @@global.super_read_only;
120+@@global.super_read_only
121+0
122+set global read_only=0;
123+select @@global.read_only;
124+@@global.read_only
125+0
126+select @@global.super_read_only;
127+@@global.super_read_only
128+0
129+# ro,sro: 0,0: set ro->1: 1,0
130+set global read_only=0;
131+set global super_read_only=0;
132+select @@global.read_only;
133+@@global.read_only
134+0
135+select @@global.super_read_only;
136+@@global.super_read_only
137+0
138+set global read_only=1;
139+select @@global.read_only;
140+@@global.read_only
141+1
142+select @@global.super_read_only;
143+@@global.super_read_only
144+0
145+# ro,sro: 0,0: set sro->0: 0,0
146+set global read_only=0;
147+set global super_read_only=0;
148+select @@global.read_only;
149+@@global.read_only
150+0
151+select @@global.super_read_only;
152+@@global.super_read_only
153+0
154+set global super_read_only=0;
155+select @@global.read_only;
156+@@global.read_only
157+0
158+select @@global.super_read_only;
159+@@global.super_read_only
160+0
161+# ro,sro: 0,0: set sro->1: 1,1
162+set global read_only=0;
163+set global super_read_only=0;
164+select @@global.read_only;
165+@@global.read_only
166+0
167+select @@global.super_read_only;
168+@@global.super_read_only
169+0
170+set global super_read_only=1;
171+select @@global.read_only;
172+@@global.read_only
173+1
174+select @@global.super_read_only;
175+@@global.super_read_only
176+1
177+# ro,sro: 1,0: set ro->0: 0,0
178+set global read_only=1;
179+set global super_read_only=0;
180+select @@global.read_only;
181+@@global.read_only
182+1
183+select @@global.super_read_only;
184+@@global.super_read_only
185+0
186+set global read_only=0;
187+select @@global.read_only;
188+@@global.read_only
189+0
190+select @@global.super_read_only;
191+@@global.super_read_only
192+0
193+# ro,sro: 1,0: set ro->1: 1,0
194+set global read_only=1;
195+set global super_read_only=0;
196+select @@global.read_only;
197+@@global.read_only
198+1
199+select @@global.super_read_only;
200+@@global.super_read_only
201+0
202+set global read_only=1;
203+select @@global.read_only;
204+@@global.read_only
205+1
206+select @@global.super_read_only;
207+@@global.super_read_only
208+0
209+# ro,sro: 1,0: set sro->0: 1,0
210+set global read_only=1;
211+set global super_read_only=0;
212+select @@global.read_only;
213+@@global.read_only
214+1
215+select @@global.super_read_only;
216+@@global.super_read_only
217+0
218+set global super_read_only=0;
219+select @@global.read_only;
220+@@global.read_only
221+1
222+select @@global.super_read_only;
223+@@global.super_read_only
224+0
225+# ro,sro: 1,0: set sro->1: 1,1
226+set global read_only=1;
227+set global super_read_only=0;
228+select @@global.read_only;
229+@@global.read_only
230+1
231+select @@global.super_read_only;
232+@@global.super_read_only
233+0
234+set global super_read_only=1;
235+select @@global.read_only;
236+@@global.read_only
237+1
238+select @@global.super_read_only;
239+@@global.super_read_only
240+1
241+# ro,sro: 1,1: set ro->0: 0,0
242+set global read_only=1;
243+set global super_read_only=1;
244+select @@global.read_only;
245+@@global.read_only
246+1
247+select @@global.super_read_only;
248+@@global.super_read_only
249+1
250+set global read_only=0;
251+select @@global.read_only;
252+@@global.read_only
253+0
254+select @@global.super_read_only;
255+@@global.super_read_only
256+0
257+# ro,sro: 1,1: set ro->1: 1,1
258+set global read_only=1;
259+set global super_read_only=1;
260+select @@global.read_only;
261+@@global.read_only
262+1
263+select @@global.super_read_only;
264+@@global.super_read_only
265+1
266+set global read_only=1;
267+select @@global.read_only;
268+@@global.read_only
269+1
270+select @@global.super_read_only;
271+@@global.super_read_only
272+1
273+# ro,sro: 1,1: set sro->0: 1,0
274+set global read_only=1;
275+set global super_read_only=1;
276+select @@global.read_only;
277+@@global.read_only
278+1
279+select @@global.super_read_only;
280+@@global.super_read_only
281+1
282+set global super_read_only=0;
283+select @@global.read_only;
284+@@global.read_only
285+1
286+select @@global.super_read_only;
287+@@global.super_read_only
288+0
289+# ro,sro: 1,1: set sro->1: 1,1
290+set global read_only=1;
291+set global super_read_only=1;
292+select @@global.read_only;
293+@@global.read_only
294+1
295+select @@global.super_read_only;
296+@@global.super_read_only
297+1
298+set global super_read_only=1;
299+select @@global.read_only;
300+@@global.read_only
301+1
302+select @@global.super_read_only;
303+@@global.super_read_only
304+1
305+set global read_only=0;
306+set global super_read_only=0;
307+DROP TABLE IF EXISTS t1,t2,t3;
308+#
309+# Create tables/Make sure normal writes work
310+#
311+set global super_read_only=0;
312+connection con1;
313+create table t1 (a int);
314+insert into t1 values(1);
315+create table t2 select * from t1;
316+update t1, t2 set t1.a=2, t2.a=2;
317+start transaction read write;
318+commit;
319+create trigger trig before insert on t1 for each row set new.a = new.a;
320+connection default;
321+#
322+# Make sure it blocks SUPER
323+#
324+set global super_read_only=1;
325+create table t3 (a int);
326+ERROR HY000: The MySQL server is running with the --read-only (super) option so it cannot execute this statement
327+drop table t3;
328+ERROR HY000: The MySQL server is running with the --read-only (super) option so it cannot execute this statement
329+update t1, t2 set t1.a=3, t2.a=3;
330+ERROR HY000: The MySQL server is running with the --read-only (super) option so it cannot execute this statement
331+start transaction read write;
332+ERROR HY000: The MySQL server is running with the --read-only (super) option so it cannot execute this statement
333+drop trigger trig;
334+ERROR HY000: The MySQL server is running with the --read-only (super) option so it cannot execute this statement
335+#
336+# Make sure it still blocks for non-super
337+#
338+connection con1;
339+select @@global.read_only;
340+@@global.read_only
341+1
342+select @@global.super_read_only;
343+@@global.super_read_only
344+1
345+create table t3 (a int);
346+ERROR HY000: The MySQL server is running with the --read-only (super) option so it cannot execute this statement
347+insert into t1 values(1);
348+ERROR HY000: The MySQL server is running with the --read-only (super) option so it cannot execute this statement
349+update t1, t2 set t1.a=3, t2.a=3;
350+ERROR HY000: The MySQL server is running with the --read-only (super) option so it cannot execute this statement
351+start transaction read write;
352+ERROR HY000: The MySQL server is running with the --read-only (super) option so it cannot execute this statement
353+drop trigger trig;
354+ERROR HY000: The MySQL server is running with the --read-only (super) option so it cannot execute this statement
355+#
356+# Cleanup
357+#
358+connection default;
359+set global super_read_only=0;
360+drop table t1,t2;
361+drop user test@localhost;
362+set global read_only= @start_read_only;
363+set global super_read_only= @start_super_read_only;
364
365=== added file 'mysql-test/suite/sys_vars/t/super_read_only_basic.test'
366--- mysql-test/suite/sys_vars/t/super_read_only_basic.test 1970-01-01 00:00:00 +0000
367+++ mysql-test/suite/sys_vars/t/super_read_only_basic.test 2014-10-17 16:06:20 +0000
368@@ -0,0 +1,232 @@
369+# Test of the SUPER_READ_ONLY modification to the READ_ONLY global variable:
370+# check that it blocks updates even with SUPER privs
371+
372+# should work with embedded server after mysqltest is fixed
373+--source include/not_embedded.inc
374+
375+
376+--echo #
377+--echo # Setup
378+--echo #
379+
380+--echo # Save original value
381+set @start_read_only= @@global.read_only;
382+set @start_super_read_only= @@global.super_read_only;
383+
384+grant CREATE, SELECT, DROP on *.* to test@localhost;
385+
386+--echo # connect (con1,localhost,test,,test);
387+connect (con1,localhost,test,,test);
388+
389+--echo # connection default;
390+connection default;
391+
392+
393+--echo #
394+--echo # Test combinations of settings and changes
395+--echo #
396+
397+--echo # ro,sro: 0,0: set ro->0: 0,0
398+set global read_only=0;
399+set global super_read_only=0;
400+select @@global.read_only;
401+select @@global.super_read_only;
402+set global read_only=0;
403+select @@global.read_only;
404+select @@global.super_read_only;
405+
406+--echo # ro,sro: 0,0: set ro->1: 1,0
407+set global read_only=0;
408+set global super_read_only=0;
409+select @@global.read_only;
410+select @@global.super_read_only;
411+set global read_only=1;
412+select @@global.read_only;
413+select @@global.super_read_only;
414+
415+--echo # ro,sro: 0,0: set sro->0: 0,0
416+set global read_only=0;
417+set global super_read_only=0;
418+select @@global.read_only;
419+select @@global.super_read_only;
420+set global super_read_only=0;
421+select @@global.read_only;
422+select @@global.super_read_only;
423+
424+--echo # ro,sro: 0,0: set sro->1: 1,1
425+set global read_only=0;
426+set global super_read_only=0;
427+select @@global.read_only;
428+select @@global.super_read_only;
429+set global super_read_only=1;
430+select @@global.read_only;
431+select @@global.super_read_only;
432+
433+# We don't care about 0,1 - since all this ensures it can't happen.
434+
435+--echo # ro,sro: 1,0: set ro->0: 0,0
436+set global read_only=1;
437+set global super_read_only=0;
438+select @@global.read_only;
439+select @@global.super_read_only;
440+set global read_only=0;
441+select @@global.read_only;
442+select @@global.super_read_only;
443+
444+--echo # ro,sro: 1,0: set ro->1: 1,0
445+set global read_only=1;
446+set global super_read_only=0;
447+select @@global.read_only;
448+select @@global.super_read_only;
449+set global read_only=1;
450+select @@global.read_only;
451+select @@global.super_read_only;
452+
453+--echo # ro,sro: 1,0: set sro->0: 1,0
454+set global read_only=1;
455+set global super_read_only=0;
456+select @@global.read_only;
457+select @@global.super_read_only;
458+set global super_read_only=0;
459+select @@global.read_only;
460+select @@global.super_read_only;
461+
462+--echo # ro,sro: 1,0: set sro->1: 1,1
463+set global read_only=1;
464+set global super_read_only=0;
465+select @@global.read_only;
466+select @@global.super_read_only;
467+set global super_read_only=1;
468+select @@global.read_only;
469+select @@global.super_read_only;
470+
471+
472+--echo # ro,sro: 1,1: set ro->0: 0,0
473+set global read_only=1;
474+set global super_read_only=1;
475+select @@global.read_only;
476+select @@global.super_read_only;
477+set global read_only=0;
478+select @@global.read_only;
479+select @@global.super_read_only;
480+
481+--echo # ro,sro: 1,1: set ro->1: 1,1
482+set global read_only=1;
483+set global super_read_only=1;
484+select @@global.read_only;
485+select @@global.super_read_only;
486+set global read_only=1;
487+select @@global.read_only;
488+select @@global.super_read_only;
489+
490+--echo # ro,sro: 1,1: set sro->0: 1,0
491+set global read_only=1;
492+set global super_read_only=1;
493+select @@global.read_only;
494+select @@global.super_read_only;
495+set global super_read_only=0;
496+select @@global.read_only;
497+select @@global.super_read_only;
498+
499+--echo # ro,sro: 1,1: set sro->1: 1,1
500+set global read_only=1;
501+set global super_read_only=1;
502+select @@global.read_only;
503+select @@global.super_read_only;
504+set global super_read_only=1;
505+select @@global.read_only;
506+select @@global.super_read_only;
507+
508+--disable_warnings
509+set global read_only=0;
510+set global super_read_only=0;
511+DROP TABLE IF EXISTS t1,t2,t3;
512+--enable_warnings
513+
514+
515+--echo #
516+--echo # Create tables/Make sure normal writes work
517+--echo #
518+
519+set global super_read_only=0;
520+
521+--echo connection con1;
522+connection con1;
523+
524+create table t1 (a int);
525+
526+insert into t1 values(1);
527+
528+create table t2 select * from t1;
529+
530+update t1, t2 set t1.a=2, t2.a=2;
531+
532+start transaction read write;
533+commit;
534+
535+create trigger trig before insert on t1 for each row set new.a = new.a;
536+
537+--echo connection default;
538+connection default;
539+
540+
541+--echo #
542+--echo # Make sure it blocks SUPER
543+--echo #
544+
545+set global super_read_only=1;
546+
547+--error ER_OPTION_PREVENTS_STATEMENT
548+create table t3 (a int);
549+
550+--error ER_OPTION_PREVENTS_STATEMENT
551+drop table t3;
552+
553+--error ER_OPTION_PREVENTS_STATEMENT
554+update t1, t2 set t1.a=3, t2.a=3;
555+
556+--error ER_OPTION_PREVENTS_STATEMENT
557+start transaction read write;
558+
559+--error ER_OPTION_PREVENTS_STATEMENT
560+drop trigger trig;
561+
562+--echo #
563+--echo # Make sure it still blocks for non-super
564+--echo #
565+
566+--echo connection con1;
567+connection con1;
568+
569+select @@global.read_only;
570+select @@global.super_read_only;
571+
572+--error ER_OPTION_PREVENTS_STATEMENT
573+create table t3 (a int);
574+
575+--error ER_OPTION_PREVENTS_STATEMENT
576+insert into t1 values(1);
577+
578+--error ER_OPTION_PREVENTS_STATEMENT
579+update t1, t2 set t1.a=3, t2.a=3;
580+
581+--error ER_OPTION_PREVENTS_STATEMENT
582+start transaction read write;
583+
584+--error ER_OPTION_PREVENTS_STATEMENT
585+drop trigger trig;
586+
587+--echo #
588+--echo # Cleanup
589+--echo #
590+
591+--echo connection default;
592+connection default;
593+set global super_read_only=0;
594+disconnect con1;
595+drop table t1,t2;
596+drop user test@localhost;
597+
598+# Restore original value
599+set global read_only= @start_read_only;
600+set global super_read_only= @start_super_read_only;
601
602=== modified file 'sql/handler.cc'
603--- sql/handler.cc 2014-08-22 10:02:24 +0000
604+++ sql/handler.cc 2014-10-17 16:06:20 +0000
605@@ -1483,12 +1483,23 @@
606 DEBUG_SYNC(thd, "ha_commit_trans_after_acquire_commit_lock");
607 }
608
609+ bool enforce_ro= true;
610+ if (!opt_super_readonly)
611+ enforce_ro= !(thd->security_ctx->master_access & SUPER_ACL);
612+ /*
613+ Ignore super_read_only when ignore_global_read_lock is set.
614+ ignore_global_read_lock is set for transactions on replication
615+ repository tables.
616+ */
617+ if (ignore_global_read_lock)
618+ enforce_ro= false;
619 if (rw_trans &&
620 opt_readonly &&
621- !(thd->security_ctx->master_access & SUPER_ACL) &&
622+ enforce_ro &&
623 !thd->slave_thread)
624 {
625- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
626+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
627+ opt_super_readonly ? "--read-only (super)" : "--read-only");
628 ha_rollback_trans(thd, all);
629 error= 1;
630 goto end;
631
632=== modified file 'sql/lock.cc'
633--- sql/lock.cc 2014-02-25 07:30:22 +0000
634+++ sql/lock.cc 2014-10-17 16:06:20 +0000
635@@ -116,7 +116,7 @@
636 lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
637 {
638 uint system_count= 0, i= 0;
639- bool is_superuser= false;
640+ bool enforce_ro= true;
641 /*
642 Identifies if the executed sql command can updated either a log
643 or rpl info table.
644@@ -125,7 +125,8 @@
645
646 DBUG_ENTER("lock_tables_check");
647
648- is_superuser= thd->security_ctx->master_access & SUPER_ACL;
649+ if (!opt_super_readonly)
650+ enforce_ro= !(thd->security_ctx->master_access & SUPER_ACL);
651 log_table_write_query=
652 is_log_table_write_query(thd->lex->sql_command);
653
654@@ -197,9 +198,10 @@
655 if (!(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) && !t->s->tmp_table)
656 {
657 if (t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE &&
658- !is_superuser && opt_readonly && !thd->slave_thread)
659+ enforce_ro && opt_readonly && !thd->slave_thread)
660 {
661- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
662+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
663+ opt_super_readonly ? "--read-only (super)" : "--read-only");
664 DBUG_RETURN(1);
665 }
666 }
667
668=== modified file 'sql/mysqld.cc'
669--- sql/mysqld.cc 2014-09-26 04:43:24 +0000
670+++ sql/mysqld.cc 2014-10-17 16:06:20 +0000
671@@ -456,6 +456,7 @@
672 uint opt_server_id_bits= 0;
673 ulong opt_server_id_mask= 0;
674 my_bool read_only= 0, opt_readonly= 0;
675+my_bool super_read_only= 0, opt_super_readonly= 0;
676 my_bool use_temp_pool, relay_log_purge;
677 my_bool relay_log_recovery;
678 my_bool opt_sync_frm, opt_allow_suspicious_udfs;
679@@ -9259,6 +9260,7 @@
680 MY_TEST(global_system_variables.optimizer_switch &
681 OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN);
682
683+ opt_super_readonly= super_read_only;
684 opt_readonly= read_only;
685
686 return 0;
687
688=== modified file 'sql/mysqld.h'
689--- sql/mysqld.h 2014-09-26 04:43:24 +0000
690+++ sql/mysqld.h 2014-10-17 16:06:20 +0000
691@@ -120,7 +120,7 @@
692 extern my_bool opt_slave_compressed_protocol, use_temp_pool;
693 extern ulong slave_exec_mode_options;
694 extern ulonglong slave_type_conversions_options;
695-extern my_bool read_only, opt_readonly;
696+extern my_bool read_only, opt_readonly, super_read_only, opt_super_readonly;
697 extern my_bool lower_case_file_system;
698 extern ulonglong slave_rows_search_algorithms_options;
699 #ifndef DBUG_OFF
700
701=== modified file 'sql/sql_parse.cc'
702--- sql/sql_parse.cc 2014-09-26 15:39:39 +0000
703+++ sql/sql_parse.cc 2014-10-17 16:06:20 +0000
704@@ -1083,7 +1083,7 @@
705 ((ulong)(thd->security_ctx->master_access & SUPER_ACL) ==
706 (ulong)SUPER_ACL);
707
708- if (user_is_super)
709+ if (user_is_super && (!opt_super_readonly))
710 DBUG_RETURN(FALSE);
711
712 if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
713@@ -2782,7 +2782,8 @@
714 */
715 if (deny_updates_if_read_only_option(thd, all_tables))
716 {
717- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
718+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
719+ opt_super_readonly ? "--read-only (super)" : "--read-only");
720 DBUG_RETURN(-1);
721 }
722 #ifdef HAVE_REPLICATION
723@@ -3756,12 +3757,15 @@
724 #endif /* HAVE_REPLICATION */
725 if (res)
726 break;
727+ bool enforce_ro = true;
728+ if (!opt_super_readonly)
729+ enforce_ro = !(thd->security_ctx->master_access & SUPER_ACL);
730 if (opt_readonly &&
731- !(thd->security_ctx->master_access & SUPER_ACL) &&
732+ enforce_ro &&
733 some_non_temp_table_to_be_updated(thd, all_tables))
734 {
735- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
736- break;
737+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
738+ opt_super_readonly ? "--read-only (super)" : "--read-only");
739 }
740 #ifdef HAVE_REPLICATION
741 } /* unlikely */
742
743=== modified file 'sql/sql_trigger.cc'
744--- sql/sql_trigger.cc 2014-08-22 10:02:24 +0000
745+++ sql/sql_trigger.cc 2014-10-17 16:06:20 +0000
746@@ -444,6 +444,9 @@
747 if (!create)
748 {
749 bool if_exists= thd->lex->drop_if_exists;
750+ bool enforce_ro= true;
751+ if (!opt_super_readonly)
752+ enforce_ro= !(thd->security_ctx->master_access & SUPER_ACL);
753
754 /*
755 Protect the query table list from the temporary and potentially
756@@ -458,10 +461,10 @@
757 */
758 thd->lex->sql_command= backup.sql_command;
759
760- if (opt_readonly && !(thd->security_ctx->master_access & SUPER_ACL) &&
761- !thd->slave_thread)
762+ if (opt_readonly && enforce_ro && !thd->slave_thread)
763 {
764- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
765+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
766+ opt_super_readonly ? "--read-only (super)" : "--read-only");
767 goto end;
768 }
769
770
771=== modified file 'sql/sys_vars.cc'
772--- sql/sys_vars.cc 2014-10-15 04:59:52 +0000
773+++ sql/sys_vars.cc 2014-10-17 16:06:20 +0000
774@@ -2339,11 +2339,22 @@
775 static bool fix_read_only(sys_var *self, THD *thd, enum_var_type type)
776 {
777 bool result= true;
778+
779+ if (read_only == FALSE && super_read_only == TRUE)
780+ {
781+ if (opt_readonly == TRUE)
782+ super_read_only= FALSE;
783+ else
784+ read_only= TRUE;
785+ }
786+
787 my_bool new_read_only= read_only; // make a copy before releasing a mutex
788+ my_bool new_super_read_only= super_read_only;
789 DBUG_ENTER("sys_var_opt_readonly::update");
790
791 if (read_only == FALSE || read_only == opt_readonly)
792 {
793+ opt_super_readonly= super_read_only;
794 opt_readonly= read_only;
795 DBUG_RETURN(false);
796 }
797@@ -2359,6 +2370,7 @@
798 - FLUSH TABLES WITH READ LOCK
799 - SET GLOBAL READ_ONLY = 1
800 */
801+ opt_super_readonly= super_read_only;
802 opt_readonly= read_only;
803 DBUG_RETURN(false);
804 }
805@@ -2375,6 +2387,7 @@
806 Prevents transactions from committing.
807 */
808
809+ super_read_only= opt_super_readonly;
810 read_only= opt_readonly;
811 mysql_mutex_unlock(&LOCK_global_system_variables);
812
813@@ -2385,6 +2398,7 @@
814 goto end_with_read_lock;
815
816 /* Change the opt_readonly system variable, safe because the lock is held */
817+ opt_super_readonly= new_super_read_only;
818 opt_readonly= new_read_only;
819 result= false;
820
821@@ -2394,6 +2408,7 @@
822 end_with_mutex_unlock:
823 mysql_mutex_lock(&LOCK_global_system_variables);
824 end:
825+ super_read_only= opt_super_readonly;
826 read_only= opt_readonly;
827 DBUG_RETURN(result);
828 }
829@@ -2426,6 +2441,14 @@
830 "Control TABLE_STATISTICS running, when userstat is enabled",
831 GLOBAL_VAR(opt_thread_statistics), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
832
833+static Sys_var_mybool Sys_super_readonly(
834+ "super_read_only",
835+ "Enable read_only, and also block writes by "
836+ "users with the SUPER privilege",
837+ GLOBAL_VAR(super_read_only), CMD_LINE(OPT_ARG), DEFAULT(FALSE),
838+ NO_MUTEX_GUARD, NOT_IN_BINLOG,
839+ ON_CHECK(check_read_only), ON_UPDATE(fix_read_only));
840+
841 // Small lower limit to be able to test MRR
842 static Sys_var_ulong Sys_read_rnd_buff_size(
843 "read_rnd_buffer_size",
844
845=== modified file 'sql/transaction.cc'
846--- sql/transaction.cc 2014-02-17 11:12:40 +0000
847+++ sql/transaction.cc 2014-10-17 16:06:20 +0000
848@@ -171,11 +171,13 @@
849 Implicitly starting a RW transaction is allowed for backward
850 compatibility.
851 */
852- const bool user_is_super=
853- MY_TEST(thd->security_ctx->master_access & SUPER_ACL);
854- if (opt_readonly && !user_is_super)
855+ bool enforce_ro= true;
856+ if (!opt_super_readonly)
857+ enforce_ro= !(thd->security_ctx->master_access & SUPER_ACL);
858+ if (opt_readonly && enforce_ro)
859 {
860- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
861+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
862+ opt_super_readonly ? "--read-only (super)" : "--read-only");
863 DBUG_RETURN(true);
864 }
865 thd->tx_read_only= false;

Subscribers

People subscribed via source and target branches