Skip to content

Commit c45e61a

Browse files
committed
Bug#30152258 MYSQLDUMP HANG ON DUMP_TABLESPACES WHEN DISK DATA TABLES
EXIST Hang occurs in acquire_lock() when querying for information about the tablespace. The problem only occurs on participant mysqld after a table in the tablespace has been dropped. The root cause is that a MDL lock on the tablespace in TRANSACTIONAL scope has not been released while dropping the table on participant. Fix by releasing all MDL locks aquired by called functions in TRANSACTIONAL or STATEMENT scope. This is done by extending the Ndb_dd_client to release all new MDL locks taken in TRANSACTIONAL and STATEMENT scope in addition to the EXPLICIT scope locks it already releases. Move the release of EXPLICIT MDL locks to after rollback. Change-Id: I5a47b22f7298a1a82aedb9c360a50510a060be8c
1 parent f737137 commit c45e61a

File tree

4 files changed

+89
-5
lines changed

4 files changed

+89
-5
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Create logfile group, tablespace, and table in the tablespace
2+
CREATE LOGFILE GROUP lg1
3+
ADD UNDOFILE 'lg1_undofile.dat'
4+
INITIAL_SIZE 1M
5+
UNDO_BUFFER_SIZE = 1M
6+
ENGINE NDB;
7+
CREATE TABLESPACE ts1
8+
ADD DATAFILE 'ts1_datafile.dat'
9+
USE LOGFILE GROUP lg1
10+
INITIAL_SIZE 2M
11+
ENGINE NDB;
12+
CREATE TABLE t10 (
13+
a INT PRIMARY KEY,
14+
b VARCHAR(255)
15+
) ENGINE NDB
16+
TABLESPACE ts1
17+
STORAGE DISK;
18+
# Drop the table, this caused problem on participant which didn't
19+
# release an MDL lock in TRANSACTIONAL scope
20+
DROP TABLE t10;
21+
# mysqld2> Run query accessing the tablespace where t10 was located
22+
SELECT LOGFILE_GROUP_NAME, FILE_NAME, TOTAL_EXTENTS, INITIAL_SIZE, ENGINE, EXTRA
23+
FROM INFORMATION_SCHEMA.FILES
24+
WHERE FILE_TYPE = 'UNDO LOG'
25+
AND FILE_NAME IS NOT NULL
26+
AND LOGFILE_GROUP_NAME IS NOT NULL
27+
ORDER BY LOGFILE_GROUP_NAME;
28+
LOGFILE_GROUP_NAME FILE_NAME TOTAL_EXTENTS INITIAL_SIZE ENGINE EXTRA
29+
lg1 ./lg1_undofile.dat 262144 1048576 ndbcluster UNDO_BUFFER_SIZE=1048576
30+
# Cleanup
31+
ALTER TABLESPACE ts1
32+
DROP DATAFILE 'ts1_datafile.dat';
33+
DROP TABLESPACE ts1;
34+
DROP LOGFILE GROUP lg1 ENGINE NDB;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--source connect.inc
2+
3+
--echo # Create logfile group, tablespace, and table in the tablespace
4+
CREATE LOGFILE GROUP lg1
5+
ADD UNDOFILE 'lg1_undofile.dat'
6+
INITIAL_SIZE 1M
7+
UNDO_BUFFER_SIZE = 1M
8+
ENGINE NDB;
9+
10+
CREATE TABLESPACE ts1
11+
ADD DATAFILE 'ts1_datafile.dat'
12+
USE LOGFILE GROUP lg1
13+
INITIAL_SIZE 2M
14+
ENGINE NDB;
15+
16+
CREATE TABLE t10 (
17+
a INT PRIMARY KEY,
18+
b VARCHAR(255)
19+
) ENGINE NDB
20+
TABLESPACE ts1
21+
STORAGE DISK;
22+
23+
--echo # Drop the table, this caused problem on participant which didn't
24+
--echo # release an MDL lock in TRANSACTIONAL scope
25+
DROP TABLE t10;
26+
27+
--connection mysqld2
28+
--echo # mysqld2> Run query accessing the tablespace where t10 was located
29+
SELECT LOGFILE_GROUP_NAME, FILE_NAME, TOTAL_EXTENTS, INITIAL_SIZE, ENGINE, EXTRA
30+
FROM INFORMATION_SCHEMA.FILES
31+
WHERE FILE_TYPE = 'UNDO LOG'
32+
AND FILE_NAME IS NOT NULL
33+
AND LOGFILE_GROUP_NAME IS NOT NULL
34+
ORDER BY LOGFILE_GROUP_NAME;
35+
36+
--echo # Cleanup
37+
--connection mysqld1
38+
ALTER TABLESPACE ts1
39+
DROP DATAFILE 'ts1_datafile.dat';
40+
DROP TABLESPACE ts1;
41+
DROP LOGFILE GROUP lg1 ENGINE NDB;

