Skip to content

Commit a19ee0a

Browse files
committed
Wait GC completion in cfs_gc_control
1 parent 64678ba commit a19ee0a

File tree

3 files changed

+52
-12
lines changed

3 files changed

+52
-12
lines changed

src/backend/access/transam/xlog.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "storage/barrier.h"
5555
#include "storage/bufmgr.h"
5656
#include "storage/fd.h"
57+
#include "storage/cfs.h"
5758
#include "storage/ipc.h"
5859
#include "storage/large_object.h"
5960
#include "storage/latch.h"
@@ -121,6 +122,7 @@ int CheckPointSegments;
121122
/* Estimated distance between checkpoints, in bytes */
122123
static double CheckPointDistanceEstimate = 0;
123124
static double PrevCheckPointDistance = 0;
125+
static bool SavedGCState = false;
124126

125127
/*
126128
* GUC support
@@ -9872,6 +9874,8 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p,
98729874
XLogCtl->Insert.forcePageWrites = true;
98739875
WALInsertLockRelease();
98749876

9877+
SavedGCState = cfs_control_gc(false); /* disable GC during backup */
9878+
98759879
/* Ensure we release forcePageWrites if fail below */
98769880
PG_ENSURE_ERROR_CLEANUP(pg_start_backup_callback, (Datum) BoolGetDatum(exclusive));
98779881
{
@@ -10234,6 +10238,8 @@ pg_start_backup_callback(int code, Datum arg)
1023410238
XLogCtl->Insert.forcePageWrites = false;
1023510239
}
1023610240
WALInsertLockRelease();
10241+
10242+
cfs_control_gc(SavedGCState); /* Restore CFS GC activity */
1023710243
}
1023810244

1023910245
/*
@@ -10594,6 +10600,8 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
1059410600
ereport(NOTICE,
1059510601
(errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
1059610602

10603+
cfs_control_gc(SavedGCState); /* Restore CFS GC activity */
10604+
1059710605
/*
1059810606
* We're done. As a convenience, return the ending WAL location.
1059910607
*/

src/backend/storage/file/cfs.c

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,11 @@ void cfs_initialize()
281281
cfs_state = (CfsState*)ShmemAlloc(sizeof(CfsState));
282282
memset(&cfs_state->gc_stat, 0, sizeof cfs_state->gc_stat);
283283
pg_atomic_init_flag(&cfs_state->gc_started);
284+
pg_atomic_init_u32(&cfs_state->n_active_gc, 0);
284285
cfs_state->n_workers = 0;
285286
cfs_state->gc_enabled = true;
286287
cfs_state->max_iterations = 0;
288+
287289
if (cfs_encryption) {
288290
cfs_rc4_init();
289291
}
@@ -470,26 +472,34 @@ static bool cfs_gc_file(char* map_path)
470472
uint32 virtSize;
471473
int suf = strlen(map_path)-4;
472474
int fd = -1, fd2 = -1, md2 = -1;
473-
bool succeed = true;
475+
bool succeed = false;
476+
477+
pg_atomic_fetch_add_u32(&cfs_state->n_active_gc, 1);
474478

