Seperate pools for essential tasks like profile loading and profile saving.

This commit is contained in:
t00thpick1 2014-08-19 17:57:52 -04:00
parent a23d093271
commit d8ad519cd0
3 changed files with 85 additions and 30 deletions

View File

@ -9,6 +9,7 @@ import org.bukkit.TreeSpecies;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import com.gmail.nossr50.database.SQLDatabaseManager.PoolIdentifier;
import com.gmail.nossr50.datatypes.MobHealthbarType; import com.gmail.nossr50.datatypes.MobHealthbarType;
import com.gmail.nossr50.datatypes.party.PartyFeature; import com.gmail.nossr50.datatypes.party.PartyFeature;
import com.gmail.nossr50.datatypes.skills.AbilityType; import com.gmail.nossr50.datatypes.skills.AbilityType;
@ -41,6 +42,16 @@ public class Config extends AutoUpdateConfigLoader {
reason.add("General.Save_Interval should be greater than 0!"); reason.add("General.Save_Interval should be greater than 0!");
} }
/* MySQL Settings */
for (PoolIdentifier identifier : PoolIdentifier.values()) {
if (getMySQLMaxConnections(identifier) <= 0) {
reason.add("MySQL.Database.MaxConnections." + StringUtils.getCapitalized(identifier.toString()) + " should be greater than 0!");
}
if (getMySQLMaxPoolSize(identifier) <= 0) {
reason.add("MySQL.Database.MaxPoolSize." + StringUtils.getCapitalized(identifier.toString()) + " should be greater than 0!");
}
}
/* Mob Healthbar */ /* Mob Healthbar */
if (getMobHealthbarTime() == 0) { if (getMobHealthbarTime() == 0) {
reason.add("Mob_Healthbar.Display_Time cannot be 0! Set to -1 to disable or set a valid value."); reason.add("Mob_Healthbar.Display_Time cannot be 0! Set to -1 to disable or set a valid value.");
@ -315,8 +326,8 @@ public class Config extends AutoUpdateConfigLoader {
public int getMySQLServerPort() { return config.getInt("MySQL.Server.Port", 3306); } public int getMySQLServerPort() { return config.getInt("MySQL.Server.Port", 3306); }
public String getMySQLServerName() { return config.getString("MySQL.Server.Address", "localhost"); } public String getMySQLServerName() { return config.getString("MySQL.Server.Address", "localhost"); }
public String getMySQLUserPassword() { return getStringIncludingInts("MySQL.Database.User_Password"); } public String getMySQLUserPassword() { return getStringIncludingInts("MySQL.Database.User_Password"); }
public int getMySQLMaxConnections() { return config.getInt("MySQL.Database.MaxConnections", 30); } public int getMySQLMaxConnections(PoolIdentifier identifier) { return config.getInt("MySQL.Database.MaxConnections." + StringUtils.getCapitalized(identifier.toString()), 30); }
public int getMySQLMaxPoolSize() { return config.getInt("MySQL.Database.MaxPoolSize", 20); } public int getMySQLMaxPoolSize(PoolIdentifier identifier) { return config.getInt("MySQL.Database.MaxPoolSize." + StringUtils.getCapitalized(identifier.toString()), 10); }
private String getStringIncludingInts(String key) { private String getStringIncludingInts(String key) {
String str = config.getString(key); String str = config.getString(key);

View File

@ -33,14 +33,15 @@ import snaq.db.ConnectionPool;
public final class SQLDatabaseManager implements DatabaseManager { public final class SQLDatabaseManager implements DatabaseManager {
private static final String ALL_QUERY_VERSION = "taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing+alchemy"; private static final String ALL_QUERY_VERSION = "taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing+alchemy";
private static final String S_ALL_QUERY_STRING = "s.taming+s.mining+s.woodcutting+s.repair+s.unarmed+s.herbalism+s.excavation+s.archery+s.swords+s.axes+s.acrobatics+s.fishing+s.alchemy";
private String tablePrefix = Config.getInstance().getMySQLTablePrefix(); private String tablePrefix = Config.getInstance().getMySQLTablePrefix();
private final int POOL_FETCH_TIMEOUT = 360000; private final int POOL_FETCH_TIMEOUT = 360000;
private final Map<UUID, Integer> cachedUserIDs = new HashMap<UUID, Integer>(); private final Map<UUID, Integer> cachedUserIDs = new HashMap<UUID, Integer>();
private ConnectionPool connectionPool; private ConnectionPool miscPool;
private ConnectionPool loadPool;
private ConnectionPool savePool;
private ReentrantLock massUpdateLock = new ReentrantLock(); private ReentrantLock massUpdateLock = new ReentrantLock();
@ -65,15 +66,33 @@ public final class SQLDatabaseManager implements DatabaseManager {
connectionProperties.put("prepStmtCacheSize", "64"); connectionProperties.put("prepStmtCacheSize", "64");
connectionProperties.put("prepStmtCacheSqlLimit", "2048"); connectionProperties.put("prepStmtCacheSqlLimit", "2048");
connectionProperties.put("useServerPrepStmts", "true"); connectionProperties.put("useServerPrepStmts", "true");
connectionPool = new ConnectionPool("mcMMO-Pool", miscPool = new ConnectionPool("mcMMO-Misc-Pool",
1 /*Minimum of one*/, 0 /*No Minimum really needed*/,
Config.getInstance().getMySQLMaxPoolSize() /*max pool size */, Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.MISC) /*max pool size */,
Config.getInstance().getMySQLMaxConnections() /*max num connections*/, Config.getInstance().getMySQLMaxConnections(PoolIdentifier.MISC) /*max num connections*/,
0 /* idle timeout of connections */, 0 /* idle timeout of connections */,
connectionString, connectionString,
connectionProperties); connectionProperties);
connectionPool.init(); // Init first connection loadPool = new ConnectionPool("mcMMO-Load-Pool",
connectionPool.registerShutdownHook(); // Auto release on jvm exit just in case 1 /*Minimum of one*/,
Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.LOAD) /*max pool size */,
Config.getInstance().getMySQLMaxConnections(PoolIdentifier.LOAD) /*max num connections*/,
0 /* idle timeout of connections */,
connectionString,
connectionProperties);
savePool = new ConnectionPool("mcMMO-Save-Pool",
1 /*Minimum of one*/,
Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.SAVE) /*max pool size */,
Config.getInstance().getMySQLMaxConnections(PoolIdentifier.SAVE) /*max num connections*/,
0 /* idle timeout of connections */,
connectionString,
connectionProperties);
miscPool.init(); // Init first connection
miscPool.registerShutdownHook(); // Auto release on jvm exit just in case
loadPool.init();
loadPool.registerShutdownHook();
savePool.init();
savePool.registerShutdownHook();
checkStructure(); checkStructure();
@ -88,7 +107,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
int purged = 0; int purged = 0;
try { try {
connection = getConnection(); connection = getConnection(PoolIdentifier.MISC);
statement = connection.createStatement(); statement = connection.createStatement();
purged = statement.executeUpdate("DELETE FROM " + tablePrefix + "skills WHERE " purged = statement.executeUpdate("DELETE FROM " + tablePrefix + "skills WHERE "
@ -137,7 +156,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
int purged = 0; int purged = 0;
try { try {
connection = getConnection(); connection = getConnection(PoolIdentifier.MISC);
statement = connection.createStatement(); statement = connection.createStatement();
purged = statement.executeUpdate("DELETE FROM u, e, h, s, c USING " + tablePrefix + "users u " + purged = statement.executeUpdate("DELETE FROM u, e, h, s, c USING " + tablePrefix + "users u " +
@ -179,7 +198,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
PreparedStatement statement = null; PreparedStatement statement = null;
try { try {
connection = getConnection(); connection = getConnection(PoolIdentifier.MISC);
statement = connection.prepareStatement("DELETE FROM u, e, h, s, c " + statement = connection.prepareStatement("DELETE FROM u, e, h, s, c " +
"USING " + tablePrefix + "users u " + "USING " + tablePrefix + "users u " +
"JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " + "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " +
@ -227,7 +246,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
Connection connection = null; Connection connection = null;
try { try {
connection = getConnection(); connection = getConnection(PoolIdentifier.SAVE);
int id = getUserID(connection, profile.getPlayerName(), profile.getUniqueId()); int id = getUserID(connection, profile.getPlayerName(), profile.getUniqueId());
@ -342,7 +361,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
Connection connection = null; Connection connection = null;
try { try {
connection = getConnection(); connection = getConnection(PoolIdentifier.MISC);
statement = connection.prepareStatement("SELECT " + query + ", user, NOW() FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 ORDER BY " + query + " DESC, user LIMIT ?, ?"); statement = connection.prepareStatement("SELECT " + query + ", user, NOW() FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 ORDER BY " + query + " DESC, user LIMIT ?, ?");
statement.setInt(1, (pageNumber * statsPerPage) - statsPerPage); statement.setInt(1, (pageNumber * statsPerPage) - statsPerPage);
statement.setInt(2, statsPerPage); statement.setInt(2, statsPerPage);
@ -399,7 +418,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
Connection connection = null; Connection connection = null;
try { try {
connection = getConnection(); connection = getConnection(PoolIdentifier.MISC);
for (SkillType skillType : SkillType.NON_CHILD_SKILLS) { for (SkillType skillType : SkillType.NON_CHILD_SKILLS) {
String skillName = skillType.name().toLowerCase(); String skillName = skillType.name().toLowerCase();
String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " + String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
@ -510,7 +529,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
Connection connection = null; Connection connection = null;
try { try {
connection = getConnection(); connection = getConnection(PoolIdentifier.MISC);
newUser(connection, playerName, uuid); newUser(connection, playerName, uuid);
} }
catch (SQLException ex) { catch (SQLException ex) {
@ -590,7 +609,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
ResultSet resultSet = null; ResultSet resultSet = null;
try { try {
connection = getConnection(); connection = getConnection(PoolIdentifier.LOAD);
int id = getUserID(connection, playerName, uuid); int id = getUserID(connection, playerName, uuid);
if (id == -1) { if (id == -1) {
@ -696,7 +715,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
ResultSet resultSet = null; ResultSet resultSet = null;
try { try {
connection = getConnection(); connection = getConnection(PoolIdentifier.MISC);
statement = connection.prepareStatement( statement = connection.prepareStatement(
"SELECT " "SELECT "
+ "s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, s.alchemy, " + "s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, s.alchemy, "
@ -764,7 +783,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
Connection connection = null; Connection connection = null;
try { try {
connection = getConnection(); connection = getConnection(PoolIdentifier.MISC);
statement = connection.prepareStatement( statement = connection.prepareStatement(
"UPDATE `" + tablePrefix + "users` SET " "UPDATE `" + tablePrefix + "users` SET "
+ " uuid = ? WHERE user = ?"); + " uuid = ? WHERE user = ?");
@ -804,7 +823,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
Connection connection = null; Connection connection = null;
try { try {
connection = getConnection(); connection = getConnection(PoolIdentifier.MISC);
statement = connection.prepareStatement("UPDATE " + tablePrefix + "users SET uuid = ? WHERE user = ?"); statement = connection.prepareStatement("UPDATE " + tablePrefix + "users SET uuid = ? WHERE user = ?");
for (Map.Entry<String, UUID> entry : fetchedUUIDs.entrySet()) { for (Map.Entry<String, UUID> entry : fetchedUUIDs.entrySet()) {
@ -859,7 +878,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
ResultSet resultSet = null; ResultSet resultSet = null;
try { try {
connection = getConnection(); connection = getConnection(PoolIdentifier.MISC);
statement = connection.createStatement(); statement = connection.createStatement();
resultSet = statement.executeQuery("SELECT user FROM " + tablePrefix + "users"); resultSet = statement.executeQuery("SELECT user FROM " + tablePrefix + "users");
while (resultSet.next()) { while (resultSet.next()) {
@ -910,7 +929,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
Connection connection = null; Connection connection = null;
try { try {
connection = getConnection(); connection = getConnection(PoolIdentifier.MISC);
statement = connection.prepareStatement("SELECT table_name FROM INFORMATION_SCHEMA.TABLES" statement = connection.prepareStatement("SELECT table_name FROM INFORMATION_SCHEMA.TABLES"
+ " WHERE table_schema = ?" + " WHERE table_schema = ?"
+ " AND table_name = ?"); + " AND table_name = ?");
@ -1070,10 +1089,21 @@ public final class SQLDatabaseManager implements DatabaseManager {
} }
private Connection getConnection() throws SQLException { private Connection getConnection(PoolIdentifier identifier) throws SQLException {
Connection connection = connectionPool.getConnection(POOL_FETCH_TIMEOUT); Connection connection = null;
switch (identifier) {
case LOAD:
connection = loadPool.getConnection(POOL_FETCH_TIMEOUT);
break;
case MISC:
connection = miscPool.getConnection(POOL_FETCH_TIMEOUT);
break;
case SAVE:
connection = savePool.getConnection(POOL_FETCH_TIMEOUT);
break;
}
if (connection == null) { if (connection == null) {
throw new RuntimeException("getConnection() timed out. Increase max connections settings."); throw new RuntimeException("getConnection() for " + identifier.name().toLowerCase() + " pool timed out. Increase max connections settings.");
} }
return connection; return connection;
} }
@ -1399,7 +1429,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
ResultSet resultSet = null; ResultSet resultSet = null;
try { try {
try { try {
connection = connectionPool.getConnection(); connection = miscPool.getConnection();
statement = connection.createStatement(); statement = connection.createStatement();
resultSet = statement.executeQuery("SELECT `user` FROM `" + tablePrefix + "users` WHERE `uuid` IS NULL"); resultSet = statement.executeQuery("SELECT `user` FROM `" + tablePrefix + "users` WHERE `uuid` IS NULL");
@ -1563,6 +1593,14 @@ public final class SQLDatabaseManager implements DatabaseManager {
@Override @Override
public void onDisable() { public void onDisable() {
mcMMO.p.debug("Releasing connection pool resource..."); mcMMO.p.debug("Releasing connection pool resource...");
connectionPool.release(); miscPool.release();
loadPool.release();
savePool.release();
}
public enum PoolIdentifier {
MISC,
LOAD,
SAVE;
} }
} }

View File

@ -131,10 +131,16 @@ MySQL:
TablePrefix: mcmmo_ TablePrefix: mcmmo_
# This setting is the max simultaneous mysql connections allowed at a time, needs to be # This setting is the max simultaneous mysql connections allowed at a time, needs to be
# high enough to support multiple player logins in quick succession # high enough to support multiple player logins in quick succession
MaxConnections: 30 MaxConnections:
Misc: 30
Load: 30
Save: 30
# This setting is the max size of the pool of cached connections that we hold available # This setting is the max size of the pool of cached connections that we hold available
# at any given time # at any given time
MaxPoolSize: 20 MaxPoolSize:
Misc: 10
Load: 20
Save: 20
Server: Server:
Port: 3306 Port: 3306
Address: localhost Address: localhost