From 25323de2a4397d9ab37ebdfddf4442c8d0dd22c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 9 Apr 2015 08:13:07 +0300 Subject: [PATCH] Bug#20816223 InnoDB crash on shutdown if XA PREPARE transactions hold explicit locks. innobase_shutdown_for_mysql(): Call trx_sys_close() before lock_sys_close() (and dict_close()) so that trx_free_prepared() will see all locks intact. RB: 8561 Reviewed-by: Vasil Dimov --- mysql-test/suite/innodb/r/xa_recovery.result | 17 ++++++++ mysql-test/suite/innodb/t/xa_recovery.test | 41 ++++++++++++++++++++ storage/innobase/srv/srv0start.c | 4 +- 3 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb/r/xa_recovery.result create mode 100644 mysql-test/suite/innodb/t/xa_recovery.test diff --git a/mysql-test/suite/innodb/r/xa_recovery.result b/mysql-test/suite/innodb/r/xa_recovery.result new file mode 100644 index 00000000000..84cb37ef7c9 --- /dev/null +++ b/mysql-test/suite/innodb/r/xa_recovery.result @@ -0,0 +1,17 @@ +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +XA START 'x'; +UPDATE t1 set a=2; +XA END 'x'; +XA PREPARE 'x'; +call mtr.add_suppression("Found 1 prepared XA transactions"); +SELECT * FROM t1 LOCK IN SHARE MODE; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +SELECT * FROM t1; +a +2 +XA ROLLBACK 'x'; +SELECT * FROM t1; +a +1 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/xa_recovery.test b/mysql-test/suite/innodb/t/xa_recovery.test new file mode 100644 index 00000000000..d62206d57bb --- /dev/null +++ b/mysql-test/suite/innodb/t/xa_recovery.test @@ -0,0 +1,41 @@ +--source include/have_innodb.inc + +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +connect (con1,localhost,root); +XA START 'x'; UPDATE t1 set a=2; XA END 'x'; XA PREPARE 'x'; +connection default; + +call mtr.add_suppression("Found 1 prepared XA transactions"); + +# Kill and restart the server. +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- shutdown_server 0 +-- source include/wait_until_disconnected.inc + +-- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- enable_reconnect +-- source include/wait_until_connected_again.inc +-- disable_reconnect + +disconnect con1; +connect (con1,localhost,root); +--send SELECT * FROM t1 LOCK IN SHARE MODE + +connection default; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'Sending data' and + info = 'SELECT * FROM t1 LOCK IN SHARE MODE'; +--source include/wait_condition.inc + +--source include/restart_mysqld.inc + +disconnect con1; + +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +SELECT * FROM t1; +XA ROLLBACK 'x'; +SELECT * FROM t1; + +DROP TABLE t1; diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index d64f64fc934..45f8c6d53ab 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2009, Percona Inc. @@ -2230,9 +2230,9 @@ innobase_shutdown_for_mysql(void) ibuf_close(); log_shutdown(); - lock_sys_close(); trx_sys_file_format_close(); trx_sys_close(); + lock_sys_close(); mutex_free(&srv_monitor_file_mutex); mutex_free(&srv_dict_tmpfile_mutex);