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

Proposed by Laurynas Biveinis
Status: Merged
Approved by: Alexey Kopytov
Approved revision: 578
Merged at revision: 590
Proposed branch: lp:~laurynas-biveinis/percona-server/bug1217002-5.1
Merge into: lp:percona-server/5.1
Diff against target: 308 lines (+173/-7)
9 files modified
Percona-Server/mysql-test/r/percona_server_variables_debug.result (+2/-0)
Percona-Server/mysql-test/suite/innodb_plugin/r/percona_changed_page_bmp_debug.result (+14/-0)
Percona-Server/mysql-test/suite/innodb_plugin/t/percona_changed_page_bmp_debug-master.opt (+1/-1)
Percona-Server/mysql-test/suite/innodb_plugin/t/percona_changed_page_bmp_debug.test (+46/-0)
Percona-Server/storage/innodb_plugin/fil/fil0fil.c (+5/-0)
Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc (+80/-3)
Percona-Server/storage/innodb_plugin/log/log0recv.c (+2/-1)
Percona-Server/storage/innodb_plugin/row/row0merge.c (+17/-2)
Percona-Server/storage/innodb_plugin/srv/srv0srv.c (+6/-0)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/bug1217002-5.1
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Approve
Review via email: mp+184616@code.launchpad.net

Description of the change

a QA blocker.

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

Fix
- bug 1217002 (RENAME/DROP crashes with innodb_track_changed_pages);
- bug 1213885 (Failing assertion: error == DB_SUCCESS in file
  handler0alter.cc line 4897 | abort in commit_cache_rebuild).

Both bugs are caused by a recent upstream change that makes
MLOG_FILE_RENAME to replay unconditionally whenever such log record is
parsed, which includes online log tracking.

Fix by
- asserting in fil_op_log_parse_or_replay() that, if a file operation
  is about to be executed, that recovery is on, and
- adjusting recv_parse_or_apply_log_rec_body() to only pass non-zero
  space_id to fil_op_log_parse_or_replay if recovery is on. A
  non-zero space_id is what causes fil_op_log_parse_or_replay() to
  replay and not only parse the log record.

Changes for testing:
- backport from 5.5+ the debug-only innodb_log_checkpoint_now system
  variable;
- make innodb_track_changed_pages a dynamic variable, for debug builds
  only, to provide the ability to stop log tracking temporarily;
- add a new debug-only system variable innodb_track_redo_log_now, that
  issues a synchronuous redo log parse request;
- add a new debug sync point to row_merge_rename_tables();
- use all of the above to add a testcase to
  percona_changed_page_bmp_debug test.

