Fix stress test issue in MOT when using DDLs in transaction

This commit is contained in:
Vinoth
2020-08-20 15:45:25 +08:00
parent 10f145be69
commit f19e73a11c
4 changed files with 41 additions and 12 deletions

View File

@ -451,18 +451,18 @@ RC Table::InsertRow(Row* row, TxnManager* txn)
uint64_t surrogateprimaryKey = 0;
MOT::Index* ix = GetPrimaryIndex();
uint32_t numIndexes = GetNumIndexes();
MOT::Key* cleanupKeys[numIndexes] = {nullptr};
// add row
// set primary key
row->SetRowId(txn->GetSurrogateKey());
mot_vector<Key*> cleanupKeys;
key = txn->GetTxnKey(ix);
if (key == nullptr) {
MOT_REPORT_ERROR(MOT_ERROR_OOM, "Insert Row", "Failed to create primary key");
return RC_MEMORY_ALLOCATION_ERROR;
}
cleanupKeys.push_back(key);
cleanupKeys[0] = key;
if (ix->IsFakePrimary()) {
surrogateprimaryKey = htobe64(row->GetRowId());
row->SetSurrogateKey(surrogateprimaryKey);
@ -480,16 +480,19 @@ RC Table::InsertRow(Row* row, TxnManager* txn)
if (key == nullptr) {
MOT_REPORT_ERROR(
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();
return RC_MEMORY_ALLOCATION_ERROR;
}
cleanupKeys.push_back(key);
cleanupKeys[i] = key;
ix->BuildKey(this, row, key);
txn->GetNextInsertItem()->SetItem(row, ix, key);
}
cleanupKeys.clear(); // subsequent call to insert row takes care of key cleanup
return txn->InsertRow(row);
}
@ -979,19 +982,23 @@ RC Table::CreateIndexFromMeta(
if (addToTable) {
// In transactional recovery we set index as committed only during commit.
ix->SetIsCommited(true);
WrLock();
if (primary) {
if (UpdatePrimaryIndex(ix, nullptr, tid) != true) {
Unlock();
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL, "Create Index from meta-data", "Failed to add primary index");
delete ix;
return RC_ERROR;
}
} else {
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");
delete ix;
return RC_ERROR;
}
}
Unlock();
}
if (outIndex != nullptr) {

View File

@ -490,8 +490,7 @@ void RecoveryManager::InsertRow(uint64_t tableId, uint64_t exId, char* keyData,
Key* key = nullptr;
MOT::Index* ix = nullptr;
mot_vector<Key*> cleanupKeys;
MOT::Key* cleanupKeys[table->GetNumIndexes()] = {nullptr};
ix = table->GetPrimaryIndex();
key = MOTCurrTxn->GetTxnKey(ix);
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");
return;
}
cleanupKeys.push_back(key);
cleanupKeys[0] = key;
if (ix->IsFakePrimary()) {
row->SetSurrogateKey(*(uint64_t*)keyData);
sState.UpdateMaxKey(rowId);
@ -516,15 +515,18 @@ void RecoveryManager::InsertRow(uint64_t tableId, uint64_t exId, char* keyData,
"Recover 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 < table->GetNumIndexes(); j++) {
if (cleanupKeys[j] != nullptr) {
MOTCurrTxn->DestroyTxnKey(cleanupKeys[j]);
}
}
MOTCurrTxn->Rollback();
return;
}
cleanupKeys.push_back(key);
cleanupKeys[i] = key;
ix->BuildKey(table, row, key);
MOTCurrTxn->GetNextInsertItem()->SetItem(row, ix, key);
}
cleanupKeys.clear(); // subsequent call to insert row takes care of key cleanup
status = MOTCurrTxn->InsertRow(row);
if (insertLocked == true) {
@ -786,7 +788,9 @@ void RecoveryManager::DropIndex(char* data, RC& status)
if (index == nullptr) {
res = RC_INDEX_NOT_FOUND;
} else {
table->WrLock();
res = MOTCurrTxn->DropIndex(index);
table->Unlock();
}
if (res != RC_OK) {
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL,

View File

@ -1136,11 +1136,23 @@ RC TxnManager::DropTable(Table* table)
if (ddl_access->GetDDLAccessType() == DDL_ACCESS_CREATE_TABLE) {
// this table was created in this transaction, can delete it from the ddl_access
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();
RemoveTableFromStat(table);
delete table;
} else if (ddl_access->GetDDLAccessType() == DDL_ACCESS_TRUNCATE_TABLE) {
Index** indexes = (Index**)ddl_access->GetEntry();
table->WrLock();
for (int i = 0; i < table->GetNumIndexes(); i++) {
Index* newIndex = table->m_indexes[i];
Index* oldIndex = indexes[i];
@ -1153,6 +1165,7 @@ RC TxnManager::DropTable(Table* table)
// assumption is the we deleted all rows
delete newIndex;
}
table->Unlock();
delete[] indexes;
m_txnDdlAccess->EraseByOid(table->GetTableExId());
m_txnDdlAccess->Add(new_ddl_access);

View File

@ -1925,10 +1925,15 @@ MOT::RC MOTAdaptor::DropIndex(DropForeignStmt* stmt, ::TransactionId tid)
stmt->indexoid,
stmt->reloid);
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 {
uint64_t table_relid = index->GetTable()->GetTableExId();
MOT::Table* table = index->GetTable();
uint64_t table_relid = table->GetTableExId();
JitExec::PurgeJitSourceCache(table_relid);
table->WrLock();
res = txn->DropIndex(index);
table->Unlock();
}
} while (0);