Skip to content

Commit a199de2

Browse files
afiskonCommitfest Bot
authored and
Commitfest Bot
committed
Always use long SLRU segment file names
PG17 introduced long SLRU segment file names (commit 4ed8f09). We used short or long file names depending on SlruCtl->long_segment_names. This commit refactors SLRU to always use long file names in order to simplify the code. Aleksander Alekseev, reviewed by Michael Paquier, Rustam Allakov Discussion: https://postgr.es/m/CAJ7c6TOy7fUW9MuNeOWor3cSFnQg9tgz=mjXHDb94GORtM_Eyg@mail.gmail.com (!!!) bump catversion and change the corresponding TODO FIXME line in pg_upgrade.h
1 parent b3754dc commit a199de2

File tree

12 files changed

+103
-85
lines changed

12 files changed

+103
-85
lines changed

src/backend/access/transam/clog.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,7 @@ CLOGShmemInit(void)
810810
XactCtl->PagePrecedes = CLOGPagePrecedes;
811811
SimpleLruInit(XactCtl, "transaction", CLOGShmemBuffers(), CLOG_LSNS_PER_PAGE,
812812
"pg_xact", LWTRANCHE_XACT_BUFFER,
813-
LWTRANCHE_XACT_SLRU, SYNC_HANDLER_CLOG, false);
813+
LWTRANCHE_XACT_SLRU, SYNC_HANDLER_CLOG);
814814
SlruPagePrecedesUnitTests(XactCtl, CLOG_XACTS_PER_PAGE);
815815
}
816816

src/backend/access/transam/commit_ts.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -556,8 +556,7 @@ CommitTsShmemInit(void)
556556
SimpleLruInit(CommitTsCtl, "commit_timestamp", CommitTsShmemBuffers(), 0,
557557
"pg_commit_ts", LWTRANCHE_COMMITTS_BUFFER,
558558
LWTRANCHE_COMMITTS_SLRU,
559-
SYNC_HANDLER_COMMIT_TS,
560-
false);
559+
SYNC_HANDLER_COMMIT_TS);
561560
SlruPagePrecedesUnitTests(CommitTsCtl, COMMIT_TS_XACTS_PER_PAGE);
562561

563562
commitTsShared = ShmemInitStruct("CommitTs shared",

src/backend/access/transam/multixact.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -1974,15 +1974,13 @@ MultiXactShmemInit(void)
19741974
"multixact_offset", multixact_offset_buffers, 0,
19751975
"pg_multixact/offsets", LWTRANCHE_MULTIXACTOFFSET_BUFFER,
19761976
LWTRANCHE_MULTIXACTOFFSET_SLRU,
1977-
SYNC_HANDLER_MULTIXACT_OFFSET,
1978-
false);
1977+
SYNC_HANDLER_MULTIXACT_OFFSET);
19791978
SlruPagePrecedesUnitTests(MultiXactOffsetCtl, MULTIXACT_OFFSETS_PER_PAGE);
19801979
SimpleLruInit(MultiXactMemberCtl,
19811980
"multixact_member", multixact_member_buffers, 0,
19821981
"pg_multixact/members", LWTRANCHE_MULTIXACTMEMBER_BUFFER,
19831982
LWTRANCHE_MULTIXACTMEMBER_SLRU,
1984-
SYNC_HANDLER_MULTIXACT_MEMBER,
1985-
false);
1983+
SYNC_HANDLER_MULTIXACT_MEMBER);
19861984
/* doesn't call SimpleLruTruncate() or meet criteria for unit tests */
19871985

19881986
/* Initialize our shared state struct */

src/backend/access/transam/slru.c

