Merge lp:~laurynas-biveinis/percona-server/bug999147-5.5 into lp:percona-server/5.5

Proposed by Laurynas Biveinis
Status: Merged
Approved by: Alexey Kopytov
Approved revision: no longer in the source branch.
Merged at revision: 241
Proposed branch: lp:~laurynas-biveinis/percona-server/bug999147-5.5
Merge into: lp:percona-server/5.5
Diff against target: 80 lines (+43/-1)
5 files modified
Percona-Server/mysql-test/suite/innodb/r/percona_bug_999147.result (+10/-0)
Percona-Server/mysql-test/suite/innodb/t/percona_bug_999147-master.opt (+1/-0)
Percona-Server/mysql-test/suite/innodb/t/percona_bug_999147.test (+29/-0)
Percona-Server/storage/innobase/handler/handler0alter.cc (+2/-0)
Percona-Server/storage/innobase/row/row0mysql.c (+1/-1)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/bug999147-5.5
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Approve
Review via email: mp+105939@code.launchpad.net

Description of the change

    Fix bug 999147 (A crash that leaves behind an InnoDB temporary table
    with indexes results in an unbootable server).

    The issue happens on server start up if there exists a temporary table
    from the crashed session that has a temporary index on it. Then
    row_merge_drop_temp_indexes() will load the table into the dictionary
    cache in order to drop the index. Later row_mysql_drop_temp_tables()
    will try to load exact same table again and will be unable to handle
    that the table is already loaded.

    The only place in InnoDB that uses temporary indexes is the regular
    table index creation and drop. This code however is not used for the
    temporary tables, as they are created anew with the final index
    definitions and then data is copied.

    However the Percona Server expanded index creation might use the
    regular index creation and drop code path in a case with
    expanded fast index creation enabled: when there is an
    already-existing secondary index on the table, it will be dropped from
    the new temp table and recreated after copying the data.

    The fix is in row_mysql_drop_temp_tables(): replace the
    dict_load_table() call with a dict_table_get_low() call that will
    check the cache and call the former only if needed.

    For testing we need to crash the server when the temporary index is
    present. For that, add a new crash injection site
    "crash_innodb_add_index_after" at the end of non-error
    ha_innobase::add_index() code path.

    Add a new test case percona_bug_999147.

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

Laurynas,

The patch looks good, thank you!

However it's not obvious why the bug is invalid for 5.1?

review: Approve
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

Alexey -

Thanks.

"Invalid for 5.1" was due to my mistaken impression that the expanded fast index creation is unavailable in 5.1. Fixed now.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'Percona-Server/mysql-test/suite/innodb/r/percona_bug_999147.result'
2--- Percona-Server/mysql-test/suite/innodb/r/percona_bug_999147.result 1970-01-01 00:00:00 +0000
3+++ Percona-Server/mysql-test/suite/innodb/r/percona_bug_999147.result 2012-05-16 08:23:21 +0000
4@@ -0,0 +1,10 @@
5+DROP TABLE IF EXISTS t1;
6+SET SESSION expand_fast_index_creation=ON;
7+CREATE TEMPORARY TABLE t1 (a INT, b INT, INDEX(a));
8+SET debug="+d,crash_innodb_add_index_after";
9+ALTER TABLE t1 ADD INDEX (b);
10+ERROR HY000: Lost connection to MySQL server during query
11+SELECT NAME, FLAG FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES;
12+NAME FLAG
13+SYS_FOREIGN 0
14+SYS_FOREIGN_COLS 0
15
16=== added file 'Percona-Server/mysql-test/suite/innodb/t/percona_bug_999147-master.opt'
17--- Percona-Server/mysql-test/suite/innodb/t/percona_bug_999147-master.opt 1970-01-01 00:00:00 +0000
18+++ Percona-Server/mysql-test/suite/innodb/t/percona_bug_999147-master.opt 2012-05-16 08:23:21 +0000
19@@ -0,0 +1,1 @@
20+--skip-stack-trace --skip-core-file --innodb-file-per-table=1
21
22=== added file 'Percona-Server/mysql-test/suite/innodb/t/percona_bug_999147.test'
23--- Percona-Server/mysql-test/suite/innodb/t/percona_bug_999147.test 1970-01-01 00:00:00 +0000
24+++ Percona-Server/mysql-test/suite/innodb/t/percona_bug_999147.test 2012-05-16 08:23:21 +0000
25@@ -0,0 +1,29 @@
26+# Test for Percona Server bug 999147 (A crash that leaves behind an
27+# InnoDB temporary table with indexes results in an unbootable server)
28+# https://bugs.launchpad.net/percona-server/+bug/999147
29+
30+-- source include/not_embedded.inc
31+-- source include/not_valgrind.inc
32+-- source include/not_crashrep.inc
33+-- source include/have_debug.inc
34+-- source include/have_innodb.inc
35+
36+--disable_warnings
37+DROP TABLE IF EXISTS t1;
38+--enable_warnings
39+
40+SET SESSION expand_fast_index_creation=ON;
41+
42+CREATE TEMPORARY TABLE t1 (a INT, b INT, INDEX(a));
43+
44+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
45+
46+SET debug="+d,crash_innodb_add_index_after";
47+--error 2013
48+ALTER TABLE t1 ADD INDEX (b);
49+
50+--enable_reconnect
51+
52+--source include/wait_until_connected_again.inc
53+
54+SELECT NAME, FLAG FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES;
55
56=== modified file 'Percona-Server/storage/innobase/handler/handler0alter.cc'
57--- Percona-Server/storage/innobase/handler/handler0alter.cc 2012-05-02 07:37:27 +0000
58+++ Percona-Server/storage/innobase/handler/handler0alter.cc 2012-05-16 08:23:21 +0000
59@@ -877,6 +877,8 @@
60 prebuilt->table, indexed_table,
61 index, num_of_idx, table);
62
63+ DBUG_EXECUTE_IF("crash_innodb_add_index_after", DBUG_SUICIDE(););
64+
65 error_handling:
66 /* After an error, remove all those index definitions from the
67 dictionary which were defined. */
68
69=== modified file 'Percona-Server/storage/innobase/row/row0mysql.c'
70--- Percona-Server/storage/innobase/row/row0mysql.c 2012-05-02 07:37:27 +0000
71+++ Percona-Server/storage/innobase/row/row0mysql.c 2012-05-16 08:23:21 +0000
72@@ -3689,7 +3689,7 @@
73 btr_pcur_store_position(&pcur, &mtr);
74 btr_pcur_commit_specify_mtr(&pcur, &mtr);
75
76- table = dict_load_table(table_name, TRUE, DICT_ERR_IGNORE_NONE);
77+ table = dict_table_get_low(table_name);
78
79 if (table) {
80 row_drop_table_for_mysql(table_name, trx, FALSE);

Subscribers

People subscribed via source and target branches