Skip to content

Commit f06ae97

Browse files
committed
Backported fix for bug #8817 : Fatal lock manager error: invalid lock id
1 parent 709bef5 commit f06ae97

3 files changed

Lines changed: 49 additions & 6 deletions

File tree

src/jrd/Relation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ const ULONG REL_jrd_view = 0x10000; // relation is VIEW
400400
const ULONG REL_gc_blocking = 0x20000; // request to downgrade\release gc lock
401401
const ULONG REL_gc_disabled = 0x40000; // gc is disabled temporarily
402402
const ULONG REL_gc_lockneed = 0x80000; // gc lock should be acquired
403+
const ULONG REL_rescan = 0x100000; // rescan request was submitted while relation being scanning
403404

404405

405406
/// class jrd_rel

src/jrd/dfw.epp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6117,8 +6117,15 @@ static bool make_version(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_
61176117
DFW_post_work(transaction, dfw_scan_relation, NULL, relation->rel_id);
61186118

61196119
// signal others about new format presence
6120-
LCK_lock(tdbb, relation->rel_rescan_lock, LCK_EX, LCK_WAIT);
61216120
LCK_release(tdbb, relation->rel_rescan_lock);
6121+
{
6122+
// Use temp lock to avoid AST call
6123+
Lock tmpLock(tdbb, sizeof(SLONG), LCK_rel_rescan);
6124+
tmpLock.lck_key.lck_long = relation->rel_id;
6125+
6126+
LCK_lock(tdbb, &tmpLock, LCK_EX, LCK_WAIT);
6127+
LCK_release(tdbb, &tmpLock);
6128+
}
61226129

61236130
break;
61246131
}

src/jrd/met.epp

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ static void save_trigger_data(thread_db*, TrigVector**, jrd_rel*, JrdStatement*,
126126
const TEXT*, FB_UINT64, bool, USHORT, const MetaName&, const string&,
127127
const bid*);
128128
static void scan_partners(thread_db*, jrd_rel*);
129+
static void scan_relation(thread_db*, jrd_rel*);
129130
static void store_dependencies(thread_db*, CompilerScratch*, const jrd_rel*,
130131
const MetaName&, int, jrd_tra*);
131132
static bool verify_TRG_ignore_perm(thread_db*, const MetaName&);
@@ -3800,6 +3801,27 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
38003801
* Scan a relation for view RecordSelExpr, computed by expressions, missing
38013802
* expressions, and validation expressions.
38023803
*
3804+
**************************************/
3805+
3806+
while (!(relation->rel_flags & (REL_scanned | REL_deleted)))
3807+
{
3808+
scan_relation(tdbb, relation);
3809+
}
3810+
}
3811+
3812+
3813+
static void scan_relation(thread_db* tdbb, jrd_rel* relation)
3814+
{
3815+
/**************************************
3816+
*
3817+
* s c a n _ r e l a t i o n
3818+
*
3819+
**************************************
3820+
*
3821+
* Functional description
3822+
* Scan a relation for view RecordSelExpr, computed by expressions, missing
3823+
* expressions, and validation expressions.
3824+
*
38033825
**************************************/
38043826
SET_TDBB(tdbb);
38053827
TrigVector* triggers[TRIGGER_MAX];
@@ -3819,10 +3841,13 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
38193841

38203842
try {
38213843

3822-
if (relation->rel_flags & (REL_scanned | REL_deleted))
3823-
return;
3844+
fb_assert(!(relation->rel_flags & (REL_scanned | REL_deleted)));
38243845

38253846
relation->rel_flags |= REL_being_scanned;
3847+
3848+
LCK_lock(tdbb, relation->rel_rescan_lock, LCK_SR, LCK_WAIT);
3849+
relation->rel_flags &= ~REL_rescan;
3850+
38263851
dependencies = (relation->rel_flags & REL_get_dependencies) ? true : false;
38273852
sys_triggers = (relation->rel_flags & REL_sys_triggers) ? true : false;
38283853
relation->rel_flags &= ~(REL_get_dependencies | REL_sys_triggers);
@@ -4128,9 +4153,14 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
41284153
MET_release_triggers(tdbb, &tmp_vector);
41294154
}
41304155

4131-
LCK_lock(tdbb, relation->rel_rescan_lock, LCK_SR, LCK_WAIT);
41324156
relation->rel_flags &= ~REL_being_scanned;
41334157

4158+
if (relation->rel_flags & REL_rescan)
4159+
{
4160+
LCK_release(tdbb, relation->rel_rescan_lock);
4161+
relation->rel_flags &= ~(REL_scanned | REL_rescan);
4162+
}
4163+
41344164
relation->rel_current_format = NULL;
41354165

41364166
} // try
@@ -4424,8 +4454,13 @@ static int rescan_ast_relation(void* ast_object)
44244454

44254455
AsyncContextHolder tdbb(dbb, FB_FUNCTION, relation->rel_rescan_lock);
44264456

4427-
LCK_release(tdbb, relation->rel_rescan_lock);
4428-
relation->rel_flags &= ~REL_scanned;
4457+
if (relation->rel_flags & REL_being_scanned)
4458+
relation->rel_flags |= REL_rescan;
4459+
else
4460+
{
4461+
LCK_release(tdbb, relation->rel_rescan_lock);
4462+
relation->rel_flags &= ~REL_scanned;
4463+
}
44294464
}
44304465
catch (const Firebird::Exception&)
44314466
{} // no-op

0 commit comments

Comments
 (0)