Skip to content

Commit a0c474d

Browse files
arnabray21dahlerlend
authored andcommitted
Bug#30627292 NDB METADATA SYNC FAILS TO SYNC TABLES BELONGING TO DETECTED SCHEMA
Problem: -------- The ndb_metadata_sync system variable is set by the user to trigger synchronization of metadata between the DD of a MySQL server and NDB Dictionary. It is designed to detect and synchronize mismatches in terms of logfile groups, tablespaces, schemata, and tables. When the user triggers a sync using the above variable, the change monitor thread enters a phase of continuous detection submitting objects to the binlog thread for synchronization. It eventually stalls itself when it determines that there are no more mismatches and waits until the binlog thread has made its way through the queue of objects to be synchronized. The ndb_metadata_sync variable was flipped when all objects in the afore-mentioned queue were processed. One scenario involving the detection of schema not present in the DD but currently being used in the NDB Dictionary sometimes led to the variable being flipped before the tables belonging to the schema were successfully synchronized. This is due to the fact that tables belonging to "detected" schema can only be detected as mismatches themselves when the schema is created in the DD of the MySQL server. The timing of this synchronization by the binlog thread is asynchronous by design. Fix: ---- The fix is to essentially delay the flipping of the ndb_metadata_sync variable. After the first instance of all objects in the queue being processed is detected, the change monitor thread embarks on at least one more detection and synchronization cycle. These cycles are repeated until it is ascertained that the entire queue has been processed for a second time. Change-Id: Ib2395f84c5516c003d57a2339591352b15ce3a2e
1 parent cc37f24 commit a0c474d

File tree

4 files changed

+246
-7
lines changed

4 files changed

+246
-7
lines changed

mysql-test/suite/ndb_ddl/metadata_immediate_sync.result

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,112 @@ DROP DATAFILE 'ts2_datafile.dat';
156156
DROP TABLESPACE ts2;
157157
DROP LOGFILE GROUP lg1
158158
ENGINE NDB;
159+
CREATE DATABASE db1;
160+
USE db1;
161+
CREATE TABLE t1_ndb (
162+
a INT PRIMARY KEY,
163+
b INT
164+
) ENGINE NDB;
165+
CREATE TABLE t2_ndb (
166+
a INT PRIMARY KEY,
167+
b VARCHAR(255)
168+
) ENGINE NDB;
169+
CREATE DATABASE db2;
170+
USE db2;
171+
CREATE TABLE t1_ndb (
172+
a INT PRIMARY KEY,
173+
b INT
174+
) ENGINE NDB;
175+
CREATE TABLE t2_ndb (
176+
a INT PRIMARY KEY,
177+
b VARCHAR(255)
178+
) ENGINE NDB;
179+
CREATE DATABASE db3;
180+
USE db3;
181+
CREATE TABLE t1_innodb (
182+
a INT PRIMARY KEY,
183+
b INT
184+
);
185+
CREATE TABLE t2_innodb (
186+
a INT PRIMARY KEY,
187+
b VARCHAR(255)
188+
);
189+
CREATE DATABASE db4;
190+
USE db4;
191+
CREATE TABLE t1_ndb (
192+
a INT PRIMARY KEY,
193+
b INT
194+
) ENGINE NDB;
195+
CREATE TABLE t2_ndb (
196+
a INT PRIMARY KEY,
197+
b VARCHAR(255)
198+
) ENGINE NDB;
199+
CREATE TABLE t1_innodb (
200+
a INT PRIMARY KEY,
201+
b INT
202+
);
203+
CREATE TABLE t2_innodb (
204+
a INT PRIMARY KEY,
205+
b VARCHAR(255)
206+
);
207+
DROP DATABASE db1;
208+
DROP DATABASE db4;
209+
SET GLOBAL ndb_metadata_sync = true;
210+
SHOW DATABASES LIKE 'db%';
211+
Database (db%)
212+
db1
213+
db2
214+
db3
215+
db4
216+
USE db1;
217+
SHOW TABLES;
218+
Tables_in_db1
219+
t1_ndb
220+
t2_ndb
221+
SHOW CREATE TABLE t1_ndb;
222+
Table Create Table
223+
t1_ndb CREATE TABLE `t1_ndb` (
224+
`a` int NOT NULL,
225+
`b` int DEFAULT NULL,
226+
PRIMARY KEY (`a`)
227+
) ENGINE=ndbcluster DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='NDB_TABLE=READ_BACKUP=1'
228+
SHOW CREATE TABLE t2_ndb;
229+
Table Create Table
230+
t2_ndb CREATE TABLE `t2_ndb` (
231+
`a` int NOT NULL,
232+
`b` varchar(255) DEFAULT NULL,
233+
PRIMARY KEY (`a`)
234+
) ENGINE=ndbcluster DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='NDB_TABLE=READ_BACKUP=1'
235+
USE db2;
236+
SHOW TABLES;
237+
Tables_in_db2
238+
t1_ndb
239+
t2_ndb
240+
USE db3;
241+
SHOW TABLES;
242+
Tables_in_db3
243+
t1_innodb
244+
t2_innodb
245+
USE db4;
246+
SHOW TABLES;
247+
Tables_in_db4
248+
t1_ndb
249+
t2_ndb
250+
SHOW CREATE TABLE t1_ndb;
251+
Table Create Table
252+
t1_ndb CREATE TABLE `t1_ndb` (
253+
`a` int NOT NULL,
254+
`b` int DEFAULT NULL,
255+
PRIMARY KEY (`a`)
256+
) ENGINE=ndbcluster DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='NDB_TABLE=READ_BACKUP=1'
257+
SHOW CREATE TABLE t2_ndb;
258+
Table Create Table
259+
t2_ndb CREATE TABLE `t2_ndb` (
260+
`a` int NOT NULL,
261+
`b` varchar(255) DEFAULT NULL,
262+
PRIMARY KEY (`a`)
263+
) ENGINE=ndbcluster DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='NDB_TABLE=READ_BACKUP=1'
264+
DROP DATABASE db1;
265+
DROP DATABASE db2;
266+
DROP DATABASE db3;
267+
DROP DATABASE db4;

