summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavan Deolasee2017-02-09 08:05:46 +0000
committerPavan Deolasee2017-02-09 08:05:46 +0000
commit7e40411483f6f917f8f316b69b26c8c660afc1c0 (patch)
tree880ff865336f89a4c554b68fd1491e5737c26822
parente7542220d25fad39b753969296510893c9f9915d (diff)
Handle locking correctly in a global session.
Rearrange code so that we first check if the backend belongs to a global sessions and if another member of the same session is holding a conflicting lock. In such cases, the requesting backend does not wait and is granted the lock immediately. PG 9.6 changed a few things in this area to support locking for parallel sessions. May be we can reuse that code in XL, but for now just use XL's code for supporting distributed sessions
-rw-r--r--src/backend/storage/lmgr/lock.c103
1 files changed, 52 insertions, 51 deletions
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 13d5379145..37eec5b00a 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -1395,57 +1395,6 @@ LockCheckConflicts(LockMethod lockMethodTable,
return STATUS_OK;
}
- /* If no group locking, it's definitely a conflict. */
- if (proclock->groupLeader == MyProc && MyProc->lockGroupLeader == NULL)
- {
- Assert(proclock->tag.myProc == MyProc);
- PROCLOCK_PRINT("LockCheckConflicts: conflicting (simple)",
- proclock);
- return STATUS_FOUND;
- }
-
- /*
- * Locks held in conflicting modes by members of our own lock group are
- * not real conflicts; we can subtract those out and see if we still have
- * a conflict. This is O(N) in the number of processes holding or
- * awaiting locks on this object. We could improve that by making the
- * shared memory state more complex (and larger) but it doesn't seem worth
- * it.
- */
- procLocks = &(lock->procLocks);
- otherproclock = (PROCLOCK *)
- SHMQueueNext(procLocks, procLocks, offsetof(PROCLOCK, lockLink));
- while (otherproclock != NULL)
- {
- if (proclock != otherproclock &&
- proclock->groupLeader == otherproclock->groupLeader &&
- (otherproclock->holdMask & conflictMask) != 0)
- {
- int intersectMask = otherproclock->holdMask & conflictMask;
-
- for (i = 1; i <= numLockModes; i++)
- {
- if ((intersectMask & LOCKBIT_ON(i)) != 0)
- {
- if (conflictsRemaining[i] <= 0)
- elog(PANIC, "proclocks held do not match lock");
- conflictsRemaining[i]--;
- totalConflictsRemaining--;
- }
- }
-
- if (totalConflictsRemaining == 0)
- {
- PROCLOCK_PRINT("LockCheckConflicts: resolved (group)",
- proclock);
- return STATUS_OK;
- }
- }
- otherproclock = (PROCLOCK *)
- SHMQueueNext(procLocks, &otherproclock->lockLink,
- offsetof(PROCLOCK, lockLink));
- }
-
#ifdef XCP
/*
* So the lock is conflicting with locks held by some other backend.
@@ -1518,6 +1467,58 @@ LockCheckConflicts(LockMethod lockMethodTable,
LWLockRelease(ProcArrayLock);
#endif
+ /* If no group locking, it's definitely a conflict. */
+ if (proclock->groupLeader == MyProc && MyProc->lockGroupLeader == NULL)
+ {
+ Assert(proclock->tag.myProc == MyProc);
+ PROCLOCK_PRINT("LockCheckConflicts: conflicting (simple)",
+ proclock);
+ return STATUS_FOUND;
+ }
+
+ /*
+ * Locks held in conflicting modes by members of our own lock group are
+ * not real conflicts; we can subtract those out and see if we still have
+ * a conflict. This is O(N) in the number of processes holding or
+ * awaiting locks on this object. We could improve that by making the
+ * shared memory state more complex (and larger) but it doesn't seem worth
+ * it.
+ */
+ procLocks = &(lock->procLocks);
+ otherproclock = (PROCLOCK *)
+ SHMQueueNext(procLocks, procLocks, offsetof(PROCLOCK, lockLink));
+ while (otherproclock != NULL)
+ {
+ if (proclock != otherproclock &&
+ proclock->groupLeader == otherproclock->groupLeader &&
+ (otherproclock->holdMask & conflictMask) != 0)
+ {
+ int intersectMask = otherproclock->holdMask & conflictMask;
+
+ for (i = 1; i <= numLockModes; i++)
+ {
+ if ((intersectMask & LOCKBIT_ON(i)) != 0)
+ {
+ if (conflictsRemaining[i] <= 0)
+ elog(PANIC, "proclocks held do not match lock");
+ conflictsRemaining[i]--;
+ totalConflictsRemaining--;
+ }
+ }
+
+ if (totalConflictsRemaining == 0)
+ {
+ PROCLOCK_PRINT("LockCheckConflicts: resolved (group)",
+ proclock);
+ return STATUS_OK;
+ }
+ }
+ otherproclock = (PROCLOCK *)
+ SHMQueueNext(procLocks, &otherproclock->lockLink,
+ offsetof(PROCLOCK, lockLink));
+ }
+
+
/* Nope, it's a real conflict. */
PROCLOCK_PRINT("LockCheckConflicts: conflicting (group)", proclock);
return STATUS_FOUND;