Merge lp:~laurynas-biveinis/percona-server/26611-bug1064333-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: 499
Proposed branch: lp:~laurynas-biveinis/percona-server/26611-bug1064333-5.1
Merge into: lp:percona-server/5.1
Prerequisite: lp:~laurynas-biveinis/percona-server/26611-bug917942-5.1
Diff against target: 289 lines (+137/-17)
4 files modified
Percona-Server/mysql-test/r/percona_innodb_fake_changes.result (+41/-1)
Percona-Server/mysql-test/t/percona_innodb_fake_changes.test (+66/-2)
Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc (+9/-3)
Percona-Server/storage/innodb_plugin/row/row0mysql.c (+21/-11)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/26611-bug1064333-5.1
Reviewer Review Type Date Requested Status
Stewart Smith (community) Approve
Review via email: mp+130366@code.launchpad.net

Description of the change

Fix bug 1064333 (Fake changes bump the changed row counters).

There are following issues with the stat acounting with fake changes:
- InnoDB handler methods write_row, update_row, delete_row update the
  userstat changed row counter unconditionally.
- row_insert_for_mysql(), row_update_for_mysql() and
  row_update_cascade_for_mysql() update the number of changed rows
  since last stat update, innodb_rows_inserted, innodb_rows_updated
  and innodb_rows_deleted unconditionally.

