mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +00:00
[11054] Do not allow async transaction execution while server is loading. Call Database::InitDelayThread() function explicitly to create async DB worker thread after server initialization is complete.
Signed-off-by: Ambal <pogrebniak@gala.net>
This commit is contained in:
parent
e6e7bf8573
commit
07c9f0cbb8
9 changed files with 59 additions and 58 deletions
|
|
@ -514,7 +514,7 @@ void InstanceSaveManager::CleanupInstances()
|
|||
CharacterDatabase.Execute("DELETE FROM creature_respawn WHERE instance <> 0 AND instance NOT IN (SELECT id FROM instance)");
|
||||
CharacterDatabase.Execute("DELETE FROM gameobject_respawn WHERE instance <> 0 AND instance NOT IN (SELECT id FROM instance)");
|
||||
//execute transaction directly
|
||||
CharacterDatabase.CommitTransactionDirect();
|
||||
CharacterDatabase.CommitTransaction();
|
||||
|
||||
bar.step();
|
||||
sLog.outString();
|
||||
|
|
@ -562,7 +562,7 @@ void InstanceSaveManager::PackInstances()
|
|||
CharacterDatabase.PExecute("UPDATE instance SET id = '%u' WHERE id = '%u'", InstanceNumber, *i);
|
||||
CharacterDatabase.PExecute("UPDATE group_instance SET instance = '%u' WHERE instance = '%u'", InstanceNumber, *i);
|
||||
//execute transaction synchronously
|
||||
CharacterDatabase.CommitTransactionDirect();
|
||||
CharacterDatabase.CommitTransaction();
|
||||
}
|
||||
|
||||
++InstanceNumber;
|
||||
|
|
|
|||
|
|
@ -5598,7 +5598,7 @@ void ObjectMgr::PackGroupIds()
|
|||
CharacterDatabase.BeginTransaction();
|
||||
CharacterDatabase.PExecute("DELETE FROM groups WHERE groupId = '%u'", id);
|
||||
CharacterDatabase.PExecute("DELETE FROM group_member WHERE groupId = '%u'", id);
|
||||
CharacterDatabase.CommitTransactionDirect();
|
||||
CharacterDatabase.CommitTransaction();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -5621,7 +5621,7 @@ void ObjectMgr::PackGroupIds()
|
|||
CharacterDatabase.BeginTransaction();
|
||||
CharacterDatabase.PExecute("UPDATE groups SET groupId = '%u' WHERE groupId = '%u'", groupId, *i);
|
||||
CharacterDatabase.PExecute("UPDATE group_member SET groupId = '%u' WHERE groupId = '%u'", groupId, *i);
|
||||
CharacterDatabase.CommitTransactionDirect();
|
||||
CharacterDatabase.CommitTransaction();
|
||||
}
|
||||
|
||||
++groupId;
|
||||
|
|
@ -5670,7 +5670,7 @@ void ObjectMgr::SetHighestGuids()
|
|||
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", m_ItemGuids.GetNextAfterMaxUsed());
|
||||
CharacterDatabase.PExecute("DELETE FROM auction WHERE itemguid >= '%u'", m_ItemGuids.GetNextAfterMaxUsed());
|
||||
CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", m_ItemGuids.GetNextAfterMaxUsed());
|
||||
CharacterDatabase.CommitTransactionDirect();
|
||||
CharacterDatabase.CommitTransaction();
|
||||
|
||||
result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject" );
|
||||
if( result )
|
||||
|
|
|
|||
|
|
@ -197,6 +197,12 @@ int Master::Run()
|
|||
///- Initialize the World
|
||||
sWorld.SetInitialWorldSettings();
|
||||
|
||||
//server loaded successfully => enable async DB requests
|
||||
//this is done to forbid any async transactions during server startup!
|
||||
CharacterDatabase.InitDelayThread();
|
||||
WorldDatabase.InitDelayThread();
|
||||
LoginDatabase.InitDelayThread();
|
||||
|
||||
///- Catch termination signals
|
||||
_HookSignals();
|
||||
|
||||
|
|
@ -208,7 +214,7 @@ int Master::Run()
|
|||
{
|
||||
std::string builds = AcceptableClientBuildsListStr();
|
||||
LoginDatabase.escape_string(builds);
|
||||
LoginDatabase.PExecute("UPDATE realmlist SET realmflags = realmflags & ~(%u), population = 0, realmbuilds = '%s' WHERE id = '%u'", REALM_FLAG_OFFLINE, builds.c_str(), realmID);
|
||||
LoginDatabase.DirectPExecute("UPDATE realmlist SET realmflags = realmflags & ~(%u), population = 0, realmbuilds = '%s' WHERE id = '%u'", REALM_FLAG_OFFLINE, builds.c_str(), realmID);
|
||||
}
|
||||
|
||||
ACE_Based::Thread* cliThread = NULL;
|
||||
|
|
@ -328,7 +334,7 @@ int Master::Run()
|
|||
}
|
||||
|
||||
///- Set server offline in realmlist
|
||||
LoginDatabase.PExecute("UPDATE realmlist SET realmflags = realmflags | %u WHERE id = '%u'", REALM_FLAG_OFFLINE, realmID);
|
||||
LoginDatabase.DirectPExecute("UPDATE realmlist SET realmflags = realmflags | %u WHERE id = '%u'", REALM_FLAG_OFFLINE, realmID);
|
||||
|
||||
///- Remove signal handling before leaving
|
||||
_UnhookSignals();
|
||||
|
|
|
|||
|
|
@ -221,8 +221,10 @@ extern int main(int argc, char **argv)
|
|||
|
||||
// cleanup query
|
||||
// set expired bans to inactive
|
||||
LoginDatabase.BeginTransaction();
|
||||
LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
|
||||
LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
|
||||
LoginDatabase.CommitTransaction();
|
||||
|
||||
///- Launch the listening network socket
|
||||
ACE_Acceptor<AuthSocket, ACE_SOCK_Acceptor> acceptor;
|
||||
|
|
@ -285,6 +287,9 @@ extern int main(int argc, char **argv)
|
|||
}
|
||||
#endif
|
||||
|
||||
//server has started up successfully => enable async DB requests
|
||||
LoginDatabase.InitDelayThread();
|
||||
|
||||
// maximum counter for next ping
|
||||
uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000));
|
||||
uint32 loopCounter = 0;
|
||||
|
|
|
|||
|
|
@ -29,13 +29,7 @@
|
|||
|
||||
Database::~Database()
|
||||
{
|
||||
HaltDelayThread();
|
||||
/*Delete objects*/
|
||||
delete m_pResultQueue;
|
||||
delete m_pAsyncConn;
|
||||
|
||||
for (int i = 0; i < m_pQueryConnections.size(); ++i)
|
||||
delete m_pQueryConnections[i];
|
||||
StopServer();
|
||||
}
|
||||
|
||||
bool Database::Initialize(const char * infoString, int nConns /*= 1*/)
|
||||
|
|
@ -80,10 +74,33 @@ bool Database::Initialize(const char * infoString, int nConns /*= 1*/)
|
|||
if(!m_pAsyncConn->Initialize(infoString))
|
||||
return false;
|
||||
|
||||
InitDelayThread();
|
||||
m_pResultQueue = new SqlResultQueue;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Database::StopServer()
|
||||
{
|
||||
HaltDelayThread();
|
||||
/*Delete objects*/
|
||||
if(m_pResultQueue)
|
||||
{
|
||||
delete m_pResultQueue;
|
||||
m_pResultQueue = NULL;
|
||||
}
|
||||
|
||||
if(m_pAsyncConn)
|
||||
{
|
||||
delete m_pAsyncConn;
|
||||
m_pAsyncConn = NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_pQueryConnections.size(); ++i)
|
||||
delete m_pQueryConnections[i];
|
||||
|
||||
m_pQueryConnections.clear();
|
||||
|
||||
}
|
||||
|
||||
SqlDelayThread * Database::CreateDelayThread()
|
||||
{
|
||||
assert(m_pAsyncConn);
|
||||
|
|
@ -94,7 +111,6 @@ void Database::InitDelayThread()
|
|||
{
|
||||
assert(!m_delayThread);
|
||||
|
||||
m_pResultQueue = new SqlResultQueue;
|
||||
//New delay thread for delay execute
|
||||
m_threadBody = CreateDelayThread(); // will deleted at m_delayThread delete
|
||||
m_delayThread = new ACE_Based::Thread(m_threadBody);
|
||||
|
|
@ -109,14 +125,6 @@ void Database::HaltDelayThread()
|
|||
delete m_delayThread; //This also deletes m_threadBody
|
||||
m_delayThread = NULL;
|
||||
m_threadBody = NULL;
|
||||
|
||||
//stop async result queue
|
||||
if(m_pResultQueue)
|
||||
{
|
||||
m_pResultQueue->Update();
|
||||
delete m_pResultQueue;
|
||||
m_pResultQueue = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Database::ThreadStart()
|
||||
|
|
@ -268,6 +276,10 @@ bool Database::Execute(const char *sql)
|
|||
}
|
||||
else
|
||||
{
|
||||
//if async execution is not available
|
||||
if(!m_threadBody)
|
||||
return DirectExecute(sql);
|
||||
|
||||
// Simple sql statement
|
||||
pTrans = new SqlTransaction;
|
||||
pTrans->DelayExecute(sql);
|
||||
|
|
@ -350,6 +362,10 @@ bool Database::CommitTransaction()
|
|||
if(!m_TransStorage->get())
|
||||
return false;
|
||||
|
||||
//if async execution is not available
|
||||
if(!m_delayThread)
|
||||
return CommitTransactionDirect();
|
||||
|
||||
//add SqlTransaction to the async queue
|
||||
m_threadBody->Delay(m_TransStorage->detach());
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -81,7 +81,11 @@ class MANGOS_DLL_SPEC Database
|
|||
virtual ~Database();
|
||||
|
||||
virtual bool Initialize(const char *infoString, int nConns = 1);
|
||||
//start worker thread for async DB request execution
|
||||
//you should call it explicitly after your server successfully started up
|
||||
//NO ASYNC TRANSACTIONS DURING SERVER STARTUP - ONLY DURING RUNTIME!!!
|
||||
virtual void InitDelayThread();
|
||||
//stop worker thread
|
||||
virtual void HaltDelayThread();
|
||||
|
||||
/// Synchronous DB queries
|
||||
|
|
@ -181,6 +185,8 @@ class MANGOS_DLL_SPEC Database
|
|||
m_nQueryCounter = -1;
|
||||
}
|
||||
|
||||
void StopServer();
|
||||
|
||||
//factory method to create SqlConnection objects
|
||||
virtual SqlConnection * CreateConnection() = 0;
|
||||
//factory method to create SqlDelayThread objects
|
||||
|
|
|
|||
|
|
@ -56,23 +56,7 @@ DatabaseMysql::DatabaseMysql()
|
|||
|
||||
DatabaseMysql::~DatabaseMysql()
|
||||
{
|
||||
if (m_delayThread)
|
||||
HaltDelayThread();
|
||||
|
||||
//destroy SqlConnection objects
|
||||
if(m_pQueryConnections.size())
|
||||
{
|
||||
for (int i = 0; i < m_pQueryConnections.size(); ++i)
|
||||
delete m_pQueryConnections[i];
|
||||
|
||||
m_pQueryConnections.clear();
|
||||
}
|
||||
|
||||
if(m_pAsyncConn)
|
||||
{
|
||||
delete m_pAsyncConn;
|
||||
m_pAsyncConn = NULL;
|
||||
}
|
||||
StopServer();
|
||||
|
||||
//Free Mysql library pointers for last ~DB
|
||||
if(--db_count == 0)
|
||||
|
|
|
|||
|
|
@ -43,23 +43,7 @@ DatabasePostgre::DatabasePostgre()
|
|||
|
||||
DatabasePostgre::~DatabasePostgre()
|
||||
{
|
||||
if (m_delayThread)
|
||||
HaltDelayThread();
|
||||
|
||||
//destroy SqlConnection objects
|
||||
if(m_pQueryConnections.size())
|
||||
{
|
||||
for (int i = 0; i < m_pQueryConnections.size(); ++i)
|
||||
delete m_pQueryConnections[i];
|
||||
|
||||
m_pQueryConnections.clear();
|
||||
}
|
||||
|
||||
if(m_pAsyncConn)
|
||||
{
|
||||
delete m_pAsyncConn;
|
||||
m_pAsyncConn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SqlConnection * DatabasePostgre::CreateConnection()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "11053"
|
||||
#define REVISION_NR "11054"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue