#At file:///home/msvensson/mysql/bug11885602/7.0/ based on revid:jonas@stripped
4400 magnus.blaudd@stripped 2011-05-23
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).
modified:
mysql-test/suite/ndb/r/ndbinfo.result
mysql-test/suite/ndb/t/ndbinfo.test
sql/ha_ndbinfo.cc
sql/ha_ndbinfo.h
storage/ndb/tools/ndbinfo_sql.cpp
=== modified file 'mysql-test/suite/ndb/r/ndbinfo.result'
--- a/mysql-test/suite/ndb/r/ndbinfo.result 2010-11-03 09:48:25 +0000
+++ b/mysql-test/suite/ndb/r/ndbinfo.result 2011-05-23 11:57:55 +0000
@@ -136,6 +136,7 @@ Variable_name Value
ndbinfo_database ndbinfo
ndbinfo_max_bytes 0
ndbinfo_max_rows 10
+ndbinfo_offline OFF
ndbinfo_show_hidden OFF
ndbinfo_table_prefix ndb$
ndbinfo_version NDB_VERSION_D
@@ -237,4 +238,56 @@ from ndbinfo.diskpagebuffer;
node_id
1
2
+
+set @@ndbinfo_offline=1;
+ERROR HY000: Variable 'ndbinfo_offline' is a GLOBAL variable and should be set with SET GLOBAL
+
+SELECT DISTINCT(node_id) FROM ndbinfo.counters ORDER BY node_id;
+node_id
+1
+2
+
+set @@global.ndbinfo_offline=TRUE;
+select @@ndbinfo_offline;
+@@ndbinfo_offline
+1
+
+CREATE TABLE ndb$does_not_exist_in_ndb(
+ node_id int,
+ message varchar(255)
+) ENGINE = ndbinfo;
+
+CREATE VIEW view_on_table_which_does_not_exist_in_ndb AS
+ SELECT node_id, message
+ FROM ndbinfo.ndb$does_not_exist_in_ndb;
+
+SHOW CREATE TABLE ndb$does_not_exist_in_ndb;
+Table Create Table
+ndb$does_not_exist_in_ndb CREATE TABLE `ndb$does_not_exist_in_ndb` (
+ `node_id` int(11) DEFAULT NULL,
+ `message` varchar(255) DEFAULT NULL
+) ENGINE=NDBINFO DEFAULT CHARSET=latin1
+
+SELECT * FROM view_on_table_which_does_not_exist_in_ndb;
+node_id message
+Warnings:
+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
+SELECT * FROM ndb$does_not_exist_in_ndb;
+node_id message
+Warnings:
+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
+SELECT DISTINCT(node_id) FROM ndbinfo.counters ORDER BY node_id;
+node_id
+Warnings:
+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
+
+DROP VIEW view_on_table_which_does_not_exist_in_ndb;
+DROP TABLE ndb$does_not_exist_in_ndb;
+
+set @@global.ndbinfo_offline = FALSE;
+
+SELECT DISTINCT(node_id) FROM ndbinfo.counters ORDER BY node_id;
+node_id
+1
+2
=== modified file 'mysql-test/suite/ndb/t/ndbinfo.test'
--- a/mysql-test/suite/ndb/t/ndbinfo.test 2010-11-03 09:48:25 +0000
+++ b/mysql-test/suite/ndb/t/ndbinfo.test 2011-05-23 11:57:55 +0000
@@ -148,4 +148,52 @@ CREATE TABLE ndb$test (node_id int AUTO_
select distinct node_id
from ndbinfo.diskpagebuffer;
+
+#
+# BUG#11885602
+# - It was allowed to CREATE TABLE which was not in NDB, but
+# creating a view on that table failed. Implement ndbinfo_offline
+# mode which allows tables to be created and opened although they
+# don't exists or have different table definition.
+# This is exactly the same behaviour as when NDBCLUSTER
+# is disabled
+#
+
+# Check ndbinfo_offline is GLOBAL variable
+--error ER_GLOBAL_VARIABLE
+set @@ndbinfo_offline=1;
+
+# Query used to check that open tables are closed
+# when offline mode is turned on and off
+let $q1 = SELECT DISTINCT(node_id) FROM ndbinfo.counters ORDER BY node_id;
+eval $q1;
+
+# Turn on ndbinfo_offline
+set @@global.ndbinfo_offline=TRUE;
+select @@ndbinfo_offline;
+
+CREATE TABLE ndb$does_not_exist_in_ndb(
+ node_id int,
+ message varchar(255)
+) ENGINE = ndbinfo;
+
+CREATE VIEW view_on_table_which_does_not_exist_in_ndb AS
+ SELECT node_id, message
+ FROM ndbinfo.ndb$does_not_exist_in_ndb;
+
+SHOW CREATE TABLE ndb$does_not_exist_in_ndb;
+
+# SELECTs return no rows in offline mode
+SELECT * FROM view_on_table_which_does_not_exist_in_ndb;
+SELECT * FROM ndb$does_not_exist_in_ndb;
+eval $q1;
+
+DROP VIEW view_on_table_which_does_not_exist_in_ndb;
+DROP TABLE ndb$does_not_exist_in_ndb;
+
+# Restore original value
+set @@global.ndbinfo_offline = FALSE;
+
+eval $q1;
+
--source ndbinfo_drop.inc
=== modified file 'sql/ha_ndbinfo.cc'
--- a/sql/ha_ndbinfo.cc 2010-11-10 14:17:13 +0000
+++ b/sql/ha_ndbinfo.cc 2011-05-23 11:57:55 +0000
@@ -92,6 +92,45 @@ static MYSQL_SYSVAR_UINT(
0 /* block */
);
+static my_bool opt_ndbinfo_offline;
+
+static
+void
+offline_update(THD* thd, struct st_mysql_sys_var* var,
+ void* var_ptr, const void* save)
+{
+ DBUG_ENTER("offline_update");
+
+ const my_bool new_offline =
+ (*(static_cast<const my_bool*>(save)) != 0);
+ if (new_offline == opt_ndbinfo_offline)
+ {
+ // No change
+ DBUG_VOID_RETURN;
+ }
+
+ // Set offline mode, any tables opened from here on will
+ // be opened in the new mode
+ opt_ndbinfo_offline = new_offline;
+
+ // Close any open tables which may be in the old mode
+ (void)close_cached_tables(thd, NULL, false, true, false);
+
+ DBUG_VOID_RETURN;
+}
+
+static MYSQL_SYSVAR_BOOL(
+ offline, /* name */
+ opt_ndbinfo_offline, /* var */
+ PLUGIN_VAR_NOCMDOPT,
+ "Set ndbinfo in offline mode, tables and views can "
+ "be opened even if they don't exist or have different "
+ "definition in NDB. No rows will be returned.",
+ NULL, /* check func. */
+ offline_update, /* update func. */
+ 0 /* default */
+);
+
static NdbInfo* g_ndbinfo;
@@ -124,10 +163,15 @@ struct ha_ndbinfo_impl
Vector<const NdbInfoRecAttr *> m_columns;
bool m_first_use;
+ // Indicates if table has been opened in offline mode
+ // can only be reset by closing the table
+ bool m_offline;
+
ha_ndbinfo_impl() :
m_table(NULL),
m_scan_op(NULL),
- m_first_use(true)
+ m_first_use(true),
+ m_offline(false)
{
}
};
@@ -289,12 +333,18 @@ bool ha_ndbinfo::is_open(void) const
return m_impl.m_table != NULL;
}
+bool ha_ndbinfo::is_offline(void) const
+{
+ return m_impl.m_offline;
+}
+
int ha_ndbinfo::open(const char *name, int mode, uint test_if_locked)
{
DBUG_ENTER("ha_ndbinfo::open");
DBUG_PRINT("enter", ("name: %s, mode: %d", name, mode));
assert(is_closed());
+ assert(!is_offline()); // Closed table can not be offline
if (mode == O_RDWR)
{
@@ -307,9 +357,11 @@ int ha_ndbinfo::open(const char *name, i
DBUG_ASSERT(false);
}
- if (ndbcluster_is_disabled())
+ if (opt_ndbinfo_offline ||
+ ndbcluster_is_disabled())
{
- // Allow table to be opened with ndbcluster disabled
+ // Mark table as being offline and allow it to be opened
+ m_impl.m_offline = true;
DBUG_RETURN(0);
}
@@ -378,7 +430,7 @@ int ha_ndbinfo::close(void)
{
DBUG_ENTER("ha_ndbinfo::close");
- if (ndbcluster_is_disabled())
+ if (is_offline())
DBUG_RETURN(0);
assert(is_open());
@@ -395,12 +447,13 @@ int ha_ndbinfo::rnd_init(bool scan)
DBUG_ENTER("ha_ndbinfo::rnd_init");
DBUG_PRINT("info", ("scan: %d", scan));
- if (ndbcluster_is_disabled())
+ if (is_offline())
{
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE, 1,
- "'NDBINFO' has been started "
- "in limited mode since the 'NDBCLUSTER' "
- "engine is disabled - no rows can be returned");
+ "'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");
DBUG_RETURN(0);
}
@@ -466,7 +519,7 @@ int ha_ndbinfo::rnd_end()
{
DBUG_ENTER("ha_ndbinfo::rnd_end");
- if (ndbcluster_is_disabled())
+ if (is_offline())
DBUG_RETURN(0);
assert(is_open());
@@ -486,7 +539,7 @@ int ha_ndbinfo::rnd_next(uchar *buf)
int err;
DBUG_ENTER("ha_ndbinfo::rnd_next");
- if (ndbcluster_is_disabled())
+ if (is_offline())
DBUG_RETURN(HA_ERR_END_OF_FILE);
assert(is_open());
@@ -712,6 +765,7 @@ struct st_mysql_sys_var* ndbinfo_system_
MYSQL_SYSVAR(database),
MYSQL_SYSVAR(table_prefix),
MYSQL_SYSVAR(version),
+ MYSQL_SYSVAR(offline),
NULL
};
=== modified file 'sql/ha_ndbinfo.h'
--- a/sql/ha_ndbinfo.h 2011-02-01 14:58:21 +0000
+++ b/sql/ha_ndbinfo.h 2011-05-23 11:57:55 +0000
@@ -83,6 +83,8 @@ private:
bool is_open(void) const;
bool is_closed(void) const { return ! is_open(); };
+ bool is_offline(void) const;
+
struct ha_ndbinfo_impl& m_impl;
};
=== modified file 'storage/ndb/tools/ndbinfo_sql.cpp'
--- a/storage/ndb/tools/ndbinfo_sql.cpp 2011-04-12 11:59:36 +0000
+++ b/storage/ndb/tools/ndbinfo_sql.cpp 2011-05-23 11:57:55 +0000
@@ -327,6 +327,12 @@ int main(int argc, char** argv){
sql.assfmt("CREATE DATABASE IF NOT EXISTS `%s`", opt_ndbinfo_db);
print_conditional_sql(sql);
+ printf("# Set NDBINFO in offline mode during (re)create of tables\n");
+ printf("# and views to avoid errors caused by no such table or\n");
+ printf("# different table definition in NDB\n");
+ sql.assfmt("SET @@global.ndbinfo_offline=TRUE");
+ print_conditional_sql(sql);
+
printf("# Drop any old views in %s\n", opt_ndbinfo_db);
for (size_t i = 0; i < num_views; i++)
{
@@ -430,6 +436,10 @@ int main(int argc, char** argv){
print_conditional_sql(sql);
}
+ printf("# Finally turn off offline mode\n");
+ sql.assfmt("SET @@global.ndbinfo_offline=FALSE");
+ print_conditional_sql(sql);
+
return 0;
}
Attachment: [text/bzr-bundle] bzr/magnus.blaudd@oracle.com-20110523115755-3l1esbdcl4reaj9m.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-telco-7.0 branch (magnus.blaudd:4400) Bug#11885602 | magnus.blaudd | 23 May |