Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  002_actions.pl

  Sprache: Shell
 


# Copyright (c) 2021-2025, PostgreSQL Global Development Group

# Do basic sanity checks supported by pg_checksums using
# an initialized cluster.

use strict;
use warnings FATAL => 'all';
use Config;
use PostgreSQL::Test::Cluster;
use PostgreSQL::Test::Utils;

use Test::More;


# Utility routine to create and check a table with corrupted checksums
# on a wanted tablespace.  Note that this stops and starts the node
# multiple times to perform the checks, leaving the node started
# at the end.
sub check_relation_corruption
{
 my $node = shift;
 my $table = shift;
 my $tablespace = shift;
 my $pgdata = $node->data_dir;

 # Create table and discover its filesystem location.
 $node->safe_psql(
  'postgres',
  "CREATE TABLE $table AS SELECT a FROM generate_series(1,10000) AS a;
  ALTER TABLE $table SET (autovacuum_enabled=false);");

 $node->safe_psql('postgres',
  "ALTER TABLE " . $table . " SET TABLESPACE " . $tablespace . ";");

 my $file_corrupted =
   $node->safe_psql('postgres'"SELECT pg_relation_filepath('$table');");
 my $relfilenode_corrupted = $node->safe_psql('postgres',
  "SELECT relfilenode FROM pg_class WHERE relname = '$table';");

 $node->stop;

 # Checksums are correct for single relfilenode as the table is not
 # corrupted yet.
 command_ok(
  [
   'pg_checksums',
   '--check',
   '--pgdata' => $pgdata,
   '--filenode' => $relfilenode_corrupted,
  ],
  "succeeds for single relfilenode on tablespace $tablespace with offline cluster"
 );

 # Time to create some corruption
 $node->corrupt_page_checksum($file_corrupted, 0);

 # Checksum checks on single relfilenode fail
 $node->command_checks_all(
  [
   'pg_checksums',
   '--check',
   '--pgdata' => $pgdata,
   '--filenode' => $relfilenode_corrupted,
  ],
  1,
  [qr/Bad checksums:.*1/],
  [qr/checksum verification failed/],
  "fails with corrupted data for single relfilenode on tablespace $tablespace"
 );

 # Global checksum checks fail as well
 $node->command_checks_all(
  [ 'pg_checksums''--check''--pgdata' => $pgdata ],
  1,
  [qr/Bad checksums:.*1/],
  [qr/checksum verification failed/],
  "fails with corrupted data on tablespace $tablespace");

 # Drop corrupted table again and make sure there is no more corruption.
 $node->start;
 $node->safe_psql('postgres'"DROP TABLE $table;");
 $node->stop;
 $node->command_ok(
  [ 'pg_checksums''--check''--pgdata' => $pgdata ],
  "succeeds again after table drop on tablespace $tablespace");

 $node->start;
 return;
}

# Initialize node with checksums disabled.
my $node = PostgreSQL::Test::Cluster->new('node_checksum');
$node->init(no_data_checksums => 1);
my $pgdata = $node->data_dir;

# Control file should know that checksums are disabled.
command_like(
 [ 'pg_controldata', $pgdata ],
 qr/Data page checksum version:.*0/,
 'checksums disabled in control file');

# These are correct but empty files, so they should pass through.
append_to_file "$pgdata/global/99999""";
append_to_file "$pgdata/global/99999.123""";
append_to_file "$pgdata/global/99999_fsm""";
append_to_file "$pgdata/global/99999_init""";
append_to_file "$pgdata/global/99999_vm""";
append_to_file "$pgdata/global/99999_init.123""";
append_to_file "$pgdata/global/99999_fsm.123""";
append_to_file "$pgdata/global/99999_vm.123""";

# These are temporary files and folders with dummy contents, which
# should be ignored by the scan.
append_to_file "$pgdata/global/pgsql_tmp_123""foo";
mkdir "$pgdata/global/pgsql_tmp";
append_to_file "$pgdata/global/pgsql_tmp/1.1""foo";
append_to_file "$pgdata/global/pg_internal.init""foo";
append_to_file "$pgdata/global/pg_internal.init.123""foo";

# These are non-postgres macOS files, which should be ignored by the scan.
# Only perform this test on non-macOS systems though as creating incorrect
# system files may have side effects on macOS.
append_to_file "$pgdata/global/.DS_Store""foo"
  unless ($Config{osname} eq 'darwin');

# Enable checksums.
command_ok([ 'pg_checksums''--enable''--no-sync''--pgdata' => $pgdata ],
 "checksums successfully enabled in cluster");

# Successive attempt to enable checksums fails.
command_fails(
 [ 'pg_checksums''--enable''--no-sync''--pgdata' => $pgdata ],
 "enabling checksums fails if already enabled");

# Control file should know that checksums are enabled.
command_like(
 [ 'pg_controldata', $pgdata ],
 qr/Data page checksum version:.*1/,
 'checksums enabled in control file');

# Disable checksums again.  Flush result here as that should be cheap.
command_ok(
 [ 'pg_checksums''--disable''--pgdata' => $pgdata ],
 "checksums successfully disabled in cluster");

# Successive attempt to disable checksums fails.
command_fails(
 [ 'pg_checksums''--disable''--no-sync''--pgdata' => $pgdata ],
 "disabling checksums fails if already disabled");

# Control file should know that checksums are disabled.
command_like(
 [ 'pg_controldata', $pgdata ],
 qr/Data page checksum version:.*0/,
 'checksums disabled in control file');

# Enable checksums again for follow-up tests.
command_ok([ 'pg_checksums''--enable''--no-sync''--pgdata' => $pgdata ],
 "checksums successfully enabled in cluster");

# Control file should know that checksums are enabled.
command_like(
 [ 'pg_controldata', $pgdata ],
 qr/Data page checksum version:.*1/,
 'checksums enabled in control file');

# Checksums pass on a newly-created cluster
command_ok([ 'pg_checksums''--check''--pgdata' => $pgdata ],
 "succeeds with offline cluster");

# Checksums are verified if no other arguments are specified
command_ok(
 [ 'pg_checksums''--pgdata' => $pgdata ],
 "verifies checksums as default action");

# Specific relation files cannot be requested when action is --disable
# or --enable.
command_fails(
 [
  'pg_checksums',
  '--disable',
  '--filenode' => '1234',
  '--pgdata' => $pgdata
 ],
 "fails when relfilenodes are requested and action is --disable");
command_fails(
 [
  'pg_checksums',
  '--enable',
  '--filenode' => '1234',
  '--pgdata' => $pgdata
 ],
 "fails when relfilenodes are requested and action is --enable");

# Test postgres -C for an offline cluster.
# Run-time GUCs are safe to query here.  Note that a lock file is created,
# then removed, leading to an extra LOG entry showing in stderr.  This uses
# log_min_messages=fatal to remove any noise.  This test uses a startup
# wrapped with pg_ctl to allow the case where this runs under a privileged
# account on Windows.
command_checks_all(
 [
  'pg_ctl''start',
  '--silent',
  '--pgdata' => $pgdata,
  '-o' => '-C data_checksums -c log_min_messages=fatal',
 ],
 1,
 [qr/^on$/],
 [qr/could not start server/],
 'data_checksums=on is reported on an offline cluster');

# Checks cannot happen with an online cluster
$node->start;
command_fails([ 'pg_checksums''--check''--pgdata' => $pgdata ],
 "fails with online cluster");

# Check corruption of table on default tablespace.
check_relation_corruption($node, 'corrupt1''pg_default');

# Create tablespace to check corruptions in a non-default tablespace.
my $basedir = $node->basedir;
my $tablespace_dir = "$basedir/ts_corrupt_dir";
mkdir($tablespace_dir);
$node->safe_psql('postgres',
 "CREATE TABLESPACE ts_corrupt LOCATION '$tablespace_dir';");
check_relation_corruption($node, 'corrupt2''ts_corrupt');

# Utility routine to check that pg_checksums is able to detect
# correctly-named relation files filled with some corrupted data.
sub fail_corrupt
{
 my $node = shift;
 my $file = shift;
 my $pgdata = $node->data_dir;

 # Create the file with some dummy data in it.
 my $file_name = "$pgdata/global/$file";
 append_to_file $file_name, "foo";

 $node->command_checks_all(
  [ 'pg_checksums''--check''--pgdata' => $pgdata ],
  1,
  [qr/^$/],
  [qr/could not read block 0 in file.*$file\":/],
  "fails for corrupted data in $file");

 # Remove file to prevent future lookup errors on conflicts.
 unlink $file_name;
 return;
}

# Stop instance for the follow-up checks.
$node->stop;

# Create a fake tablespace location that should not be scanned
# when verifying checksums.
mkdir "$tablespace_dir/PG_99_999999991/";
append_to_file "$tablespace_dir/PG_99_999999991/foo""123";
command_ok([ 'pg_checksums''--check''--pgdata' => $pgdata ],
 "succeeds with foreign tablespace");

# Authorized relation files filled with corrupted data cause the
# checksum checks to fail.  Make sure to use file names different
# than the previous ones.
fail_corrupt($node, "99990");
fail_corrupt($node, "99990.123");
fail_corrupt($node, "99990_fsm");
fail_corrupt($node, "99990_init");
fail_corrupt($node, "99990_vm");
fail_corrupt($node, "99990_init.123");
fail_corrupt($node, "99990_fsm.123");
fail_corrupt($node, "99990_vm.123");

done_testing();

¤ Dauer der Verarbeitung: 0.22 Sekunden  (vorverarbeitet am  2026-08-10) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=752002