Merge lp:~laurynas-biveinis/percona-server/bug1064326-5.1 into lp:percona-server/5.1

Proposed by Laurynas Biveinis
Status: Merged
Approved by: Stewart Smith
Approved revision: no longer in the source branch.
Merged at revision: 501
Proposed branch: lp:~laurynas-biveinis/percona-server/bug1064326-5.1
Merge into: lp:percona-server/5.1
Prerequisite: lp:~laurynas-biveinis/percona-server/bug890404-5.1
Diff against target: 333 lines (+203/-14)
8 files modified
Percona-Server/mysql-test/r/percona_innodb_fake_changes_locks.result (+68/-4)
Percona-Server/mysql-test/r/percona_server_variables_debug.result (+1/-0)
Percona-Server/mysql-test/r/percona_server_variables_release.result (+1/-0)
Percona-Server/mysql-test/t/percona_innodb_fake_changes_locks.test (+103/-6)
Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc (+8/-0)
Percona-Server/storage/innodb_plugin/include/srv0srv.h (+4/-0)
Percona-Server/storage/innodb_plugin/lock/lock0lock.c (+14/-4)
Percona-Server/storage/innodb_plugin/srv/srv0srv.c (+4/-0)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/bug1064326-5.1
Reviewer Review Type Date Requested Status
Stewart Smith (community) Approve
Review via email: mp+129423@code.launchpad.net

Description of the change

Fix bug 1064326 (Fake changes blocking real changes due to locking).

The issue is that, although fake change transactions downgrade the
requested X row locks to S locks, these S locks prevent X locks from
being taken.

Fixed by porting lp:mysqlatfacebook/51 revisions 3771 and 3775. This
fix introduces a new option innodb_locking_fake_changes, which, when
set to FALSE, makes fake transactions not to take any row locks.
However, this option is not safe to set to FALSE by default, because
the fake changes implementation is not ready for lock-less operation
for all workloads. Namely, if a real transacation will remove a row
that a fake transaction is doing a secondary index maintenance for,
the latter will fail. The new option is considered experimental and
might be removed in the future if lockless operation mode fixes are
implemented.

The name of variable is different from FB innodb_fake_changes_locks to
avoid making innodb_fake_changes a prefix of it.

Adjust percona_innodb_fake_changes_locks testcase to test
innodb_locking_fake_changes=0 operation and that fake changes do not
cause any real data changes to the tables.

Re-record percona_server_variables_debug and
percona_server_variables_release tests.

http://jenkins.percona.com/job/percona-server-5.1-param/442/

26611

