From 870cc30f95404471550d9058927d2a023c9163ec Mon Sep 17 00:00:00 2001 From: hvlad Date: Thu, 6 May 2010 12:27:17 +0000 Subject: [PATCH] Backport fix for bug CORE-2993 : Fatal lock manager error "Invalid lock id (NNN)" while working with monitoring tables on a highly loaded system --- src/jrd/DatabaseSnapshot.cpp | 1 + src/jrd/jrd.cpp | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/jrd/DatabaseSnapshot.cpp b/src/jrd/DatabaseSnapshot.cpp index ce0e21f7ac3..2a1ba67e73c 100644 --- a/src/jrd/DatabaseSnapshot.cpp +++ b/src/jrd/DatabaseSnapshot.cpp @@ -452,6 +452,7 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool) // Release our own lock LCK_release(tdbb, dbb->dbb_monitor_lock); + dbb->dbb_ast_flags &= ~DBB_monitor_off; { // scope for the RAII object diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 351a768b06f..c385f2671c9 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -4682,9 +4682,18 @@ bool JRD_reschedule(thread_db* tdbb, SLONG quantum, bool punt) // Enable signal handler for the monitoring stuff - if (dbb->dbb_ast_flags & DBB_monitor_off) { + if (dbb->dbb_ast_flags & DBB_monitor_off) + { dbb->dbb_ast_flags &= ~DBB_monitor_off; LCK_lock(tdbb, dbb->dbb_monitor_lock, LCK_SR, LCK_WAIT); + + // While waiting for return from LCK_lock call above the blocking AST (see + // DatabaseSnapshot::blockingAst) was called and set DBB_monitor_off flag + // again. But it not released lock as lck_id was unknown at that moment. + // Do it now to not block another process waiting for a monitoring lock. + + if (dbb->dbb_ast_flags & DBB_monitor_off) + LCK_release(tdbb, dbb->dbb_monitor_lock); } tdbb->tdbb_quantum = (tdbb->tdbb_quantum <= 0) ? @@ -5007,11 +5016,16 @@ static ISC_STATUS check_database(thread_db* tdbb, Attachment* attachment, ISC_ST return error(user_status); } - // Enable signal handler for the monitoring stuff + // Enable signal handler for the monitoring stuff. + // See also comments in JRD_reshedule. - if (dbb->dbb_ast_flags & DBB_monitor_off) { + if (dbb->dbb_ast_flags & DBB_monitor_off) + { dbb->dbb_ast_flags &= ~DBB_monitor_off; LCK_lock(tdbb, dbb->dbb_monitor_lock, LCK_SR, LCK_WAIT); + + if (dbb->dbb_ast_flags & DBB_monitor_off) + LCK_release(tdbb, dbb->dbb_monitor_lock); } return FB_SUCCESS;