postgrespro.git / summary / log / commit / refs
commit bb76134b08aa46cdeb0ff1e6d7b392d315529a8c
Author: Peter Eisentraut <peter@eisentraut.org>
Date: Fri Mar 29 09:53:40 2019 +0000
Fix incorrect code in new REINDEX CONCURRENTLY code
The previous code was adding pointers to transient variables to a
list, but by the time the list was read, the variable might be gone,
depending on the compiler. Fix it by making copies in the proper
memory context.
src/backend/commands/indexcmds.c | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index c68d8d5816..ea07be69db 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -2813,7 +2813,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
Relation indexRel;
Relation heapRel;
Relation newIndexRel;
- LockRelId lockrelid;
+ LockRelId *lockrelid;
indexRel = index_open(indexId, ShareUpdateExclusiveLock);
heapRel = table_open(indexRel->rd_index->indrelid,
@@ -2847,10 +2847,12 @@ ReindexRelationConcurrently(Oid relationOid, int options)
* avoid multiple locks taken on the same relation, instead we rely on
* parentRelationIds built earlier.
*/
- lockrelid = indexRel->rd_lockInfo.lockRelId;
- relationLocks = lappend(relationLocks, &lockrelid);
- lockrelid = newIndexRel->rd_lockInfo.lockRelId;
- relationLocks = lappend(relationLocks, &lockrelid);
+ lockrelid = palloc(sizeof(*lockrelid));
+ *lockrelid = indexRel->rd_lockInfo.lockRelId;
+ relationLocks = lappend(relationLocks, lockrelid);
+ lockrelid = palloc(sizeof(*lockrelid));
+ *lockrelid = newIndexRel->rd_lockInfo.lockRelId;
+ relationLocks = lappend(relationLocks, lockrelid);
MemoryContextSwitchTo(oldcontext);
@@ -2866,19 +2868,21 @@ ReindexRelationConcurrently(Oid relationOid, int options)
foreach(lc, heapRelationIds)
{
Relation heapRelation = table_open(lfirst_oid(lc), ShareUpdateExclusiveLock);
- LockRelId lockrelid = heapRelation->rd_lockInfo.lockRelId;
+ LockRelId *lockrelid;
LOCKTAG *heaplocktag;
/* Save the list of locks in private context */
oldcontext = MemoryContextSwitchTo(private_context);
/* Add lockrelid of heap relation to the list of locked relations */
- relationLocks = lappend(relationLocks, &lockrelid);
+ lockrelid = palloc(sizeof(*lockrelid));
+ *lockrelid = heapRelation->rd_lockInfo.lockRelId;
+ relationLocks = lappend(relationLocks, lockrelid);
heaplocktag = (LOCKTAG *) palloc(sizeof(LOCKTAG));
/* Save the LOCKTAG for this parent relation for the wait phase */
- SET_LOCKTAG_RELATION(*heaplocktag, lockrelid.dbId, lockrelid.relId);
+ SET_LOCKTAG_RELATION(*heaplocktag, lockrelid->dbId, lockrelid->relId);
lockTags = lappend(lockTags, heaplocktag);
MemoryContextSwitchTo(oldcontext);
@@ -2890,9 +2894,9 @@ ReindexRelationConcurrently(Oid relationOid, int options)
/* Get a session-level lock on each table. */
foreach(lc, relationLocks)
{
- LockRelId lockRel = *((LockRelId *) lfirst(lc));
+ LockRelId *lockrelid = (LockRelId *) lfirst(lc);
- LockRelationIdForSession(&lockRel, ShareUpdateExclusiveLock);
+ LockRelationIdForSession(lockrelid, ShareUpdateExclusiveLock);
}
PopActiveSnapshot();
@@ -3127,9 +3131,9 @@ ReindexRelationConcurrently(Oid relationOid, int options)
*/
foreach(lc, relationLocks)
{
- LockRelId lockRel = *((LockRelId *) lfirst(lc));
+ LockRelId *lockrelid = (LockRelId *) lfirst(lc);
- UnlockRelationIdForSession(&lockRel, ShareUpdateExclusiveLock);
+ UnlockRelationIdForSession(lockrelid, ShareUpdateExclusiveLock);
}
/* Start a new transaction to finish process properly */
[parent: 5dc92b844e68]