+13-58
Original file line numberDiff line numberDiff line change
@@ -77,41 +77,21 @@
7777
*
7878
* "path" should point to a buffer at least MAXPGPATH characters long.
7979
*
80-
* If ctl->long_segment_names is true, segno can be in the range [0, 2^60-1].
81-
* The resulting file name is made of 15 characters, e.g. dir/123456789ABCDEF.
82-
*
83-
* If ctl->long_segment_names is false, segno can be in the range [0, 2^24-1].
84-
* The resulting file name is made of 4 to 6 characters, as of:
85-
*
86-
* dir/1234 for [0, 2^16-1]
87-
* dir/12345 for [2^16, 2^20-1]
88-
* dir/123456 for [2^20, 2^24-1]
80+
* segno can be in the range [0, 2^60-1]. The resulting file name is made
81+
* of 15 characters, e.g. dir/123456789ABCDEF.
8982
*/
9083
static inline int
9184
SlruFileName(SlruCtl ctl, char *path, int64 segno)
9285
{
93-
if (ctl->long_segment_names)
94-
{
95-
/*
96-
* We could use 16 characters here but the disadvantage would be that
97-
* the SLRU segments will be hard to distinguish from WAL segments.
98-
*
99-
* For this reason we use 15 characters. It is enough but also means
100-
* that in the future we can't decrease SLRU_PAGES_PER_SEGMENT easily.
101-
*/
102-
Assert(segno >= 0 && segno <= INT64CONST(0xFFFFFFFFFFFFFFF));
103-
return snprintf(path, MAXPGPATH, "%s/%015" PRIX64, ctl->Dir, segno);
104-
}
105-
else
106-
{
107-
/*
108-
* Despite the fact that %04X format string is used up to 24 bit
109-
* integers are allowed. See SlruCorrectSegmentFilenameLength()
110-
*/
111-
Assert(segno >= 0 && segno <= INT64CONST(0xFFFFFF));
112-
return snprintf(path, MAXPGPATH, "%s/%04X", (ctl)->Dir,
113-
(unsigned int) segno);
114-
}
86+
/*
87+
* We could use 16 characters here but the disadvantage would be that
88+
* the SLRU segments will be hard to distinguish from WAL segments.
89+
*
90+
* For this reason we use 15 characters. It is enough but also means
91+
* that in the future we can't decrease SLRU_PAGES_PER_SEGMENT easily.
92+
*/
93+
Assert(segno >= 0 && segno <= INT64CONST(0xFFFFFFFFFFFFFFF));
94+
return snprintf(path, MAXPGPATH, "%s/%015" PRIX64, ctl->Dir, segno);
11595
}
11696

11797
/*
@@ -250,7 +230,7 @@ SimpleLruAutotuneBuffers(int divisor, int max)
250230
void
251231
SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
252232
const char *subdir, int buffer_tranche_id, int bank_tranche_id,
253-
SyncRequestHandler sync_handler, bool long_segment_names)
233+
SyncRequestHandler sync_handler)
254234
{
255235
SlruShared shared;
256236
bool found;
@@ -341,7 +321,6 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
341321
*/
342322
ctl->shared = shared;
343323
ctl->sync_handler = sync_handler;
344-
ctl->long_segment_names = long_segment_names;
345324
ctl->nbanks = nbanks;
346325
strlcpy(ctl->Dir, subdir, sizeof(ctl->Dir));
347326
}
@@ -1747,30 +1726,6 @@ SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int64 segpage, void *data)
17471726
return false; /* keep going */
17481727
}
17491728

