Skip to content

Commit a2e406c

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 579ff5c commit a2e406c

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
@@ -404,6 +404,7 @@ inline constexpr ULONG REL_jrd_view = 0x8000; // relation is VIEW
404404
inline constexpr ULONG REL_gc_blocking = 0x10000; // request to downgrade\release gc lock
405405
inline constexpr ULONG REL_gc_disabled = 0x20000; // gc is disabled temporarily
406406
inline constexpr ULONG REL_gc_lockneed = 0x40000; // gc lock should be acquired
407+
inline constexpr ULONG REL_rescan = 0x100000; // rescan request was submitted while relation being scanning
407408

408409

409410
/// class jrd_rel

src/jrd/dfw.epp

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

62776277
// signal others about new format presence
6278-
LCK_lock(tdbb, relation->rel_rescan_lock, LCK_EX, LCK_WAIT);
62796278
LCK_release(tdbb, relation->rel_rescan_lock);
6279+
{
6280+
// Use temp lock to avoid AST call
6281+
Lock tmpLock(tdbb, sizeof(SLONG), LCK_rel_rescan);
6282+
tmpLock.setKey(relation->rel_id);
6283+
6284+
LCK_lock(tdbb, &tmpLock, LCK_EX, LCK_WAIT);
6285+
LCK_release(tdbb, &tmpLock);
6286+
}
62806287

62816288
break;
62826289
}

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 QualifiedName*, FB_UINT64, SSHORT, USHORT, const MetaName&, const string&,
128128
const bid*, TriState 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 QualifiedName&);
131132

132133

@@ -3917,6 +3918,27 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
39173918
* Scan a relation for view RecordSelExpr, computed by expressions, missing
39183919
* expressions, and validation expressions.
39193920
*
3921+
**************************************/
3922+
3923+
while (!(relation->rel_flags & (REL_scanned | REL_deleted)))
3924+
{
3925+
scan_relation(tdbb, relation);
3926+
}
3927+
}
3928+
3929+
3930+
static void scan_relation(thread_db* tdbb, jrd_rel* relation)
3931+
{
3932+
/**************************************
3933+
*
3934+
* s c a n _ r e l a t i o n
3935+
*
3936+
**************************************
3937+
*
3938+
* Functional description
3939+
* Scan a relation for view RecordSelExpr, computed by expressions, missing
3940+
* expressions, and validation expressions.
3941+
*
39203942
**************************************/
39213943
SET_TDBB(tdbb);
39223944
TrigVector* triggers[TRIGGER_MAX];
@@ -3935,10 +3957,13 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
39353957

39363958
try {
39373959

3938-
if (relation->rel_flags & (REL_scanned | REL_deleted))
3939-
return;
3960+
fb_assert(!(relation->rel_flags & (REL_scanned | REL_deleted)));
39403961

39413962
relation->rel_flags |= REL_being_scanned;
3963+
3964+
LCK_lock(tdbb, relation->rel_rescan_lock, LCK_SR, LCK_WAIT);
3965+
relation->rel_flags &= ~REL_rescan;
3966+
39423967
dependencies = (relation->rel_flags & REL_get_dependencies) ? true : false;
39433968
relation->rel_flags &= ~REL_get_dependencies;
39443969

@@ -4232,9 +4257,14 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
42324257
// It's now time to place them at their rightful place inside the relation block.
42334258
relation->replaceTriggers(tdbb, triggers);
42344259

4235-
LCK_lock(tdbb, relation->rel_rescan_lock, LCK_SR, LCK_WAIT);
42364260
relation->rel_flags &= ~REL_being_scanned;
42374261

4262+
if (relation->rel_flags & REL_rescan)
4263+
{
4264+
LCK_release(tdbb, relation->rel_rescan_lock);
4265+
relation->rel_flags &= ~(REL_scanned | REL_rescan);
4266+
}
4267+
42384268
relation->rel_current_format = NULL;
42394269

42404270
} // try
@@ -4542,8 +4572,13 @@ static int rescan_ast_relation(void* ast_object)
45424572

45434573
AsyncContextHolder tdbb(dbb, FB_FUNCTION, relation->rel_rescan_lock);
45444574

4545-
LCK_release(tdbb, relation->rel_rescan_lock);
4546-
relation->rel_flags &= ~REL_scanned;
4575+
if (relation->rel_flags & REL_being_scanned)
4576+
relation->rel_flags |= REL_rescan;
4577+
else
4578+
{
4579+
LCK_release(tdbb, relation->rel_rescan_lock);
4580+
relation->rel_flags &= ~REL_scanned;
4581+
}
45474582
}
45484583
catch (const Firebird::Exception&)
45494584
{} // no-op

0 commit comments

Comments
 (0)