Skip to content

Commit 5c5d48e

Browse files
committed
Merge pull request #8818 from FirebirdSQL/work/gh-8817
This should fix bug #8817 : Fatal lock manager error: invalid lock id
1 parent a75ec4f commit 5c5d48e

File tree

3 files changed

+49
-6
lines changed

3 files changed

+49
-6
lines changed

src/jrd/Relation.h

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

403404

404405
/// class jrd_rel

src/jrd/dfw.epp

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

63136313
// signal others about new format presence
6314-
LCK_lock(tdbb, relation->rel_rescan_lock, LCK_EX, LCK_WAIT);
63156314
LCK_release(tdbb, relation->rel_rescan_lock);
6315+
{
6316+
// Use temp lock to avoid AST call
6317+
Lock tmpLock(tdbb, sizeof(SLONG), LCK_rel_rescan);
6318+
tmpLock.setKey(relation->rel_id);
6319+
6320+
LCK_lock(tdbb, &tmpLock, LCK_EX, LCK_WAIT);
6321+
LCK_release(tdbb, &tmpLock);
6322+
}
63166323

63176324
break;
63186325
}

src/jrd/met.epp

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ static void save_trigger_data(thread_db*, TrigVector**, jrd_rel*, Statement*, bl
127127
const TEXT*, FB_UINT64, SSHORT, USHORT, const MetaName&, const string&,
128128
const bid*, Nullable<bool> ssDefiner);
129129
static void scan_partners(thread_db*, jrd_rel*);
130+
static void scan_relation(thread_db*, jrd_rel*);
130131
static bool verify_TRG_ignore_perm(thread_db*, const MetaName&);
131132

132133

@@ -4035,6 +4036,27 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
40354036
* Scan a relation for view RecordSelExpr, computed by expressions, missing
40364037
* expressions, and validation expressions.
40374038
*
4039+
**************************************/
4040+
4041+
while (!(relation->rel_flags & (REL_scanned | REL_deleted)))
4042+
{
4043+
scan_relation(tdbb, relation);
4044+
}
4045+
}
4046+
4047+
4048+
static void scan_relation(thread_db* tdbb, jrd_rel* relation)
4049+
{
4050+
/**************************************
4051+
*
4052+
* s c a n _ r e l a t i o n
4053+
*
4054+
**************************************
4055+
*
4056+
* Functional description
4057+
* Scan a relation for view RecordSelExpr, computed by expressions, missing
4058+
* expressions, and validation expressions.
4059+
*
40384060
**************************************/
40394061
SET_TDBB(tdbb);
40404062
TrigVector* triggers[TRIGGER_MAX];
@@ -4054,10 +4076,13 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
40544076

40554077
try {
40564078

4057-
if (relation->rel_flags & (REL_scanned | REL_deleted))
4058-
return;
4079+
fb_assert(!(relation->rel_flags & (REL_scanned | REL_deleted)));
40594080

40604081
relation->rel_flags |= REL_being_scanned;
4082+
4083+
LCK_lock(tdbb, relation->rel_rescan_lock, LCK_SR, LCK_WAIT);
4084+
relation->rel_flags &= ~REL_rescan;
4085+
40614086
dependencies = (relation->rel_flags & REL_get_dependencies) ? true : false;
40624087
sys_triggers = (relation->rel_flags & REL_sys_triggers) ? true : false;
40634088
relation->rel_flags &= ~(REL_get_dependencies | REL_sys_triggers);
@@ -4360,9 +4385,14 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
43604385
relation->replaceTriggers(tdbb, triggers);
43614386
}
43624387

4363-
LCK_lock(tdbb, relation->rel_rescan_lock, LCK_SR, LCK_WAIT);
43644388
relation->rel_flags &= ~REL_being_scanned;
43654389

4390+
if (relation->rel_flags & REL_rescan)
4391+
{
4392+
LCK_release(tdbb, relation->rel_rescan_lock);
4393+
relation->rel_flags &= ~(REL_scanned | REL_rescan);
4394+
}
4395+
43664396
relation->rel_current_format = NULL;
43674397

43684398
} // try
@@ -4669,8 +4699,13 @@ static int rescan_ast_relation(void* ast_object)
46694699

46704700
AsyncContextHolder tdbb(dbb, FB_FUNCTION, relation->rel_rescan_lock);
46714701

4672-
LCK_release(tdbb, relation->rel_rescan_lock);
4673-
relation->rel_flags &= ~REL_scanned;
4702+
if (relation->rel_flags & REL_being_scanned)
4703+
relation->rel_flags |= REL_rescan;
4704+
else
4705+
{
4706+
LCK_release(tdbb, relation->rel_rescan_lock);
4707+
relation->rel_flags &= ~REL_scanned;
4708+
}
46744709
}
46754710
catch (const Firebird::Exception&)
46764711
{} // no-op

0 commit comments

Comments
 (0)