Skip to content

Commit ae9e64d

Browse files
Bug#11885602 - mysql_upgrade fails upgrading from 7.1.8 to later release
- It was allowed to CREATE TABLE which was not in NDB, but creating a view on that table failed since the table has to be opened as part of the create. - Make it possible to workaround this with a new "ndbinfo_offline" mode which allows tables to be created and opened although they don't exist or have different table definition. This is exactly the same behaviour as when NDBCLUSTER is disabled. SELECTs on a table which has been opened in offline mode, return no rows and a warning is printed(like before).
1 parent d375089 commit ae9e64d

5 files changed

Lines changed: 177 additions & 10 deletions

File tree

mysql-test/suite/ndb/r/ndbinfo.result

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ Variable_name Value
136136
ndbinfo_database ndbinfo
137137
ndbinfo_max_bytes 0
138138
ndbinfo_max_rows 10
139+
ndbinfo_offline OFF
139140
ndbinfo_show_hidden OFF
140141
ndbinfo_table_prefix ndb$
141142
ndbinfo_version NDB_VERSION_D
@@ -238,3 +239,55 @@ node_id
238239
1
239240
2
240241

242+
set @@ndbinfo_offline=1;
243+
ERROR HY000: Variable 'ndbinfo_offline' is a GLOBAL variable and should be set with SET GLOBAL
244+
245+
SELECT DISTINCT(node_id) FROM ndbinfo.counters ORDER BY node_id;
246+
node_id
247+
1
248+
2
249+
250+
set @@global.ndbinfo_offline=TRUE;
251+
select @@ndbinfo_offline;
252+
@@ndbinfo_offline
253+
1
254+
255+
CREATE TABLE ndb$does_not_exist_in_ndb(
256+
node_id int,
257+
message varchar(255)
258+
) ENGINE = ndbinfo;
259+
260+
CREATE VIEW view_on_table_which_does_not_exist_in_ndb AS
261+
SELECT node_id, message
262+
FROM ndbinfo.ndb$does_not_exist_in_ndb;
263+
264+
SHOW CREATE TABLE ndb$does_not_exist_in_ndb;
265+
Table Create Table
266+
ndb$does_not_exist_in_ndb CREATE TABLE `ndb$does_not_exist_in_ndb` (
267+
`node_id` int(11) DEFAULT NULL,
268+
`message` varchar(255) DEFAULT NULL
269+
) ENGINE=NDBINFO DEFAULT CHARSET=latin1
270+
271+
SELECT * FROM view_on_table_which_does_not_exist_in_ndb;
272+
node_id message
273+
Warnings:
274+
Note 1 'NDBINFO' has been started in offline mode since the 'NDBCLUSTER' engine is disabled or @@global.ndbinfo_offline is turned on - no rows can be returned
275+
SELECT * FROM ndb$does_not_exist_in_ndb;
276+
node_id message
277+
Warnings:
278+
Note 1 'NDBINFO' has been started in offline mode since the 'NDBCLUSTER' engine is disabled or @@global.ndbinfo_offline is turned on - no rows can be returned
279+
SELECT DISTINCT(node_id) FROM ndbinfo.counters ORDER BY node_id;
280+
node_id
281+
Warnings:
282+
Note 1 'NDBINFO' has been started in offline mode since the 'NDBCLUSTER' engine is disabled or @@global.ndbinfo_offline is turned on - no rows can be returned
283+
284+
DROP VIEW view_on_table_which_does_not_exist_in_ndb;
285+
DROP TABLE ndb$does_not_exist_in_ndb;
286+
287+
set @@global.ndbinfo_offline = FALSE;
288+
289+
SELECT DISTINCT(node_id) FROM ndbinfo.counters ORDER BY node_id;
290+
node_id
291+
1
292+
2
293+

mysql-test/suite/ndb/t/ndbinfo.test

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,52 @@ CREATE TABLE ndb$test (node_id int AUTO_INCREMENT) ENGINE = ndbinfo;
148148
select distinct node_id
149149
from ndbinfo.diskpagebuffer;
150150