mysql-test/suite/ndb_ddl/metadata_immediate_sync.test

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
--source suite/ndb/include/backup_restore_setup.inc
33

44
#
5-
# Basic schema detection + synchronization test using
5+
# Case 1: Basic schema detection + synchronization test using
66
# the ndb_metadata_sync option. This is a duplicate of
77
# case 1 in the metadata_sync test.
88
# - Cause mismatch between NDB Dictionary and DD
@@ -171,5 +171,116 @@ ALTER TABLESPACE ts2
171171
DROP TABLESPACE ts2;
172172
DROP LOGFILE GROUP lg1
173173
ENGINE NDB;
174+
175+
#
176+
# Case 2: Automatic synchronization of schemata.
177+
# This is a duplicate of case 2 in the metadata_sync test
178+
# - Cause mismatch in terms of schema between NDB Dictionary and DD
179+
# - Check if the schema mismatch is detected
180+
# - Check if the schema mismatch is synchronized
181+
#
182+
183+
# db1 - Only NDB tables
184+
CREATE DATABASE db1;
185+
USE db1;
186+
CREATE TABLE t1_ndb (
187+
a INT PRIMARY KEY,
188+
b INT
189+
) ENGINE NDB;
190+
CREATE TABLE t2_ndb (
191+
a INT PRIMARY KEY,
192+
b VARCHAR(255)
193+
) ENGINE NDB;
194+
195+
# db2 - Only NDB tables
196+
CREATE DATABASE db2;
197+
USE db2;
198+
CREATE TABLE t1_ndb (
199+
a INT PRIMARY KEY,
200+
b INT
201+
) ENGINE NDB;
202+
CREATE TABLE t2_ndb (
203+
a INT PRIMARY KEY,
204+
b VARCHAR(255)
205+
) ENGINE NDB;
206+
207+
# db3 - Only InnoDB tables
208+
CREATE DATABASE db3;
209+
USE db3;
210+
CREATE TABLE t1_innodb (
211+
a INT PRIMARY KEY,
212+
b INT
213+
);
214+
CREATE TABLE t2_innodb (
215+
a INT PRIMARY KEY,
216+
b VARCHAR(255)
217+
);
218+
219+
# db4 - Both NDB and InnoDB tables
220+
CREATE DATABASE db4;
221+
USE db4;
222+
CREATE TABLE t1_ndb (
223+
a INT PRIMARY KEY,
224+
b INT
225+
) ENGINE NDB;
226+
CREATE TABLE t2_ndb (
227+
a INT PRIMARY KEY,
228+
b VARCHAR(255)
229+
) ENGINE NDB;
230+
CREATE TABLE t1_innodb (
231+
a INT PRIMARY KEY,
232+
b INT
233+
);
234+
CREATE TABLE t2_innodb (
235+
a INT PRIMARY KEY,
236+
b VARCHAR(255)
237+
);
238+
239+
# backup
240+
--disable_query_log
241+
--source include/ndb_backup.inc
242+
--enable_query_log
243+
244+
# Cause mismatch by dropping db1 and db4 and restoring metadata
245+
DROP DATABASE db1;
246+
DROP DATABASE db4;
247+
248+
--exec $NDB_RESTORE -b $the_backup_id -n 1 -m --exclude-databases=db2 $NDB_BACKUPS-$the_backup_id >> $NDB_TOOLS_OUTPUT
249+
250+
#
251+
# At this point the state of the schemata is as follows:
252+
# - db1: Used in NDB Dictionary, non-existent in DD
253+
# - db2: Used in NDB Dictionary, exists in DD
254+
# - db3: Not used in NDB Dictionary, exists in DD
255+
# - db4: Used in NDB Dictionary, non-existent in DD
256+
#
257+
# The auto sync mechanism will create db1 and db4 in the DD.
258+
# It will also synchronize all NDB tables contained in db1 and db4
259+
#
260+
261+
# Wait until the changes have been synced
262+
--let $max_wait = 60
263+
--source wait_immediate_metadata_sync.inc
264+
265+
# Check if the objects have been synchronized as expected
266+
SHOW DATABASES LIKE 'db%';
267+
USE db1;
268+
SHOW TABLES;
269+
SHOW CREATE TABLE t1_ndb;
270+
SHOW CREATE TABLE t2_ndb;
271+
USE db2;
272+
SHOW TABLES;
273+
USE db3;
274+
SHOW TABLES;
275+
USE db4;
276+
SHOW TABLES;
277+
SHOW CREATE TABLE t1_ndb;
278+
SHOW CREATE TABLE t2_ndb;
279+
280+
# Clean up
281+
DROP DATABASE db1;
282+
DROP DATABASE db2;
283+
DROP DATABASE db3;
284+
DROP DATABASE db4;
174285
--source suite/ndb/include/backup_restore_cleanup.inc
175286
--remove_file $NDB_TOOLS_OUTPUT