storage/ndb/plugin/ndb_dd_client.cc

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
#include "sql/dd/properties.h"
3535
#include "sql/dd/types/schema.h"
3636
#include "sql/dd/types/table.h"
37-
#include "sql/mdl.h" // MDL_*
3837
#include "sql/query_options.h" // OPTION_AUTOCOMMIT
3938
#include "sql/sql_class.h" // THD
4039
#include "sql/sql_trigger.h" // remove_all_triggers_from_perfschema
@@ -52,7 +51,9 @@
5251
#include "storage/ndb/plugin/ndb_thd.h"
5352

5453
Ndb_dd_client::Ndb_dd_client(THD *thd)
55-
: m_thd(thd), m_client(thd->dd_client()) {
54+
: m_thd(thd),
55+
m_client(thd->dd_client()),
56+
m_save_mdl_locks(thd->mdl_context.mdl_savepoint()) {
5657
disable_autocommit();
5758

5859
// Create dictionary client auto releaser, stored as
@@ -63,9 +64,6 @@ Ndb_dd_client::Ndb_dd_client(THD *thd)
6364
}
6465

6566
Ndb_dd_client::~Ndb_dd_client() {
66-
// Automatically release acquired MDL locks
67-
mdl_locks_release();
68-
6967
// Automatically restore the option_bits in THD if they have
7068
// been modified
7169
if (m_save_option_bits) m_thd->variables.option_bits = m_save_option_bits;
@@ -75,6 +73,9 @@ Ndb_dd_client::~Ndb_dd_client() {
7573
if (!m_comitted) rollback();
7674
}
7775

76+
// Release MDL locks
77+
mdl_locks_release();
78+
7879
// Free the dictionary client auto releaser
7980
dd::cache::Dictionary_client::Auto_releaser *ar =
8081
(dd::cache::Dictionary_client::Auto_releaser *)m_auto_releaser;
@@ -328,9 +329,12 @@ bool Ndb_dd_client::mdl_locks_acquire_exclusive(const char *schema_name,
328329
}
329330

330331
void Ndb_dd_client::mdl_locks_release() {
332+
// Release MDL locks acquired in EXPLICIT scope
331333
for (MDL_ticket *ticket : m_acquired_mdl_tickets) {
332334
m_thd->mdl_context.release_lock(ticket);
333335
}
336+
// Release new MDL locks acquired in TRANSACTIONAL and STATEMENT scope
337+
m_thd->mdl_context.rollback_to_savepoint(m_save_mdl_locks);
334338
}
335339

336340
void Ndb_dd_client::disable_autocommit() {

storage/ndb/plugin/ndb_dd_client.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "my_inttypes.h"
3535
#include "sql/dd/object_id.h"
3636
#include "sql/dd/string_type.h"
37+
#include "sql/mdl.h"
3738

3839
namespace dd {
3940
typedef String_type sdi_t;
@@ -85,7 +86,11 @@ class Ndb_dd_client {
8586
class THD *const m_thd;
8687
dd::cache::Dictionary_client *m_client;
8788
void *m_auto_releaser; // Opaque pointer
89+
// List of MDL locks taken in EXPLICIT scope by Ndb_dd_client
8890
std::vector<class MDL_ticket *> m_acquired_mdl_tickets;
91+
// MDL savepoint which allows releasing MDL locks taken by called
92+
// functions in TRANSACTIONAL and STATEMENT scope
93+
const MDL_savepoint m_save_mdl_locks;
8994
ulonglong m_save_option_bits{0};
9095
bool m_comitted{false};
9196
bool m_auto_rollback{true};

0 commit comments

Comments
 (0)