To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) :
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_server_variables_debug.result'
2--- Percona-Server/mysql-test/r/percona_server_variables_debug.result 2013-06-03 03:53:55 +0000
3+++ Percona-Server/mysql-test/r/percona_server_variables_debug.result 2013-09-09 16:35:56 +0000
4@@ -127,6 +127,7 @@
5 INNODB_LOCK_WAIT_TIMEOUT
6 INNODB_LOG_BLOCK_SIZE
7 INNODB_LOG_BUFFER_SIZE
8+INNODB_LOG_CHECKPOINT_NOW
9 INNODB_LOG_FILES_IN_GROUP
10 INNODB_LOG_FILE_SIZE
11 INNODB_LOG_GROUP_HOME_DIR
12@@ -165,6 +166,7 @@
13 INNODB_THREAD_CONCURRENCY_TIMER_BASED
14 INNODB_THREAD_SLEEP_DELAY
15 INNODB_TRACK_CHANGED_PAGES
16+INNODB_TRACK_REDO_LOG_NOW
17 INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG
18 INNODB_TRX_RSEG_N_SLOTS_DEBUG
19 INNODB_USE_PURGE_THREAD
20
21=== modified file 'Percona-Server/mysql-test/suite/innodb_plugin/r/percona_changed_page_bmp_debug.result'
22--- Percona-Server/mysql-test/suite/innodb_plugin/r/percona_changed_page_bmp_debug.result 2013-02-07 07:29:35 +0000
23+++ Percona-Server/mysql-test/suite/innodb_plugin/r/percona_changed_page_bmp_debug.result 2013-09-09 16:35:56 +0000
24@@ -21,3 +21,17 @@
25 INSERT INTO t1 SELECT x FROM t1;
26 3rd restart
27 DROP TABLE t1;
28+CREATE TABLE t1 (x INT NOT NULL UNIQUE KEY) ENGINE=InnoDB;
29+INSERT INTO t1 VALUES(5);
30+SET @@GLOBAL.innodb_track_changed_pages=FALSE;
31+SET @@GLOBAL.innodb_log_checkpoint_now=TRUE;
32+RENAME TABLE t1 TO t2;
33+SET DEBUG_SYNC="row_merge_rename_tables_between_renames SIGNAL alter_table_ready WAIT_FOR finish_alter_table";
34+ALTER TABLE t2 ADD PRIMARY KEY(x);
35+SET DEBUG_SYNC="now WAIT_FOR alter_table_ready";
36+SET @@GLOBAL.innodb_log_checkpoint_now=TRUE;
37+SET @@GLOBAL.innodb_track_changed_pages=TRUE;
38+SET @@GLOBAL.innodb_track_redo_log_now=TRUE;
39+SET DEBUG_SYNC="now SIGNAL finish_alter_table";
40+SET DEBUG_SYNC="RESET";
41+DROP TABLE t2;
42
43=== modified file 'Percona-Server/mysql-test/suite/innodb_plugin/t/percona_changed_page_bmp_debug-master.opt'
44--- Percona-Server/mysql-test/suite/innodb_plugin/t/percona_changed_page_bmp_debug-master.opt 2013-02-07 07:29:35 +0000
45+++ Percona-Server/mysql-test/suite/innodb_plugin/t/percona_changed_page_bmp_debug-master.opt 2013-09-09 16:35:56 +0000
46@@ -1,1 +1,1 @@
47---innodb_track_changed_pages=TRUE --innodb_log_file_size=1M
48+--innodb_track_changed_pages=TRUE --innodb_log_file_size=1M --innodb-file-per-table
49
50=== modified file 'Percona-Server/mysql-test/suite/innodb_plugin/t/percona_changed_page_bmp_debug.test'
51--- Percona-Server/mysql-test/suite/innodb_plugin/t/percona_changed_page_bmp_debug.test 2013-02-07 07:29:35 +0000
52+++ Percona-Server/mysql-test/suite/innodb_plugin/t/percona_changed_page_bmp_debug.test 2013-09-09 16:35:56 +0000
53@@ -3,6 +3,7 @@
54 #
55 --source include/have_debug.inc
56 --source include/have_innodb_plugin.inc
57+--source include/count_sessions.inc
58
59 --disable_warnings
60 DROP TABLE IF EXISTS t1;
61@@ -54,3 +55,48 @@
62 --source include/restart_mysqld.inc
63
64 DROP TABLE t1;
65+
66+#
67+# Test for bug 1217002 (RENAME/DROP crashes with innodb_track_changed_pages)
68+#
69+CREATE TABLE t1 (x INT NOT NULL UNIQUE KEY) ENGINE=InnoDB;
70+INSERT INTO t1 VALUES(5);
71+
72+# 1. Pause the log tracking thread
73+SET @@GLOBAL.innodb_track_changed_pages=FALSE;
74+SET @@GLOBAL.innodb_log_checkpoint_now=TRUE;
75+
76+# 2. Rename a table to log a MLOG_FILE_RENAME operation
77+RENAME TABLE t1 TO t2;
78+
79+# 3. Start an ALTER TABLE and stop it after the table -> temp table rename
80+--connect (con2,localhost,root,,)
81+--connection default
82+
83+SET DEBUG_SYNC="row_merge_rename_tables_between_renames SIGNAL alter_table_ready WAIT_FOR finish_alter_table";
84+
85+send ALTER TABLE t2 ADD PRIMARY KEY(x);
86+
87+# 4. Force a checkpoint and resume the log tracker thread, so that it misapplies the t1 > t2 rename.
88+--connection con2
89+
90+SET DEBUG_SYNC="now WAIT_FOR alter_table_ready";
91+
92+SET @@GLOBAL.innodb_log_checkpoint_now=TRUE;
93+SET @@GLOBAL.innodb_track_changed_pages=TRUE;
94+
95+# 5. Force the log tracker to catch up.
96+SET @@GLOBAL.innodb_track_redo_log_now=TRUE;
97+
98+# 6. Finish the ALTER TABLE, which then crashes if the bug is present.
99+SET DEBUG_SYNC="now SIGNAL finish_alter_table";
100+
101+--connection default
102+reap;
103+SET DEBUG_SYNC="RESET";
104+
105+disconnect con2;
106+
107+DROP TABLE t2;
108+
109+--source include/wait_until_count_sessions.inc
110
111=== modified file 'Percona-Server/storage/innodb_plugin/fil/fil0fil.c'
112--- Percona-Server/storage/innodb_plugin/fil/fil0fil.c 2013-08-05 13:11:52 +0000
113+++ Percona-Server/storage/innodb_plugin/fil/fil0fil.c 2013-09-09 16:35:56 +0000
114@@ -2114,6 +2114,11 @@
115 if (!space_id) {
116
117 return(ptr);
118+ } else {
119+ /* Only replay file ops during recovery. This is a
120+ release-build assert to minimize any data loss risk by a
121+ misapplied file operation. */
122+ ut_a(recv_recovery_is_on());
123 }
124
125 /* Let us try to perform the file operation, if sensible. Note that
126
127=== modified file 'Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc'
128--- Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc 2013-08-23 07:34:57 +0000
129+++ Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc 2013-09-09 16:35:56 +0000
130@@ -11897,6 +11897,63 @@
131 #endif
132 }
133
134+#ifdef UNIV_DEBUG
135+static my_bool innodb_log_checkpoint_now = TRUE;
136+
137+/****************************************************************//**
138+Force innodb to checkpoint. */
139+static
140+void
141+checkpoint_now_set(
142+/*===============*/
143+ THD* thd /*!< in: thread handle */
144+ __attribute__((unused)),
145+ struct st_mysql_sys_var* var /*!< in: pointer to system
146+ variable */
147+ __attribute__((unused)),
148+ void* var_ptr /*!< out: where the formal
149+ string goes */
150+ __attribute__((unused)),
151+ const void* save) /*!< in: immediate result from
152+ check function */
153+{
154+ if (*(my_bool*) save) {
155+ while (log_sys->last_checkpoint_lsn < log_sys->lsn) {
156+ log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE);
157+ fil_flush_file_spaces(FIL_LOG);
158+ }
159+ fil_write_flushed_lsn_to_data_files(log_sys->lsn, 0);
160+ fil_flush_file_spaces(FIL_TABLESPACE);
161+ }
162+}
163+
164+static my_bool innodb_track_redo_log_now = TRUE;
165+
166+/****************************************************************//**
167+Force log tracker to track the log synchronously. */
168+static
169+void
170+track_redo_log_now_set(
171+/*===================*/
172+ THD* thd /*!< in: thread handle */
173+ __attribute__((unused)),
174+ struct st_mysql_sys_var* var /*!< in: pointer to system
175+ variable */
176+ __attribute__((unused)),
177+ void* var_ptr /*!< out: where the formal
178+ string goes */
179+ __attribute__((unused)),
180+ const void* save) /*!< in: immediate result from
181+ check function */
182+{
183+ if (*(my_bool*) save && srv_track_changed_pages) {
184+
185+ log_online_follow_redo_log();
186+ }
187+}
188+
189+
190+#endif /* UNIV_DEBUG */
191
192 static SHOW_VAR innodb_status_variables_export[]= {
193 {"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
194@@ -12306,9 +12363,15 @@
195 NULL, NULL, SRV_STATS_NULLS_EQUAL, &innodb_stats_method_typelib);
196
197 static MYSQL_SYSVAR_BOOL(track_changed_pages, srv_track_changed_pages,
198- PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
199- "Track the redo log for changed pages and output a changed page bitmap",
200- NULL, NULL, FALSE);
201+ PLUGIN_VAR_NOCMDARG
202+#ifndef UNIV_DEBUG
203+ /* Make this variable dynamic for debug builds to
204+ provide a testcase sync facility */
205+ | PLUGIN_VAR_READONLY
206+#endif
207+ ,
208+ "Track the redo log for changed pages and output a changed page bitmap",
209+ NULL, NULL, FALSE);
210
211 static MYSQL_SYSVAR_ULONGLONG(max_bitmap_file_size, srv_max_bitmap_file_size,
212 PLUGIN_VAR_RQCMDARG,
213@@ -12494,6 +12557,18 @@
214 "It is to create artificially the situation the purge view have been updated "
215 "but the each purges were not done yet.",
216 NULL, NULL, FALSE);
217+
218+static MYSQL_SYSVAR_BOOL(log_checkpoint_now, innodb_log_checkpoint_now,
219+ PLUGIN_VAR_OPCMDARG,
220+ "Force checkpoint now",
221+ NULL, checkpoint_now_set, FALSE);
222+
223+static MYSQL_SYSVAR_BOOL(track_redo_log_now,
224+ innodb_track_redo_log_now,
225+ PLUGIN_VAR_OPCMDARG,
226+ "Force log tracker to catch up with checkpoint now",
227+ NULL, track_redo_log_now_set, FALSE);
228+
229 #endif /* UNIV_DEBUG */
230
231 static MYSQL_SYSVAR_BOOL(locking_fake_changes, srv_fake_changes_locks,
232@@ -12613,6 +12688,8 @@
233 MYSQL_SYSVAR(trx_rseg_n_slots_debug),
234 MYSQL_SYSVAR(limit_optimistic_insert_debug),
235 MYSQL_SYSVAR(trx_purge_view_update_only_debug),
236+ MYSQL_SYSVAR(log_checkpoint_now),
237+ MYSQL_SYSVAR(track_redo_log_now),
238 #endif /* UNIV_DEBUG */
239 NULL
240 };
241
242=== modified file 'Percona-Server/storage/innodb_plugin/log/log0recv.c'
243--- Percona-Server/storage/innodb_plugin/log/log0recv.c 2013-08-05 13:11:52 +0000
244+++ Percona-Server/storage/innodb_plugin/log/log0recv.c 2013-09-09 16:35:56 +0000
245@@ -1256,7 +1256,8 @@
246 break;
247 case MLOG_FILE_RENAME:
248 ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type,
249- space_id, 0);
250+ (recv_recovery_is_on()
251+ ? space_id : 0), 0);
252 break;
253 case MLOG_FILE_CREATE:
254 case MLOG_FILE_DELETE:
255
256=== modified file 'Percona-Server/storage/innodb_plugin/row/row0merge.c'
257--- Percona-Server/storage/innodb_plugin/row/row0merge.c 2013-08-05 13:11:52 +0000
258+++ Percona-Server/storage/innodb_plugin/row/row0merge.c 2013-09-09 16:35:56 +0000
259@@ -58,6 +58,14 @@
260 #include "handler0alter.h"
261 #include "ha_prototypes.h"
262
263+#ifdef __WIN__
264+/* error LNK2001: unresolved external symbol _debug_sync_C_callback_ptr */
265+# define DEBUG_SYNC_C(dummy) ((void) 0)
266+#else
267+# include "m_string.h" /* for my_sys.h */
268+# include "my_sys.h" /* DEBUG_SYNC_C */
269+#endif
270+
271 #ifdef UNIV_DEBUG
272 /** Set these in order ot enable debug printout. */
273 /* @{ */
274@@ -2465,8 +2473,15 @@
275 /* The following calls will also rename the .ibd data files if
276 the tables are stored in a single-table tablespace */
277
278- if (!dict_table_rename_in_cache(old_table, tmp_name, FALSE)
279- || !dict_table_rename_in_cache(new_table, old_name, FALSE)) {
280+ if (!dict_table_rename_in_cache(old_table, tmp_name, FALSE)) {
281+
282+ err = DB_ERROR;
283+ goto err_exit;
284+ }
285+
286+ DEBUG_SYNC_C("row_merge_rename_tables_between_renames");
287+
288+ if (!dict_table_rename_in_cache(new_table, old_name, FALSE)) {
289
290 err = DB_ERROR;
291 goto err_exit;
292
293=== modified file 'Percona-Server/storage/innodb_plugin/srv/srv0srv.c'
294--- Percona-Server/storage/innodb_plugin/srv/srv0srv.c 2013-08-05 13:11:52 +0000
295+++ Percona-Server/storage/innodb_plugin/srv/srv0srv.c 2013-09-09 16:35:56 +0000
296@@ -2759,6 +2759,12 @@
297 os_event_wait(srv_checkpoint_completed_event);
298 os_event_reset(srv_checkpoint_completed_event);
299
300+#ifdef UNIV_DEBUG
301+ if (!srv_track_changed_pages) {
302+ continue;
303+ }
304+#endif
305+
306 if (!log_online_follow_redo_log()) {
307 /* TODO: sync with I_S log tracking status? */
308 fprintf(stderr,

Subscribers

People subscribed via source and target branches