@ -66,6 +66,7 @@ typedef struct
{
{
FileTag tag ; /* identifies handler and file */
FileTag tag ; /* identifies handler and file */
CycleCtr cycle_ctr ; /* checkpoint_cycle_ctr when request was made */
CycleCtr cycle_ctr ; /* checkpoint_cycle_ctr when request was made */
bool canceled ; /* true if request has been canceled */
} PendingUnlinkEntry ;
} PendingUnlinkEntry ;
static HTAB * pendingOps = NULL ;
static HTAB * pendingOps = NULL ;
@ -174,13 +175,18 @@ void
SyncPostCheckpoint ( void )
SyncPostCheckpoint ( void )
{
{
int absorb_counter ;
int absorb_counter ;
ListCell * lc ;
absorb_counter = UNLINKS_PER_ABSORB ;
absorb_counter = UNLINKS_PER_ABSORB ;
while ( pendingUnlinks ! = NIL )
foreach ( lc , pendingUnlinks )
{
{
PendingUnlinkEntry * entry = ( PendingUnlinkEntry * ) linitial ( pendingUnlinks ) ;
PendingUnlinkEntry * entry = ( PendingUnlinkEntry * ) lfirst ( lc ) ;
char path [ MAXPGPATH ] ;
char path [ MAXPGPATH ] ;
/* Skip over any canceled entries */
if ( entry - > canceled )
continue ;
/*
/*
* New entries are appended to the end , so if the entry is new we ' ve
* New entries are appended to the end , so if the entry is new we ' ve
* reached the end of old entries .
* reached the end of old entries .
@ -210,15 +216,13 @@ SyncPostCheckpoint(void)
errmsg ( " could not remove file \" %s \" : %m " , path ) ) ) ;
errmsg ( " could not remove file \" %s \" : %m " , path ) ) ) ;
}
}
/* And remove the list entry */
/* Mark the list entry as canceled, just in case */
pendingUnlinks = list_delete_first ( pendingUnlinks ) ;
entry - > canceled = true ;
pfree ( entry ) ;
/*
/*
* As in ProcessSyncRequests , we don ' t want to stop absorbing fsync
* As in ProcessSyncRequests , we don ' t want to stop absorbing fsync
* requests for a long time when there are many deletions to be done .
* requests for a long time when there are many deletions to be done .
* We can safely call AbsorbSyncRequests ( ) at this point in the loop
* We can safely call AbsorbSyncRequests ( ) at this point in the loop .
* ( note it might try to delete list entries ) .
*/
*/
if ( - - absorb_counter < = 0 )
if ( - - absorb_counter < = 0 )
{
{
@ -226,6 +230,26 @@ SyncPostCheckpoint(void)
absorb_counter = UNLINKS_PER_ABSORB ;
absorb_counter = UNLINKS_PER_ABSORB ;
}
}
}
}
/*
* If we reached the end of the list , we can just remove the whole list
* ( remembering to pfree all the PendingUnlinkEntry objects ) . Otherwise ,
* we must keep the entries at or after " lc " .
*/
if ( lc = = NULL )
{
list_free_deep ( pendingUnlinks ) ;
pendingUnlinks = NIL ;
}
else
{
int ntodelete = list_cell_number ( pendingUnlinks , lc ) ;
for ( int i = 0 ; i < ntodelete ; i + + )
pfree ( list_nth ( pendingUnlinks , i ) ) ;
pendingUnlinks = list_delete_first_n ( pendingUnlinks , ntodelete ) ;
}
}
}
/*
/*
@ -465,17 +489,14 @@ RememberSyncRequest(const FileTag *ftag, SyncRequestType type)
entry - > canceled = true ;
entry - > canceled = true ;
}
}
/* Remove matching unlink requests */
/* Cancel matching unlink requests */
foreach ( cell , pendingUnlinks )
foreach ( cell , pendingUnlinks )
{
{
PendingUnlinkEntry * entry = ( PendingUnlinkEntry * ) lfirst ( cell ) ;
PendingUnlinkEntry * entry = ( PendingUnlinkEntry * ) lfirst ( cell ) ;
if ( entry - > tag . handler = = ftag - > handler & &
if ( entry - > tag . handler = = ftag - > handler & &
syncsw [ ftag - > handler ] . sync_filetagmatches ( ftag , & entry - > tag ) )
syncsw [ ftag - > handler ] . sync_filetagmatches ( ftag , & entry - > tag ) )
{
entry - > canceled = true ;
pendingUnlinks = foreach_delete_current ( pendingUnlinks , cell ) ;
pfree ( entry ) ;
}
}
}
}
}
else if ( type = = SYNC_UNLINK_REQUEST )
else if ( type = = SYNC_UNLINK_REQUEST )
@ -487,6 +508,7 @@ RememberSyncRequest(const FileTag *ftag, SyncRequestType type)
entry = palloc ( sizeof ( PendingUnlinkEntry ) ) ;
entry = palloc ( sizeof ( PendingUnlinkEntry ) ) ;
entry - > tag = * ftag ;
entry - > tag = * ftag ;
entry - > cycle_ctr = checkpoint_cycle_ctr ;
entry - > cycle_ctr = checkpoint_cycle_ctr ;
entry - > canceled = false ;
pendingUnlinks = lappend ( pendingUnlinks , entry ) ;
pendingUnlinks = lappend ( pendingUnlinks , entry ) ;