storage/ndb/plugin/ndb_metadata_change_monitor.cc

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
#include "storage/ndb/plugin/ndb_thd_ndb.h" // Thd_ndb
4747

4848
Ndb_metadata_change_monitor::Ndb_metadata_change_monitor()
49-
: Ndb_component("Metadata") {}
49+
: Ndb_component("Metadata"), m_mark_sync_complete{false} {}
5050

5151
Ndb_metadata_change_monitor::~Ndb_metadata_change_monitor() {}
5252

@@ -612,18 +612,36 @@ void Ndb_metadata_change_monitor::do_run() {
612612
log_verbose(10, "Metadata check completed");
613613

614614
if (controller.get_metadata_sync() && controller.all_changes_detected()) {
615-
log_info("Metadata detection complete");
616615
// All changes at this point in time have been detected. Since the
617616
// ndb_metadata_sync option has been set, we don't expect more changes.
618617
// Stall the thread and prevent it from checking for further mismatches
619618
// until the current queue has been synchronized by the binlog thread
620619
mysql_mutex_lock(&m_sync_done_mutex);
621620
mysql_cond_wait(&m_sync_done_cond, &m_sync_done_mutex);
622621
mysql_mutex_unlock(&m_sync_done_mutex);
623-
log_info("Metadata synchronization complete");
624-
// Set ndb_metadata_sync to false to denote that all changes have been
625-
// detected and synchronized
626-
opt_ndb_metadata_sync = false;
622+
if (!m_mark_sync_complete) {
623+
// This is the first instance of the binlog thread having synchronized
624+
// all changes submitted to it. However, the change monitor thread
625+
// has been stalled for a while so we opt for at least one more
626+
// detection and sync cycle to ensure that all changes are synced.
627+
// This is particularly relevant to synchronization of schema objects
628+
// since they have to be installed in DD for their tables to be
629+
// detected. This synchronization is dependent on the load on the
630+
// binlog thread so an additional detection and sync run after we know
631+
// for a fact that such schemata have been installed could be useful.
632+
//
633+
// The below flag denotes that the we've already detected an instance
634+
// of all objects having been synchronized and that ndb_metadata_sync
635+
// can be flipped the next time we detect the same condition
636+
m_mark_sync_complete = true;
637+
} else {
638+
log_info("Metadata synchronization complete");
639+
// Set ndb_metadata_sync to false to denote that all changes have been
640+
// detected and synchronized
641+
opt_ndb_metadata_sync = false;
642+
// Reset the flag to its default value
643+
m_mark_sync_complete = false;
644+
}
627645
}
628646
}
629647
}

storage/ndb/plugin/ndb_metadata_change_monitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class Ndb_metadata_change_monitor : public Ndb_component {
4343
mysql_cond_t m_wait_cond;
4444
static mysql_mutex_t m_sync_done_mutex; // protects m_sync_done_cond
4545
static mysql_cond_t m_sync_done_cond;
46+
bool m_mark_sync_complete;
4647

4748
public:
4849
Ndb_metadata_change_monitor();

0 commit comments

Comments
 (0)