From 62b5a561910f8001c288bcc75c11516a4d061cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 21 Jul 2015 12:51:14 +0300 Subject: [PATCH] MDEV-8501: encryption.create_or_replace fails in buildbot on P8 builders Analysis: There is race between drop table and encryption threads that could cause encryption thread to enter mutex that has been already released. Fix: When destroying crypt_data first enter the mutex and set crypt data unavailable, then release the memory and clean up the data. This should make the race more unprobable. Additionally, added big_test for create_or_replace as it could fail testcase timeout if you have slow I/O (tested that testcase passes with --mem). --- mysql-test/suite/encryption/t/create_or_replace.test | 2 ++ storage/innobase/fil/fil0crypt.cc | 8 +++++++- storage/xtradb/fil/fil0crypt.cc | 6 ++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/encryption/t/create_or_replace.test b/mysql-test/suite/encryption/t/create_or_replace.test index ca68f950588..3b2970e5162 100644 --- a/mysql-test/suite/encryption/t/create_or_replace.test +++ b/mysql-test/suite/encryption/t/create_or_replace.test @@ -1,6 +1,8 @@ --source include/have_innodb.inc --source include/have_file_key_management_plugin.inc --source include/not_embedded.inc +# This is needed for longer testcase timeout at least P7/P8 +--source include/big_test.inc # # MDEV-8164: Server crashes in pfs_mutex_enter_func after fil_crypt_is_closing or alike diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index d5b942a652b..4efaaefe72f 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -364,7 +364,13 @@ fil_space_destroy_crypt_data( fil_space_crypt_t **crypt_data) /*!< out: crypt data */ { if (crypt_data != NULL && (*crypt_data) != NULL) { - mutex_free(& (*crypt_data)->mutex); + /* Make sure that this thread owns the crypt_data + and make it unawailable, this does not fully + avoid the race between drop table and crypt thread */ + mutex_enter(&(*crypt_data)->mutex); + (*crypt_data)->inited = false; + mutex_exit(&(*crypt_data)->mutex); + mutex_free(&(*crypt_data)->mutex); memset(*crypt_data, 0, sizeof(fil_space_crypt_t)); free(*crypt_data); (*crypt_data) = NULL; diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc index a60e55f3de6..0358ce44bd7 100644 --- a/storage/xtradb/fil/fil0crypt.cc +++ b/storage/xtradb/fil/fil0crypt.cc @@ -364,6 +364,12 @@ fil_space_destroy_crypt_data( fil_space_crypt_t **crypt_data) /*!< out: crypt data */ { if (crypt_data != NULL && (*crypt_data) != NULL) { + /* Make sure that this thread owns the crypt_data + and make it unawailable, this does not fully + avoid the race between drop table and crypt thread */ + mutex_enter(&(*crypt_data)->mutex); + (*crypt_data)->inited = false; + mutex_exit(&(*crypt_data)->mutex); mutex_free(& (*crypt_data)->mutex); memset(*crypt_data, 0, sizeof(fil_space_crypt_t)); free(*crypt_data);