aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Data/MySQL/MySQLGridData.cs198
-rw-r--r--OpenSim/Data/MySQL/MySQLManager.cs2
-rw-r--r--OpenSim/Data/MySQL/MySQLSuperManager.cs9
3 files changed, 140 insertions, 69 deletions
diff --git a/OpenSim/Data/MySQL/MySQLGridData.cs b/OpenSim/Data/MySQL/MySQLGridData.cs
index fcbceb8..9dc3d18 100644
--- a/OpenSim/Data/MySQL/MySQLGridData.cs
+++ b/OpenSim/Data/MySQL/MySQLGridData.cs
@@ -29,8 +29,6 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Data; 30using System.Data;
31using System.Reflection; 31using System.Reflection;
32using System.Security.Cryptography;
33using System.Text;
34using libsecondlife; 32using libsecondlife;
35using log4net; 33using log4net;
36using OpenSim.Framework; 34using OpenSim.Framework;
@@ -49,6 +47,45 @@ namespace OpenSim.Data.MySQL
49 /// </summary> 47 /// </summary>
50 private MySQLManager database; 48 private MySQLManager database;
51 49
50
51 /// <summary>
52 /// Better DB manager. Swap-in replacement too.
53 /// </summary>
54 public Dictionary<int, MySQLSuperManager> m_dbconnections = new Dictionary<int, MySQLSuperManager>();
55
56 public int m_maxConnections = 10;
57 public int m_lastConnect;
58
59 public MySQLSuperManager GetLockedConnection()
60 {
61 int lockedCons = 0;
62 while (true)
63 {
64 m_lastConnect++;
65
66 // Overflow protection
67 if (m_lastConnect == int.MaxValue)
68 m_lastConnect = 0;
69
70 MySQLSuperManager x = m_dbconnections[m_lastConnect % m_maxConnections];
71 if (!x.Locked)
72 {
73 x.GetLock();
74 return x;
75 }
76
77 lockedCons++;
78 if (lockedCons > m_maxConnections)
79 {
80 lockedCons = 0;
81 System.Threading.Thread.Sleep(1000); // Wait some time before searching them again.
82 m_log.Debug(
83 "WARNING: All threads are in use. Probable cause: Something didnt release a mutex properly, or high volume of requests inbound.");
84 }
85 }
86 }
87
88
52 override public void Initialise() 89 override public void Initialise()
53 { 90 {
54 m_log.Info("[MySQLGridData]: " + Name + " cannot be default-initialized!"); 91 m_log.Info("[MySQLGridData]: " + Name + " cannot be default-initialized!");
@@ -71,6 +108,16 @@ namespace OpenSim.Data.MySQL
71 if (connect != String.Empty) 108 if (connect != String.Empty)
72 { 109 {
73 database = new MySQLManager(connect); 110 database = new MySQLManager(connect);
111
112 m_log.Info("Creating " + m_maxConnections + " DB connections...");
113 for (int i = 0; i < m_maxConnections; i++)
114 {
115 m_log.Info("Connecting to DB... [" + i + "]");
116 MySQLSuperManager msm = new MySQLSuperManager();
117 msm.Manager = new MySQLManager(connect);
118 m_dbconnections.Add(i, msm);
119 }
120
74 } 121 }
75 else 122 else
76 { 123 {
@@ -85,6 +132,16 @@ namespace OpenSim.Data.MySQL
85 132
86 database = new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, 133 database = new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword,
87 settingPooling, settingPort); 134 settingPooling, settingPort);
135
136 m_log.Info("Creating " + m_maxConnections + " DB connections...");
137 for (int i = 0; i < m_maxConnections; i++)
138 {
139 m_log.Info("Connecting to DB... [" + i + "]");
140 MySQLSuperManager msm = new MySQLSuperManager();
141 msm.Manager = new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword,
142 settingPooling, settingPort);
143 m_dbconnections.Add(i, msm);
144 }
88 } 145 }
89 146
90 // This actually does the roll forward assembly stuff 147 // This actually does the roll forward assembly stuff
@@ -184,10 +241,10 @@ namespace OpenSim.Data.MySQL
184 /// <returns>Array of sim profiles</returns> 241 /// <returns>Array of sim profiles</returns>
185 override public RegionProfileData[] GetProfilesInRange(uint xmin, uint ymin, uint xmax, uint ymax) 242 override public RegionProfileData[] GetProfilesInRange(uint xmin, uint ymin, uint xmax, uint ymax)
186 { 243 {
244 MySQLSuperManager dbm = GetLockedConnection();
245
187 try 246 try
188 { 247 {
189 lock (database)
190 {
191 Dictionary<string, string> param = new Dictionary<string, string>(); 248 Dictionary<string, string> param = new Dictionary<string, string>();
192 param["?xmin"] = xmin.ToString(); 249 param["?xmin"] = xmin.ToString();
193 param["?ymin"] = ymin.ToString(); 250 param["?ymin"] = ymin.ToString();
@@ -195,7 +252,7 @@ namespace OpenSim.Data.MySQL
195 param["?ymax"] = ymax.ToString(); 252 param["?ymax"] = ymax.ToString();
196 253
197 IDbCommand result = 254 IDbCommand result =
198 database.Query( 255 dbm.Manager.Query(
199 "SELECT * FROM regions WHERE locX >= ?xmin AND locX <= ?xmax AND locY >= ?ymin AND locY <= ?ymax", 256 "SELECT * FROM regions WHERE locX >= ?xmin AND locX <= ?xmax AND locY >= ?ymin AND locY <= ?ymax",
200 param); 257 param);
201 IDataReader reader = result.ExecuteReader(); 258 IDataReader reader = result.ExecuteReader();
@@ -204,7 +261,7 @@ namespace OpenSim.Data.MySQL
204 261
205 List<RegionProfileData> rows = new List<RegionProfileData>(); 262 List<RegionProfileData> rows = new List<RegionProfileData>();
206 263
207 while ((row = database.readSimRow(reader)) != null) 264 while ((row = dbm.Manager.readSimRow(reader)) != null)
208 { 265 {
209 rows.Add(row); 266 rows.Add(row);
210 } 267 }
@@ -212,14 +269,17 @@ namespace OpenSim.Data.MySQL
212 result.Dispose(); 269 result.Dispose();
213 270
214 return rows.ToArray(); 271 return rows.ToArray();
215 }
216 } 272 }
217 catch (Exception e) 273 catch (Exception e)
218 { 274 {
219 database.Reconnect(); 275 dbm.Manager.Reconnect();
220 m_log.Error(e.ToString()); 276 m_log.Error(e.ToString());
221 return null; 277 return null;
222 } 278 }
279 finally
280 {
281 dbm.Release();
282 }
223 } 283 }
224 284
225 /// <summary> 285 /// <summary>
@@ -229,29 +289,32 @@ namespace OpenSim.Data.MySQL
229 /// <returns>Sim profile</returns> 289 /// <returns>Sim profile</returns>
230 override public RegionProfileData GetProfileByHandle(ulong handle) 290 override public RegionProfileData GetProfileByHandle(ulong handle)
231 { 291 {
292 MySQLSuperManager dbm = GetLockedConnection();
293
232 try 294 try
233 { 295 {
234 lock (database)
235 {
236 Dictionary<string, string> param = new Dictionary<string, string>(); 296 Dictionary<string, string> param = new Dictionary<string, string>();
237 param["?handle"] = handle.ToString(); 297 param["?handle"] = handle.ToString();
238 298
239 IDbCommand result = database.Query("SELECT * FROM regions WHERE regionHandle = ?handle", param); 299 IDbCommand result = dbm.Manager.Query("SELECT * FROM regions WHERE regionHandle = ?handle", param);
240 IDataReader reader = result.ExecuteReader(); 300 IDataReader reader = result.ExecuteReader();
241 301
242 RegionProfileData row = database.readSimRow(reader); 302 RegionProfileData row = dbm.Manager.readSimRow(reader);
243 reader.Close(); 303 reader.Close();
244 result.Dispose(); 304 result.Dispose();
245 305
246 return row; 306 return row;
247 } 307 }
248 }
249 catch (Exception e) 308 catch (Exception e)
250 { 309 {
251 database.Reconnect(); 310 dbm.Manager.Reconnect();
252 m_log.Error(e.ToString()); 311 m_log.Error(e.ToString());
253 return null; 312 return null;
254 } 313 }
314 finally
315 {
316 dbm.Release();
317 }
255 } 318 }
256 319
257 /// <summary> 320 /// <summary>
@@ -261,70 +324,76 @@ namespace OpenSim.Data.MySQL
261 /// <returns>The sim profile</returns> 324 /// <returns>The sim profile</returns>
262 override public RegionProfileData GetProfileByLLUUID(LLUUID uuid) 325 override public RegionProfileData GetProfileByLLUUID(LLUUID uuid)
263 { 326 {
327 MySQLSuperManager dbm = GetLockedConnection();
328
264 try 329 try
265 { 330 {
266 lock (database)
267 {
268 Dictionary<string, string> param = new Dictionary<string, string>(); 331 Dictionary<string, string> param = new Dictionary<string, string>();
269 param["?uuid"] = uuid.ToString(); 332 param["?uuid"] = uuid.ToString();
270 333
271 IDbCommand result = database.Query("SELECT * FROM regions WHERE uuid = ?uuid", param); 334 IDbCommand result = dbm.Manager.Query("SELECT * FROM regions WHERE uuid = ?uuid", param);
272 IDataReader reader = result.ExecuteReader(); 335 IDataReader reader = result.ExecuteReader();
273 336
274 RegionProfileData row = database.readSimRow(reader); 337 RegionProfileData row = dbm.Manager.readSimRow(reader);
275 reader.Close(); 338 reader.Close();
276 result.Dispose(); 339 result.Dispose();
277 340
278 return row; 341 return row;
279 } 342 }
280 }
281 catch (Exception e) 343 catch (Exception e)
282 { 344 {
283 database.Reconnect(); 345 dbm.Manager.Reconnect();
284 m_log.Error(e.ToString()); 346 m_log.Error(e.ToString());
285 return null; 347 return null;
348 } finally
349 {
350 dbm.Release();
286 } 351 }
287 } 352 }
288 353
289 /// <summary> 354 /// <summary>
290 /// Returns a sim profile from it's Region name string 355 /// Returns a sim profile from it's Region name string
291 /// </summary> 356 /// </summary>
292 /// <param name="uuid">The region name search query</param>
293 /// <returns>The sim profile</returns> 357 /// <returns>The sim profile</returns>
294 override public RegionProfileData GetProfileByString(string regionName) 358 override public RegionProfileData GetProfileByString(string regionName)
295 { 359 {
360 MySQLSuperManager dbm = GetLockedConnection();
361
296 if (regionName.Length > 2) 362 if (regionName.Length > 2)
297 { 363 {
298 try 364 try
299 { 365 {
300 lock (database) 366 Dictionary<string, string> param = new Dictionary<string, string>();
301 { 367 // Add % because this is a like query.
302 Dictionary<string, string> param = new Dictionary<string, string>(); 368 param["?regionName"] = regionName + "%";
303 // Add % because this is a like query. 369 // Order by statement will return shorter matches first. Only returns one record or no record.
304 param["?regionName"] = regionName + "%"; 370 IDbCommand result =
305 // Order by statement will return shorter matches first. Only returns one record or no record. 371 dbm.Manager.Query(
306 IDbCommand result = database.Query("SELECT * FROM regions WHERE regionName like ?regionName order by LENGTH(regionName) asc LIMIT 1", param); 372 "SELECT * FROM regions WHERE regionName like ?regionName order by LENGTH(regionName) asc LIMIT 1",
307 IDataReader reader = result.ExecuteReader(); 373 param);
308 374 IDataReader reader = result.ExecuteReader();
309 RegionProfileData row = database.readSimRow(reader); 375
310 reader.Close(); 376 RegionProfileData row = dbm.Manager.readSimRow(reader);
311 result.Dispose(); 377 reader.Close();
312 378 result.Dispose();
313 return row; 379
314 } 380 return row;
315 } 381 }
316 catch (Exception e) 382 catch (Exception e)
317 { 383 {
318 database.Reconnect(); 384 dbm.Manager.Reconnect();
319 m_log.Error(e.ToString()); 385 m_log.Error(e.ToString());
320 return null; 386 return null;
321 } 387 }
388 finally
389 {
390 dbm.Release();
391
392 }
322 } 393 }
323 else 394 dbm.Release();
324 { 395 m_log.Error("[GRID DB]: Searched for a Region Name shorter then 3 characters");
325 m_log.Error("[GRID DB]: Searched for a Region Name shorter then 3 characters"); 396 return null;
326 return null;
327 }
328 } 397 }
329 398
330 /// <summary> 399 /// <summary>
@@ -334,16 +403,17 @@ namespace OpenSim.Data.MySQL
334 /// <returns>Successful?</returns> 403 /// <returns>Successful?</returns>
335 override public DataResponse AddProfile(RegionProfileData profile) 404 override public DataResponse AddProfile(RegionProfileData profile)
336 { 405 {
337 lock (database) 406 MySQLSuperManager dbm = GetLockedConnection();
338 { 407 try {
339 if (database.insertRegion(profile)) 408 if (dbm.Manager.insertRegion(profile))
340 { 409 {
341 return DataResponse.RESPONSE_OK; 410 return DataResponse.RESPONSE_OK;
342 } 411 }
343 else 412 return DataResponse.RESPONSE_ERROR;
344 { 413 }
345 return DataResponse.RESPONSE_ERROR; 414 finally
346 } 415 {
416 dbm.Release();
347 } 417 }
348 } 418 }
349 419
@@ -366,16 +436,18 @@ namespace OpenSim.Data.MySQL
366 //public DataResponse DeleteProfile(RegionProfileData profile) 436 //public DataResponse DeleteProfile(RegionProfileData profile)
367 public DataResponse DeleteProfile(string uuid) 437 public DataResponse DeleteProfile(string uuid)
368 { 438 {
369 lock (database) 439 MySQLSuperManager dbm = GetLockedConnection();
370 { 440
371 if (database.deleteRegion(uuid)) 441
442 try {
443 if (dbm.Manager.deleteRegion(uuid))
372 { 444 {
373 return DataResponse.RESPONSE_OK; 445 return DataResponse.RESPONSE_OK;
374 } 446 }
375 else 447 return DataResponse.RESPONSE_ERROR;
376 { 448 } finally
377 return DataResponse.RESPONSE_ERROR; 449 {
378 } 450 dbm.Release();
379 } 451 }
380 } 452 }
381 453
@@ -426,31 +498,33 @@ namespace OpenSim.Data.MySQL
426 /// <returns></returns> 498 /// <returns></returns>
427 override public ReservationData GetReservationAtPoint(uint x, uint y) 499 override public ReservationData GetReservationAtPoint(uint x, uint y)
428 { 500 {
501 MySQLSuperManager dbm = GetLockedConnection();
502
429 try 503 try
430 { 504 {
431 lock (database)
432 {
433 Dictionary<string, string> param = new Dictionary<string, string>(); 505 Dictionary<string, string> param = new Dictionary<string, string>();
434 param["?x"] = x.ToString(); 506 param["?x"] = x.ToString();
435 param["?y"] = y.ToString(); 507 param["?y"] = y.ToString();
436 IDbCommand result = 508 IDbCommand result =
437 database.Query( 509 dbm.Manager.Query(
438 "SELECT * FROM reservations WHERE resXMin <= ?x AND resXMax >= ?x AND resYMin <= ?y AND resYMax >= ?y", 510 "SELECT * FROM reservations WHERE resXMin <= ?x AND resXMax >= ?x AND resYMin <= ?y AND resYMax >= ?y",
439 param); 511 param);
440 IDataReader reader = result.ExecuteReader(); 512 IDataReader reader = result.ExecuteReader();
441 513
442 ReservationData row = database.readReservationRow(reader); 514 ReservationData row = dbm.Manager.readReservationRow(reader);
443 reader.Close(); 515 reader.Close();
444 result.Dispose(); 516 result.Dispose();
445 517
446 return row; 518 return row;
447 }
448 } 519 }
449 catch (Exception e) 520 catch (Exception e)
450 { 521 {
451 database.Reconnect(); 522 dbm.Manager.Reconnect();
452 m_log.Error(e.ToString()); 523 m_log.Error(e.ToString());
453 return null; 524 return null;
525 } finally
526 {
527 dbm.Release();
454 } 528 }
455 } 529 }
456 } 530 }
diff --git a/OpenSim/Data/MySQL/MySQLManager.cs b/OpenSim/Data/MySQL/MySQLManager.cs
index d193c72..15bdf44 100644
--- a/OpenSim/Data/MySQL/MySQLManager.cs
+++ b/OpenSim/Data/MySQL/MySQLManager.cs
@@ -41,7 +41,7 @@ namespace OpenSim.Data.MySQL
41 /// <summary> 41 /// <summary>
42 /// A MySQL Database manager 42 /// A MySQL Database manager
43 /// </summary> 43 /// </summary>
44 internal class MySQLManager 44 public class MySQLManager
45 { 45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 47
diff --git a/OpenSim/Data/MySQL/MySQLSuperManager.cs b/OpenSim/Data/MySQL/MySQLSuperManager.cs
index effdac7..4a9c7fa 100644
--- a/OpenSim/Data/MySQL/MySQLSuperManager.cs
+++ b/OpenSim/Data/MySQL/MySQLSuperManager.cs
@@ -1,14 +1,11 @@
1using System; 1using System.Threading;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading;
5 2
6namespace OpenSim.Data.MySQL 3namespace OpenSim.Data.MySQL
7{ 4{
8 class MySQLSuperManager 5 public class MySQLSuperManager
9 { 6 {
10 public bool Locked; 7 public bool Locked;
11 private Mutex m_lock = new Mutex(false); 8 private readonly Mutex m_lock = new Mutex(false);
12 public MySQLManager Manager; 9 public MySQLManager Manager;
13 10
14 public void GetLock() 11 public void GetLock()