FsyncRequest_delete_v1.patch
application/octet-stream
Filename: FsyncRequest_delete_v1.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v1
| File | + | − |
|---|---|---|
| src/backend/storage/smgr/md.c | 0 | 0 |
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
new file mode 100644
index e5dec9d..d3028da
*** a/src/backend/storage/smgr/md.c
--- b/src/backend/storage/smgr/md.c
***************
*** 59,64 ****
--- 59,66 ----
#define FILE_POSSIBLY_DELETED(err) ((err) == ENOENT || (err) == EACCES)
#endif
+ static bool mdsync_scan_in_progress = false;
+
/*
* The magnetic disk storage manager keeps track of open file
* descriptors in its own descriptor pool. This is done to make it
*************** static MdfdVec *_mdfd_getseg(SMgrRelatio
*** 176,181 ****
--- 178,184 ----
BlockNumber blkno, bool skipFsync, ExtensionBehavior behavior);
static BlockNumber _mdnblocks(SMgrRelation reln, ForkNumber forknum,
MdfdVec *seg);
+ static void _cancel_fsync(PendingOperationEntry *entry);
/*
*************** mdsync(void)
*** 1010,1015 ****
--- 1013,1021 ----
/* Set flag to detect failure if we don't reach the end of the loop */
mdsync_in_progress = true;
+ /* advice FORGET_*_FSYNC operations that they can't delete from the pendingOpsTable */
+ mdsync_scan_in_progress = true;
+
/* Now scan the hashtable for fsync requests to process */
absorb_counter = FSYNCS_PER_ABSORB;
hash_seq_init(&hstat, pendingOpsTable);
*************** mdsync(void)
*** 1125,1133 ****
--- 1131,1142 ----
entry->tag.segno);
if (!FILE_POSSIBLY_DELETED(errno) ||
failures > 0)
+ {
+ mdsync_scan_in_progress = false;
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not fsync file \"%s\": %m", path)));
+ }
else
ereport(DEBUG1,
(errcode_for_file_access(),
*************** mdsync(void)
*** 1163,1168 ****
--- 1172,1178 ----
/* Flag successful completion of mdsync */
mdsync_in_progress = false;
+ mdsync_scan_in_progress = false;
}
/*
*************** register_unlink(RelFileNodeBackend rnode
*** 1328,1336 ****
* - UNLINK_RELATION_REQUEST is a request to delete the file after the next
* checkpoint.
*
! * (Handling the FORGET_* requests is a tad slow because the hash table has
* to be searched linearly, but it doesn't seem worth rethinking the table
! * structure for them.)
*/
void
RememberFsyncRequest(RelFileNodeBackend rnode, ForkNumber forknum,
--- 1338,1349 ----
* - UNLINK_RELATION_REQUEST is a request to delete the file after the next
* checkpoint.
*
! * Handling the FORGET_* requests is a tad slow because the hash table has
* to be searched linearly, but it doesn't seem worth rethinking the table
! * structure for them. However, when it is safe to delete the entry
! * rather than mark it canceled, do so. This prevents excessive bloat
! * when relations are being created and dropped (or truncated) at a
! * prodigous rate.
*/
void
RememberFsyncRequest(RelFileNodeBackend rnode, ForkNumber forknum,
*************** RememberFsyncRequest(RelFileNodeBackend
*** 1349,1358 ****
{
if (RelFileNodeBackendEquals(entry->tag.rnode, rnode) &&
entry->tag.forknum == forknum)
! {
! /* Okay, cancel this entry */
! entry->canceled = true;
! }
}
}
else if (segno == FORGET_DATABASE_FSYNC)
--- 1362,1368 ----
{
if (RelFileNodeBackendEquals(entry->tag.rnode, rnode) &&
entry->tag.forknum == forknum)
! _cancel_fsync(entry);
}
}
else if (segno == FORGET_DATABASE_FSYNC)
*************** RememberFsyncRequest(RelFileNodeBackend
*** 1369,1378 ****
while ((entry = (PendingOperationEntry *) hash_seq_search(&hstat)) != NULL)
{
if (entry->tag.rnode.node.dbNode == rnode.node.dbNode)
! {
! /* Okay, cancel this entry */
! entry->canceled = true;
! }
}
/* Remove unlink requests */
--- 1379,1385 ----
while ((entry = (PendingOperationEntry *) hash_seq_search(&hstat)) != NULL)
{
if (entry->tag.rnode.node.dbNode == rnode.node.dbNode)
! _cancel_fsync(entry);
}
/* Remove unlink requests */
*************** _mdnblocks(SMgrRelation reln, ForkNumber
*** 1670,1672 ****
--- 1677,1694 ----
/* note that this calculation will ignore any partial block at EOF */
return (BlockNumber) (len / BLCKSZ);
}
+
+ static void
+ _cancel_fsync(PendingOperationEntry *entry)
+ {
+ /* When we are sure there is no other seq_scan going on, just delete the entry
+ * rather than marking it canceled
+ */
+ if (mdsync_scan_in_progress) {
+ entry->canceled = true;
+ } else {
+ if (hash_search(pendingOpsTable, &entry->tag,
+ HASH_REMOVE, NULL) == NULL)
+ elog(ERROR, "pendingOpsTable corrupted");
+ };
+ };