fix-concurrent-tablespace-update.patch
text/x-diff
Filename: fix-concurrent-tablespace-update.patch
Type: text/x-diff
Part: 0
colordiff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
new file mode 100644
index 1f6e02d..60a5099
*** a/src/backend/commands/dbcommands.c
--- b/src/backend/commands/dbcommands.c
*************** createdb(const CreatedbStmt *stmt)
*** 549,556 ****
/*
* Iterate through all tablespaces of the template database, and copy
* each one to the new database.
*/
! rel = heap_open(TableSpaceRelationId, AccessShareLock);
scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
{
--- 549,563 ----
/*
* Iterate through all tablespaces of the template database, and copy
* each one to the new database.
+ *
+ * We need to use ShareLock to prevent other processes from updating a
+ * tablespace (such as changing an ACL, for example) or we will end up
+ * running into the same tablespace multiple times during our heap scan
+ * (the prior-to-update tuple and then the new tuple after the update)
+ * and copydir() will, rightfully, complain that the directory already
+ * exists.
*/
! rel = heap_open(TableSpaceRelationId, ShareLock);
scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
{
*************** createdb(const CreatedbStmt *stmt)
*** 607,613 ****
}
}
heap_endscan(scan);
! heap_close(rel, AccessShareLock);
/*
* We force a checkpoint before committing. This effectively means
--- 614,620 ----
}
}
heap_endscan(scan);
! heap_close(rel, ShareLock);
/*
* We force a checkpoint before committing. This effectively means