mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-06-20 23:49:25 +02:00
fix(Core/Travel): Chunk saveNodeStore path inserts to avoid mega-tx
This commit is contained in:
parent
795384d1f8
commit
f0ec70c3ea
@ -2018,6 +2018,9 @@ void TravelNodeMap::saveNodeStore()
|
|||||||
|
|
||||||
hasToSave = false;
|
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();
|
PlayerbotsDatabaseTransaction trans = PlayerbotsDatabase.BeginTransaction();
|
||||||
|
|
||||||
trans->Append(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_TRAVELNODE));
|
trans->Append(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_TRAVELNODE));
|
||||||
@ -2076,13 +2079,22 @@ void TravelNodeMap::saveNodeStore()
|
|||||||
paths++;
|
paths++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Path points: bulk raw SQL multi-row INSERTs (~500 rows each) instead of
|
|
||||||
// 1M+ individual prepared statements. Appended to the same transaction so
|
PlayerbotsDatabase.CommitTransaction(trans);
|
||||||
// ordering is guaranteed.
|
|
||||||
|
// Phase 2: path points in chunked transactions. Previously all
|
||||||
|
// ~1.5M point inserts went into a single mega-transaction which
|
||||||
|
// exceeded MySQL's packet/transaction limits and partial-committed,
|
||||||
|
// corrupting the DB (links saved, paths empty). Chunk now commits
|
||||||
|
// every ~10000 rows. A failed chunk loses only its rows; the rest
|
||||||
|
// survive.
|
||||||
constexpr uint32 BATCH_SIZE = 500;
|
constexpr uint32 BATCH_SIZE = 500;
|
||||||
|
constexpr uint32 BATCHES_PER_COMMIT = 20; // 20 * 500 = 10000 rows per tx
|
||||||
uint32 points = 0;
|
uint32 points = 0;
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
uint32 batchCount = 0;
|
uint32 batchCount = 0;
|
||||||
|
uint32 batchesInCurrentTx = 0;
|
||||||
|
PlayerbotsDatabaseTransaction pathTrans = PlayerbotsDatabase.BeginTransaction();
|
||||||
|
|
||||||
auto flushBatch = [&]()
|
auto flushBatch = [&]()
|
||||||
{
|
{
|
||||||
@ -2091,10 +2103,21 @@ void TravelNodeMap::saveNodeStore()
|
|||||||
|
|
||||||
std::string sql = ss.str();
|
std::string sql = ss.str();
|
||||||
sql.back() = ';'; // Replace trailing comma
|
sql.back() = ';'; // Replace trailing comma
|
||||||
trans->Append(sql.c_str());
|
pathTrans->Append(sql.c_str());
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss.clear();
|
ss.clear();
|
||||||
batchCount = 0;
|
batchCount = 0;
|
||||||
|
batchesInCurrentTx++;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto commitIfFull = [&]()
|
||||||
|
{
|
||||||
|
if (batchesInCurrentTx >= BATCHES_PER_COMMIT)
|
||||||
|
{
|
||||||
|
PlayerbotsDatabase.CommitTransaction(pathTrans);
|
||||||
|
pathTrans = PlayerbotsDatabase.BeginTransaction();
|
||||||
|
batchesInCurrentTx = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (uint32 i = 0; i < anodes.size(); i++)
|
for (uint32 i = 0; i < anodes.size(); i++)
|
||||||
@ -2125,16 +2148,18 @@ void TravelNodeMap::saveNodeStore()
|
|||||||
points++;
|
points++;
|
||||||
|
|
||||||
if (batchCount >= BATCH_SIZE)
|
if (batchCount >= BATCH_SIZE)
|
||||||
|
{
|
||||||
flushBatch();
|
flushBatch();
|
||||||
|
commitIfFull();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flushBatch();
|
flushBatch();
|
||||||
|
PlayerbotsDatabase.CommitTransaction(pathTrans);
|
||||||
|
|
||||||
LOG_INFO("playerbots", ">> Saved {} travelNode Paths, {} points.", paths, points);
|
LOG_INFO("playerbots", ">> Saved {} travelNode Paths, {} points.", paths, points);
|
||||||
|
|
||||||
PlayerbotsDatabase.CommitTransaction(trans);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TravelNodeMap::LoadNodeStore()
|
void TravelNodeMap::LoadNodeStore()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user