* Introduce experimental wait timeout checking to mysql region datastore code * This should mean that if the mysql connection has timed out, we should automatically reconnect and not fail or drop queries on region database manipulations0.6.0-stable
parent
7917398451
commit
31c63558c8
|
@ -191,7 +191,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString()
|
"[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString()
|
||||||
+ Environment.NewLine + "Attempting reconnection", assetID);
|
+ Environment.NewLine + "Reconnecting", assetID);
|
||||||
_dbConnection.Reconnect();
|
_dbConnection.Reconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,19 +54,32 @@ namespace OpenSim.Data.MySQL
|
||||||
private const string m_landSelect = "select * from land";
|
private const string m_landSelect = "select * from land";
|
||||||
private const string m_landAccessListSelect = "select * from landaccesslist";
|
private const string m_landAccessListSelect = "select * from landaccesslist";
|
||||||
private const string m_regionBanListSelect = "select * from regionban";
|
private const string m_regionBanListSelect = "select * from regionban";
|
||||||
private const string m_regionSettingsSelect = "select * from regionsettings";
|
private const string m_regionSettingsSelect = "select * from regionsettings";
|
||||||
|
private const string m_waitTimeoutSelect = "select @@wait_timeout";
|
||||||
|
|
||||||
|
private MySqlConnection m_connection;
|
||||||
|
private string m_connectionString;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// We're only using this to version the table!
|
/// Wait timeout for our connection in ticks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
private long m_waitTimeout;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make our storage of the timeout this amount smaller than it actually is, to give us a margin on long
|
||||||
|
/// running database operations.
|
||||||
|
/// </summary>
|
||||||
|
private long m_waitTimeoutLeeway = 60 * TimeSpan.TicksPerSecond;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Holds the last tick time that the connection was used.
|
||||||
|
/// </summary>
|
||||||
|
private long m_lastConnectionUse;
|
||||||
|
|
||||||
private DataSet m_dataSet;
|
private DataSet m_dataSet;
|
||||||
private MySqlDataAdapter m_primDataAdapter;
|
private MySqlDataAdapter m_primDataAdapter;
|
||||||
private MySqlDataAdapter m_shapeDataAdapter;
|
private MySqlDataAdapter m_shapeDataAdapter;
|
||||||
private MySqlDataAdapter m_itemsDataAdapter;
|
private MySqlDataAdapter m_itemsDataAdapter;
|
||||||
private MySqlConnection m_connection;
|
|
||||||
private MySqlDataAdapter m_terrainDataAdapter;
|
private MySqlDataAdapter m_terrainDataAdapter;
|
||||||
private MySqlDataAdapter m_landDataAdapter;
|
private MySqlDataAdapter m_landDataAdapter;
|
||||||
private MySqlDataAdapter m_landAccessListDataAdapter;
|
private MySqlDataAdapter m_landAccessListDataAdapter;
|
||||||
|
@ -96,14 +109,18 @@ namespace OpenSim.Data.MySQL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="connectionstring"></param>
|
/// <param name="connectionstring"></param>
|
||||||
/// <param name="persistPrimInventories"></param>
|
/// <param name="persistPrimInventories"></param>
|
||||||
public void Initialise(string connectionstring, bool persistPrimInventories)
|
public void Initialise(string connectionString, bool persistPrimInventories)
|
||||||
{
|
{
|
||||||
|
m_connectionString = connectionString;
|
||||||
|
|
||||||
m_dataSet = new DataSet();
|
m_dataSet = new DataSet();
|
||||||
this.persistPrimInventories = persistPrimInventories;
|
this.persistPrimInventories = persistPrimInventories;
|
||||||
|
|
||||||
m_log.Info("[REGION DB]: MySql - connecting: " + connectionstring);
|
m_log.Info("[REGION DB]: MySql - connecting: " + m_connectionString);
|
||||||
m_connection = new MySqlConnection(connectionstring);
|
m_connection = new MySqlConnection(m_connectionString);
|
||||||
m_connection.Open();
|
m_connection.Open();
|
||||||
|
|
||||||
|
GetWaitTimeout();
|
||||||
|
|
||||||
// This actually does the roll forward assembly stuff
|
// This actually does the roll forward assembly stuff
|
||||||
Assembly assem = GetType().Assembly;
|
Assembly assem = GetType().Assembly;
|
||||||
|
@ -115,7 +132,6 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
m.Update();
|
m.Update();
|
||||||
|
|
||||||
|
|
||||||
MySqlCommand primSelectCmd = new MySqlCommand(m_primSelect, m_connection);
|
MySqlCommand primSelectCmd = new MySqlCommand(m_primSelect, m_connection);
|
||||||
m_primDataAdapter = new MySqlDataAdapter(primSelectCmd);
|
m_primDataAdapter = new MySqlDataAdapter(primSelectCmd);
|
||||||
|
|
||||||
|
@ -187,6 +203,58 @@ namespace OpenSim.Data.MySQL
|
||||||
m_regionSettingsDataAdapter.Fill(m_regionSettingsTable);
|
m_regionSettingsDataAdapter.Fill(m_regionSettingsTable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the wait_timeout value for our connection
|
||||||
|
/// </summary>
|
||||||
|
protected void GetWaitTimeout()
|
||||||
|
{
|
||||||
|
MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, m_connection);
|
||||||
|
|
||||||
|
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||||
|
{
|
||||||
|
if (dbReader.Read())
|
||||||
|
{
|
||||||
|
m_waitTimeout
|
||||||
|
= Convert.ToInt32(dbReader["@@wait_timeout"]) * TimeSpan.TicksPerSecond + m_waitTimeoutLeeway;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbReader.Close();
|
||||||
|
cmd.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lastConnectionUse = System.DateTime.Now.Ticks;
|
||||||
|
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[REGION DB]: Connection wait timeout {0} seconds", m_waitTimeout / TimeSpan.TicksPerSecond);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should be called before any db operation. This checks to see if the connection has not timed out
|
||||||
|
/// </summary>
|
||||||
|
protected void CheckConnection()
|
||||||
|
{
|
||||||
|
//m_log.Debug("[REGION DB]: Checking connection");
|
||||||
|
|
||||||
|
long timeNow = System.DateTime.Now.Ticks;
|
||||||
|
if (timeNow - m_lastConnectionUse > m_waitTimeout || m_connection.State != ConnectionState.Open)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[REGION DB]: Database connection has gone away - reconnecting");
|
||||||
|
|
||||||
|
lock (m_connection)
|
||||||
|
{
|
||||||
|
m_connection.Close();
|
||||||
|
m_connection = new MySqlConnection(m_connectionString);
|
||||||
|
m_connection.Open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strictly, we should set this after the actual db operation. But it's more convenient to set here rather
|
||||||
|
// than require the code to call another method - the timeout leeway should be large enough to cover the
|
||||||
|
// inaccuracy.
|
||||||
|
m_lastConnectionUse = timeNow;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Given a list of tables, return the version of the tables, as seen in the database
|
/// Given a list of tables, return the version of the tables, as seen in the database
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -201,6 +269,8 @@ namespace OpenSim.Data.MySQL
|
||||||
"SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?dbname",
|
"SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?dbname",
|
||||||
dbcon);
|
dbcon);
|
||||||
tablesCmd.Parameters.AddWithValue("?dbname", dbcon.Database);
|
tablesCmd.Parameters.AddWithValue("?dbname", dbcon.Database);
|
||||||
|
|
||||||
|
CheckConnection();
|
||||||
using (MySqlDataReader tables = tablesCmd.ExecuteReader())
|
using (MySqlDataReader tables = tablesCmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
while (tables.Read())
|
while (tables.Read())
|
||||||
|
@ -396,6 +466,7 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
lock (m_dataSet)
|
lock (m_dataSet)
|
||||||
{
|
{
|
||||||
|
CheckConnection();
|
||||||
DataRow[] primsForRegion = prims.Select(byRegion, orderByParent);
|
DataRow[] primsForRegion = prims.Select(byRegion, orderByParent);
|
||||||
m_log.Info("[REGION DB]: " +
|
m_log.Info("[REGION DB]: " +
|
||||||
"Loaded " + primsForRegion.Length + " prims for region: " + regionUUID);
|
"Loaded " + primsForRegion.Length + " prims for region: " + regionUUID);
|
||||||
|
@ -473,6 +544,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
lock (m_dataSet)
|
lock (m_dataSet)
|
||||||
{
|
{
|
||||||
|
CheckConnection();
|
||||||
//m_log.InfoFormat("[DATASTORE]: Loading inventory for {0}, {1}", prim.Name, prim.UUID);
|
//m_log.InfoFormat("[DATASTORE]: Loading inventory for {0}, {1}", prim.Name, prim.UUID);
|
||||||
|
|
||||||
DataTable dbItems = m_itemsTable;
|
DataTable dbItems = m_itemsTable;
|
||||||
|
@ -519,6 +591,8 @@ namespace OpenSim.Data.MySQL
|
||||||
using (cmd)
|
using (cmd)
|
||||||
{
|
{
|
||||||
delete.Parameters.Add(new MySqlParameter("?RegionUUID", Util.ToRawUuidString(regionID)));
|
delete.Parameters.Add(new MySqlParameter("?RegionUUID", Util.ToRawUuidString(regionID)));
|
||||||
|
|
||||||
|
CheckConnection();
|
||||||
delete.ExecuteNonQuery();
|
delete.ExecuteNonQuery();
|
||||||
|
|
||||||
cmd.Parameters.Add(new MySqlParameter("?RegionUUID", Util.ToRawUuidString(regionID)));
|
cmd.Parameters.Add(new MySqlParameter("?RegionUUID", Util.ToRawUuidString(regionID)));
|
||||||
|
@ -554,6 +628,7 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
lock (m_dataSet)
|
lock (m_dataSet)
|
||||||
{
|
{
|
||||||
|
CheckConnection();
|
||||||
using (MySqlDataReader row = cmd.ExecuteReader())
|
using (MySqlDataReader row = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
int rev = 0;
|
int rev = 0;
|
||||||
|
@ -593,6 +668,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
lock (m_dataSet)
|
lock (m_dataSet)
|
||||||
{
|
{
|
||||||
|
CheckConnection();
|
||||||
using (MySqlCommand cmd = new MySqlCommand("delete from land where UUID=?UUID", m_connection))
|
using (MySqlCommand cmd = new MySqlCommand("delete from land where UUID=?UUID", m_connection))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(new MySqlParameter("?UUID", Util.ToRawUuidString(globalID)));
|
cmd.Parameters.Add(new MySqlParameter("?UUID", Util.ToRawUuidString(globalID)));
|
||||||
|
@ -616,6 +692,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
lock (m_dataSet)
|
lock (m_dataSet)
|
||||||
{
|
{
|
||||||
|
CheckConnection();
|
||||||
DataTable land = m_landTable;
|
DataTable land = m_landTable;
|
||||||
DataTable landaccesslist = m_landAccessListTable;
|
DataTable landaccesslist = m_landAccessListTable;
|
||||||
|
|
||||||
|
@ -654,6 +731,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
lock(m_dataSet)
|
lock(m_dataSet)
|
||||||
{
|
{
|
||||||
|
CheckConnection();
|
||||||
DataTable regionsettings = m_regionSettingsTable;
|
DataTable regionsettings = m_regionSettingsTable;
|
||||||
string searchExp = "regionUUID = '" + regionUUID.ToString() + "'";
|
string searchExp = "regionUUID = '" + regionUUID.ToString() + "'";
|
||||||
DataRow[] rawsettings = regionsettings.Select(searchExp);
|
DataRow[] rawsettings = regionsettings.Select(searchExp);
|
||||||
|
@ -669,6 +747,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
lock (m_dataSet)
|
lock (m_dataSet)
|
||||||
{
|
{
|
||||||
|
CheckConnection();
|
||||||
DataTable regionsettings = m_dataSet.Tables["regionsettings"];
|
DataTable regionsettings = m_dataSet.Tables["regionsettings"];
|
||||||
|
|
||||||
DataRow settingsRow = regionsettings.Rows.Find(rs.RegionUUID.ToString());
|
DataRow settingsRow = regionsettings.Rows.Find(rs.RegionUUID.ToString());
|
||||||
|
@ -695,6 +774,7 @@ namespace OpenSim.Data.MySQL
|
||||||
List<RegionBanListItem> regionbanlist = new List<RegionBanListItem>();
|
List<RegionBanListItem> regionbanlist = new List<RegionBanListItem>();
|
||||||
lock (m_dataSet)
|
lock (m_dataSet)
|
||||||
{
|
{
|
||||||
|
CheckConnection();
|
||||||
DataTable regionban = m_regionBanListTable;
|
DataTable regionban = m_regionBanListTable;
|
||||||
string searchExp = "regionUUID = '" + regionUUID.ToString() + "'";
|
string searchExp = "regionUUID = '" + regionUUID.ToString() + "'";
|
||||||
DataRow[] rawbanlist = regionban.Select(searchExp);
|
DataRow[] rawbanlist = regionban.Select(searchExp);
|
||||||
|
@ -724,6 +804,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
lock (m_dataSet)
|
lock (m_dataSet)
|
||||||
{
|
{
|
||||||
|
CheckConnection();
|
||||||
DataTable regionban = m_regionBanListTable;
|
DataTable regionban = m_regionBanListTable;
|
||||||
string searchExp = "regionUUID = '" + item.regionUUID.ToString() + "' AND bannedUUID = '" + item.bannedUUID.ToString() + "'";
|
string searchExp = "regionUUID = '" + item.regionUUID.ToString() + "' AND bannedUUID = '" + item.bannedUUID.ToString() + "'";
|
||||||
DataRow[] rawbanlist = regionban.Select(searchExp);
|
DataRow[] rawbanlist = regionban.Select(searchExp);
|
||||||
|
@ -748,6 +829,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
lock (m_dataSet)
|
lock (m_dataSet)
|
||||||
{
|
{
|
||||||
|
CheckConnection();
|
||||||
DataTable regionban = m_regionBanListTable;
|
DataTable regionban = m_regionBanListTable;
|
||||||
string searchExp = "regionUUID = '" + item.regionUUID.ToString() + "' AND bannedUUID = '" + item.bannedUUID.ToString() + "'";
|
string searchExp = "regionUUID = '" + item.regionUUID.ToString() + "' AND bannedUUID = '" + item.bannedUUID.ToString() + "'";
|
||||||
DataRow[] rawbanlist = regionban.Select(searchExp);
|
DataRow[] rawbanlist = regionban.Select(searchExp);
|
||||||
|
@ -760,10 +842,6 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
Commit();
|
Commit();
|
||||||
}
|
}
|
||||||
if (m_connection.State != ConnectionState.Open)
|
|
||||||
{
|
|
||||||
m_connection.Open();
|
|
||||||
}
|
|
||||||
|
|
||||||
using
|
using
|
||||||
(
|
(
|
||||||
|
@ -773,6 +851,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(new MySqlParameter("?regionUUID", item.regionUUID.ToString()));
|
cmd.Parameters.Add(new MySqlParameter("?regionUUID", item.regionUUID.ToString()));
|
||||||
cmd.Parameters.Add(new MySqlParameter("?bannedUUID", item.bannedUUID.ToString()));
|
cmd.Parameters.Add(new MySqlParameter("?bannedUUID", item.bannedUUID.ToString()));
|
||||||
|
CheckConnection();
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -788,6 +867,7 @@ namespace OpenSim.Data.MySQL
|
||||||
List<LandData> landDataForRegion = new List<LandData>();
|
List<LandData> landDataForRegion = new List<LandData>();
|
||||||
lock (m_dataSet)
|
lock (m_dataSet)
|
||||||
{
|
{
|
||||||
|
CheckConnection();
|
||||||
DataTable land = m_landTable;
|
DataTable land = m_landTable;
|
||||||
DataTable landaccesslist = m_landAccessListTable;
|
DataTable landaccesslist = m_landAccessListTable;
|
||||||
string searchExp = "RegionUUID = '" + Util.ToRawUuidString(regionUUID) + "'";
|
string searchExp = "RegionUUID = '" + Util.ToRawUuidString(regionUUID) + "'";
|
||||||
|
@ -813,13 +893,9 @@ namespace OpenSim.Data.MySQL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Commit()
|
public void Commit()
|
||||||
{
|
{
|
||||||
if (m_connection.State != ConnectionState.Open)
|
|
||||||
{
|
|
||||||
m_connection.Open();
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (m_dataSet)
|
lock (m_dataSet)
|
||||||
{
|
{
|
||||||
|
CheckConnection();
|
||||||
// DisplayDataSet(m_dataSet, "Region DataSet");
|
// DisplayDataSet(m_dataSet, "Region DataSet");
|
||||||
|
|
||||||
m_primDataAdapter.Update(m_primTable);
|
m_primDataAdapter.Update(m_primTable);
|
||||||
|
|
Loading…
Reference in New Issue