475479
while (!cfs_state->gc_enabled) {
476-
int rc = WaitLatch(MyLatch,
477-
WL_TIMEOUT | WL_POSTMASTER_DEATH,
478-
CFS_DISABLE_TIMEOUT /* ms */ );
480+
int rc;
481+
482+
pg_atomic_fetch_sub_u32(&cfs_state->n_active_gc, 1);
483+
484+
rc = WaitLatch(MyLatch,
485+
WL_TIMEOUT | WL_POSTMASTER_DEATH,
486+
CFS_DISABLE_TIMEOUT /* ms */,
487+
WAIT_EVENT_CFS_GC_ENABLE);
479488
if (cfs_stop || (rc & WL_POSTMASTER_DEATH)) {
480489
exit(1);
481490
}
482491
}
483492
if (md < 0) {
484493
elog(LOG, "Failed to open map file %s: %m", map_path);
485-
return false;
494+
goto FinishGC;
486495
}
487496
map = cfs_mmap(md);
488497
if (map == MAP_FAILED) {
489498
elog(LOG, "Failed to map file %s: %m", map_path);
490499
close(md);
491-
return false;
500+
goto FinishGC;
492501
}
502+
succeed = true;
493503
usedSize = pg_atomic_read_u32(&map->usedSize);
494504
physSize = pg_atomic_read_u32(&map->physSize);
495505
virtSize = pg_atomic_read_u32(&map->virtSize);
@@ -525,7 +535,8 @@ static bool cfs_gc_file(char* map_path)
525535
break;
526536
}
527537
if (cfs_stop) {
528-
return false;
538+
succeed = false;
539+
goto FinishGC;
529540
}
530541
if (access_count >= CFS_GC_LOCK) {
531542
/* Uhhh... looks like last GC was interrupted.
@@ -734,6 +745,8 @@ static bool cfs_gc_file(char* map_path)
734745
elog(LOG, "Failed to close file %s: %m", map_path);
735746
succeed = false;
736747
}
748+
FinishGC:
749+
pg_atomic_fetch_sub_u32(&cfs_state->n_active_gc, 1);
737750
return succeed;
738751
}
739752

@@ -833,6 +846,25 @@ void cfs_start_background_gc()
833846
elog(LOG, "Start %d background CFS background workers", i);
834847
}
835848

849+
bool cfs_control_gc(bool enabled)
850+
{
851+
bool was_enabled = cfs_state->gc_enabled;
852+
cfs_state->gc_enabled = enabled;
853+
if (was_enabled && !enabled) {
854+
/* Wait until there are no active GC workers */
855+
while (pg_atomic_read_u32(&cfs_state->n_active_gc) != 0) {
856+
int rc = WaitLatch(MyLatch,
857+
WL_TIMEOUT | WL_POSTMASTER_DEATH,
858+
CFS_DISABLE_TIMEOUT /* ms */,
859+
WAIT_EVENT_CFS_GC_ENABLE);
860+
if (rc & WL_POSTMASTER_DEATH) {
861+
exit(1);
862+
}
863+
}
864+
}
865+
return was_enabled;
866+
}
867+
836868
PG_MODULE_MAGIC;
837869

838870
PG_FUNCTION_INFO_V1(cfs_start_gc);
@@ -883,11 +915,10 @@ Datum cfs_start_gc(PG_FUNCTION_ARGS)
883915
PG_RETURN_INT32(i);
884916
}
885917

918+
886919
Datum cfs_enable_gc(PG_FUNCTION_ARGS)
887-
{
888-
bool prev = cfs_state->gc_enabled;
889-
cfs_state->gc_enabled = PG_GETARG_BOOL(0);
890-
PG_RETURN_BOOL(prev);
920+
{
921+
PG_RETURN_BOOL(cfs_control_gc(PG_GETARG_BOOL(0)));
891922
}
892923

893924
Datum cfs_version(PG_FUNCTION_ARGS)

src/include/storage/cfs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ typedef struct
5555
typedef struct
5656
{
5757
pg_atomic_flag gc_started;
58+
pg_atomic_uint32 n_active_gc;
5859
int n_workers;
5960
int max_iterations;
6061
bool gc_enabled;
@@ -77,7 +78,7 @@ void cfs_lock_file(FileMap* map, char const* path);
7778
void cfs_unlock_file(FileMap* map);
7879
uint32 cfs_alloc_page(FileMap* map, uint32 oldSize, uint32 newSize);
7980
void cfs_extend(FileMap* map, uint32 pos);
80-
81+
bool cfs_control_gc(bool enabled);
8182
int cfs_msync(FileMap* map);
8283
FileMap* cfs_mmap(int md);
8384
int cfs_munmap(FileMap* map);

0 commit comments

Comments
 (0)