mirror of
https://github.com/MariaDB/server.git
synced 2025-01-30 18:41:56 +01:00
Bug #20897 race condition between drop table and suma drop trigger
- keep accounting for aoutstanding drop trigger requests - also lock table object in suma while doing that (should be impossible right now though since dict serializes all requests)
This commit is contained in:
parent
5e3861cb95
commit
5ab4800fc2
3 changed files with 41 additions and 17 deletions
|
@ -1445,12 +1445,13 @@ Suma::initTable(Signal *signal, Uint32 tableId, TablePtr &tabPtr)
|
||||||
tabPtr.p->m_error = 0;
|
tabPtr.p->m_error = 0;
|
||||||
tabPtr.p->m_schemaVersion = RNIL;
|
tabPtr.p->m_schemaVersion = RNIL;
|
||||||
tabPtr.p->m_state = Table::DEFINING;
|
tabPtr.p->m_state = Table::DEFINING;
|
||||||
tabPtr.p->m_hasTriggerDefined[0] = 0;
|
tabPtr.p->m_drop_subbPtr.p = 0;
|
||||||
tabPtr.p->m_hasTriggerDefined[1] = 0;
|
for (int j= 0; j < 3; j++)
|
||||||
tabPtr.p->m_hasTriggerDefined[2] = 0;
|
{
|
||||||
tabPtr.p->m_triggerIds[0] = ILLEGAL_TRIGGER_ID;
|
tabPtr.p->m_hasTriggerDefined[j] = 0;
|
||||||
tabPtr.p->m_triggerIds[1] = ILLEGAL_TRIGGER_ID;
|
tabPtr.p->m_hasOutstandingTriggerReq[j] = 0;
|
||||||
tabPtr.p->m_triggerIds[2] = ILLEGAL_TRIGGER_ID;
|
tabPtr.p->m_triggerIds[j] = ILLEGAL_TRIGGER_ID;
|
||||||
|
}
|
||||||
|
|
||||||
c_tables.add(tabPtr);
|
c_tables.add(tabPtr);
|
||||||
|
|
||||||
|
@ -2491,6 +2492,13 @@ Suma::execSUB_STOP_REQ(Signal* signal){
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tabPtr.p->m_drop_subbPtr.p != 0) {
|
||||||
|
jam();
|
||||||
|
DBUG_PRINT("error", ("table locked"));
|
||||||
|
sendSubStopRef(signal, 1420);
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_PRINT("info",("subscription: %u tableId: %u[i=%u] id: %u key: %u",
|
DBUG_PRINT("info",("subscription: %u tableId: %u[i=%u] id: %u key: %u",
|
||||||
subPtr.i, subPtr.p->m_tableId, tabPtr.i,
|
subPtr.i, subPtr.p->m_tableId, tabPtr.i,
|
||||||
subPtr.p->m_subscriptionId,subPtr.p->m_subscriptionKey));
|
subPtr.p->m_subscriptionId,subPtr.p->m_subscriptionKey));
|
||||||
|
@ -2560,6 +2568,7 @@ Suma::execSUB_STOP_REQ(Signal* signal){
|
||||||
tabPtr.p->m_tableId, tabPtr.p->n_subscribers));
|
tabPtr.p->m_tableId, tabPtr.p->n_subscribers));
|
||||||
tabPtr.p->checkRelease(*this);
|
tabPtr.p->checkRelease(*this);
|
||||||
sendSubStopComplete(signal, tabPtr.p->m_drop_subbPtr);
|
sendSubStopComplete(signal, tabPtr.p->m_drop_subbPtr);
|
||||||
|
tabPtr.p->m_drop_subbPtr.p = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2894,6 +2903,9 @@ Suma::Table::dropTrigger(Signal* signal,Suma& suma)
|
||||||
jam();
|
jam();
|
||||||
DBUG_ENTER("Suma::dropTrigger");
|
DBUG_ENTER("Suma::dropTrigger");
|
||||||
|
|
||||||
|
m_hasOutstandingTriggerReq[0] =
|
||||||
|
m_hasOutstandingTriggerReq[1] =
|
||||||
|
m_hasOutstandingTriggerReq[2] = 1;
|
||||||
for(Uint32 j = 0; j<3; j++){
|
for(Uint32 j = 0; j<3; j++){
|
||||||
jam();
|
jam();
|
||||||
suma.suma_ndbrequire(m_triggerIds[j] != ILLEGAL_TRIGGER_ID);
|
suma.suma_ndbrequire(m_triggerIds[j] != ILLEGAL_TRIGGER_ID);
|
||||||
|
@ -2972,14 +2984,18 @@ Suma::Table::runDropTrigger(Signal* signal,
|
||||||
|
|
||||||
suma.suma_ndbrequire(type < 3);
|
suma.suma_ndbrequire(type < 3);
|
||||||
suma.suma_ndbrequire(m_triggerIds[type] == triggerId);
|
suma.suma_ndbrequire(m_triggerIds[type] == triggerId);
|
||||||
|
suma.suma_ndbrequire(m_hasTriggerDefined[type] > 0);
|
||||||
|
suma.suma_ndbrequire(m_hasOutstandingTriggerReq[type] == 1);
|
||||||
m_hasTriggerDefined[type]--;
|
m_hasTriggerDefined[type]--;
|
||||||
|
m_hasOutstandingTriggerReq[type] = 0;
|
||||||
if (m_hasTriggerDefined[type] == 0)
|
if (m_hasTriggerDefined[type] == 0)
|
||||||
{
|
{
|
||||||
jam();
|
jam();
|
||||||
m_triggerIds[type] = ILLEGAL_TRIGGER_ID;
|
m_triggerIds[type] = ILLEGAL_TRIGGER_ID;
|
||||||
}
|
}
|
||||||
if( m_hasTriggerDefined[0] != m_hasTriggerDefined[1] ||
|
if( m_hasOutstandingTriggerReq[0] ||
|
||||||
m_hasTriggerDefined[0] != m_hasTriggerDefined[2])
|
m_hasOutstandingTriggerReq[1] ||
|
||||||
|
m_hasOutstandingTriggerReq[2])
|
||||||
{
|
{
|
||||||
// more to come
|
// more to come
|
||||||
jam();
|
jam();
|
||||||
|
@ -2997,6 +3013,7 @@ Suma::Table::runDropTrigger(Signal* signal,
|
||||||
checkRelease(suma);
|
checkRelease(suma);
|
||||||
|
|
||||||
suma.sendSubStopComplete(signal, m_drop_subbPtr);
|
suma.sendSubStopComplete(signal, m_drop_subbPtr);
|
||||||
|
m_drop_subbPtr.p = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Suma::suma_ndbrequire(bool v) { ndbrequire(v); }
|
void Suma::suma_ndbrequire(bool v) { ndbrequire(v); }
|
||||||
|
@ -3551,13 +3568,17 @@ Suma::execDROP_TAB_CONF(Signal *signal)
|
||||||
DBUG_PRINT("info",("drop table id: %d[i=%u]", tableId, tabPtr.i));
|
DBUG_PRINT("info",("drop table id: %d[i=%u]", tableId, tabPtr.i));
|
||||||
|
|
||||||
tabPtr.p->m_state = Table::DROPPED;
|
tabPtr.p->m_state = Table::DROPPED;
|
||||||
tabPtr.p->m_hasTriggerDefined[0] = 0;
|
for (int j= 0; j < 3; j++)
|
||||||
tabPtr.p->m_hasTriggerDefined[1] = 0;
|
{
|
||||||
tabPtr.p->m_hasTriggerDefined[2] = 0;
|
if (!tabPtr.p->m_hasOutstandingTriggerReq[j])
|
||||||
tabPtr.p->m_triggerIds[0] = ILLEGAL_TRIGGER_ID;
|
{
|
||||||
tabPtr.p->m_triggerIds[1] = ILLEGAL_TRIGGER_ID;
|
tabPtr.p->m_hasTriggerDefined[j] = 0;
|
||||||
tabPtr.p->m_triggerIds[2] = ILLEGAL_TRIGGER_ID;
|
tabPtr.p->m_hasOutstandingTriggerReq[j] = 0;
|
||||||
|
tabPtr.p->m_triggerIds[j] = ILLEGAL_TRIGGER_ID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tabPtr.p->m_hasTriggerDefined[j] = 1;
|
||||||
|
}
|
||||||
if (senderRef == 0)
|
if (senderRef == 0)
|
||||||
{
|
{
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
|
|
@ -301,7 +301,8 @@ public:
|
||||||
|
|
||||||
union { Uint32 m_tableId; Uint32 key; };
|
union { Uint32 m_tableId; Uint32 key; };
|
||||||
Uint32 m_schemaVersion;
|
Uint32 m_schemaVersion;
|
||||||
Uint32 m_hasTriggerDefined[3]; // Insert/Update/Delete
|
Uint8 m_hasTriggerDefined[3]; // Insert/Update/Delete
|
||||||
|
Uint8 m_hasOutstandingTriggerReq[3]; // Insert/Update/Delete
|
||||||
Uint32 m_triggerIds[3]; // Insert/Update/Delete
|
Uint32 m_triggerIds[3]; // Insert/Update/Delete
|
||||||
|
|
||||||
Uint32 m_error;
|
Uint32 m_error;
|
||||||
|
|
|
@ -484,6 +484,8 @@ ErrorBundle ErrorCodes[] = {
|
||||||
{ 1418, DMEC, SE, "Subscription dropped, no new subscribers allowed" },
|
{ 1418, DMEC, SE, "Subscription dropped, no new subscribers allowed" },
|
||||||
{ 1419, DMEC, SE, "Subscription already dropped" },
|
{ 1419, DMEC, SE, "Subscription already dropped" },
|
||||||
|
|
||||||
|
{ 1420, DMEC, TR, "Subscriber manager busy with adding/removing a table" },
|
||||||
|
|
||||||
{ 4004, DMEC, AE, "Attribute name not found in the Table" },
|
{ 4004, DMEC, AE, "Attribute name not found in the Table" },
|
||||||
|
|
||||||
{ 4100, DMEC, AE, "Status Error in NDB" },
|
{ 4100, DMEC, AE, "Status Error in NDB" },
|
||||||
|
|
Loading…
Add table
Reference in a new issue