mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Add data_page_checksum_version to pg_control_checkpoint
Commit f19c0eccae added the data_checksum_version to the pg_controldata
output, but omitted a corresponding change to the pg_control_checkpoint
SQL function, which reports the same checkpoint information. The field
is named to match what pg_control_init already reports for consistency.
The integer version reported is an implementation detail which bleeds
through, but it is quite widely used and a more holistic approach to
improving this is left as an excercise for the next major version. The
mapping between states and versions is added to the documentation to
make it easier for users.
Backpatch to v19 where online checksums were introduced.
Author: Ian Barwick <barwick@gmail.com>
Co-authored-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Discussion: https://postgr.es/m/CAB8KJ=hb765sE8bKC-6sh=Yp3sCjN8xs474yuBrkwyoTM2pgZA@mail.gmail.com
Backpatch-through: 19
This commit is contained in:
@@ -3496,6 +3496,11 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres}
|
||||
<entry><type>xid</type></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>data_page_checksum_version</structfield></entry>
|
||||
<entry><type>integer</type></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>checkpoint_time</structfield></entry>
|
||||
<entry><type>timestamp with time zone</type></entry>
|
||||
|
||||
@@ -256,9 +256,52 @@
|
||||
The current state of checksums in the cluster can be verified by viewing the
|
||||
value of the read-only configuration variable <xref
|
||||
linkend="guc-data-checksums" /> by issuing the command <command>SHOW
|
||||
data_checksums</command>.
|
||||
data_checksums</command>. <link linkend="functions-pg-control-init">
|
||||
<literal>pg_control_init</literal></link> and
|
||||
<link linkend="functions-pg-control-checkpoint">
|
||||
<literal>pg_control_checkpoint</literal></link> can also be used for
|
||||
inspecting the data checksum state at cluster initialization and current
|
||||
checkpoint. Data checksum states are often referred to as data checksum
|
||||
versions using an integer representation due to how they were originally
|
||||
implemented. <xref linkend="data-checksums-mapping" /> contains a mapping
|
||||
between state names and versions, which are defined in
|
||||
<filename>src/include/storage/checksum.h</filename>.
|
||||
</para>
|
||||
|
||||
<table id="data-checksums-mapping">
|
||||
<title>Data Checksums States and Version Mapping</title>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>State</entry>
|
||||
<entry>Version</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>off</entry>
|
||||
<entry>0</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>on</entry>
|
||||
<entry>1</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>inprogress-off</entry>
|
||||
<entry>2</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>inprogress-on</entry>
|
||||
<entry>3</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>
|
||||
When attempting to recover from page corruptions, it may be necessary to
|
||||
bypass the checksum protection. To do this, temporarily set the
|
||||
|
||||
@@ -69,8 +69,8 @@ pg_control_system(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_control_checkpoint(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Datum values[19];
|
||||
bool nulls[19];
|
||||
Datum values[20];
|
||||
bool nulls[20];
|
||||
TupleDesc tupdesc;
|
||||
HeapTuple htup;
|
||||
ControlFileData *ControlFile;
|
||||
@@ -154,9 +154,12 @@ pg_control_checkpoint(PG_FUNCTION_ARGS)
|
||||
values[17] = TransactionIdGetDatum(ControlFile->checkPointCopy.newestCommitTsXid);
|
||||
nulls[17] = false;
|
||||
|
||||
values[18] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time));
|
||||
values[18] = Int32GetDatum(ControlFile->checkPointCopy.dataChecksumState);
|
||||
nulls[18] = false;
|
||||
|
||||
values[19] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time));
|
||||
nulls[19] = false;
|
||||
|
||||
htup = heap_form_tuple(tupdesc, values, nulls);
|
||||
|
||||
PG_RETURN_DATUM(HeapTupleGetDatum(htup));
|
||||
|
||||
@@ -57,6 +57,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 202607272
|
||||
#define CATALOG_VERSION_NO 202608182
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12346,9 +12346,9 @@
|
||||
descr => 'pg_controldata checkpoint state information as a function',
|
||||
proname => 'pg_control_checkpoint', provolatile => 'v',
|
||||
prorettype => 'record', proargtypes => '',
|
||||
proallargtypes => '{pg_lsn,pg_lsn,text,int4,int4,bool,bool,text,oid,xid,xid,xid,oid,xid,xid,oid,xid,xid,timestamptz}',
|
||||
proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
|
||||
proargnames => '{checkpoint_lsn,redo_lsn,redo_wal_file,timeline_id,prev_timeline_id,full_page_writes,logical_decoding,next_xid,next_oid,next_multixact_id,next_multi_offset,oldest_xid,oldest_xid_dbid,oldest_active_xid,oldest_multi_xid,oldest_multi_dbid,oldest_commit_ts_xid,newest_commit_ts_xid,checkpoint_time}',
|
||||
proallargtypes => '{pg_lsn,pg_lsn,text,int4,int4,bool,bool,text,oid,xid,xid,xid,oid,xid,xid,oid,xid,xid,int4,timestamptz}',
|
||||
proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
|
||||
proargnames => '{checkpoint_lsn,redo_lsn,redo_wal_file,timeline_id,prev_timeline_id,full_page_writes,logical_decoding,next_xid,next_oid,next_multixact_id,next_multi_offset,oldest_xid,oldest_xid_dbid,oldest_active_xid,oldest_multi_xid,oldest_multi_dbid,oldest_commit_ts_xid,newest_commit_ts_xid,data_page_checksum_version,checkpoint_time}',
|
||||
prosrc => 'pg_control_checkpoint' },
|
||||
|
||||
{ oid => '3443',
|
||||
|
||||
@@ -43,6 +43,18 @@ enable_data_checksums($node, wait => 'on');
|
||||
$result = $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1 ");
|
||||
is($result, '9999', 'ensure checksummed pages can be read back');
|
||||
|
||||
# Ensure the new state is registered properly in pg_control_checkpoint()
|
||||
$result =
|
||||
$node->safe_psql('postgres',
|
||||
'SELECT data_page_checksum_version FROM pg_control_checkpoint();');
|
||||
is($result, '1', 'ensure pg_control_checkpoint reports enabled state');
|
||||
# Regardless of the new state, pg_control_init() should still report checksums
|
||||
# as on.
|
||||
$result =
|
||||
$node->safe_psql('postgres',
|
||||
'SELECT data_page_checksum_version FROM pg_control_init();');
|
||||
is($result, '1', 'ensure pg_control_init reports enabled state');
|
||||
|
||||
# Enable data checksums again which should be a no-op so we explicitly don't
|
||||
# wait for any state transition as none should happen here.
|
||||
enable_data_checksums($node);
|
||||
@@ -59,6 +71,12 @@ disable_data_checksums($node, wait => 1);
|
||||
$result = $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1");
|
||||
is($result, '10000', 'ensure previously checksummed pages can be read back');
|
||||
|
||||
# And ensure the disabled state is shown in pg_control_checkpoint()
|
||||
$result =
|
||||
$node->safe_psql('postgres',
|
||||
'SELECT data_page_checksum_version FROM pg_control_checkpoint();');
|
||||
is($result, '0', 'ensure pg_control_checkpoint reports disabled state');
|
||||
|
||||
# Re-enable checksums and make sure that the underlying data has changed to
|
||||
# ensure that checksums will be different.
|
||||
$node->safe_psql('postgres', "UPDATE t SET a = a + 1;");
|
||||
|
||||
@@ -40,6 +40,18 @@ $node->start;
|
||||
# Ensure that checksums are enabled
|
||||
test_checksum_state($node, 'on');
|
||||
|
||||
# Since offline checksums don't issue a checkpoint like online checksums, the
|
||||
# first call to pg_control_checkpoint will show the state as off even though
|
||||
# checksums are enabled. After a CHECKPOINT, pg_control_checkpoint shall
|
||||
# return 1.
|
||||
$result = $node->safe_psql('postgres',
|
||||
'SELECT data_page_checksum_version FROM pg_control_checkpoint();');
|
||||
is($result, '0', 'latest checkpoint will still see off state');
|
||||
$node->safe_psql('postgres', 'CHECKPOINT;');
|
||||
$result = $node->safe_psql('postgres',
|
||||
'SELECT data_page_checksum_version FROM pg_control_checkpoint();');
|
||||
is($result, '1', 'latest checkpoint will now see on state');
|
||||
|
||||
# Make sure pg_control_init still reports the initial state as disabled even
|
||||
# though the current state has changed.
|
||||
$result = $node->safe_psql('postgres',
|
||||
|
||||
Reference in New Issue
Block a user