1750-
/*
1751-
* An internal function used by SlruScanDirectory().
1752-
*
1753-
* Returns true if a file with a name of a given length may be a correct
1754-
* SLRU segment.
1755-
*/
1756-
static inline bool
1757-
SlruCorrectSegmentFilenameLength(SlruCtl ctl, size_t len)
1758-
{
1759-
if (ctl->long_segment_names)
1760-
return (len == 15); /* see SlruFileName() */
1761-
else
1762-
1763-
/*
1764-
* Commit 638cf09e76d allowed 5-character lengths. Later commit
1765-
* 73c986adde5 allowed 6-character length.
1766-
*
1767-
* Note: There is an ongoing plan to migrate all SLRUs to 64-bit page
1768-
* numbers, and the corresponding 15-character file names, which may
1769-
* eventually deprecate the support for 4, 5, and 6-character names.
1770-
*/
1771-
return (len == 4 || len == 5 || len == 6);
1772-
}
1773-
17741729
/*
17751730
* Scan the SimpleLru directory and apply a callback to each file found in it.
17761731
*
@@ -1802,7 +1757,7 @@ SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data)
18021757

18031758
len = strlen(clde->d_name);
18041759

1805-
if (SlruCorrectSegmentFilenameLength(ctl, len) &&
1760+
if ((len == 15) &&
18061761
strspn(clde->d_name, "0123456789ABCDEF") == len)
18071762
{
18081763
segno = strtoi64(clde->d_name, NULL, 16);

src/backend/access/transam/subtrans.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ SUBTRANSShmemInit(void)
243243
SubTransCtl->PagePrecedes = SubTransPagePrecedes;
244244
SimpleLruInit(SubTransCtl, "subtransaction", SUBTRANSShmemBuffers(), 0,
245245
"pg_subtrans", LWTRANCHE_SUBTRANS_BUFFER,
246-
LWTRANCHE_SUBTRANS_SLRU, SYNC_HANDLER_NONE, false);
246+
LWTRANCHE_SUBTRANS_SLRU, SYNC_HANDLER_NONE);
247247
SlruPagePrecedesUnitTests(SubTransCtl, SUBTRANS_XACTS_PER_PAGE);
248248
}
249249

src/backend/commands/async.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ AsyncShmemInit(void)
537537
NotifyCtl->PagePrecedes = asyncQueuePagePrecedes;
538538
SimpleLruInit(NotifyCtl, "notify", notify_buffers, 0,
539539
"pg_notify", LWTRANCHE_NOTIFY_BUFFER, LWTRANCHE_NOTIFY_SLRU,
540-
SYNC_HANDLER_NONE, true);
540+
SYNC_HANDLER_NONE);
541541

542542
if (!found)
543543
{

src/backend/storage/lmgr/predicate.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ SerialInit(void)
814814
SimpleLruInit(SerialSlruCtl, "serializable",
815815
serializable_buffers, 0, "pg_serial",
816816
LWTRANCHE_SERIAL_BUFFER, LWTRANCHE_SERIAL_SLRU,
817-
SYNC_HANDLER_NONE, false);
817+
SYNC_HANDLER_NONE);
818818
#ifdef USE_ASSERT_CHECKING
819819
SerialPagePrecedesLogicallyUnitTests();
820820
#endif

src/bin/pg_upgrade/pg_upgrade.c

+74
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
#include "postgres_fe.h"
4343

44+
#include <dirent.h>
4445
#include <time.h>
4546

4647
#include "catalog/pg_class_d.h"
@@ -63,6 +64,8 @@ static void prepare_new_cluster(void);
6364
static void prepare_new_globals(void);
6465
static void create_new_objects(void);
6566
static void copy_xact_xlog_xid(void);
67+
static void check_slru_segment_filenames(void);
68+
static void rename_slru_segments(const char *dirname);
6669
static void set_frozenxids(bool minmxid_only);
6770
static void make_outputdirs(char *pgdata);
6871
static void setup(char *argv0);
@@ -159,6 +162,7 @@ main(int argc, char **argv)
159162

160163
copy_xact_xlog_xid();
161164
set_new_cluster_char_signedness();
165+
check_slru_segment_filenames();
162166

163167
/* New now using xids of the old system */
164168

@@ -849,6 +853,76 @@ copy_xact_xlog_xid(void)
849853
check_ok();
850854
}
851855

856+
static void
857+
rename_slru_segments(const char* dirname)
858+
{
859+
DIR *dir;
860+
struct dirent *de;
861+
int len;
862+
int64 segno;
863+
char dir_path[MAXPGPATH];
864+
char old_path[MAXPGPATH];
865+
char new_path[MAXPGPATH];
866+
867+
prep_status("Renaming SLRU segments in %s", dirname);
868+
snprintf(dir_path, sizeof(dir_path), "%s/%s", new_cluster.pgdata, dirname);
869+
870+
dir = opendir(dir_path);
871+
if (dir == NULL)
872+
pg_fatal("could not open directory \"%s\": %m", dir_path);
873+
874+
while (errno = 0, (de = readdir(dir)) != NULL)
875+
{
876+
/*
877+
* ignore '.', '..' and everything else that doesn't look
878+
* like an SLRU segment with a short file name
879+
*/
880+
881+
len = strlen(de->d_name);
882+
if(len != 4 && len != 5 && len != 6)
883+
continue;
884+
885+
if(strspn(de->d_name, "0123456789ABCDEF") != len)
886+
continue;
887+
888+
segno = strtoi64(de->d_name, NULL, 16);
889+
snprintf(new_path, MAXPGPATH, "%s/%015llX", dir_path,
890+
(long long) segno);
891+
snprintf(old_path, MAXPGPATH, "%s/%s", dir_path, de->d_name);
892+
893+
if (pg_mv_file(old_path, new_path) != 0)
894+
pg_fatal("could not rename file \"%s\" to \"%s\": %m",
895+
old_path, new_path);
896+
}
897+
898+
if (errno)
899+
pg_fatal("could not read directory \"%s\": %m", dir_path);
900+
901+
if (closedir(dir))
902+
pg_fatal("could not close directory \"%s\": %m", dir_path);
903+
904+
check_ok();
905+
}
906+
907+
static void
908+
check_slru_segment_filenames(void)
909+
{
910+
int i;
911+
static const char* dirs[] = {
912+
"pg_xact",
913+
"pg_commit_ts",
914+
"pg_multixact/offsets",
915+
"pg_multixact/members",
916+
"pg_subtrans",
917+
"pg_serial",
918+
};
919+
920+
if(old_cluster.controldata.cat_ver >= SLRU_SEG_FILENAMES_CHANGE_CAT_VER)
921+
return;
922+
923+
for (i = 0; i < sizeof(dirs)/sizeof(dirs[0]); i++)
924+
rename_slru_segments(dirs[i]);
925+
}
852926

