fix(Core/Travel): Chunk all saveNodeStore phases (deletes, nodes, links)

This commit is contained in:
bash 2026-05-17 13:05:33 +02:00
parent 5b39d1552c
commit 0d7b7bb1da

View File

@ -2018,18 +2018,24 @@ void TravelNodeMap::saveNodeStore()
hasToSave = false;
// Phase 1: deletes + nodes + links in a single transaction. ~4400
// nodes + ~18000 links = ~22000 prepared statements, comfortably
// within MySQL transaction limits.
PlayerbotsDatabaseTransaction trans = PlayerbotsDatabase.BeginTransaction();
constexpr uint32 STMTS_PER_TX = 500; // bounded transaction size
trans->Append(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_TRAVELNODE));
trans->Append(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_TRAVELNODE_LINK));
trans->Append(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_TRAVELNODE_PATH));
// Phase 1: deletes in their own transaction.
{
PlayerbotsDatabaseTransaction delTrans = PlayerbotsDatabase.BeginTransaction();
delTrans->Append(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_TRAVELNODE));
delTrans->Append(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_TRAVELNODE_LINK));
delTrans->Append(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_TRAVELNODE_PATH));
PlayerbotsDatabase.CommitTransaction(delTrans);
}
std::unordered_map<TravelNode*, uint32> saveNodes;
std::vector<TravelNode*> anodes = TravelNodeMap::instance().getNodes();
// Phase 2: node inserts, chunked at STMTS_PER_TX per transaction.
{
PlayerbotsDatabaseTransaction nodeTrans = PlayerbotsDatabase.BeginTransaction();
uint32 inTx = 0;
for (uint32 i = 0; i < anodes.size(); i++)
{
TravelNode* node = anodes[i];
@ -2045,14 +2051,27 @@ void TravelNodeMap::saveNodeStore()
stmt->SetData(4, node->getY());
stmt->SetData(5, node->getZ());
stmt->SetData(6, node->isLinked());
trans->Append(stmt);
nodeTrans->Append(stmt);
saveNodes.insert(std::make_pair(node, i));
if (++inTx >= STMTS_PER_TX)
{
PlayerbotsDatabase.CommitTransaction(nodeTrans);
nodeTrans = PlayerbotsDatabase.BeginTransaction();
inTx = 0;
}
}
PlayerbotsDatabase.CommitTransaction(nodeTrans);
}
LOG_INFO("playerbots", ">> Saved {} travelNodes.", anodes.size());
// Phase 3: link inserts, chunked at STMTS_PER_TX per transaction.
uint32 paths = 0;
{
PlayerbotsDatabaseTransaction linkTrans = PlayerbotsDatabase.BeginTransaction();
uint32 inTx = 0;
for (uint32 i = 0; i < anodes.size(); i++)
{
TravelNode* node = anodes[i];
@ -2074,13 +2093,20 @@ void TravelNodeMap::saveNodeStore()
stmt->SetData(8, path->getMaxLevelCreature()[0]);
stmt->SetData(9, path->getMaxLevelCreature()[1]);
stmt->SetData(10, path->getMaxLevelCreature()[2]);
trans->Append(stmt);
linkTrans->Append(stmt);
paths++;
}
}
PlayerbotsDatabase.CommitTransaction(trans);
if (++inTx >= STMTS_PER_TX)
{
PlayerbotsDatabase.CommitTransaction(linkTrans);
linkTrans = PlayerbotsDatabase.BeginTransaction();
inTx = 0;
}
}
}
PlayerbotsDatabase.CommitTransaction(linkTrans);
}
// Phase 2: path points in chunked transactions. Previously all
// ~1.5M point inserts went into a single mega-transaction which