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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy