Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cca1863

Browse filesBrowse files
committed
Add pg_dissect_walfile_name()
This function takes in input a WAL segment name and returns a tuple made of the segment sequence number (dependent on the WAL segment size of the cluster) and its timeline, as of a thin SQL wrapper around the existing XLogFromFileName(). This function has multiple usages, like being able to compile a LSN from a file name and an offset, or finding the timeline of a segment without having to do to some maths based on the first eight characters of the segment. Bump catalog version. Author: Bharath Rupireddy Reviewed-by: Nathan Bossart, Kyotaro Horiguchi, Maxim Orlov, Michael Paquier Discussion: https://postgr.es/m/CALj2ACWV=FCddsxcGbVOA=cvPyMr75YCFbSQT6g4KDj=gcJK4g@mail.gmail.com
1 parent b3bb7d1 commit cca1863
Copy full SHA for cca1863

File tree

6 files changed

+125
-1
lines changed
Filter options

6 files changed

+125
-1
lines changed

‎doc/src/sgml/func.sgml

Copy file name to clipboardExpand all lines: doc/src/sgml/func.sgml
+33Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26098,6 +26098,22 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560
2609826098
</para></entry>
2609926099
</row>
2610026100

26101+
<row>
26102+
<entry role="func_table_entry"><para role="func_signature">
26103+
<indexterm>
26104+
<primary>pg_dissect_walfile_name</primary>
26105+
</indexterm>
26106+
<function>pg_dissect_walfile_name</function> ( <parameter>file_name</parameter> <type>text</type> )
26107+
<returnvalue>record</returnvalue>
26108+
( <parameter>segno</parameter> <type>numeric</type>,
26109+
<parameter>timeline_id</parameter> <type>bigint</type> )
26110+
</para>
26111+
<para>
26112+
Extracts the file sequence number and timeline ID from a WAL file
26113+
name.
26114+
</para></entry>
26115+
</row>
26116+
2610126117
<row>
2610226118
<entry role="func_table_entry"><para role="func_signature">
2610326119
<indexterm>
@@ -26155,6 +26171,23 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn);
2615526171
needs to be archived.
2615626172
</para>
2615726173

26174+
<para>
26175+
<function>pg_dissect_walfile_name</function> is useful to compute a
26176+
<acronym>LSN</acronym> from a file offset and WAL file name, for example:
26177+
<programlisting>
26178+
postgres=# \set file_name '000000010000000100C000AB'
26179+
postgres=# \set offset 256
26180+
postgres=# SELECT '0/0'::pg_lsn + pd.segno * ps.setting::int + :offset AS lsn
26181+
FROM pg_dissect_walfile_name(:'file_name') pd,
26182+
pg_show_all_settings() ps
26183+
WHERE ps.name = 'wal_segment_size';
26184+
lsn
26185+
---------------
26186+
C001/AB000100
26187+
(1 row)
26188+
</programlisting>
26189+
</para>
26190+
2615826191
</sect2>
2615926192

2616026193
<sect2 id="functions-recovery-control">

‎src/backend/access/transam/xlogfuncs.c

Copy file name to clipboardExpand all lines: src/backend/access/transam/xlogfuncs.c
+53Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,59 @@ pg_walfile_name(PG_FUNCTION_ARGS)
432432
PG_RETURN_TEXT_P(cstring_to_text(xlogfilename));
433433
}
434434

435+
/*
436+
* Extract the sequence number and the timeline ID from given a WAL file
437+
* name.
438+
*/
439+
Datum
440+
pg_dissect_walfile_name(PG_FUNCTION_ARGS)
441+
{
442+
#define PG_DISSECT_WALFILE_NAME_COLS 2
443+
char *fname = text_to_cstring(PG_GETARG_TEXT_PP(0));
444+
char *fname_upper;
445+
char *p;
446+
TimeLineID tli;
447+
XLogSegNo segno;
448+
Datum values[PG_DISSECT_WALFILE_NAME_COLS] = {0};
449+
bool isnull[PG_DISSECT_WALFILE_NAME_COLS] = {0};
450+
TupleDesc tupdesc;
451+
HeapTuple tuple;
452+
char buf[256];
453+
Datum result;
454+
455+
fname_upper = pstrdup(fname);
456+
457+
/* Capitalize WAL file name. */
458+
for (p = fname_upper; *p; p++)
459+
*p = pg_toupper((unsigned char) *p);
460+
461+
if (!IsXLogFileName(fname_upper))
462+
ereport(ERROR,
463+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
464+
errmsg("invalid WAL file name \"%s\"", fname)));
465+
466+
XLogFromFileName(fname_upper, &tli, &segno, wal_segment_size);
467+
468+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
469+
elog(ERROR, "return type must be a row type");
470+
471+
/* Convert to numeric. */
472+
snprintf(buf, sizeof buf, UINT64_FORMAT, segno);
473+
values[0] = DirectFunctionCall3(numeric_in,
474+
CStringGetDatum(buf),
475+
ObjectIdGetDatum(0),
476+
Int32GetDatum(-1));
477+
478+
values[1] = Int64GetDatum(tli);
479+
480+
tuple = heap_form_tuple(tupdesc, values, isnull);
481+
result = HeapTupleGetDatum(tuple);
482+
483+
PG_RETURN_DATUM(result);
484+
485+
#undef PG_DISSECT_WALFILE_NAME_COLS
486+
}
487+
435488
/*
436489
* pg_wal_replay_pause - Request to pause recovery
437490
*

‎src/include/catalog/catversion.h

Copy file name to clipboardExpand all lines: src/include/catalog/catversion.h
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@
5757
*/
5858

5959
/* yyyymmddN */
60-
#define CATALOG_VERSION_NO 202212191
60+
#define CATALOG_VERSION_NO 202212201
6161

6262
#endif

‎src/include/catalog/pg_proc.dat

Copy file name to clipboardExpand all lines: src/include/catalog/pg_proc.dat
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6372,6 +6372,13 @@
63726372
{ oid => '2851', descr => 'wal filename, given a wal location',
63736373
proname => 'pg_walfile_name', prorettype => 'text', proargtypes => 'pg_lsn',
63746374
prosrc => 'pg_walfile_name' },
6375+
{ oid => '8205',
6376+
descr => 'sequence number and timeline ID given a wal filename',
6377+
proname => 'pg_dissect_walfile_name', provolatile => 's',
6378+
prorettype => 'record', proargtypes => 'text',
6379+
proallargtypes => '{text,numeric,int8}', proargmodes => '{i,o,o}',
6380+
proargnames => '{file_name,segno,timeline_id}',
6381+
prosrc => 'pg_dissect_walfile_name' },
63756382

63766383
{ oid => '3165', descr => 'difference in bytes, given two wal locations',
63776384
proname => 'pg_wal_lsn_diff', prorettype => 'numeric',

‎src/test/regress/expected/misc_functions.out

Copy file name to clipboardExpand all lines: src/test/regress/expected/misc_functions.out
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,3 +619,26 @@ SELECT count(*) > 0 AS ok FROM pg_control_system();
619619
t
620620
(1 row)
621621

622+
-- pg_dissect_walfile_name
623+
SELECT * FROM pg_dissect_walfile_name(NULL);
624+
segno | timeline_id
625+
-------+-------------
626+
|
627+
(1 row)
628+
629+
SELECT * FROM pg_dissect_walfile_name('invalid');
630+
ERROR: invalid WAL file name "invalid"
631+
SELECT segno > 0 AS ok_segno, timeline_id
632+
FROM pg_dissect_walfile_name('000000010000000100000000');
633+
ok_segno | timeline_id
634+
----------+-------------
635+
t | 1
636+
(1 row)
637+
638+
SELECT segno > 0 AS ok_segno, timeline_id
639+
FROM pg_dissect_walfile_name('ffffffFF00000001000000af');
640+
ok_segno | timeline_id
641+
----------+-------------
642+
t | 4294967295
643+
(1 row)
644+

‎src/test/regress/sql/misc_functions.sql

Copy file name to clipboardExpand all lines: src/test/regress/sql/misc_functions.sql
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,11 @@ SELECT count(*) > 0 AS ok FROM pg_control_checkpoint();
229229
SELECT count(*) > 0 AS ok FROM pg_control_init();
230230
SELECT count(*) > 0 AS ok FROM pg_control_recovery();
231231
SELECT count(*) > 0 AS ok FROM pg_control_system();
232+
233+
-- pg_dissect_walfile_name
234+
SELECT * FROM pg_dissect_walfile_name(NULL);
235+
SELECT * FROM pg_dissect_walfile_name('invalid');
236+
SELECT segno > 0 AS ok_segno, timeline_id
237+
FROM pg_dissect_walfile_name('000000010000000100000000');
238+
SELECT segno > 0 AS ok_segno, timeline_id
239+
FROM pg_dissect_walfile_name('ffffffFF00000001000000af');

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.