Skip to content

Commit c642236

Browse files
authored
Merge pull request #8818 from FirebirdSQL/work/gh-8817
This should fix bug #8817 : Fatal lock manager error: invalid lock id
2 parents 512c777 + 30cfa06 commit c642236

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 = 0x10000; // relation is VIEW
399399
const ULONG REL_gc_blocking = 0x20000; // request to downgrade\release gc lock
400400
const ULONG REL_gc_disabled = 0x40000; // gc is disabled temporarily
401401
const ULONG REL_gc_lockneed = 0x80000; // 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
@@ -6129,8 +6129,15 @@ static bool make_version(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_
61296129
DFW_post_work(transaction, dfw_scan_relation, NULL, relation->rel_id);
61306130

61316131
// signal others about new format presence
6132-
LCK_lock(tdbb, relation->rel_rescan_lock, LCK_EX, LCK_WAIT);
61336132
LCK_release(tdbb, relation->rel_rescan_lock);
6133+
{
6134+
// Use temp lock to avoid AST call
6135+
Lock tmpLock(tdbb, sizeof(SLONG), LCK_rel_rescan);
6136+
tmpLock.setKey(relation->rel_id);
6137+
6138+
LCK_lock(tdbb, &tmpLock, LCK_EX, LCK_WAIT);
6139+
LCK_release(tdbb, &tmpLock);
6140+
}
61346141

61356142
break;
61366143
}

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, SSHORT, USHORT, const MetaName&, const string&,
127127
const bid*, Nullable<bool> ssDefiner);
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&);
@@ -3892,6 +3893,27 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
38923893
* Scan a relation for view RecordSelExpr, computed by expressions, missing
38933894
* expressions, and validation expressions.
38943895
*
3896+
**************************************/
3897+
3898+
while (!(relation->rel_flags & (REL_scanned | REL_deleted)))
3899+
{
3900+
scan_relation(tdbb, relation);
3901+
}
3902+
}
3903+
3904+
3905+
static void scan_relation(thread_db* tdbb, jrd_rel* relation)
3906+
{
3907+
/**************************************
3908+
*
3909+
* s c a n _ r e l a t i o n
3910+
*
3911+
**************************************
3912+
*
3913+
* Functional description
3914+
* Scan a relation for view RecordSelExpr, computed by expressions, missing
3915+
* expressions, and validation expressions.
3916+
*
38953917
**************************************/
38963918
SET_TDBB(tdbb);
38973919
TrigVector* triggers[TRIGGER_MAX];
@@ -3911,10 +3933,13 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
39113933

39123934
try {
39133935

3914-
if (relation->rel_flags & (REL_scanned | REL_deleted))
3915-
return;
3936+
fb_assert(!(relation->rel_flags & (REL_scanned | REL_deleted)));
39163937

39173938
relation->rel_flags |= REL_being_scanned;
3939+
3940+
LCK_lock(tdbb, relation->rel_rescan_lock, LCK_SR, LCK_WAIT);
3941+
relation->rel_flags &= ~REL_rescan;
3942+
39183943
dependencies = (relation->rel_flags & REL_get_dependencies) ? true : false;
39193944
sys_triggers = (relation->rel_flags & REL_sys_triggers) ? true : false;
39203945
relation->rel_flags &= ~(REL_get_dependencies | REL_sys_triggers);
@@ -4217,9 +4242,14 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
42174242
relation->replaceTriggers(tdbb, triggers);
42184243
}
42194244

4220-
LCK_lock(tdbb, relation->rel_rescan_lock, LCK_SR, LCK_WAIT);
42214245
relation->rel_flags &= ~REL_being_scanned;
42224246

4247+
if (relation->rel_flags & REL_rescan)
4248+
{
4249+
LCK_release(tdbb, relation->rel_rescan_lock);
4250+
relation->rel_flags &= ~(REL_scanned | REL_rescan);
4251+
}
4252+
42234253
relation->rel_current_format = NULL;
42244254

42254255
} // try
@@ -4526,8 +4556,13 @@ static int rescan_ast_relation(void* ast_object)
45264556

45274557
AsyncContextHolder tdbb(dbb, FB_FUNCTION, relation->rel_rescan_lock);
45284558

4529-
LCK_release(tdbb, relation->rel_rescan_lock);
4530-
relation->rel_flags &= ~REL_scanned;
4559+
if (relation->rel_flags & REL_being_scanned)
4560+
relation->rel_flags |= REL_rescan;
4561+
else
4562+
{
4563+
LCK_release(tdbb, relation->rel_rescan_lock);
4564+
relation->rel_flags &= ~REL_scanned;
4565+
}
45314566
}
45324567
catch (const Firebird::Exception&)
45334568
{} // no-op

0 commit comments

Comments
 (0)