DatabaseWorkerPool<T>::DatabaseWorkerPool() : _queue(new ProducerConsumerQueue<SQLOperation*>()), _async_threads(0), _synch_threads(0) { WPFatal(mysql_thread_safe(), "Used MySQL library isn't thread-safe."); WPFatal(mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION, "TrinityCore does not support MySQL versions below 5.1"); WPFatal(mysql_get_client_version() == MYSQL_VERSION_ID, "Used MySQL library version (%s) does not match the version used to compile TrinityCore (%s).", mysql_get_client_info(), MYSQL_SERVER_VERSION); }
DatabaseWorkerPool::DatabaseWorkerPool() : m_queue(new ACE_Activation_Queue(new ACE_Message_Queue<ACE_MT_SYNCH>)), m_connections(0) { m_infoString = ""; mysql_library_init(-1, NULL, NULL); WPFatal (mysql_thread_safe(), "Used MySQL library isn't thread-safe."); }
void LoadGameTables(std::string const& dataPath) { uint32 oldMSTime = getMSTime(); boost::filesystem::path gtPath(dataPath); gtPath /= "gt"; std::vector<std::string> bad_gt_files; uint32 gameTableCount = 0, expectedGameTableCount = 0; #define LOAD_GT(store, file) gameTableCount += LoadGameTable(bad_gt_files, store, gtPath / file); ++expectedGameTableCount; LOAD_GT(sArmorMitigationByLvlGameTable, "ArmorMitigationByLvl.txt"); LOAD_GT(sArtifactLevelXPGameTable, "artifactLevelXP.txt"); LOAD_GT(sBarberShopCostBaseGameTable, "BarberShopCostBase.txt"); LOAD_GT(sBaseMPGameTable, "BaseMp.txt"); LOAD_GT(sCombatRatingsGameTable, "CombatRatings.txt"); LOAD_GT(sCombatRatingsMultByILvlGameTable, "CombatRatingsMultByILvl.txt"); LOAD_GT(sItemSocketCostPerLevelGameTable, "ItemSocketCostPerLevel.txt"); LOAD_GT(sHpPerStaGameTable, "HpPerSta.txt"); LOAD_GT(sNpcDamageByClassGameTable[0], "NpcDamageByClass.txt"); LOAD_GT(sNpcDamageByClassGameTable[1], "NpcDamageByClassExp1.txt"); LOAD_GT(sNpcDamageByClassGameTable[2], "NpcDamageByClassExp2.txt"); LOAD_GT(sNpcDamageByClassGameTable[3], "NpcDamageByClassExp3.txt"); LOAD_GT(sNpcDamageByClassGameTable[4], "NpcDamageByClassExp4.txt"); LOAD_GT(sNpcDamageByClassGameTable[5], "NpcDamageByClassExp5.txt"); LOAD_GT(sNpcDamageByClassGameTable[6], "NpcDamageByClassExp6.txt"); LOAD_GT(sNpcManaCostScalerGameTable, "NpcManaCostScaler.txt"); LOAD_GT(sNpcTotalHpGameTable[0], "NpcTotalHp.txt"); LOAD_GT(sNpcTotalHpGameTable[1], "NpcTotalHpExp1.txt"); LOAD_GT(sNpcTotalHpGameTable[2], "NpcTotalHpExp2.txt"); LOAD_GT(sNpcTotalHpGameTable[3], "NpcTotalHpExp3.txt"); LOAD_GT(sNpcTotalHpGameTable[4], "NpcTotalHpExp4.txt"); LOAD_GT(sNpcTotalHpGameTable[5], "NpcTotalHpExp5.txt"); LOAD_GT(sNpcTotalHpGameTable[6], "NpcTotalHpExp6.txt"); LOAD_GT(sSpellScalingGameTable, "SpellScaling.txt"); LOAD_GT(sXpGameTable, "xp.txt"); #undef LOAD_GT // error checks if (gameTableCount != expectedGameTableCount) { std::ostringstream str; for (std::string const& err : bad_gt_files) str << err << std::endl; WPFatal(false, "Some required *.txt GameTable files (" SZFMTD ") not found or not compatible:\n%s", bad_gt_files.size(), str.str().c_str()); } TC_LOG_INFO("server.loading", ">> Initialized %d GameTables in %u ms", gameTableCount, GetMSTimeDiffToNow(oldMSTime)); }
bool MySQLConnection::_HandleMySQLErrno(uint32 errNo) { switch (errNo) { case 2006: // "MySQL server has gone away" case 2013: // "Lost connection to MySQL server during query" case 2048: // "Invalid connection handle" case 2055: // "Lost connection to MySQL server at '%s', system error: %d" { m_reconnecting = true; uint64 oldThreadId = mysql_thread_id(GetHandle()); mysql_close(GetHandle()); if (this->Open()) // Don't remove 'this' pointer unless you want to skip loading all prepared statements.... { sLog->outSQLDriver("Connection to the MySQL server is active."); if (oldThreadId != mysql_thread_id(GetHandle())) sLog->outSQLDriver("Successfully reconnected to %s @%s:%s (%s).", m_connectionInfo.database.c_str(), m_connectionInfo.host.c_str(), m_connectionInfo.port_or_socket.c_str(), (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous"); m_reconnecting = false; return true; } uint32 lErrno = mysql_errno(GetHandle()); // It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here. ACE_OS::sleep(3); // Sleep 3 seconds return _HandleMySQLErrno(lErrno); // Call self (recursive) } case 1213: // "Deadlock found when trying to get lock; try restarting transaction" return false; // Implemented in TransactionTask::Execute and DatabaseWorkerPool<T>::DirectCommitTransaction // Query related errors - skip query case 1058: // "Column count doesn't match value count" case 1062: // "Duplicate entry '%s' for key '%d'" return false; // Outdated table or database structure - terminate core case 1054: // "Unknown column '%s' in '%s'" case 1146: // "Table '%s' doesn't exist" WPFatal(!errNo, "Your database structure is not up to date. Please make sure you've executed all queries in the sql/updates folders."); return false; default: sLog->outSQLDriver("Unhandled MySQL errno %u. Unexpected behaviour possible.", errNo); return false; } }
uint32 DatabaseWorkerPool<T>::Open() { WPFatal(_connectionInfo.get(), "Connection info was not set!"); TC_LOG_INFO("sql.driver", "Opening DatabasePool '%s'. " "Asynchronous connections: %u, synchronous connections: %u.", GetDatabaseName(), _async_threads, _synch_threads); uint32 error = OpenConnections(IDX_ASYNC, _async_threads); if (error) return error; error = OpenConnections(IDX_SYNCH, _synch_threads); if (!error) { TC_LOG_INFO("sql.driver", "DatabasePool '%s' opened successfully. " SZFMTD " total connections running.", GetDatabaseName(), (_connections[IDX_SYNCH].size() + _connections[IDX_ASYNC].size())); } return error; }