5
5
use warnings;
6
6
use PostgresNode;
7
7
use TestLib;
8
- use Test::More tests => 36;
8
+ use Test::More tests => 45;
9
+
10
+
11
+ # Utility routine to create and check a table with corrupted checksums
12
+ # on a wanted tablespace. Note that this stops and starts the node
13
+ # multiple times to perform the checks, leaving the node started
14
+ # at the end.
15
+ sub check_relation_corruption
16
+ {
17
+ my $node = shift ;
18
+ my $table = shift ;
19
+ my $tablespace = shift ;
20
+ my $pgdata = $node -> data_dir;
21
+
22
+ $node -> safe_psql(' postgres' ,
23
+ " SELECT a INTO $table FROM generate_series(1,10000) AS a;
24
+ ALTER TABLE $table SET (autovacuum_enabled=false);" );
25
+
26
+ $node -> safe_psql(' postgres' ,
27
+ " ALTER TABLE " .$table ." SET TABLESPACE " .$tablespace ." ;" );
28
+
29
+ my $file_corrupted = $node -> safe_psql(' postgres' ,
30
+ " SELECT pg_relation_filepath('$table ');" );
31
+ my $relfilenode_corrupted = $node -> safe_psql(' postgres' ,
32
+ " SELECT relfilenode FROM pg_class WHERE relname = '$table ';" );
33
+
34
+ # Set page header and block size
35
+ my $pageheader_size = 24;
36
+ my $block_size = $node -> safe_psql(' postgres' , ' SHOW block_size;' );
37
+ $node -> stop;
38
+
39
+ # Checksums are correct for single relfilenode as the table is not
40
+ # corrupted yet.
41
+ command_ok([' pg_verify_checksums' , ' -D' , $pgdata ,
42
+ ' -r' , $relfilenode_corrupted ],
43
+ " succeeds for single relfilenode on tablespace $tablespace with offline cluster" );
44
+
45
+ # Time to create some corruption
46
+ open my $file , ' +<' , " $pgdata /$file_corrupted " ;
47
+ seek ($file , $pageheader_size , 0);
48
+ syswrite ($file , ' \0\0\0\0\0\0\0\0\0' );
49
+ close $file ;
50
+
51
+ # Checksum checks on single relfilenode fail
52
+ $node -> command_checks_all([ ' pg_verify_checksums' , ' -D' , $pgdata , ' -r' ,
53
+ $relfilenode_corrupted ],
54
+ 1,
55
+ [qr / Bad checksums:.*1/ ],
56
+ [qr / checksum verification failed/ ],
57
+ " fails with corrupted data for single relfilenode on tablespace $tablespace " );
58
+
59
+ # Global checksum checks fail as well
60
+ $node -> command_checks_all([ ' pg_verify_checksums' , ' -D' , $pgdata ],
61
+ 1,
62
+ [qr / Bad checksums:.*1/ ],
63
+ [qr / checksum verification failed/ ],
64
+ " fails with corrupted data on tablespace $tablespace " );
65
+
66
+ # Drop corrupted table again and make sure there is no more corruption.
67
+ $node -> start;
68
+ $node -> safe_psql(' postgres' , " DROP TABLE $table ;" );
69
+ $node -> stop;
70
+ $node -> command_ok([' pg_verify_checksums' , ' -D' , $pgdata ],
71
+ " succeeds again after table drop on tablespace $tablespace " );
72
+
73
+ $node -> start;
74
+ return ;
75
+ }
9
76
10
77
# Initialize node with checksums enabled.
11
78
my $node = get_new_node(' node_checksum' );
27
94
append_to_file " $pgdata /global/99999_fsm.123" , " " ;
28
95
append_to_file " $pgdata /global/99999_vm.123" , " " ;
29
96
97
+ # These are temporary files and folders with dummy contents, which
98
+ # should be ignored by the scan.
99
+ append_to_file " $pgdata /global/pgsql_tmp_123" , " foo" ;
100
+ mkdir " $pgdata /global/pgsql_tmp" ;
101
+ append_to_file " $pgdata /global/pgsql_tmp/1.1" , " foo" ;
102
+
30
103
# Checksums pass on a newly-created cluster
31
104
command_ok([' pg_verify_checksums' , ' -D' , $pgdata ],
32
105
" succeeds with offline cluster" );
36
109
command_fails([' pg_verify_checksums' , ' -D' , $pgdata ],
37
110
" fails with online cluster" );
38
111
39
- # Create table to corrupt and get its relfilenode
40
- $node -> safe_psql(' postgres' ,
41
- " SELECT a INTO corrupt1 FROM generate_series(1,10000) AS a;
42
- ALTER TABLE corrupt1 SET (autovacuum_enabled=false);" );
43
-
44
- my $file_corrupted = $node -> safe_psql(' postgres' ,
45
- " SELECT pg_relation_filepath('corrupt1')" );
46
- my $relfilenode_corrupted = $node -> safe_psql(' postgres' ,
47
- " SELECT relfilenode FROM pg_class WHERE relname = 'corrupt1';" );
48
-
49
- # Set page header and block size
50
- my $pageheader_size = 24;
51
- my $block_size = $node -> safe_psql(' postgres' , ' SHOW block_size;' );
52
- $node -> stop;
53
-
54
- # Checksums are correct for single relfilenode as the table is not
55
- # corrupted yet.
56
- command_ok([' pg_verify_checksums' , ' -D' , $pgdata ,
57
- ' -r' , $relfilenode_corrupted ],
58
- " succeeds for single relfilenode with offline cluster" );
59
-
60
- # Time to create some corruption
61
- open my $file , ' +<' , " $pgdata /$file_corrupted " ;
62
- seek ($file , $pageheader_size , 0);
63
- syswrite ($file , ' \0\0\0\0\0\0\0\0\0' );
64
- close $file ;
112
+ # Check corruption of table on default tablespace.
113
+ check_relation_corruption($node , ' corrupt1' , ' pg_default' );
65
114
66
- # Global checksum checks fail
67
- $node -> command_checks_all([ ' pg_verify_checksums' , ' -D' , $pgdata ],
68
- 1,
69
- [qr / Bad checksums:.*1/ ],
70
- [qr / checksum verification failed/ ],
71
- ' fails with corrupted data' );
72
-
73
- # Checksum checks on single relfilenode fail
74
- $node -> command_checks_all([ ' pg_verify_checksums' , ' -D' , $pgdata , ' -r' ,
75
- $relfilenode_corrupted ],
76
- 1,
77
- [qr / Bad checksums:.*1/ ],
78
- [qr / checksum verification failed/ ],
79
- ' fails for corrupted data on single relfilenode' );
115
+ # Create tablespace to check corruptions in a non-default tablespace.
116
+ my $basedir = $node -> basedir;
117
+ my $tablespace_dir = " $basedir /ts_corrupt_dir" ;
118
+ mkdir ($tablespace_dir );
119
+ $node -> safe_psql(' postgres' ,
120
+ " CREATE TABLESPACE ts_corrupt LOCATION '$tablespace_dir ';" );
121
+ check_relation_corruption($node , ' corrupt2' , ' ts_corrupt' );
80
122
81
123
# Utility routine to check that pg_verify_checksums is able to detect
82
124
# correctly-named relation files filled with some corrupted data.
@@ -101,6 +143,9 @@ sub fail_corrupt
101
143
return ;
102
144
}
103
145
146
+ # Stop instance for the follow-up checks.
147
+ $node -> stop;
148
+
104
149
# Authorized relation files filled with corrupted data cause the
105
150
# checksum checks to fail. Make sure to use file names different
106
151
# than the previous ones.
0 commit comments