853927
/*
854928
* set_frozenxids()

src/bin/pg_upgrade/pg_upgrade.h

+6
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,12 @@ extern char *output_files[];
131131
*/
132132
#define DEFAULT_CHAR_SIGNEDNESS_CAT_VER 202502212
133133

134+
/*
135+
* change of SLRU segment filenames length in 18.0
136+
* TODO FIXME CHANGE TO THE ACTUAL VALUE BEFORE COMMITTING
137+
*/
138+
#define SLRU_SEG_FILENAMES_CHANGE_CAT_VER 202412201
139+
134140
/*
135141
* Each relation is represented by a relinfo structure.
136142
*/

src/bin/pg_verifybackup/t/003_corruption.pl

+1-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ sub mutilate_extra_tablespace_file
246246
sub mutilate_missing_file
247247
{
248248
my ($backup_path) = @_;
249-
my $pathname = "$backup_path/pg_xact/0000";
249+
my $pathname = "$backup_path/pg_xact/000000000000000";
250250
unlink($pathname) || die "$pathname: $!";
251251
return;
252252
}

src/include/access/slru.h

+1-9
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,6 @@ typedef struct SlruCtlData
131131
/* Number of banks in this SLRU. */
132132
uint16 nbanks;
133133

134-
/*
135-
* If true, use long segment file names. Otherwise, use short file names.
136-
*
137-
* For details about the file name format, see SlruFileName().
138-
*/
139-
bool long_segment_names;
140-
141134
/*
142135
* Which sync handler function to use when handing sync requests over to
143136
* the checkpointer. SYNC_HANDLER_NONE to disable fsync (eg pg_notify).
@@ -184,8 +177,7 @@ extern Size SimpleLruShmemSize(int nslots, int nlsns);
184177
extern int SimpleLruAutotuneBuffers(int divisor, int max);
185178
extern void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
186179
const char *subdir, int buffer_tranche_id,
187-
int bank_tranche_id, SyncRequestHandler sync_handler,
188-
bool long_segment_names);
180+
int bank_tranche_id, SyncRequestHandler sync_handler);
189181
extern int SimpleLruZeroPage(SlruCtl ctl, int64 pageno);
190182
extern int SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok,
191183
TransactionId xid);

src/test/modules/test_slru/test_slru.c

+1-7
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,6 @@ test_slru_page_precedes_logically(int64 page1, int64 page2)
213213
static void
214214
test_slru_shmem_startup(void)
215215
{
216-
/*
217-
* Short segments names are well tested elsewhere so in this test we are
218-
* focusing on long names.
219-
*/
220-
const bool long_segment_names = true;
221216
const char slru_dir_name[] = "pg_test_slru";
222217
int test_tranche_id;
223218
int test_buffer_tranche_id;
@@ -241,8 +236,7 @@ test_slru_shmem_startup(void)
241236
TestSlruCtl->PagePrecedes = test_slru_page_precedes_logically;
242237
SimpleLruInit(TestSlruCtl, "TestSLRU",
243238
NUM_TEST_BUFFERS, 0, slru_dir_name,
244-
test_buffer_tranche_id, test_tranche_id, SYNC_HANDLER_NONE,
245-
long_segment_names);
239+
test_buffer_tranche_id, test_tranche_id, SYNC_HANDLER_NONE);
246240
}
247241

248242
void

0 commit comments

Comments
 (0)