Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1f3StB-0008V6-Ec for pgsql-committers@arkaria.postgresql.org; Tue, 03 Apr 2018 20:50:45 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1f3StA-0001Iy-FW for pgsql-committers@arkaria.postgresql.org; Tue, 03 Apr 2018 20:50:44 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1f3StA-0001Ik-A8; Tue, 03 Apr 2018 20:50:44 +0000 Received: from mout.gmx.net ([212.227.15.19]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1f3St6-00012g-K6; Tue, 03 Apr 2018 20:50:43 +0000 Received: from nighthawk.chemicalconnection.dyndns.org ([88.217.96.158]) by mail.gmx.com (mrgmx001 [212.227.17.190]) with ESMTPSA (Nemesis) id 0LtJAR-1eMayT34Wp-012p5w; Tue, 03 Apr 2018 22:50:22 +0200 Received: from mbanck by nighthawk.chemicalconnection.dyndns.org with local (Exim 4.84_2) (envelope-from ) id 1f3Sql-0003gj-Us; Tue, 03 Apr 2018 22:48:16 +0200 Date: Tue, 3 Apr 2018 22:48:15 +0200 From: Michael Banck To: Magnus Hagander Cc: Tom Lane , Andres Freund , David Steele , PostgreSQL-development , pgsql-committers@lists.postgresql.org Subject: Re: pgsql: Validate page level checksums in base backups Message-ID: <20180403204815.GD20852@nighthawk.caipicrew.dd-dns.de> References: <20180403171356.v4ji5sfhbc4sggij@alap3.anarazel.de> <22322.1522780151@sss.pgh.pa.us> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="5QAgd0e35j3NYeGe" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) Sender: X-Provags-ID: V03:K1:5zvh8uefU5XUB3Nt75vMq65y0G1PIFbDKd8jh0AQ9iIVlD2dMmN Ug/7Q9B2s3PnGA19aLbOB9JdUv9iZrA5wqdr+KI/U5ByacvJk602lWucUEmjvyqgAe4fzud s6Gk7M/jG2pbBG1sYwWrV3wHkgb7ra8EnMycZXkHE1wP0vmViT0gcwiv7Mwv6nlnh2faCGQ hhTXT3jBqmP7tZRBlnxDQ== X-UI-Out-Filterresults: notjunk:1;V01:K0:cbZyBProuJ0=:zXAaRn8pBbYAEqsbSCIXVp a0/h0LPW0Xf0ATdt+vlbS36i7ngPxTojr7WfUb/yTDpNXsjWExKN/fRz7t2BnTWFFjCfonihn DinvUi6Ganu546BQRv9Q4aX/PgrYvk9SD5PhwtRp8wwr+xmyINbMIHctjUe4+8zPIYJnnYFws Ik9khEQ2Y6aEI3RApEF7huu0z+wUIdjnoCrG1iI3zcTKp/xdLo3oHwSu9J2zWDPKR4MsZLKvp SpkSn9G3v0Ld/FrshvAWtu640XQ/IAXqL+LBtzERt/MB83v/I9TGAhG3XeQiRW2c0EjQtq2hp wskyLyMurTpEhEevr95pU//EDnZxKAB9wEynZQRoWNo+Lctxku+ytMXMi17+LDHoaGYbnTLjg EICjlXMnjZijopOyWz9t3ZU4BwjQ7yBpeCSa/V12FBgPRZGQ6dXahcAwG4lnsii2m2/vwzj0c RAWf+ki8kqO0cJwp9+MuNKy68eUsKT11rESaZK4s5UBk3iMB+vyxgTnY4L6LtGs9Pyl4jdsR3 KEbFWW5exLRB2gqhCi0uTAWzjMg2oJmkV/Jh3zN/x1r+26mu8G06KLGVCFb8IFxUmkL/goXSn K51zpY+nMzY8VHQzl1KajKgn37ubgaRqniDvSo1xwO+YfpZjifHTXuh5nZlrQ+VYMYfUZsjvU LY7z3/a+OUI5fm7Pq/jJBi9wi2sNFj7/9rIsZfgBJm9KQKWMhA3pvipG02aj3NqLcYLLj0gFP h9HTlnFlAqAbzQuBolvgF7wIfVrOeuulKWl2L+SAR9Om91poWUHb5sDs1hnPH4k4QgKTxX2M0 ZXehZP/3TNPq6xzLpvtn7a0AFaABA== List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --5QAgd0e35j3NYeGe Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit Hi, On Tue, Apr 03, 2018 at 08:48:08PM +0200, Magnus Hagander wrote: > On Tue, Apr 3, 2018 at 8:29 PM, Tom Lane wrote: > I'd bet a good lunch that nondefault BLCKSZ would break it, as well, > > since the way in which the corruption is induced is just guessing > > as to where page boundaries are. > > Yeah, that might be a problem. Those should be calculated from the block > size. > > Also, scribbling on tables as sensitive as pg_class is just asking for > > trouble IMO. I don't see anything in this test, for example, that > > prevents autovacuum from running and causing a PANIC before the test > > can complete. Even with AV off, there's a good chance that clobber- > > cache-always animals will fall over because they do so many more > > physical accesses to the system catalogs. I'd suggest inducing the > > corruption in some user table(s) that we can more tightly constrain > > the source server's accesses to. > > Yeah, that seems like a good idea. And probably also shut the server down > while writing the corruption, just in case. > > Will stick looking into that on my todo for when I'm back, unless beaten to > it. Michael, you want a stab at it? Attached is a patch which does that hopefully: 1. creates two user tables, one large enough for at least 6 blocks (around 360kb), the other just one block. 2. stops the cluster before scribbling over its data and starts it afterwards. 3. uses the blocksize (and the pager header size) to determine offsets for scribbling. I've tested it with blocksizes 8 and 32 now, the latter should make sure that the first table is indeed large enough, but maybe something less arbitrary than "10000 integers" should be used? Anyway, sorry for the hassle. Michael -- Michael Banck Projektleiter / Senior Berater Tel.: +49 2166 9901-171 Fax: +49 2166 9901-100 Email: michael.banck@credativ.de credativ GmbH, HRB Mönchengladbach 12080 USt-ID-Nummer: DE204566209 Trompeterallee 108, 41189 Mönchengladbach Geschäftsführung: Dr. Michael Meskes, Jörg Folz, Sascha Heuer --5QAgd0e35j3NYeGe Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="basebackup-verify-checksum_test-fixes.patch" diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl index 3162cdcd01..3fe49f68a7 100644 --- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl +++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl @@ -406,19 +406,25 @@ like( my $checksum = $node->safe_psql('postgres', 'SHOW data_checksums;'); is($checksum, 'on', 'checksums are enabled'); -# get relfilenodes of relations to corrupt -my $pg_class = $node->safe_psql('postgres', - q{SELECT pg_relation_filepath('pg_class')} +# create tables to corrupt and get their relfilenodes +my $file_corrupt1 = $node->safe_psql('postgres', + q{SELECT a INTO corrupt1 FROM generate_series(1,10000) AS a; SELECT pg_relation_filepath('corrupt1')} ); -my $pg_index = $node->safe_psql('postgres', - q{SELECT pg_relation_filepath('pg_index')} +my $file_corrupt2 = $node->safe_psql('postgres', + q{SELECT b INTO corrupt2 FROM generate_series(1,2) AS b; SELECT pg_relation_filepath('corrupt2')} ); +# set page header and block sizes +my $pageheader_size = 24; +my $block_size = $node->safe_psql('postgres', 'SHOW block_size;'); + # induce corruption -open $file, '+<', "$pgdata/$pg_class"; -seek($file, 4000, 0); +system_or_bail 'pg_ctl', '-D', $pgdata, 'stop'; +open $file, '+<', "$pgdata/$file_corrupt1"; +seek($file, $pageheader_size, 0); syswrite($file, '\0\0\0\0\0\0\0\0\0'); close $file; +system_or_bail 'pg_ctl', '-D', $pgdata, 'start'; $node->command_checks_all([ 'pg_basebackup', '-D', "$tempdir/backup_corrupt"], 1, @@ -428,13 +434,15 @@ $node->command_checks_all([ 'pg_basebackup', '-D', "$tempdir/backup_corrupt"], ); # induce further corruption in 5 more blocks -open $file, '+<', "$pgdata/$pg_class"; -my @offsets = (12192, 20384, 28576, 36768, 44960); -foreach my $offset (@offsets) { +system_or_bail 'pg_ctl', '-D', $pgdata, 'stop'; +open $file, '+<', "$pgdata/$file_corrupt1"; +for my $i ( 1..5 ) { + my $offset = $pageheader_size + $i * $block_size; seek($file, $offset, 0); syswrite($file, '\0\0\0\0\0\0\0\0\0'); } close $file; +system_or_bail 'pg_ctl', '-D', $pgdata, 'start'; $node->command_checks_all([ 'pg_basebackup', '-D', "$tempdir/backup_corrupt2"], 1, @@ -444,10 +452,12 @@ $node->command_checks_all([ 'pg_basebackup', '-D', "$tempdir/backup_corrupt2"], ); # induce corruption in a second file -open $file, '+<', "$pgdata/$pg_index"; +system_or_bail 'pg_ctl', '-D', $pgdata, 'stop'; +open $file, '+<', "$pgdata/$file_corrupt2"; seek($file, 4000, 0); syswrite($file, '\0\0\0\0\0\0\0\0\0'); close $file; +system_or_bail 'pg_ctl', '-D', $pgdata, 'start'; $node->command_checks_all([ 'pg_basebackup', '-D', "$tempdir/backup_corrupt3"], 1, @@ -460,3 +470,6 @@ $node->command_checks_all([ 'pg_basebackup', '-D', "$tempdir/backup_corrupt3"], $node->command_ok( [ 'pg_basebackup', '-D', "$tempdir/backup_corrupt4", '-k' ], 'pg_basebackup with -k does not report checksum mismatch'); + +$node->safe_psql('postgres', "DROP TABLE corrupt1;"); +$node->safe_psql('postgres', "DROP TABLE corrupt2;"); --5QAgd0e35j3NYeGe--