Fix stress test issue in MOT when using DDLs in transaction
This commit is contained in:
@ -451,18 +451,18 @@ RC Table::InsertRow(Row* row, TxnManager* txn)
|
|||||||
uint64_t surrogateprimaryKey = 0;
|
uint64_t surrogateprimaryKey = 0;
|
||||||
MOT::Index* ix = GetPrimaryIndex();
|
MOT::Index* ix = GetPrimaryIndex();
|
||||||
uint32_t numIndexes = GetNumIndexes();
|
uint32_t numIndexes = GetNumIndexes();
|
||||||
|
MOT::Key* cleanupKeys[numIndexes] = {nullptr};
|
||||||
|
|
||||||
// add row
|
// add row
|
||||||
// set primary key
|
// set primary key
|
||||||
row->SetRowId(txn->GetSurrogateKey());
|
row->SetRowId(txn->GetSurrogateKey());
|
||||||
|
|
||||||
mot_vector<Key*> cleanupKeys;
|
|
||||||
key = txn->GetTxnKey(ix);
|
key = txn->GetTxnKey(ix);
|
||||||
if (key == nullptr) {
|
if (key == nullptr) {
|
||||||
MOT_REPORT_ERROR(MOT_ERROR_OOM, "Insert Row", "Failed to create primary key");
|
MOT_REPORT_ERROR(MOT_ERROR_OOM, "Insert Row", "Failed to create primary key");
|
||||||
return RC_MEMORY_ALLOCATION_ERROR;
|
return RC_MEMORY_ALLOCATION_ERROR;
|
||||||
}
|
}
|
||||||
cleanupKeys.push_back(key);
|
cleanupKeys[0] = key;
|
||||||
if (ix->IsFakePrimary()) {
|
if (ix->IsFakePrimary()) {
|
||||||
surrogateprimaryKey = htobe64(row->GetRowId());
|
surrogateprimaryKey = htobe64(row->GetRowId());
|
||||||
row->SetSurrogateKey(surrogateprimaryKey);
|
row->SetSurrogateKey(surrogateprimaryKey);
|
||||||
@ -480,16 +480,19 @@ RC Table::InsertRow(Row* row, TxnManager* txn)
|
|||||||
if (key == nullptr) {
|
if (key == nullptr) {
|
||||||
MOT_REPORT_ERROR(
|
MOT_REPORT_ERROR(
|
||||||
MOT_ERROR_OOM, "Insert Row", "Failed to create key for secondary index %s", ix->GetName().c_str());
|
MOT_ERROR_OOM, "Insert Row", "Failed to create key for secondary index %s", ix->GetName().c_str());
|
||||||
std::for_each(cleanupKeys.begin(), cleanupKeys.end(), [](Key*& key) { MOTCurrTxn->DestroyTxnKey(key); });
|
for (uint16_t j = 0; j < numIndexes; j++) {
|
||||||
|
if (cleanupKeys[j] != nullptr) {
|
||||||
|
MOTCurrTxn->DestroyTxnKey(cleanupKeys[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
MOTCurrTxn->Rollback();
|
MOTCurrTxn->Rollback();
|
||||||
return RC_MEMORY_ALLOCATION_ERROR;
|
return RC_MEMORY_ALLOCATION_ERROR;
|
||||||
}
|
}
|
||||||
cleanupKeys.push_back(key);
|
cleanupKeys[i] = key;
|
||||||
ix->BuildKey(this, row, key);
|
ix->BuildKey(this, row, key);
|
||||||
txn->GetNextInsertItem()->SetItem(row, ix, key);
|
txn->GetNextInsertItem()->SetItem(row, ix, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanupKeys.clear(); // subsequent call to insert row takes care of key cleanup
|
|
||||||
return txn->InsertRow(row);
|
return txn->InsertRow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -979,19 +982,23 @@ RC Table::CreateIndexFromMeta(
|
|||||||
if (addToTable) {
|
if (addToTable) {
|
||||||
// In transactional recovery we set index as committed only during commit.
|
// In transactional recovery we set index as committed only during commit.
|
||||||
ix->SetIsCommited(true);
|
ix->SetIsCommited(true);
|
||||||
|
WrLock();
|
||||||
if (primary) {
|
if (primary) {
|
||||||
if (UpdatePrimaryIndex(ix, nullptr, tid) != true) {
|
if (UpdatePrimaryIndex(ix, nullptr, tid) != true) {
|
||||||
|
Unlock();
|
||||||
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL, "Create Index from meta-data", "Failed to add primary index");
|
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL, "Create Index from meta-data", "Failed to add primary index");
|
||||||
delete ix;
|
delete ix;
|
||||||
return RC_ERROR;
|
return RC_ERROR;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (AddSecondaryIndex(ix->GetName(), (Index*)ix, nullptr, tid) != true) {
|
if (AddSecondaryIndex(ix->GetName(), (Index*)ix, nullptr, tid) != true) {
|
||||||
|
Unlock();
|
||||||
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL, "Create Index from meta-data", "Failed to add secondary index");
|
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL, "Create Index from meta-data", "Failed to add secondary index");
|
||||||
delete ix;
|
delete ix;
|
||||||
return RC_ERROR;
|
return RC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outIndex != nullptr) {
|
if (outIndex != nullptr) {
|
||||||
|
@ -490,8 +490,7 @@ void RecoveryManager::InsertRow(uint64_t tableId, uint64_t exId, char* keyData,
|
|||||||
|
|
||||||
Key* key = nullptr;
|
Key* key = nullptr;
|
||||||
MOT::Index* ix = nullptr;
|
MOT::Index* ix = nullptr;
|
||||||
|
MOT::Key* cleanupKeys[table->GetNumIndexes()] = {nullptr};
|
||||||
mot_vector<Key*> cleanupKeys;
|
|
||||||
ix = table->GetPrimaryIndex();
|
ix = table->GetPrimaryIndex();
|
||||||
key = MOTCurrTxn->GetTxnKey(ix);
|
key = MOTCurrTxn->GetTxnKey(ix);
|
||||||
if (key == nullptr) {
|
if (key == nullptr) {
|
||||||
@ -500,7 +499,7 @@ void RecoveryManager::InsertRow(uint64_t tableId, uint64_t exId, char* keyData,
|
|||||||
MOT_REPORT_ERROR(MOT_ERROR_OOM, "Recover Insert Row", "Failed to create primary key");
|
MOT_REPORT_ERROR(MOT_ERROR_OOM, "Recover Insert Row", "Failed to create primary key");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cleanupKeys.push_back(key);
|
cleanupKeys[0] = key;
|
||||||
if (ix->IsFakePrimary()) {
|
if (ix->IsFakePrimary()) {
|
||||||
row->SetSurrogateKey(*(uint64_t*)keyData);
|
row->SetSurrogateKey(*(uint64_t*)keyData);
|
||||||
sState.UpdateMaxKey(rowId);
|
sState.UpdateMaxKey(rowId);
|
||||||
@ -516,15 +515,18 @@ void RecoveryManager::InsertRow(uint64_t tableId, uint64_t exId, char* keyData,
|
|||||||
"Recover Insert Row",
|
"Recover Insert Row",
|
||||||
"Failed to create key for secondary index %s",
|
"Failed to create key for secondary index %s",
|
||||||
ix->GetName().c_str());
|
ix->GetName().c_str());
|
||||||
std::for_each(cleanupKeys.begin(), cleanupKeys.end(), [](Key*& key) { MOTCurrTxn->DestroyTxnKey(key); });
|
for (uint16_t j = 0; j < table->GetNumIndexes(); j++) {
|
||||||
|
if (cleanupKeys[j] != nullptr) {
|
||||||
|
MOTCurrTxn->DestroyTxnKey(cleanupKeys[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
MOTCurrTxn->Rollback();
|
MOTCurrTxn->Rollback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cleanupKeys.push_back(key);
|
cleanupKeys[i] = key;
|
||||||
ix->BuildKey(table, row, key);
|
ix->BuildKey(table, row, key);
|
||||||
MOTCurrTxn->GetNextInsertItem()->SetItem(row, ix, key);
|
MOTCurrTxn->GetNextInsertItem()->SetItem(row, ix, key);
|
||||||
}
|
}
|
||||||
cleanupKeys.clear(); // subsequent call to insert row takes care of key cleanup
|
|
||||||
status = MOTCurrTxn->InsertRow(row);
|
status = MOTCurrTxn->InsertRow(row);
|
||||||
|
|
||||||
if (insertLocked == true) {
|
if (insertLocked == true) {
|
||||||
@ -786,7 +788,9 @@ void RecoveryManager::DropIndex(char* data, RC& status)
|
|||||||
if (index == nullptr) {
|
if (index == nullptr) {
|
||||||
res = RC_INDEX_NOT_FOUND;
|
res = RC_INDEX_NOT_FOUND;
|
||||||
} else {
|
} else {
|
||||||
|
table->WrLock();
|
||||||
res = MOTCurrTxn->DropIndex(index);
|
res = MOTCurrTxn->DropIndex(index);
|
||||||
|
table->Unlock();
|
||||||
}
|
}
|
||||||
if (res != RC_OK) {
|
if (res != RC_OK) {
|
||||||
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL,
|
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL,
|
||||||
|
@ -1136,11 +1136,23 @@ RC TxnManager::DropTable(Table* table)
|
|||||||
if (ddl_access->GetDDLAccessType() == DDL_ACCESS_CREATE_TABLE) {
|
if (ddl_access->GetDDLAccessType() == DDL_ACCESS_CREATE_TABLE) {
|
||||||
// this table was created in this transaction, can delete it from the ddl_access
|
// this table was created in this transaction, can delete it from the ddl_access
|
||||||
m_txnDdlAccess->EraseByOid(table->GetTableExId());
|
m_txnDdlAccess->EraseByOid(table->GetTableExId());
|
||||||
|
// check for create and drop index ddls
|
||||||
|
for (uint16_t i = 0; i < table->GetNumIndexes(); i++) {
|
||||||
|
m_txnDdlAccess->EraseByOid(table->GetIndex(i)->GetExtId());
|
||||||
|
}
|
||||||
|
// erase drop fake primary index if exists
|
||||||
|
TxnDDLAccess::DDLAccess* iddl = m_txnDdlAccess->GetByOid(table->GetTableExId() + 1);
|
||||||
|
if (iddl != nullptr) {
|
||||||
|
MOT::Index* ix = (MOT::Index*)iddl->GetEntry();
|
||||||
|
GcManager::ClearIndexElements(ix->GetIndexId());
|
||||||
|
table->DeletePrimaryIndex(ix);
|
||||||
|
}
|
||||||
table->DropImpl();
|
table->DropImpl();
|
||||||
RemoveTableFromStat(table);
|
RemoveTableFromStat(table);
|
||||||
delete table;
|
delete table;
|
||||||
} else if (ddl_access->GetDDLAccessType() == DDL_ACCESS_TRUNCATE_TABLE) {
|
} else if (ddl_access->GetDDLAccessType() == DDL_ACCESS_TRUNCATE_TABLE) {
|
||||||
Index** indexes = (Index**)ddl_access->GetEntry();
|
Index** indexes = (Index**)ddl_access->GetEntry();
|
||||||
|
table->WrLock();
|
||||||
for (int i = 0; i < table->GetNumIndexes(); i++) {
|
for (int i = 0; i < table->GetNumIndexes(); i++) {
|
||||||
Index* newIndex = table->m_indexes[i];
|
Index* newIndex = table->m_indexes[i];
|
||||||
Index* oldIndex = indexes[i];
|
Index* oldIndex = indexes[i];
|
||||||
@ -1153,6 +1165,7 @@ RC TxnManager::DropTable(Table* table)
|
|||||||
// assumption is the we deleted all rows
|
// assumption is the we deleted all rows
|
||||||
delete newIndex;
|
delete newIndex;
|
||||||
}
|
}
|
||||||
|
table->Unlock();
|
||||||
delete[] indexes;
|
delete[] indexes;
|
||||||
m_txnDdlAccess->EraseByOid(table->GetTableExId());
|
m_txnDdlAccess->EraseByOid(table->GetTableExId());
|
||||||
m_txnDdlAccess->Add(new_ddl_access);
|
m_txnDdlAccess->Add(new_ddl_access);
|
||||||
|
@ -1925,10 +1925,15 @@ MOT::RC MOTAdaptor::DropIndex(DropForeignStmt* stmt, ::TransactionId tid)
|
|||||||
stmt->indexoid,
|
stmt->indexoid,
|
||||||
stmt->reloid);
|
stmt->reloid);
|
||||||
res = MOT::RC_INDEX_NOT_FOUND;
|
res = MOT::RC_INDEX_NOT_FOUND;
|
||||||
|
} else if (index->IsPrimaryKey()) {
|
||||||
|
elog(LOG, "Drop primary index is not supported, failed to drop index: %s", stmt->name);
|
||||||
} else {
|
} else {
|
||||||
uint64_t table_relid = index->GetTable()->GetTableExId();
|
MOT::Table* table = index->GetTable();
|
||||||
|
uint64_t table_relid = table->GetTableExId();
|
||||||
JitExec::PurgeJitSourceCache(table_relid);
|
JitExec::PurgeJitSourceCache(table_relid);
|
||||||
|
table->WrLock();
|
||||||
res = txn->DropIndex(index);
|
res = txn->DropIndex(index);
|
||||||
|
table->Unlock();
|
||||||
}
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user