151+
152+
#
153+
# BUG#11885602
154+
# - It was allowed to CREATE TABLE which was not in NDB, but
155+
# creating a view on that table failed. Implement ndbinfo_offline
156+
# mode which allows tables to be created and opened although they
157+
# don't exists or have different table definition.
158+
# This is exactly the same behaviour as when NDBCLUSTER
159+
# is disabled
160+
#
161+
162+
# Check ndbinfo_offline is GLOBAL variable
163+
--error ER_GLOBAL_VARIABLE
164+
set @@ndbinfo_offline=1;
165+
166+
# Query used to check that open tables are closed
167+
# when offline mode is turned on and off
168+
let $q1 = SELECT DISTINCT(node_id) FROM ndbinfo.counters ORDER BY node_id;
169+
eval $q1;
170+
171+
# Turn on ndbinfo_offline
172+
set @@global.ndbinfo_offline=TRUE;
173+
select @@ndbinfo_offline;
174+
175+
CREATE TABLE ndb$does_not_exist_in_ndb(
176+
node_id int,
177+
message varchar(255)
178+
) ENGINE = ndbinfo;
179+
180+
CREATE VIEW view_on_table_which_does_not_exist_in_ndb AS
181+
SELECT node_id, message
182+
FROM ndbinfo.ndb$does_not_exist_in_ndb;
183+
184+
SHOW CREATE TABLE ndb$does_not_exist_in_ndb;
185+
186+
# SELECTs return no rows in offline mode
187+
SELECT * FROM view_on_table_which_does_not_exist_in_ndb;
188+
SELECT * FROM ndb$does_not_exist_in_ndb;
189+
eval $q1;
190+
191+
DROP VIEW view_on_table_which_does_not_exist_in_ndb;
192+
DROP TABLE ndb$does_not_exist_in_ndb;
193+
194+
# Restore original value
195+
set @@global.ndbinfo_offline = FALSE;
196+
197+
eval $q1;
198+
151199
--source ndbinfo_drop.inc

sql/ha_ndbinfo.cc

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,45 @@ static MYSQL_SYSVAR_UINT(
9292
0 /* block */
9393
);
9494

95+
static my_bool opt_ndbinfo_offline;
96+
97+
static
98+
void
99+
offline_update(THD* thd, struct st_mysql_sys_var* var,
100+
void* var_ptr, const void* save)
101+
{
102+
DBUG_ENTER("offline_update");
103+
104+
const my_bool new_offline =
105+
(*(static_cast<const my_bool*>(save)) != 0);
106+
if (new_offline == opt_ndbinfo_offline)
107+
{
108+
// No change
109+
DBUG_VOID_RETURN;
110+
}
111+
112+
// Set offline mode, any tables opened from here on will
113+
// be opened in the new mode
114+
opt_ndbinfo_offline = new_offline;
115+
116+
// Close any open tables which may be in the old mode
117+
(void)close_cached_tables(thd, NULL, false, true, false);
118+
119+
DBUG_VOID_RETURN;
120+
}
121+
122+
static MYSQL_SYSVAR_BOOL(
123+
offline, /* name */
124+
opt_ndbinfo_offline, /* var */
125+
PLUGIN_VAR_NOCMDOPT,
126+
"Set ndbinfo in offline mode, tables and views can "
127+
"be opened even if they don't exist or have different "
128+
"definition in NDB. No rows will be returned.",
129+
NULL, /* check func. */
130+
offline_update, /* update func. */
131+
0 /* default */
132+
);
133+
95134

96135
static NdbInfo* g_ndbinfo;
97136

@@ -124,10 +163,15 @@ struct ha_ndbinfo_impl
124163
Vector<const NdbInfoRecAttr *> m_columns;
125164
bool m_first_use;
126165

166+
// Indicates if table has been opened in offline mode
167+
// can only be reset by closing the table
168+
bool m_offline;
169+
127170
ha_ndbinfo_impl() :
128171
m_table(NULL),
129172
m_scan_op(NULL),
130-
m_first_use(true)
173+
m_first_use(true),
174+
m_offline(false)
131175
{
132176
}
133177
};
@@ -289,12 +333,18 @@ bool ha_ndbinfo::is_open(void) const
289333
return m_impl.m_table != NULL;
290334
}
291335