Fixed and extended the percona_innodb_fake_changes testcase to check
these stats for all the fixed cases.

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

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
1=== modified file 'Percona-Server/mysql-test/r/percona_innodb_fake_changes.result'
2--- Percona-Server/mysql-test/r/percona_innodb_fake_changes.result 2012-10-18 14:17:27 +0000
3+++ Percona-Server/mysql-test/r/percona_innodb_fake_changes.result 2012-10-18 14:17:28 +0000
4@@ -22,6 +22,7 @@
5 OFF
6 # Explicit COMMIT should fail when innodb_fake_changes is enabled
7 # DML should be fine
8+SET @@GLOBAL.userstat_running= TRUE;
9 CREATE TABLE t1 (a INT) ENGINE=InnoDB;
10 INSERT INTO t1 VALUES (1);
11 SET autocommit=0;
12@@ -42,9 +43,21 @@
13 test.t1 check status OK
14 should_be_1
15 1
16+should_be_0
17+0
18+should_be_0
19+0
20+should_be_0
21+0
22+should_be_0
23+0
24+should_be_0
25+0
26+should_be_0
27+0
28 DROP TABLE t1;
29 # DDL must result in error
30-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
31+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
32 SET autocommit=0;
33 SET innodb_fake_changes=1;
34 BEGIN;
35@@ -58,6 +71,32 @@
36 ERROR HY000: Got error 131 during COMMIT
37 ROLLBACK;
38 SET innodb_fake_changes=0;
39+INSERT INTO t1 VALUES (1), (2);
40+COMMIT;
41+CREATE TABLE t2 (a INT PRIMARY KEY, b INT, INDEX b_ind (b),
42+FOREIGN KEY (b) REFERENCES t1(a) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB;
43+INSERT INTO t2 VALUES (1, 1);
44+INSERT INTO t2 VALUES (2, 2);
45+COMMIT;
46+SET innodb_fake_changes=1;
47+DELETE FROM t1 WHERE a=1;
48+UPDATE t1 SET a=3 WHERE a=2;
49+COMMIT;
50+ERROR HY000: Got error 131 during COMMIT
51+should_be_1
52+1
53+should_be_0
54+0
55+should_be_0
56+0
57+should_be_0
58+0
59+should_be_0
60+0
61+should_be_0
62+0
63+SET innodb_fake_changes=0;
64+DROP TABLE t2;
65 CREATE TABLE t3 (a INT primary key, b text) ENGINE=InnoDB;
66 INSERT INTO t3 VALUES (1,'');
67 COMMIT;
68@@ -73,3 +112,4 @@
69 should_be_1
70 1
71 DROP TABLE t1, t3;
72+SET @@GLOBAL.userstat_running= default;
73
74=== modified file 'Percona-Server/mysql-test/t/percona_innodb_fake_changes.test'
75--- Percona-Server/mysql-test/t/percona_innodb_fake_changes.test 2012-10-18 14:17:27 +0000
76+++ Percona-Server/mysql-test/t/percona_innodb_fake_changes.test 2012-10-18 14:17:28 +0000
77@@ -17,9 +17,18 @@
78
79 --echo # Explicit COMMIT should fail when innodb_fake_changes is enabled
80 --echo # DML should be fine
81+SET @@GLOBAL.userstat_running= TRUE;
82 CREATE TABLE t1 (a INT) ENGINE=InnoDB;
83 INSERT INTO t1 VALUES (1);
84+
85 let $t1_checksum_1= `CHECKSUM TABLE t1 EXTENDED`;
86+let $innodb_rows_inserted_1= `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_rows_inserted'`;
87+let $innodb_rows_deleted_1= `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_rows_deleted'`;
88+let $innodb_rows_updated_1= `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_rows_updated'`;
89+let $table_rows_estimate_1= `SELECT ROWS FROM INFORMATION_SCHEMA.INNODB_TABLE_STATS WHERE TABLE_SCHEMA LIKE 'test' AND TABLE_NAME LIKE 't1'`;
90+let $table_rows_changed_1= `SELECT ROWS_CHANGED FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_SCHEMA LIKE 'test' AND TABLE_NAME LIKE 't1'`;
91+let $table_rows_changed_x_indexes_1= `SELECT ROWS_CHANGED_X_INDEXES FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_SCHEMA LIKE 'test' AND TABLE_NAME LIKE 't1'`;
92+
93 SET autocommit=0;
94 SET innodb_fake_changes=1;
95 BEGIN;
96@@ -33,13 +42,25 @@
97 --echo # Verify that the fake changes to t1 did not leak through
98 CHECK TABLE t1;
99 let $t1_checksum_2= `CHECKSUM TABLE t1 EXTENDED`;
100+let $innodb_rows_inserted_2= `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_rows_inserted'`;
101+let $innodb_rows_deleted_2= `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_rows_deleted'`;
102+let $innodb_rows_updated_2= `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_rows_updated'`;
103+let $table_rows_estimate_2= `SELECT ROWS FROM INFORMATION_SCHEMA.INNODB_TABLE_STATS WHERE TABLE_SCHEMA LIKE 'test' AND TABLE_NAME LIKE 't1'`;
104+let $table_rows_changed_2= `SELECT ROWS_CHANGED FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_SCHEMA LIKE 'test' AND TABLE_NAME LIKE 't1'`;
105+let $table_rows_changed_x_indexes_2= `SELECT ROWS_CHANGED_X_INDEXES FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_SCHEMA LIKE 'test' AND TABLE_NAME LIKE 't1'`;
106 --disable_query_log
107 eval SELECT "$t1_checksum_1" LIKE "$t1_checksum_2" AS should_be_1;
108+eval SELECT "$innodb_rows_inserted_2" - "$innodb_rows_inserted_1" AS should_be_0;
109+eval SELECT "$innodb_rows_deleted_2" - "$innodb_rows_deleted_1" AS should_be_0;
110+eval SELECT "$innodb_rows_updated_2" - "$innodb_rows_updated_1" AS should_be_0;
111+eval SELECT "$table_rows_estimate_2" - "$table_rows_estimate_1" AS should_be_0;
112+eval SELECT "$table_rows_changed_2" - "$table_rows_changed_1" AS should_be_0;
113+eval SELECT "$table_rows_changed_x_indexes_2" - "$table_rows_changed_x_indexes_1" AS should_be_0;
114 --enable_query_log
115 DROP TABLE t1;
116
117 --echo # DDL must result in error
118-CREATE TABLE t1 (a INT) ENGINE=InnoDB;
119+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
120 SET autocommit=0;
121 SET innodb_fake_changes=1;
122 BEGIN;
123@@ -53,8 +74,49 @@
124 ALTER TABLE t1 ENGINE=MyISAM;
125 ROLLBACK;
126
127+# Test stat counters foreign key constraints
128+SET innodb_fake_changes=0;
129+INSERT INTO t1 VALUES (1), (2);
130+COMMIT;
131+CREATE TABLE t2 (a INT PRIMARY KEY, b INT, INDEX b_ind (b),
132+ FOREIGN KEY (b) REFERENCES t1(a) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB;
133+INSERT INTO t2 VALUES (1, 1);
134+INSERT INTO t2 VALUES (2, 2);
135+COMMIT;
136+
137+let $t2_checksum_1= `CHECKSUM TABLE t2 EXTENDED`;
138+let $innodb_rows_deleted_1= `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_rows_deleted'`;
139+let $innodb_rows_updated_1= `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_rows_updated'`;
140+let $table_rows_estimate_1= `SELECT ROWS FROM INFORMATION_SCHEMA.INNODB_TABLE_STATS WHERE TABLE_SCHEMA LIKE 'test' AND TABLE_NAME LIKE 't2'`;
141+let $table_rows_changed_1= `SELECT ROWS_CHANGED FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_SCHEMA LIKE 'test' AND TABLE_NAME LIKE 't2'`;
142+let $table_rows_changed_x_indexes_1= `SELECT ROWS_CHANGED_X_INDEXES FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_SCHEMA LIKE 'test' AND TABLE_NAME LIKE 't2'`;
143+
144+SET innodb_fake_changes=1;
145+DELETE FROM t1 WHERE a=1;
146+UPDATE t1 SET a=3 WHERE a=2;
147+--error 1180
148+COMMIT;
149+
150+let $t2_checksum_2= `CHECKSUM TABLE t2 EXTENDED`;
151+let $innodb_rows_deleted_2= `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_rows_deleted'`;
152+let $innodb_rows_updated_2= `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_rows_updated'`;
153+let $table_rows_estimate_2= `SELECT ROWS FROM INFORMATION_SCHEMA.INNODB_TABLE_STATS WHERE TABLE_SCHEMA LIKE 'test' AND TABLE_NAME LIKE 't2'`;
154+let $table_rows_changed_2= `SELECT ROWS_CHANGED FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_SCHEMA LIKE 'test' AND TABLE_NAME LIKE 't2'`;
155+let $table_rows_changed_x_indexes_2= `SELECT ROWS_CHANGED_X_INDEXES FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_SCHEMA LIKE 'test' AND TABLE_NAME LIKE 't2'`;
156+
157+--disable_query_log
158+eval SELECT "$t2_checksum_1" LIKE "$t2_checksum_2" AS should_be_1;
159+eval SELECT "$innodb_rows_deleted_2" - "$innodb_rows_deleted_1" AS should_be_0;
160+eval SELECT "$innodb_rows_updated_2" - "$innodb_rows_updated_1" AS should_be_0;
161+eval SELECT "$table_rows_estimate_2" - "$table_rows_estimate_1" AS should_be_0;
162+eval SELECT "$table_rows_changed_2" - "$table_rows_changed_1" AS should_be_0;
163+eval SELECT "$table_rows_changed_x_indexes_2" - "$table_rows_changed_x_indexes_1" AS should_be_0;
164+--enable_query_log
165+
166+SET innodb_fake_changes=0;
167+DROP TABLE t2;
168+
169 # Test for bug 890404: uninitialized value warning in btr_cur_pessimistic_update
170-SET innodb_fake_changes=0;
171 CREATE TABLE t3 (a INT primary key, b text) ENGINE=InnoDB;
172 INSERT INTO t3 VALUES (1,'');
173 COMMIT;
174@@ -73,3 +135,5 @@
175 eval SELECT "$t3_checksum_1" LIKE "$t3_checksum_2" AS should_be_1;
176 --enable_query_log
177 DROP TABLE t1, t3;
178+
179+SET @@GLOBAL.userstat_running= default;
180
181=== modified file 'Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc'
182--- Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc 2012-10-18 14:17:27 +0000
183+++ Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc 2012-10-18 14:17:28 +0000
184@@ -5367,7 +5367,9 @@
185 error = row_insert_for_mysql((byte*) record, prebuilt);
186
187 #ifdef EXTENDED_FOR_USERSTAT
188- if (error == DB_SUCCESS) rows_changed++;
189+ if (UNIV_LIKELY(error == DB_SUCCESS && !trx->fake_changes)) {
190+ rows_changed++;
191+ }
192 #endif
193
194 /* Handle duplicate key errors */
195@@ -5714,7 +5716,9 @@
196 }
197
198 #ifdef EXTENDED_FOR_USERSTAT
199- if (error == DB_SUCCESS) rows_changed++;
200+ if (UNIV_LIKELY(error == DB_SUCCESS && !trx->fake_changes)) {
201+ rows_changed++;
202+ }
203 #endif
204
205 innodb_srv_conc_exit_innodb(trx);
206@@ -5779,7 +5783,9 @@
207 error = row_update_for_mysql((byte*) record, prebuilt);
208
209 #ifdef EXTENDED_FOR_USERSTAT
210- if (error == DB_SUCCESS) rows_changed++;
211+ if (UNIV_LIKELY(error == DB_SUCCESS && !trx->fake_changes)) {
212+ rows_changed++;
213+ }
214 #endif
215
216 innodb_srv_conc_exit_innodb(trx);
217
218=== modified file 'Percona-Server/storage/innodb_plugin/row/row0mysql.c'
219--- Percona-Server/storage/innodb_plugin/row/row0mysql.c 2012-05-29 06:32:03 +0000
220+++ Percona-Server/storage/innodb_plugin/row/row0mysql.c 2012-10-18 14:17:28 +0000
221@@ -1188,17 +1188,19 @@
222
223 que_thr_stop_for_mysql_no_error(thr, trx);
224
225- prebuilt->table->stat_n_rows++;
226-
227- srv_n_rows_inserted++;
228-
229- if (prebuilt->table->stat_n_rows == 0) {
230- /* Avoid wrap-over */
231- prebuilt->table->stat_n_rows--;
232+ if (UNIV_LIKELY(!(trx->fake_changes))) {
233+
234+ prebuilt->table->stat_n_rows++;
235+
236+ if (prebuilt->table->stat_n_rows == 0) {
237+ /* Avoid wrap-over */
238+ prebuilt->table->stat_n_rows--;
239+ }
240+
241+ srv_n_rows_inserted++;
242+ row_update_statistics_if_needed(prebuilt->table);
243 }
244
245- if (!(trx->fake_changes))
246- row_update_statistics_if_needed(prebuilt->table);
247 trx->op_info = "";
248
249 return((int) err);
250@@ -1446,6 +1448,11 @@
251
252 que_thr_stop_for_mysql_no_error(thr, trx);
253
254+ if (UNIV_UNLIKELY(trx->fake_changes)) {
255+ trx->op_info = "";
256+ return((int) err);
257+ }
258+
259 if (node->is_delete) {
260 if (prebuilt->table->stat_n_rows > 0) {
261 prebuilt->table->stat_n_rows--;
262@@ -1460,7 +1467,6 @@
263 that changes indexed columns, UPDATEs that change only non-indexed
264 columns would not affect statistics. */
265 if (node->is_delete || !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
266- if (!(trx->fake_changes))
267 row_update_statistics_if_needed(prebuilt->table);
268 }
269
270@@ -1669,6 +1675,11 @@
271 return(err);
272 }
273
274+ if (UNIV_UNLIKELY((trx->fake_changes))) {
275+
276+ return(err);
277+ }
278+
279 if (node->is_delete) {
280 if (table->stat_n_rows > 0) {
281 table->stat_n_rows--;
282@@ -1679,7 +1690,6 @@
283 srv_n_rows_updated++;
284 }
285
286- if (!(trx->fake_changes))
287 row_update_statistics_if_needed(table);
288
289 return(err);

Subscribers

People subscribed via source and target branches