mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
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
This commit is contained in:
parent
b3bb7d12af
commit
cca1863489
@ -26098,6 +26098,22 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560
|
|||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry role="func_table_entry"><para role="func_signature">
|
||||||
|
<indexterm>
|
||||||
|
<primary>pg_dissect_walfile_name</primary>
|
||||||
|
</indexterm>
|
||||||
|
<function>pg_dissect_walfile_name</function> ( <parameter>file_name</parameter> <type>text</type> )
|
||||||
|
<returnvalue>record</returnvalue>
|
||||||
|
( <parameter>segno</parameter> <type>numeric</type>,
|
||||||
|
<parameter>timeline_id</parameter> <type>bigint</type> )
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Extracts the file sequence number and timeline ID from a WAL file
|
||||||
|
name.
|
||||||
|
</para></entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry role="func_table_entry"><para role="func_signature">
|
<entry role="func_table_entry"><para role="func_signature">
|
||||||
<indexterm>
|
<indexterm>
|
||||||
@ -26155,6 +26171,23 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn);
|
|||||||
needs to be archived.
|
needs to be archived.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<function>pg_dissect_walfile_name</function> is useful to compute a
|
||||||
|
<acronym>LSN</acronym> from a file offset and WAL file name, for example:
|
||||||
|
<programlisting>
|
||||||
|
postgres=# \set file_name '000000010000000100C000AB'
|
||||||
|
postgres=# \set offset 256
|
||||||
|
postgres=# SELECT '0/0'::pg_lsn + pd.segno * ps.setting::int + :offset AS lsn
|
||||||
|
FROM pg_dissect_walfile_name(:'file_name') pd,
|
||||||
|
pg_show_all_settings() ps
|
||||||
|
WHERE ps.name = 'wal_segment_size';
|
||||||
|
lsn
|
||||||
|
---------------
|
||||||
|
C001/AB000100
|
||||||
|
(1 row)
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="functions-recovery-control">
|
<sect2 id="functions-recovery-control">
|
||||||
|
@ -432,6 +432,59 @@ pg_walfile_name(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_TEXT_P(cstring_to_text(xlogfilename));
|
PG_RETURN_TEXT_P(cstring_to_text(xlogfilename));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract the sequence number and the timeline ID from given a WAL file
|
||||||
|
* name.
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
pg_dissect_walfile_name(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
#define PG_DISSECT_WALFILE_NAME_COLS 2
|
||||||
|
char *fname = text_to_cstring(PG_GETARG_TEXT_PP(0));
|
||||||
|
char *fname_upper;
|
||||||
|
char *p;
|
||||||
|
TimeLineID tli;
|
||||||
|
XLogSegNo segno;
|
||||||
|
Datum values[PG_DISSECT_WALFILE_NAME_COLS] = {0};
|
||||||
|
bool isnull[PG_DISSECT_WALFILE_NAME_COLS] = {0};
|
||||||
|
TupleDesc tupdesc;
|
||||||
|
HeapTuple tuple;
|
||||||
|
char buf[256];
|
||||||
|
Datum result;
|
||||||
|
|
||||||
|
fname_upper = pstrdup(fname);
|
||||||
|
|
||||||
|
/* Capitalize WAL file name. */
|
||||||
|
for (p = fname_upper; *p; p++)
|
||||||
|
*p = pg_toupper((unsigned char) *p);
|
||||||
|
|
||||||
|
if (!IsXLogFileName(fname_upper))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
|
errmsg("invalid WAL file name \"%s\"", fname)));
|
||||||
|
|
||||||
|
XLogFromFileName(fname_upper, &tli, &segno, wal_segment_size);
|
||||||
|
|
||||||
|
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
||||||
|
elog(ERROR, "return type must be a row type");
|
||||||
|
|
||||||
|
/* Convert to numeric. */
|
||||||
|
snprintf(buf, sizeof buf, UINT64_FORMAT, segno);
|
||||||
|
values[0] = DirectFunctionCall3(numeric_in,
|
||||||
|
CStringGetDatum(buf),
|
||||||
|
ObjectIdGetDatum(0),
|
||||||
|
Int32GetDatum(-1));
|
||||||
|
|
||||||
|
values[1] = Int64GetDatum(tli);
|
||||||
|
|
||||||
|
tuple = heap_form_tuple(tupdesc, values, isnull);
|
||||||
|
result = HeapTupleGetDatum(tuple);
|
||||||
|
|
||||||
|
PG_RETURN_DATUM(result);
|
||||||
|
|
||||||
|
#undef PG_DISSECT_WALFILE_NAME_COLS
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pg_wal_replay_pause - Request to pause recovery
|
* pg_wal_replay_pause - Request to pause recovery
|
||||||
*
|
*
|
||||||
|
@ -57,6 +57,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 202212191
|
#define CATALOG_VERSION_NO 202212201
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6372,6 +6372,13 @@
|
|||||||
{ oid => '2851', descr => 'wal filename, given a wal location',
|
{ oid => '2851', descr => 'wal filename, given a wal location',
|
||||||
proname => 'pg_walfile_name', prorettype => 'text', proargtypes => 'pg_lsn',
|
proname => 'pg_walfile_name', prorettype => 'text', proargtypes => 'pg_lsn',
|
||||||
prosrc => 'pg_walfile_name' },
|
prosrc => 'pg_walfile_name' },
|
||||||
|
{ oid => '8205',
|
||||||
|
descr => 'sequence number and timeline ID given a wal filename',
|
||||||
|
proname => 'pg_dissect_walfile_name', provolatile => 's',
|
||||||
|
prorettype => 'record', proargtypes => 'text',
|
||||||
|
proallargtypes => '{text,numeric,int8}', proargmodes => '{i,o,o}',
|
||||||
|
proargnames => '{file_name,segno,timeline_id}',
|
||||||
|
prosrc => 'pg_dissect_walfile_name' },
|
||||||
|
|
||||||
{ oid => '3165', descr => 'difference in bytes, given two wal locations',
|
{ oid => '3165', descr => 'difference in bytes, given two wal locations',
|
||||||
proname => 'pg_wal_lsn_diff', prorettype => 'numeric',
|
proname => 'pg_wal_lsn_diff', prorettype => 'numeric',
|
||||||
|
@ -619,3 +619,26 @@ SELECT count(*) > 0 AS ok FROM pg_control_system();
|
|||||||
t
|
t
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- pg_dissect_walfile_name
|
||||||
|
SELECT * FROM pg_dissect_walfile_name(NULL);
|
||||||
|
segno | timeline_id
|
||||||
|
-------+-------------
|
||||||
|
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM pg_dissect_walfile_name('invalid');
|
||||||
|
ERROR: invalid WAL file name "invalid"
|
||||||
|
SELECT segno > 0 AS ok_segno, timeline_id
|
||||||
|
FROM pg_dissect_walfile_name('000000010000000100000000');
|
||||||
|
ok_segno | timeline_id
|
||||||
|
----------+-------------
|
||||||
|
t | 1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT segno > 0 AS ok_segno, timeline_id
|
||||||
|
FROM pg_dissect_walfile_name('ffffffFF00000001000000af');
|
||||||
|
ok_segno | timeline_id
|
||||||
|
----------+-------------
|
||||||
|
t | 4294967295
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
@ -229,3 +229,11 @@ SELECT count(*) > 0 AS ok FROM pg_control_checkpoint();
|
|||||||
SELECT count(*) > 0 AS ok FROM pg_control_init();
|
SELECT count(*) > 0 AS ok FROM pg_control_init();
|
||||||
SELECT count(*) > 0 AS ok FROM pg_control_recovery();
|
SELECT count(*) > 0 AS ok FROM pg_control_recovery();
|
||||||
SELECT count(*) > 0 AS ok FROM pg_control_system();
|
SELECT count(*) > 0 AS ok FROM pg_control_system();
|
||||||
|
|
||||||
|
-- pg_dissect_walfile_name
|
||||||
|
SELECT * FROM pg_dissect_walfile_name(NULL);
|
||||||
|
SELECT * FROM pg_dissect_walfile_name('invalid');
|
||||||
|
SELECT segno > 0 AS ok_segno, timeline_id
|
||||||
|
FROM pg_dissect_walfile_name('000000010000000100000000');
|
||||||
|
SELECT segno > 0 AS ok_segno, timeline_id
|
||||||
|
FROM pg_dissect_walfile_name('ffffffFF00000001000000af');
|
||||||
|
Loading…
Reference in New Issue
Block a user