diff options
author | Adam Frisby | 2008-08-30 19:35:22 +0000 |
---|---|---|
committer | Adam Frisby | 2008-08-30 19:35:22 +0000 |
commit | 2133fa56e7790ab63749d778c4d2db79a9b9e9bf (patch) | |
tree | a29fe533240dce8444a06450b81742cfd1bcff01 | |
parent | * minor: Tiny doc addition to trigger another build that hopefully won't fail (diff) | |
download | opensim-SC-2133fa56e7790ab63749d778c4d2db79a9b9e9bf.zip opensim-SC-2133fa56e7790ab63749d778c4d2db79a9b9e9bf.tar.gz opensim-SC-2133fa56e7790ab63749d778c4d2db79a9b9e9bf.tar.bz2 opensim-SC-2133fa56e7790ab63749d778c4d2db79a9b9e9bf.tar.xz |
* Added new MySQLSuperManager support for the grid servers.
* In theory, login and a large number of grid functions should now at least be multithreaded.
-rw-r--r-- | OpenSim/Data/MySQL/MySQLGridData.cs | 198 | ||||
-rw-r--r-- | OpenSim/Data/MySQL/MySQLManager.cs | 2 | ||||
-rw-r--r-- | OpenSim/Data/MySQL/MySQLSuperManager.cs | 9 |
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; | |||
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Data; | 30 | using System.Data; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Security.Cryptography; | ||
33 | using System.Text; | ||
34 | using libsecondlife; | 32 | using libsecondlife; |
35 | using log4net; | 33 | using log4net; |
36 | using OpenSim.Framework; | 34 | using 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 @@ | |||
1 | using System; | 1 | using System.Threading; |
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using System.Threading; | ||
5 | 2 | ||
6 | namespace OpenSim.Data.MySQL | 3 | namespace 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() |