336+
bool ha_ndbinfo::is_offline(void) const
337+
{
338+
return m_impl.m_offline;
339+
}
340+
292341
int ha_ndbinfo::open(const char *name, int mode, uint test_if_locked)
293342
{
294343
DBUG_ENTER("ha_ndbinfo::open");
295344
DBUG_PRINT("enter", ("name: %s, mode: %d", name, mode));
296345

297346
assert(is_closed());
347+
assert(!is_offline()); // Closed table can not be offline
298348

299349
if (mode == O_RDWR)
300350
{
@@ -307,9 +357,11 @@ int ha_ndbinfo::open(const char *name, int mode, uint test_if_locked)
307357
DBUG_ASSERT(false);
308358
}
309359

310-
if (ndbcluster_is_disabled())
360+
if (opt_ndbinfo_offline ||
361+
ndbcluster_is_disabled())
311362
{
312-
// Allow table to be opened with ndbcluster disabled
363+
// Mark table as being offline and allow it to be opened
364+
m_impl.m_offline = true;
313365
DBUG_RETURN(0);
314366
}
315367

@@ -378,7 +430,7 @@ int ha_ndbinfo::close(void)
378430
{
379431
DBUG_ENTER("ha_ndbinfo::close");
380432

381-
if (ndbcluster_is_disabled())
433+
if (is_offline())
382434
DBUG_RETURN(0);
383435

384436
assert(is_open());
@@ -395,12 +447,13 @@ int ha_ndbinfo::rnd_init(bool scan)
395447
DBUG_ENTER("ha_ndbinfo::rnd_init");
396448
DBUG_PRINT("info", ("scan: %d", scan));
397449

398-
if (ndbcluster_is_disabled())
450+
if (is_offline())
399451
{
400452
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE, 1,
401-
"'NDBINFO' has been started "
402-
"in limited mode since the 'NDBCLUSTER' "
403-
"engine is disabled - no rows can be returned");
453+
"'NDBINFO' has been started in offline mode "
454+
"since the 'NDBCLUSTER' engine is disabled "
455+
"or @@global.ndbinfo_offline is turned on "
456+
"- no rows can be returned");
404457
DBUG_RETURN(0);
405458
}
406459

@@ -466,7 +519,7 @@ int ha_ndbinfo::rnd_end()
466519
{
467520
DBUG_ENTER("ha_ndbinfo::rnd_end");
468521

469-
if (ndbcluster_is_disabled())
522+
if (is_offline())
470523
DBUG_RETURN(0);
471524

472525
assert(is_open());
@@ -486,7 +539,7 @@ int ha_ndbinfo::rnd_next(uchar *buf)
486539
int err;
487540
DBUG_ENTER("ha_ndbinfo::rnd_next");
488541

489-
if (ndbcluster_is_disabled())
542+
if (is_offline())
490543
DBUG_RETURN(HA_ERR_END_OF_FILE);
491544

492545
assert(is_open());
@@ -712,6 +765,7 @@ struct st_mysql_sys_var* ndbinfo_system_variables[]= {
712765
MYSQL_SYSVAR(database),
713766
MYSQL_SYSVAR(table_prefix),
714767
MYSQL_SYSVAR(version),
768+
MYSQL_SYSVAR(offline),
715769

716770
NULL
717771
};

sql/ha_ndbinfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ class ha_ndbinfo: public handler
8383
bool is_open(void) const;
8484
bool is_closed(void) const { return ! is_open(); };
8585

86+
bool is_offline(void) const;
87+
8688
struct ha_ndbinfo_impl& m_impl;
8789

8890
};

storage/ndb/tools/ndbinfo_sql.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,12 @@ int main(int argc, char** argv){
327327
sql.assfmt("CREATE DATABASE IF NOT EXISTS `%s`", opt_ndbinfo_db);
328328
print_conditional_sql(sql);
329329

330+
printf("# Set NDBINFO in offline mode during (re)create of tables\n");
331+
printf("# and views to avoid errors caused by no such table or\n");
332+
printf("# different table definition in NDB\n");
333+
sql.assfmt("SET @@global.ndbinfo_offline=TRUE");
334+
print_conditional_sql(sql);
335+
330336
printf("# Drop any old views in %s\n", opt_ndbinfo_db);
331337
for (size_t i = 0; i < num_views; i++)
332338
{
@@ -430,6 +436,10 @@ int main(int argc, char** argv){
430436
print_conditional_sql(sql);
431437
}
432438

439+
printf("# Finally turn off offline mode\n");
440+
sql.assfmt("SET @@global.ndbinfo_offline=FALSE");
441+
print_conditional_sql(sql);
442+
433443
return 0;
434444
}
435445

0 commit comments

Comments
 (0)