To post a comment you must log in.
Revision history for this message
Stewart Smith (stewart) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Percona-Server/mysql-test/r/percona_innodb_fake_changes_locks.result'
--- Percona-Server/mysql-test/r/percona_innodb_fake_changes_locks.result 2011-11-24 02:00:54 +0000
+++ Percona-Server/mysql-test/r/percona_innodb_fake_changes_locks.result 2012-10-12 13:06:39 +0000
@@ -1,7 +1,9 @@
1DROP TABLE IF EXISTS t1;1DROP TABLE IF EXISTS t1, t2;
2CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
3INSERT INTO t1 VALUES (1);
4CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB;
5INSERT INTO t2 VALUES (1, 1);
2# Verifying that X_LOCK not acquired6# Verifying that X_LOCK not acquired
3CREATE TABLE t1 (a INT) ENGINE=InnoDB;
4INSERT INTO t1 VALUES (1);
5SET autocommit=0;7SET autocommit=0;
6SET innodb_fake_changes=1;8SET innodb_fake_changes=1;
7BEGIN;9BEGIN;
@@ -15,5 +17,67 @@
15a17a
161181
17ROLLBACK;19ROLLBACK;
20# Confirm no lock wait timeouts when innodb_locking_fake_changes=0
21SET GLOBAL innodb_locking_fake_changes=0;
22BEGIN;
23SELECT * FROM t1 FOR UPDATE;
24a
251
26BEGIN;
27UPDATE t1 SET a=3 WHERE a=1;
28SELECT * FROM t1 LOCK IN SHARE MODE;
29a
303
31ROLLBACK;
32ROLLBACK;
33# Confirm that fake UPDATE does not hold a lock
34BEGIN;
35SELECT * FROM t1 FOR UPDATE;
36a
371
38BEGIN;
39UPDATE t1 SET a=3 WHERE a=1;
40ROLLBACK;
41ROLLBACK;
42BEGIN;
43UPDATE t1 SET a=3 WHERE a=1;
44BEGIN;
45UPDATE t1 SET a=3 WHERE a=1;
46ROLLBACK;
47ROLLBACK;
48# Confirm that fake INSERT does not hold a lock
49BEGIN;
50INSERT INTO t1 VALUES(4);
51BEGIN;
52INSERT INTO t1 VALUES(4);
53ROLLBACK;
54ROLLBACK;
55# Confirm that fake DELETE does not hold a lock
56BEGIN;
57DELETE FROM t1 WHERE a=1;
58BEGIN;
59DELETE FROM t1 WHERE a=1;
60ROLLBACK;
61ROLLBACK;
62# Confirm that fake REPLACE does not hold a lock
63BEGIN;
64REPLACE INTO t2 VALUES(1, 2);
65BEGIN;
66REPLACE INTO t2 VALUES(1, 2);
67ROLLBACK;
68ROLLBACK;
18SET innodb_fake_changes=default;69SET innodb_fake_changes=default;
19DROP TABLE t1;70SET GLOBAL innodb_locking_fake_changes=default;
71# Verify that the fake changes to t1 did not leak through
72CHECK TABLE t1;
73Table Op Msg_type Msg_text
74test.t1 check status OK
75should_be_1
761
77# Verify that the fake changes to t2 did not leak through
78CHECK TABLE t2;
79Table Op Msg_type Msg_text
80test.t2 check status OK
81should_be_1
821
83DROP TABLE t1, t2;
2084
=== modified file 'Percona-Server/mysql-test/r/percona_server_variables_debug.result'
--- Percona-Server/mysql-test/r/percona_server_variables_debug.result 2012-10-12 01:13:44 +0000
+++ Percona-Server/mysql-test/r/percona_server_variables_debug.result 2012-10-12 13:06:39 +0000
@@ -121,6 +121,7 @@
121INNODB_IO_CAPACITY121INNODB_IO_CAPACITY
122INNODB_KILL_IDLE_TRANSACTION122INNODB_KILL_IDLE_TRANSACTION
123INNODB_LAZY_DROP_TABLE123INNODB_LAZY_DROP_TABLE
124INNODB_LOCKING_FAKE_CHANGES
124INNODB_LOCKS_UNSAFE_FOR_BINLOG125INNODB_LOCKS_UNSAFE_FOR_BINLOG
125INNODB_LOCK_WAIT_TIMEOUT126INNODB_LOCK_WAIT_TIMEOUT
126INNODB_LOG_BLOCK_SIZE127INNODB_LOG_BLOCK_SIZE
127128
=== modified file 'Percona-Server/mysql-test/r/percona_server_variables_release.result'
--- Percona-Server/mysql-test/r/percona_server_variables_release.result 2012-09-05 22:27:47 +0000
+++ Percona-Server/mysql-test/r/percona_server_variables_release.result 2012-10-12 13:06:39 +0000
@@ -118,6 +118,7 @@
118INNODB_IO_CAPACITY118INNODB_IO_CAPACITY
119INNODB_KILL_IDLE_TRANSACTION119INNODB_KILL_IDLE_TRANSACTION
120INNODB_LAZY_DROP_TABLE120INNODB_LAZY_DROP_TABLE
121INNODB_LOCKING_FAKE_CHANGES
121INNODB_LOCKS_UNSAFE_FOR_BINLOG122INNODB_LOCKS_UNSAFE_FOR_BINLOG
122INNODB_LOCK_WAIT_TIMEOUT123INNODB_LOCK_WAIT_TIMEOUT
123INNODB_LOG_BLOCK_SIZE124INNODB_LOG_BLOCK_SIZE
124125
=== modified file 'Percona-Server/mysql-test/t/percona_innodb_fake_changes_locks.test'
--- Percona-Server/mysql-test/t/percona_innodb_fake_changes_locks.test 2011-11-24 02:00:54 +0000
+++ Percona-Server/mysql-test/t/percona_innodb_fake_changes_locks.test 2012-10-12 13:06:39 +0000
@@ -1,24 +1,121 @@
1--source include/have_innodb_plugin.inc1--source include/have_innodb_plugin.inc
22
3--disable_warnings3--disable_warnings
4DROP TABLE IF EXISTS t1;4DROP TABLE IF EXISTS t1, t2;
5--enable_warnings5--enable_warnings
66
7--echo # Verifying that X_LOCK not acquired7CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
8CREATE TABLE t1 (a INT) ENGINE=InnoDB;
9INSERT INTO t1 VALUES (1);8INSERT INTO t1 VALUES (1);
9let $t1_checksum_1= `CHECKSUM TABLE t1 EXTENDED`;
10
11CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB;
12INSERT INTO t2 VALUES (1, 1);
13let $t2_checksum_1= `CHECKSUM TABLE t2 EXTENDED`;
14
10--connect (conn1,localhost,root,,)15--connect (conn1,localhost,root,,)
11--connection conn116--connection conn1
17--echo # Verifying that X_LOCK not acquired
12SET autocommit=0;18SET autocommit=0;
13SET innodb_fake_changes=1;19SET innodb_fake_changes=1;
14BEGIN;20BEGIN;
15SELECT * FROM t1 FOR UPDATE;21SELECT * FROM t1 FOR UPDATE;
22
16--connection default23--connection default
17SET innodb_lock_wait_timeout=3;24SET innodb_lock_wait_timeout=3;
18--error 120525--error 1205
19UPDATE t1 SET a=2;26UPDATE t1 SET a=2;
20SELECT * FROM t1 LOCK IN SHARE MODE;27SELECT * FROM t1 LOCK IN SHARE MODE;
21--connection conn128
22ROLLBACK;29--connection conn1
30ROLLBACK;
31
32--echo # Confirm no lock wait timeouts when innodb_locking_fake_changes=0
33SET GLOBAL innodb_locking_fake_changes=0;
34BEGIN;
35SELECT * FROM t1 FOR UPDATE;
36
37--connect (conn2,localhost,root,,)
38--connection conn2
39BEGIN;
40UPDATE t1 SET a=3 WHERE a=1;
41SELECT * FROM t1 LOCK IN SHARE MODE;
42ROLLBACK;
43
44--connection conn1
45ROLLBACK;
46
47--echo # Confirm that fake UPDATE does not hold a lock
48BEGIN;
49SELECT * FROM t1 FOR UPDATE;
50
51--connection conn2
52BEGIN;
53UPDATE t1 SET a=3 WHERE a=1;
54ROLLBACK;
55
56--connection conn1
57ROLLBACK;
58BEGIN;
59UPDATE t1 SET a=3 WHERE a=1;
60
61--connection conn2
62BEGIN;
63UPDATE t1 SET a=3 WHERE a=1;
64ROLLBACK;
65
66--connection conn1
67ROLLBACK;
68--echo # Confirm that fake INSERT does not hold a lock
69BEGIN;
70INSERT INTO t1 VALUES(4);
71
72--connection conn2
73BEGIN;
74INSERT INTO t1 VALUES(4);
75ROLLBACK;
76
77--connection conn1
78ROLLBACK;
79--echo # Confirm that fake DELETE does not hold a lock
80BEGIN;
81DELETE FROM t1 WHERE a=1;
82
83--connection conn2
84BEGIN;
85DELETE FROM t1 WHERE a=1;
86ROLLBACK;
87
88--connection conn1
89ROLLBACK;
90--echo # Confirm that fake REPLACE does not hold a lock
91BEGIN;
92REPLACE INTO t2 VALUES(1, 2);
93
94--connection conn2
95BEGIN;
96REPLACE INTO t2 VALUES(1, 2);
97ROLLBACK;
98
99--connection conn1
100ROLLBACK;
101
23SET innodb_fake_changes=default;102SET innodb_fake_changes=default;
24DROP TABLE t1;103SET GLOBAL innodb_locking_fake_changes=default;
104--echo # Verify that the fake changes to t1 did not leak through
105CHECK TABLE t1;
106let $t1_checksum_2= `CHECKSUM TABLE t1 EXTENDED`;
107--disable_query_log
108eval SELECT "$t1_checksum_1" LIKE "$t1_checksum_2" AS should_be_1;
109--enable_query_log
110
111--echo # Verify that the fake changes to t2 did not leak through
112CHECK TABLE t2;
113let $t2_checksum_2= `CHECKSUM TABLE t2 EXTENDED`;
114--disable_query_log
115eval SELECT "$t2_checksum_1" LIKE "$t2_checksum_2" AS should_be_1;
116--enable_query_log
117
118--connection default
119--disconnect conn1
120--disconnect conn2
121DROP TABLE t1, t2;
25122
=== modified file 'Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc'
--- Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc 2012-09-14 12:19:29 +0000
+++ Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc 2012-10-12 13:06:39 +0000
@@ -12138,6 +12138,13 @@
12138 NULL, NULL, 0, 0, 1024, 0);12138 NULL, NULL, 0, 0, 1024, 0);
12139#endif /* UNIV_DEBUG */12139#endif /* UNIV_DEBUG */
1214012140
12141static MYSQL_SYSVAR_BOOL(locking_fake_changes, srv_fake_changes_locks,
12142 PLUGIN_VAR_NOCMDARG,
12143 "###EXPERIMENTAL### if enabled, transactions will get S row locks instead "
12144 "of X locks for fake changes. If disabled, fake change transactions will "
12145 "not take any locks at all.",
12146 NULL, NULL, TRUE);
12147
12141static struct st_mysql_sys_var* innobase_system_variables[]= {12148static struct st_mysql_sys_var* innobase_system_variables[]= {
12142 MYSQL_SYSVAR(page_size),12149 MYSQL_SYSVAR(page_size),
12143 MYSQL_SYSVAR(log_block_size),12150 MYSQL_SYSVAR(log_block_size),
@@ -12239,6 +12246,7 @@
12239 MYSQL_SYSVAR(pass_corrupt_table),12246 MYSQL_SYSVAR(pass_corrupt_table),
12240 MYSQL_SYSVAR(lazy_drop_table),12247 MYSQL_SYSVAR(lazy_drop_table),
12241 MYSQL_SYSVAR(fake_changes),12248 MYSQL_SYSVAR(fake_changes),
12249 MYSQL_SYSVAR(locking_fake_changes),
12242#ifdef UNIV_DEBUG12250#ifdef UNIV_DEBUG
12243 MYSQL_SYSVAR(trx_rseg_n_slots_debug),12251 MYSQL_SYSVAR(trx_rseg_n_slots_debug),
12244#endif /* UNIV_DEBUG */12252#endif /* UNIV_DEBUG */
1224512253
=== modified file 'Percona-Server/storage/innodb_plugin/include/srv0srv.h'
--- Percona-Server/storage/innodb_plugin/include/srv0srv.h 2012-09-14 12:19:29 +0000
+++ Percona-Server/storage/innodb_plugin/include/srv0srv.h 2012-10-12 13:06:39 +0000
@@ -369,6 +369,10 @@
369/** Whether startup should be blocked until buffer pool is fully restored */369/** Whether startup should be blocked until buffer pool is fully restored */
370extern ibool srv_blocking_lru_restore;370extern ibool srv_blocking_lru_restore;
371371
372/** When TRUE, fake change transcations take S rather than X row locks.
373When FALSE, row locks are not taken at all. */
374extern my_bool srv_fake_changes_locks;
375
372/** Status variables to be passed to MySQL */376/** Status variables to be passed to MySQL */
373typedef struct export_var_struct export_struc;377typedef struct export_var_struct export_struc;
374378
375379
=== modified file 'Percona-Server/storage/innodb_plugin/lock/lock0lock.c'
--- Percona-Server/storage/innodb_plugin/lock/lock0lock.c 2012-05-09 04:14:12 +0000
+++ Percona-Server/storage/innodb_plugin/lock/lock0lock.c 2012-10-12 13:06:39 +0000
@@ -5447,8 +5447,13 @@
5447 return(DB_SUCCESS);5447 return(DB_SUCCESS);
5448 }5448 }
54495449
5450 if (thr && thr_get_trx(thr)->fake_changes && mode == LOCK_X) {5450 if (UNIV_UNLIKELY((thr && thr_get_trx(thr)->fake_changes))) {
5451 mode = LOCK_S;5451 if (!srv_fake_changes_locks) {
5452 return(DB_SUCCESS);
5453 }
5454 if (mode == LOCK_X) {
5455 mode = LOCK_S;
5456 }
5452 }5457 }
54535458
5454 heap_no = page_rec_get_heap_no(rec);5459 heap_no = page_rec_get_heap_no(rec);
@@ -5528,8 +5533,13 @@
5528 return(DB_SUCCESS);5533 return(DB_SUCCESS);
5529 }5534 }
55305535
5531 if (thr && thr_get_trx(thr)->fake_changes && mode == LOCK_X) {5536 if (UNIV_UNLIKELY((thr && thr_get_trx(thr)->fake_changes))) {
5532 mode = LOCK_S;5537 if (!srv_fake_changes_locks) {
5538 return(DB_SUCCESS);
5539 }
5540 if (mode == LOCK_X) {
5541 mode = LOCK_S;
5542 }
5533 }5543 }
55345544
5535 heap_no = page_rec_get_heap_no(rec);5545 heap_no = page_rec_get_heap_no(rec);
55365546
=== modified file 'Percona-Server/storage/innodb_plugin/srv/srv0srv.c'
--- Percona-Server/storage/innodb_plugin/srv/srv0srv.c 2012-09-14 12:19:29 +0000
+++ Percona-Server/storage/innodb_plugin/srv/srv0srv.c 2012-10-12 13:06:39 +0000
@@ -166,6 +166,10 @@
166166
167UNIV_INTERN ulonglong srv_changed_pages_limit = 0;167UNIV_INTERN ulonglong srv_changed_pages_limit = 0;
168168
169/** When TRUE, fake change transcations take S rather than X row locks.
170 When FALSE, row locks are not taken at all. */
171UNIV_INTERN my_bool srv_fake_changes_locks = TRUE;
172
169/* if TRUE, then we auto-extend the last data file */173/* if TRUE, then we auto-extend the last data file */
170UNIV_INTERN ibool srv_auto_extend_last_data_file = FALSE;174UNIV_INTERN ibool srv_auto_extend_last_data_file = FALSE;
171/* if != 0, this tells the max size auto-extending may increase the175/* if != 0, this tells the max size auto-extending may increase the

Subscribers

People subscribed via source and target branches