public void ChangeActiveServerForThirdParty(string newActiveServerName, TimeSpan lockTimeout) { using (AmDatabaseOperationLock.Lock(base.DatabaseGuid, AmDbLockReason.Move, new TimeSpan?(lockTimeout))) { if (!base.State.IsAdminDismounted) { throw new ChangeActiveServerException(base.DatabaseGuid, newActiveServerName, ReplayStrings.TPRChangeFailedBecauseNotDismounted); } AmServerName activeServer = base.State.ActiveServer; AmServerName amServerName = new AmServerName(newActiveServerName); if (activeServer.Equals(amServerName)) { throw new ChangeActiveServerException(base.DatabaseGuid, newActiveServerName, ReplayStrings.TPRChangeFailedBecauseAlreadyActive(activeServer.ToString())); } IAmBcsErrorLogger errorLogger = new AmBcsSingleCopyFailureLogger(); AmBcsServerChecks checks = AmBcsServerChecks.DebugOptionDisabled | AmBcsServerChecks.ClusterNodeUp | AmBcsServerChecks.DatacenterActivationModeStarted | AmBcsServerChecks.AutoActivationAllowed; LocalizedString empty = LocalizedString.Empty; AmBcsServerValidation amBcsServerValidation = new AmBcsServerValidation(amServerName, activeServer, base.Database, base.Config, errorLogger, null); if (!amBcsServerValidation.RunChecks(checks, ref empty)) { AmTrace.Error("ChangeActiveServerForThirdParty: DB {0}: ValidateServer() returned error: {1}", new object[] { base.DatabaseName, empty }); throw new ChangeActiveServerException(base.DatabaseGuid, newActiveServerName, ReplayStrings.TPRChangeFailedServerValidation(base.DatabaseName, newActiveServerName, empty)); } base.WriteStateMountSkipped(amServerName); this.UpdateAdProperties(true, activeServer); ReplayCrimsonEvents.TPRChangeActiveServerSucceeded.Log <string, Guid, AmServerName, AmServerName>(base.DatabaseName, base.DatabaseGuid, activeServer, amServerName); } }
public static void AssertLockIsHeldByMe(Guid dbId) { lock (AmDatabaseOperationLock.s_lockTable) { AmDatabaseOperationLock amDatabaseOperationLock = null; if (AmDatabaseOperationLock.s_lockTable.TryGetValue(dbId, out amDatabaseOperationLock) && amDatabaseOperationLock != null) { AmDatabaseOperationLock.GetThreadId(); } } }
public static AmDatabaseOperationLock Lock(Guid dbId, AmDbLockReason reason, TimeSpan?timeout) { AmDatabaseOperationLock amDatabaseOperationLock = null; AmDatabaseOperationLock amDatabaseOperationLock2 = new AmDatabaseOperationLock(); amDatabaseOperationLock2.m_reason = reason; amDatabaseOperationLock2.m_dbId = dbId; amDatabaseOperationLock2.m_threadId = AmDatabaseOperationLock.GetThreadId(); lock (AmDatabaseOperationLock.s_lockTable) { if (AmDatabaseOperationLock.s_lockTable.TryGetValue(dbId, out amDatabaseOperationLock) && amDatabaseOperationLock != null) { AmTrace.Error("AmDatabaseOperationLock: conflict on db {0}. Requesting for {1} but held by {2} for {3}", new object[] { dbId, reason, amDatabaseOperationLock.ThreadId, amDatabaseOperationLock.Reason }); if (timeout == null || timeout.Value.Ticks == 0L || amDatabaseOperationLock.m_waiter != null) { throw new AmDbLockConflictException(dbId, reason.ToString(), amDatabaseOperationLock.Reason.ToString()); } amDatabaseOperationLock2.m_waiterEvent = new ManualResetEvent(false); amDatabaseOperationLock2.m_mustWaitForLock = true; amDatabaseOperationLock.m_waiter = amDatabaseOperationLock2; } else { AmDatabaseOperationLock.s_lockTable[dbId] = amDatabaseOperationLock2; amDatabaseOperationLock2.m_holdingLock = true; } } if (amDatabaseOperationLock2.m_mustWaitForLock) { amDatabaseOperationLock2.WaitForLock(timeout.Value, amDatabaseOperationLock); } AmTrace.Debug("AmDatabaseOperationLock({0},{1}) : lock obtained", new object[] { dbId, reason }); return(amDatabaseOperationLock2); }
public void Unlock() { lock (this) { if (this.m_holdingLock) { AmTrace.Debug("AmDatabaseOperationLock({0},{1}) : releasing lock", new object[] { this.DatabaseGuid, this.Reason }); lock (AmDatabaseOperationLock.s_lockTable) { AmDatabaseOperationLock amDatabaseOperationLock = null; if (AmDatabaseOperationLock.s_lockTable.TryGetValue(this.DatabaseGuid, out amDatabaseOperationLock) && amDatabaseOperationLock == this) { if (amDatabaseOperationLock.m_waiter != null) { AmTrace.Debug("AmDatabaseOperationLock({0},{1}) : granting lock to waiter:{2}", new object[] { this.DatabaseGuid, this.Reason, amDatabaseOperationLock.m_waiter.Reason }); AmDatabaseOperationLock.s_lockTable[this.DatabaseGuid] = amDatabaseOperationLock.m_waiter; amDatabaseOperationLock.m_waiter.m_holdingLock = true; amDatabaseOperationLock.m_waiter.m_waiterEvent.Set(); amDatabaseOperationLock.m_waiter = null; } else { AmDatabaseOperationLock.s_lockTable[this.DatabaseGuid] = null; } } } } } }
private void WaitForLock(TimeSpan timeout, AmDatabaseOperationLock origHolder) { AmDatabaseOperationLock amDatabaseOperationLock = null; long num = timeout.Ticks / 10000L; int num2 = (int)TimeSpan.FromHours(1.0).TotalMilliseconds; int num3; if (num > (long)num2) { num3 = num2; } else { num3 = (int)num; } AmTrace.Debug("AmDatabaseOperationLock({0},{1}) : waiting {2} ms for lock", new object[] { this.DatabaseGuid, this.Reason, num3 }); if (this.m_waiterEvent.WaitOne(num3, false)) { return; } AmTrace.Error("AmDatabaseOperationLock: timeout", new object[0]); lock (AmDatabaseOperationLock.s_lockTable) { AmDatabaseOperationLock.s_lockTable.TryGetValue(this.DatabaseGuid, out amDatabaseOperationLock); if (amDatabaseOperationLock == origHolder) { amDatabaseOperationLock.m_waiter = null; throw new AmDbLockConflictException(this.DatabaseGuid, this.Reason.ToString(), origHolder.Reason.ToString()); } AmTrace.Debug("AmDatabaseOperationLock: got lock after unlikely race", new object[0]); } }
internal void Remount(MountFlags mountFlags, DatabaseMountDialOverride mountDialoverride, AmServerName fromServer) { Exception ex = null; bool flag = true; AmServerName amServerName = null; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); try { using (AmDatabaseOperationLock.Lock(this.DatabaseGuid, AmDbLockReason.Remount, null)) { ex = AmHelper.HandleKnownExceptions(delegate(object param0, EventArgs param1) { ReplayCrimsonEvents.ToplevelRemountInitiated.LogGeneric(this.PrepareStartupArgs(new object[] { mountFlags, mountDialoverride, fromServer })); if (!this.State.IsEntryExist) { this.DbTrace.Error("Database was never mounted. Remount is applicable only if it was mounted at least once", new object[0]); throw new AmDatabaseNeverMountedException(); } if (this.State.IsAdminDismounted) { this.DbTrace.Error("Skipping remount action since the database was admin dismounted", new object[0]); throw new AmDbRemountSkippedSinceDatabaseWasAdminDismounted(this.DatabaseName); } if (!AmServerName.IsEqual(this.State.ActiveServer, fromServer)) { this.DbTrace.Error("Skipping remount action since database master had changed", new object[0]); throw new AmDbRemountSkippedSinceMasterChanged(this.DatabaseName, this.State.ActiveServer.Fqdn, fromServer.NetbiosName); } this.EnsureAutomaticActionIsAllowed(); this.RemountInternal(mountFlags, mountDialoverride, fromServer); }); this.WriteStateClearIfInProgressStatus(true); flag = false; } } catch (AmDbLockConflictException ex2) { ex = ex2; } finally { stopwatch.Stop(); if (flag || ex != null) { string text = (ex != null) ? ex.Message : ReplayStrings.UnknownError; ReplayCrimsonEvents.ToplevelRemountFailed.LogGeneric(this.PrepareCompletionArgs(new object[] { stopwatch.Elapsed, text })); ReplayEventLogConstants.Tuple_AmDatabaseMountFailed.LogEvent(null, new object[] { this.DatabaseName, amServerName, text }); } else { ReplayCrimsonEvents.ToplevelRemountSuccess.LogGeneric(this.PrepareCompletionArgs(new object[] { stopwatch.Elapsed })); ReplayEventLogConstants.Tuple_AmDatabaseMounted.LogEvent(null, new object[] { this.DatabaseName, amServerName }); } } if (ex != null) { throw ex; } }
internal void Move(MountFlags mountFlags, UnmountFlags dismountFlags, DatabaseMountDialOverride mountDialoverride, AmServerName fromServer, AmServerName targetServer, bool tryOtherHealthyServers, AmBcsSkipFlags skipValidationChecks, string moveComment, string componentName, ref AmDbOperationDetailedStatus moveStatus) { moveStatus = new AmDbOperationDetailedStatus(this.Database); Exception ex = null; bool flag = true; AmServerName initialSourceServer = null; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); string initialActive = string.Empty; AmDbOperationDetailedStatus tempStatus = moveStatus; try { using (AmDatabaseOperationLock.Lock(this.DatabaseGuid, AmDbLockReason.Move, null)) { ex = AmHelper.HandleKnownExceptions(delegate(object param0, EventArgs param1) { initialActive = this.GetSafeActiveServer(); ReplayCrimsonEvents.ToplevelMoveInitiated.LogGeneric(this.PrepareStartupArgs(new object[] { mountFlags, dismountFlags, mountDialoverride, AmServerName.IsNullOrEmpty(fromServer) ? initialActive : fromServer.Fqdn, targetServer, tryOtherHealthyServers, skipValidationChecks, moveComment, componentName })); initialSourceServer = this.State.ActiveServer; this.EnsureAutomaticActionIsAllowed(); this.ClearFailureAttemptIfAdminAction(this.DatabaseGuid); this.MoveInternal(mountFlags, dismountFlags, mountDialoverride, fromServer, targetServer, tryOtherHealthyServers, skipValidationChecks, componentName, ref tempStatus); }); this.WriteStateClearIfInProgressStatus(true); flag = false; } } catch (AmDbLockConflictException ex2) { ex = ex2; } finally { stopwatch.Stop(); moveStatus = tempStatus; if (flag || ex != null) { string text = (ex != null) ? ex.Message : ReplayStrings.UnknownError; ReplayCrimsonEvents.ToplevelMoveFailed.LogGeneric(this.PrepareCompletionArgs(new object[] { initialActive, stopwatch.Elapsed, text, moveComment })); if (AmServerName.IsNullOrEmpty(targetServer)) { ReplayEventLogConstants.Tuple_AmDatabaseMoveUnspecifiedServerFailed.LogEvent(null, new object[] { this.DatabaseName, initialSourceServer, text, moveComment }); } else { ReplayEventLogConstants.Tuple_AmDatabaseMoveFailed.LogEvent(null, new object[] { this.DatabaseName, initialActive, targetServer, text, moveComment }); } } else { ReplayCrimsonEvents.ToplevelMoveSuccess.LogGeneric(this.PrepareCompletionArgs(new object[] { initialActive, stopwatch.Elapsed, moveComment })); ReplayEventLogConstants.Tuple_AmDatabaseMoved.LogEvent(null, new object[] { this.DatabaseName, initialActive, moveStatus.FinalDbState.ActiveServer, moveComment }); } } if (ex != null) { throw ex; } }
internal void Dismount(UnmountFlags flags) { Exception ex = null; bool flag = true; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); try { using (AmDatabaseOperationLock.Lock(this.DatabaseGuid, AmDbLockReason.Dismount, this.m_lockTimeout)) { ex = AmHelper.HandleKnownExceptions(delegate(object param0, EventArgs param1) { ReplayCrimsonEvents.ToplevelDismountInitiated.LogGeneric(this.PrepareStartupArgs(new object[] { flags })); if (!this.State.IsEntryExist) { throw new AmDatabaseNeverMountedException(); } this.ClearFailureAttemptIfAdminAction(this.DatabaseGuid); this.DismountInternal(flags); }); this.WriteStateClearIfInProgressStatus(true); flag = false; } } catch (AmDbLockConflictException ex2) { ex = ex2; } finally { stopwatch.Stop(); AmSystemManager.Instance.TransientFailoverSuppressor.AdminRequestedForRemoval(this.State.ActiveServer, "Dismount-Database"); if (flag || ex != null) { string text = (ex != null) ? ex.Message : ReplayStrings.UnknownError; ReplayCrimsonEvents.ToplevelDismountFailed.LogGeneric(this.PrepareCompletionArgs(new object[] { stopwatch.Elapsed, text })); ReplayEventLogConstants.Tuple_AmDatabaseDismountFailed.LogEvent(null, new object[] { this.DatabaseName, this.State.ActiveServer, text }); } else { ReplayCrimsonEvents.ToplevelDismountSuccess.LogGeneric(this.PrepareCompletionArgs(new object[] { stopwatch.Elapsed })); ReplayEventLogConstants.Tuple_AmDatabaseDismounted.LogEvent(null, new object[] { this.DatabaseName, this.State.ActiveServer }); } } if (ex != null) { throw ex; } }
internal void Mount(MountFlags storeFlags, AmMountFlags amMountFlags, DatabaseMountDialOverride mountDialoverride, ref AmDbOperationDetailedStatus mountStatus) { mountStatus = new AmDbOperationDetailedStatus(this.Database); Exception ex = null; bool flag = true; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); AmDbOperationDetailedStatus tempStatus = mountStatus; try { using (AmDatabaseOperationLock.Lock(this.DatabaseGuid, AmDbLockReason.Mount, null)) { ex = AmHelper.HandleKnownExceptions(delegate(object param0, EventArgs param1) { ReplayCrimsonEvents.ToplevelMountInitiated.LogGeneric(this.PrepareStartupArgs(new object[] { storeFlags, mountDialoverride })); this.EnsureAutomaticActionIsAllowed(); this.ClearFailureAttemptIfAdminAction(this.DatabaseGuid); if (!this.State.IsEntryExist) { this.DbTrace.Info("Mounting database for the first time!", new object[0]); } this.MountInternal(storeFlags, amMountFlags, mountDialoverride, ref tempStatus); }); mountStatus = tempStatus; this.WriteStateClearIfInProgressStatus(true); flag = false; } } catch (AmDbLockConflictException ex2) { ex = ex2; } finally { stopwatch.Stop(); if (flag || ex != null) { string text = (ex != null) ? ex.Message : ReplayStrings.UnknownError; ReplayCrimsonEvents.ToplevelMountFailed.LogGeneric(this.PrepareCompletionArgs(new object[] { stopwatch.Elapsed, text })); ReplayEventLogConstants.Tuple_AmDatabaseMountFailed.LogEvent(null, new object[] { this.DatabaseName, this.State.ActiveServer, text }); } else { ReplayCrimsonEvents.ToplevelMountSuccess.LogGeneric(this.PrepareCompletionArgs(new object[] { stopwatch.Elapsed })); ReplayEventLogConstants.Tuple_AmDatabaseMounted.LogEvent(null, new object[] { this.DatabaseName, this.State.ActiveServer }); } } if (ex != null) { throw ex; } }