mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 10:37:02 +00:00
[11045] Rewrite internals of DB layer. Simplify code and use less locking. Spawn and use separate connections for sync and async DB requests. Implement database connection pool for SELECT queries. Up to maximum 16 connections supported. Disable 'autocommit' mode for MySQL.
UPDATE YOUR CONFIGS! Defaults: LoginDatabaseConnections = 1 WorldDatabaseConnections = 1 CharacterDatabaseConnections = 1 If you are not using <mtmaps> patch do not change the default settings - this is useless. You can try following option in your MySQL config to squeeze even more performance from your DB: [mysqld] transaction-isolation = READ-COMMITTED Great thanks to Undergarun, kero99 and selector for making tests and providing very useful feedback and DB statistics! Have fun :) Signed-off-by: Ambal <pogrebniak@gala.net>
This commit is contained in:
parent
9bc37afa28
commit
631ce36680
19 changed files with 655 additions and 547 deletions
|
|
@ -21,54 +21,60 @@
|
|||
#include "DatabaseEnv.h"
|
||||
#include "DatabaseImpl.h"
|
||||
|
||||
#define LOCK_DB_CONN(conn) SqlConnection::Lock guard(conn)
|
||||
|
||||
/// ---- ASYNC STATEMENTS / TRANSACTIONS ----
|
||||
|
||||
void SqlStatement::Execute(Database *db)
|
||||
void SqlStatement::Execute(SqlConnection *conn)
|
||||
{
|
||||
/// just do it
|
||||
db->DirectExecute(m_sql);
|
||||
LOCK_DB_CONN(conn);
|
||||
conn->Execute(m_sql);
|
||||
}
|
||||
|
||||
void SqlTransaction::Execute(Database *db)
|
||||
SqlTransaction::~SqlTransaction()
|
||||
{
|
||||
while(!m_queue.empty())
|
||||
{
|
||||
delete [] (const_cast<char*>(m_queue.back()));
|
||||
m_queue.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void SqlTransaction::Execute(SqlConnection *conn)
|
||||
{
|
||||
ACE_Guard<ACE_Thread_Mutex> _lock(m_Mutex);
|
||||
if(m_queue.empty())
|
||||
return;
|
||||
|
||||
db->DirectExecute("START TRANSACTION");
|
||||
while(!m_queue.empty())
|
||||
LOCK_DB_CONN(conn);
|
||||
|
||||
conn->BeginTransaction();
|
||||
|
||||
const int nItems = m_queue.size();
|
||||
for (int i = 0; i < nItems; ++i)
|
||||
{
|
||||
char *sql = const_cast<char*>(m_queue.front());
|
||||
m_queue.pop();
|
||||
const char *sql = m_queue[i];
|
||||
|
||||
if(!db->DirectExecute(sql))
|
||||
if(!conn->Execute(sql))
|
||||
{
|
||||
delete [] sql;
|
||||
|
||||
db->DirectExecute("ROLLBACK");
|
||||
while(!m_queue.empty())
|
||||
{
|
||||
delete [] (const_cast<char*>(m_queue.front()));
|
||||
m_queue.pop();
|
||||
}
|
||||
|
||||
conn->RollbackTransaction();
|
||||
return;
|
||||
}
|
||||
|
||||
delete [] sql;
|
||||
}
|
||||
|
||||
db->DirectExecute("COMMIT");
|
||||
conn->CommitTransaction();
|
||||
}
|
||||
|
||||
/// ---- ASYNC QUERIES ----
|
||||
|
||||
void SqlQuery::Execute(Database *db)
|
||||
void SqlQuery::Execute(SqlConnection *conn)
|
||||
{
|
||||
if(!m_callback || !m_queue)
|
||||
return;
|
||||
|
||||
LOCK_DB_CONN(conn);
|
||||
/// execute the query and store the result in the callback
|
||||
m_callback->SetResult(db->Query(m_sql));
|
||||
m_callback->SetResult(conn->Query(m_sql));
|
||||
/// add the callback to the sql result queue of the thread it originated from
|
||||
m_queue->add(m_callback);
|
||||
}
|
||||
|
|
@ -184,19 +190,19 @@ void SqlQueryHolder::SetSize(size_t size)
|
|||
m_queries.resize(size);
|
||||
}
|
||||
|
||||
void SqlQueryHolderEx::Execute(Database *db)
|
||||
void SqlQueryHolderEx::Execute(SqlConnection *conn)
|
||||
{
|
||||
if(!m_holder || !m_callback || !m_queue)
|
||||
return;
|
||||
|
||||
LOCK_DB_CONN(conn);
|
||||
/// we can do this, we are friends
|
||||
std::vector<SqlQueryHolder::SqlResultPair> &queries = m_holder->m_queries;
|
||||
|
||||
for(size_t i = 0; i < queries.size(); i++)
|
||||
{
|
||||
/// execute all queries in the holder and pass the results
|
||||
char const *sql = queries[i].first;
|
||||
if(sql) m_holder->SetResult(i, db->Query(sql));
|
||||
if(sql) m_holder->SetResult(i, conn->Query(sql));
|
||||
}
|
||||
|
||||
/// sync with the caller thread
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue