RelationReleaseRecoveryLocks(InvalidTransactionId);
}
+void
+RelationReleaseOldRecoveryLocks(TransactionId removeXid)
+{
+ ListCell *l;
+ LOCKTAG locktag;
+ List *deletionList = NIL;
+
+ /*
+ * Release all matching locks and identify list elements to remove
+ */
+ foreach(l, RecoveryLockList)
+ {
+ xl_rel_lock *lock = (xl_rel_lock *) lfirst(l);
+
+
+ if (TransactionIdPrecedes(removeXid, lock->xid))
+ {
+ elog(trace_recovery(DEBUG4),
+ "releasing recovery lock: xid %u db %d rel %d",
+ lock->xid, lock->dbOid, lock->relOid);
+ SET_LOCKTAG_RELATION(locktag, lock->dbOid, lock->relOid);
+ if (!LockRelease(&locktag, AccessExclusiveLock, true))
+ elog(trace_recovery(LOG),
+ "RecoveryLockList contains entry for lock "
+ "no longer recorded by lock manager "
+ "xid %u database %d relation %d",
+ lock->xid, lock->dbOid, lock->relOid);
+ deletionList = lappend(deletionList, lock);
+ }
+ }
+
+ /*
+ * Now remove the elements from RecoveryLockList. We can't navigate
+ * the list at the same time as deleting multiple elements from it.
+ */
+ foreach(l, deletionList)
+ {
+ xl_rel_lock *lock = (xl_rel_lock *) lfirst(l);
+
+ RecoveryLockList = list_delete_ptr(RecoveryLockList, lock);
+ pfree(lock);
+ }
+}
+
/*
* --------------------------------------------------
* Recovery handling for Rmgr RM_RELATION_ID
extern void RelationReleaseRecoveryLockTree(TransactionId xid,
int nsubxids, TransactionId *subxids);
extern void RelationReleaseAllRecoveryLocks(void);
+extern void RelationReleaseOldRecoveryLocks(TransactionId removeXid);
+
/* Recovery handlers for the Relation Rmgr (RM_RELATION_ID) */
extern void relation_redo(XLogRecPtr lsn, XLogRecord *record);