Merge pull request #1856 from citusdata/create_drop_deadlock

Avoid deadlock with DROP TABLE in ColocatedTableId
pull/1851/head
Marco Slot 2017-12-06 12:03:52 +01:00 committed by GitHub
commit d336167313
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 26 additions and 5 deletions

View File

@ -963,25 +963,46 @@ ColocatedTableId(Oid colocationId)
ScanKeyInit(&scanKey[0], Anum_pg_dist_partition_colocationid, ScanKeyInit(&scanKey[0], Anum_pg_dist_partition_colocationid,
BTEqualStrategyNumber, F_INT4EQ, ObjectIdGetDatum(colocationId)); BTEqualStrategyNumber, F_INT4EQ, ObjectIdGetDatum(colocationId));
/* do not allow any tables to be dropped while we read from pg_dist_partition */ pgDistPartition = heap_open(DistPartitionRelationId(), AccessShareLock);
pgDistPartition = heap_open(DistPartitionRelationId(), ShareLock);
tupleDescriptor = RelationGetDescr(pgDistPartition); tupleDescriptor = RelationGetDescr(pgDistPartition);
scanDescriptor = systable_beginscan(pgDistPartition, scanDescriptor = systable_beginscan(pgDistPartition,
DistPartitionColocationidIndexId(), DistPartitionColocationidIndexId(),
indexOK, NULL, scanKeyCount, scanKey); indexOK, NULL, scanKeyCount, scanKey);
heapTuple = systable_getnext(scanDescriptor); heapTuple = systable_getnext(scanDescriptor);
if (HeapTupleIsValid(heapTuple)) while (HeapTupleIsValid(heapTuple))
{ {
Relation colocatedRelation = NULL;
colocatedTableId = heap_getattr(heapTuple, Anum_pg_dist_partition_logicalrelid, colocatedTableId = heap_getattr(heapTuple, Anum_pg_dist_partition_logicalrelid,
tupleDescriptor, &isNull); tupleDescriptor, &isNull);
/* make sure the table isn't dropped for the remainder of the transaction */ /*
* Make sure the relation isn't dropped for the remainder of
* the transaction.
*/
LockRelationOid(colocatedTableId, AccessShareLock); LockRelationOid(colocatedTableId, AccessShareLock);
/*
* The relation might have been dropped just before we locked it.
* Let's look it up.
*/
colocatedRelation = RelationIdGetRelation(colocatedTableId);
if (RelationIsValid(colocatedRelation))
{
/* relation still exists, we can use it */
RelationClose(colocatedRelation);
break;
}
/* relation was dropped, try the next one */
colocatedTableId = InvalidOid;
heapTuple = systable_getnext(scanDescriptor);
} }
systable_endscan(scanDescriptor); systable_endscan(scanDescriptor);
heap_close(pgDistPartition, ShareLock); heap_close(pgDistPartition, AccessShareLock);
return colocatedTableId; return colocatedTableId;
} }