Commit 60a60a0a authored by unknown's avatar unknown

Bug #18472 race condition between multiple mysqld's when setting up cluster/schema

- check that event is the correct one, and only delete if wrong version
parent 96e8eb91
...@@ -101,8 +101,6 @@ static uint ndbcluster_alter_table_flags(uint flags) ...@@ -101,8 +101,6 @@ static uint ndbcluster_alter_table_flags(uint flags)
#define NDB_FAILED_AUTO_INCREMENT ~(Uint64)0 #define NDB_FAILED_AUTO_INCREMENT ~(Uint64)0
#define NDB_AUTO_INCREMENT_RETRIES 10 #define NDB_AUTO_INCREMENT_RETRIES 10
#define NDB_INVALID_SCHEMA_OBJECT 241
#define ERR_PRINT(err) \ #define ERR_PRINT(err) \
DBUG_PRINT("error", ("%d message: %s", err.code, err.message)) DBUG_PRINT("error", ("%d message: %s", err.code, err.message))
......
...@@ -2192,10 +2192,20 @@ ndbcluster_create_event(Ndb *ndb, const NDBTAB *ndbtab, ...@@ -2192,10 +2192,20 @@ ndbcluster_create_event(Ndb *ndb, const NDBTAB *ndbtab,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
/*
try retrieving the event, if table version/id matches, we will get
a valid event. Otherwise we have a trailing event from before
*/
if (dict->getEvent(event_name))
{
DBUG_RETURN(0);
}
/* /*
trailing event from before; an error, but try to correct it trailing event from before; an error, but try to correct it
*/ */
if (dict->dropEvent(my_event.getName())) if (dict->getNdbError().code == NDB_INVALID_SCHEMA_OBJECT &&
dict->dropEvent(my_event.getName()))
{ {
if (push_warning) if (push_warning)
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
......
...@@ -29,6 +29,8 @@ extern ulong ndb_extra_logging; ...@@ -29,6 +29,8 @@ extern ulong ndb_extra_logging;
#define INJECTOR_EVENT_LEN 200 #define INJECTOR_EVENT_LEN 200
#define NDB_INVALID_SCHEMA_OBJECT 241
/* /*
The numbers below must not change as they The numbers below must not change as they
are passed between mysql servers, and if changed are passed between mysql servers, and if changed
......
...@@ -3435,6 +3435,11 @@ NdbDictInterface::createEvent(class Ndb & ndb, ...@@ -3435,6 +3435,11 @@ NdbDictInterface::createEvent(class Ndb & ndb,
// NdbEventImpl *evntImpl = (NdbEventImpl *)evntConf->getUserData(); // NdbEventImpl *evntImpl = (NdbEventImpl *)evntConf->getUserData();
evnt.m_eventId = evntConf->getEventId();
evnt.m_eventKey = evntConf->getEventKey();
evnt.m_table_id = evntConf->getTableId();
evnt.m_table_version = evntConf->getTableVersion();
if (getFlag) { if (getFlag) {
evnt.m_attrListBitmask = evntConf->getAttrListBitmask(); evnt.m_attrListBitmask = evntConf->getAttrListBitmask();
evnt.mi_type = evntConf->getEventType(); evnt.mi_type = evntConf->getEventType();
...@@ -3449,9 +3454,6 @@ NdbDictInterface::createEvent(class Ndb & ndb, ...@@ -3449,9 +3454,6 @@ NdbDictInterface::createEvent(class Ndb & ndb,
} }
} }
evnt.m_eventId = evntConf->getEventId();
evnt.m_eventKey = evntConf->getEventKey();
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -3560,7 +3562,10 @@ NdbDictionaryImpl::getEvent(const char * eventName, NdbTableImpl* tab) ...@@ -3560,7 +3562,10 @@ NdbDictionaryImpl::getEvent(const char * eventName, NdbTableImpl* tab)
delete ev; delete ev;
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
if (info->m_table_impl->m_status != NdbDictionary::Object::Retrieved) if ((info->m_table_impl->m_status != NdbDictionary::Object::Retrieved) ||
(info->m_table_impl->m_id != ev->m_table_id) ||
(table_version_major(info->m_table_impl->m_version) !=
table_version_major(ev->m_table_version)))
{ {
removeCachedObject(*info->m_table_impl); removeCachedObject(*info->m_table_impl);
info= get_local_table_info(ev->getTableName()); info= get_local_table_info(ev->getTableName());
...@@ -3584,6 +3589,14 @@ NdbDictionaryImpl::getEvent(const char * eventName, NdbTableImpl* tab) ...@@ -3584,6 +3589,14 @@ NdbDictionaryImpl::getEvent(const char * eventName, NdbTableImpl* tab)
DBUG_PRINT("info",("Table: id: %d version: %d", DBUG_PRINT("info",("Table: id: %d version: %d",
table.m_id, table.m_version)); table.m_id, table.m_version));
if (table.m_id != ev->m_table_id ||
table_version_major(table.m_version) !=
table_version_major(ev->m_table_version))
{
m_error.code = 241;
delete ev;
DBUG_RETURN(NULL);
}
#ifndef DBUG_OFF #ifndef DBUG_OFF
char buf[128] = {0}; char buf[128] = {0};
mask.getText(buf); mask.getText(buf);
......
...@@ -303,6 +303,8 @@ public: ...@@ -303,6 +303,8 @@ public:
Uint32 m_eventId; Uint32 m_eventId;
Uint32 m_eventKey; Uint32 m_eventKey;
AttributeMask m_attrListBitmask; AttributeMask m_attrListBitmask;
Uint32 m_table_id;
Uint32 m_table_version;
BaseString m_name; BaseString m_name;
Uint32 mi_type; Uint32 mi_type;
NdbDictionary::Event::EventDurability m_dur; NdbDictionary::Event::EventDurability m_dur;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment