PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pg_checksums.c File Reference
#include "postgres_fe.h"
#include <dirent.h>
#include <limits.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "common/controldata_utils.h"
#include "common/file_utils.h"
#include "common/logging.h"
#include "common/relpath.h"
#include "fe_utils/option_utils.h"
#include "getopt_long.h"
#include "pg_getopt.h"
#include "storage/bufpage.h"
#include "storage/checksum.h"
#include "storage/checksum_impl.h"
Include dependency graph for pg_checksums.c:

Go to the source code of this file.

Data Structures

struct  exclude_list_item
 

Enumerations

enum  PgChecksumMode { PG_MODE_CHECK , PG_MODE_DISABLE , PG_MODE_ENABLE }
 

Functions

static void usage (void)
 
static void progress_report (bool finished)
 
static bool skipfile (const char *fn)
 
static void scan_file (const char *fn, int segmentno)
 
static int64 scan_directory (const char *basedir, const char *subdir, bool sizeonly)
 
int main (int argc, char *argv[])
 

Variables

static int64 files_scanned = 0
 
static int64 files_written = 0
 
static int64 blocks_scanned = 0
 
static int64 blocks_written = 0
 
static int64 badblocks = 0
 
static ControlFileDataControlFile
 
static char * only_filenode = NULL
 
static bool do_sync = true
 
static bool verbose = false
 
static bool showprogress = false
 
static DataDirSyncMethod sync_method = DATA_DIR_SYNC_METHOD_FSYNC
 
static PgChecksumMode mode = PG_MODE_CHECK
 
static const char * progname
 
static int64 total_size = 0
 
static int64 current_size = 0
 
static pg_time_t last_progress_report = 0
 
static const struct exclude_list_item skip []
 

Enumeration Type Documentation

◆ PgChecksumMode

Enumerator
PG_MODE_CHECK 
PG_MODE_DISABLE 
PG_MODE_ENABLE 

Definition at line 48 of file pg_checksums.c.

49 {
PgChecksumMode
Definition: pg_checksums.c:49
@ PG_MODE_CHECK
Definition: pg_checksums.c:50
@ PG_MODE_DISABLE
Definition: pg_checksums.c:51
@ PG_MODE_ENABLE
Definition: pg_checksums.c:52

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 432 of file pg_checksums.c.

433 {
434  static struct option long_options[] = {
435  {"check", no_argument, NULL, 'c'},
436  {"pgdata", required_argument, NULL, 'D'},
437  {"disable", no_argument, NULL, 'd'},
438  {"enable", no_argument, NULL, 'e'},
439  {"filenode", required_argument, NULL, 'f'},
440  {"no-sync", no_argument, NULL, 'N'},
441  {"progress", no_argument, NULL, 'P'},
442  {"verbose", no_argument, NULL, 'v'},
443  {"sync-method", required_argument, NULL, 1},
444  {NULL, 0, NULL, 0}
445  };
446 
447  char *DataDir = NULL;
448  int c;
449  int option_index;
450  bool crc_ok;
451 
452  pg_logging_init(argv[0]);
453  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_checksums"));
454  progname = get_progname(argv[0]);
455 
456  if (argc > 1)
457  {
458  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
459  {
460  usage();
461  exit(0);
462  }
463  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
464  {
465  puts("pg_checksums (PostgreSQL) " PG_VERSION);
466  exit(0);
467  }
468  }
469 
470  while ((c = getopt_long(argc, argv, "cdD:ef:NPv", long_options, &option_index)) != -1)
471  {
472  switch (c)
473  {
474  case 'c':
476  break;
477  case 'd':
479  break;
480  case 'D':
481  DataDir = optarg;
482  break;
483  case 'e':
485  break;
486  case 'f':
487  if (!option_parse_int(optarg, "-f/--filenode", 0,
488  INT_MAX,
489  NULL))
490  exit(1);
492  break;
493  case 'N':
494  do_sync = false;
495  break;
496  case 'P':
497  showprogress = true;
498  break;
499  case 'v':
500  verbose = true;
501  break;
502  case 1:
504  exit(1);
505  break;
506  default:
507  /* getopt_long already emitted a complaint */
508  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
509  exit(1);
510  }
511  }
512 
513  if (DataDir == NULL)
514  {
515  if (optind < argc)
516  DataDir = argv[optind++];
517  else
518  DataDir = getenv("PGDATA");
519 
520  /* If no DataDir was specified, and none could be found, error out */
521  if (DataDir == NULL)
522  {
523  pg_log_error("no data directory specified");
524  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
525  exit(1);
526  }
527  }
528 
529  /* Complain if any arguments remain */
530  if (optind < argc)
531  {
532  pg_log_error("too many command-line arguments (first is \"%s\")",
533  argv[optind]);
534  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
535  exit(1);
536  }
537 
538  /* filenode checking only works in --check mode */
539  if (mode != PG_MODE_CHECK && only_filenode)
540  {
541  pg_log_error("option -f/--filenode can only be used with --check");
542  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
543  exit(1);
544  }
545 
546  /* Read the control file and check compatibility */
547  ControlFile = get_controlfile(DataDir, &crc_ok);
548  if (!crc_ok)
549  pg_fatal("pg_control CRC value is incorrect");
550 
552  pg_fatal("cluster is not compatible with this version of pg_checksums");
553 
554  if (ControlFile->blcksz != BLCKSZ)
555  {
556  pg_log_error("database cluster is not compatible");
557  pg_log_error_detail("The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.",
558  ControlFile->blcksz, BLCKSZ);
559  exit(1);
560  }
561 
562  /*
563  * Check if cluster is running. A clean shutdown is required to avoid
564  * random checksum failures caused by torn pages. Note that this doesn't
565  * guard against someone starting the cluster concurrently.
566  */
567  if (ControlFile->state != DB_SHUTDOWNED &&
569  pg_fatal("cluster must be shut down");
570 
572  mode == PG_MODE_CHECK)
573  pg_fatal("data checksums are not enabled in cluster");
574 
577  pg_fatal("data checksums are already disabled in cluster");
578 
580  mode == PG_MODE_ENABLE)
581  pg_fatal("data checksums are already enabled in cluster");
582 
583  /* Operate on all files if checking or enabling checksums */
584  if (mode == PG_MODE_CHECK || mode == PG_MODE_ENABLE)
585  {
586  /*
587  * If progress status information is requested, we need to scan the
588  * directory tree twice: once to know how much total data needs to be
589  * processed and once to do the real work.
590  */
591  if (showprogress)
592  {
593  total_size = scan_directory(DataDir, "global", true);
594  total_size += scan_directory(DataDir, "base", true);
596  }
597 
598  (void) scan_directory(DataDir, "global", false);
599  (void) scan_directory(DataDir, "base", false);
600  (void) scan_directory(DataDir, PG_TBLSPC_DIR, false);
601 
602  if (showprogress)
603  progress_report(true);
604 
605  printf(_("Checksum operation completed\n"));
606  printf(_("Files scanned: %lld\n"), (long long) files_scanned);
607  printf(_("Blocks scanned: %lld\n"), (long long) blocks_scanned);
608  if (mode == PG_MODE_CHECK)
609  {
610  printf(_("Bad checksums: %lld\n"), (long long) badblocks);
611  printf(_("Data checksum version: %u\n"), ControlFile->data_checksum_version);
612 
613  if (badblocks > 0)
614  exit(1);
615  }
616  else if (mode == PG_MODE_ENABLE)
617  {
618  printf(_("Files written: %lld\n"), (long long) files_written);
619  printf(_("Blocks written: %lld\n"), (long long) blocks_written);
620  }
621  }
622 
623  /*
624  * Finally make the data durable on disk if enabling or disabling
625  * checksums. Flush first the data directory for safety, and then update
626  * the control file to keep the switch consistent.
627  */
629  {
632 
633  if (do_sync)
634  {
635  pg_log_info("syncing data directory");
636  sync_pgdata(DataDir, PG_VERSION_NUM, sync_method);
637  }
638 
639  pg_log_info("updating control file");
641 
642  if (verbose)
643  printf(_("Data checksum version: %u\n"), ControlFile->data_checksum_version);
644  if (mode == PG_MODE_ENABLE)
645  printf(_("Checksums enabled in cluster\n"));
646  else
647  printf(_("Checksums disabled in cluster\n"));
648  }
649 
650  return 0;
651 }
#define PG_DATA_CHECKSUM_VERSION
Definition: bufpage.h:206
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1219
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:429
void update_controlfile(const char *DataDir, ControlFileData *ControlFile, bool do_sync)
ControlFileData * get_controlfile(const char *DataDir, bool *crc_ok_p)
#define _(x)
Definition: elog.c:90
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:60
#define no_argument
Definition: getopt_long.h:24
#define required_argument
Definition: getopt_long.h:25
char * DataDir
Definition: globals.c:70
exit(1)
void pg_logging_init(const char *argv0)
Definition: logging.c:83
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_hint(...)
Definition: logging.h:112
#define pg_log_info(...)
Definition: logging.h:124
#define pg_log_error_detail(...)
Definition: logging.h:109
char * pstrdup(const char *in)
Definition: mcxt.c:1696
bool option_parse_int(const char *optarg, const char *optname, int min_range, int max_range, int *result)
Definition: option_utils.c:50
bool parse_sync_method(const char *optarg, DataDirSyncMethod *sync_method)
Definition: option_utils.c:90
#define pg_fatal(...)
static int64 total_size
Definition: pg_checksums.c:62
static PgChecksumMode mode
Definition: pg_checksums.c:55
static char * only_filenode
Definition: pg_checksums.c:42
static int64 blocks_scanned
Definition: pg_checksums.c:37
static void progress_report(bool finished)
Definition: pg_checksums.c:123
static int64 scan_directory(const char *basedir, const char *subdir, bool sizeonly)
Definition: pg_checksums.c:299
static int64 files_scanned
Definition: pg_checksums.c:35
static bool do_sync
Definition: pg_checksums.c:43
static bool verbose
Definition: pg_checksums.c:44
static ControlFileData * ControlFile
Definition: pg_checksums.c:40
static DataDirSyncMethod sync_method
Definition: pg_checksums.c:46
static int64 blocks_written
Definition: pg_checksums.c:38
static bool showprogress
Definition: pg_checksums.c:45
static const char * progname
Definition: pg_checksums.c:57
static void usage(void)
Definition: pg_checksums.c:67
static int64 files_written
Definition: pg_checksums.c:36
static int64 badblocks
Definition: pg_checksums.c:39
#define PG_CONTROL_VERSION
Definition: pg_control.h:25
@ DB_SHUTDOWNED_IN_RECOVERY
Definition: pg_control.h:93
@ DB_SHUTDOWNED
Definition: pg_control.h:92
PGDLLIMPORT int optind
Definition: getopt.c:51
PGDLLIMPORT char * optarg
Definition: getopt.c:53
const char * get_progname(const char *argv0)
Definition: path.c:575
#define printf(...)
Definition: port.h:244
char * c
#define PG_TBLSPC_DIR
Definition: relpath.h:41
uint32 pg_control_version
Definition: pg_control.h:125
uint32 data_checksum_version
Definition: pg_control.h:222

References _, badblocks, ControlFileData::blcksz, blocks_scanned, blocks_written, ControlFile, ControlFileData::data_checksum_version, DataDir, DB_SHUTDOWNED, DB_SHUTDOWNED_IN_RECOVERY, do_sync, exit(), files_scanned, files_written, get_controlfile(), get_progname(), getopt_long(), mode, no_argument, only_filenode, optarg, optind, option_parse_int(), parse_sync_method(), PG_CONTROL_VERSION, ControlFileData::pg_control_version, PG_DATA_CHECKSUM_VERSION, pg_fatal, pg_log_error, pg_log_error_detail, pg_log_error_hint, pg_log_info, pg_logging_init(), PG_MODE_CHECK, PG_MODE_DISABLE, PG_MODE_ENABLE, PG_TBLSPC_DIR, PG_TEXTDOMAIN, printf, progname, progress_report(), pstrdup(), required_argument, scan_directory(), set_pglocale_pgservice(), showprogress, ControlFileData::state, sync_method, total_size, update_controlfile(), usage(), and verbose.

◆ progress_report()

static void progress_report ( bool  finished)
static

Definition at line 123 of file pg_checksums.c.

124 {
125  int percent;
126  pg_time_t now;
127 
129 
130  now = time(NULL);
131  if (now == last_progress_report && !finished)
132  return; /* Max once per second */
133 
134  /* Save current time */
136 
137  /* Adjust total size if current_size is larger */
138  if (current_size > total_size)
140 
141  /* Calculate current percentage of size done */
142  percent = total_size ? (int) ((current_size) * 100 / total_size) : 0;
143 
144  fprintf(stderr, _("%lld/%lld MB (%d%%) computed"),
145  (long long) (current_size / (1024 * 1024)),
146  (long long) (total_size / (1024 * 1024)),
147  percent);
148 
149  /*
150  * Stay on the same line if reporting to a terminal and we're not done
151  * yet.
152  */
153  fputc((!finished && isatty(fileno(stderr))) ? '\r' : '\n', stderr);
154 }
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1608
#define Assert(condition)
Definition: c.h:863
static int64 current_size
Definition: pg_checksums.c:63
static pg_time_t last_progress_report
Definition: pg_checksums.c:64
int64 pg_time_t
Definition: pgtime.h:23
#define fprintf
Definition: port.h:242

References _, Assert, current_size, fprintf, last_progress_report, now(), showprogress, and total_size.

Referenced by main(), and scan_file().

◆ scan_directory()

static int64 scan_directory ( const char *  basedir,
const char *  subdir,
bool  sizeonly 
)
static

Definition at line 299 of file pg_checksums.c.

300 {
301  int64 dirsize = 0;
302  char path[MAXPGPATH];
303  DIR *dir;
304  struct dirent *de;
305 
306  snprintf(path, sizeof(path), "%s/%s", basedir, subdir);
307  dir = opendir(path);
308  if (!dir)
309  pg_fatal("could not open directory \"%s\": %m", path);
310  while ((de = readdir(dir)) != NULL)
311  {
312  char fn[MAXPGPATH];
313  struct stat st;
314 
315  if (strcmp(de->d_name, ".") == 0 ||
316  strcmp(de->d_name, "..") == 0)
317  continue;
318 
319  /* Skip temporary files */
320  if (strncmp(de->d_name,
322  strlen(PG_TEMP_FILE_PREFIX)) == 0)
323  continue;
324 
325  /* Skip temporary folders */
326  if (strncmp(de->d_name,
328  strlen(PG_TEMP_FILES_DIR)) == 0)
329  continue;
330 
331  /* Skip macOS system files */
332  if (strcmp(de->d_name, ".DS_Store") == 0)
333  continue;
334 
335  snprintf(fn, sizeof(fn), "%s/%s", path, de->d_name);
336  if (lstat(fn, &st) < 0)
337  pg_fatal("could not stat file \"%s\": %m", fn);
338  if (S_ISREG(st.st_mode))
339  {
340  char fnonly[MAXPGPATH];
341  char *forkpath,
342  *segmentpath;
343  int segmentno = 0;
344 
345  if (skipfile(de->d_name))
346  continue;
347 
348  /*
349  * Cut off at the segment boundary (".") to get the segment number
350  * in order to mix it into the checksum. Then also cut off at the
351  * fork boundary, to get the filenode the file belongs to for
352  * filtering.
353  */
354  strlcpy(fnonly, de->d_name, sizeof(fnonly));
355  segmentpath = strchr(fnonly, '.');
356  if (segmentpath != NULL)
357  {
358  *segmentpath++ = '\0';
359  segmentno = atoi(segmentpath);
360  if (segmentno == 0)
361  pg_fatal("invalid segment number %d in file name \"%s\"",
362  segmentno, fn);
363  }
364 
365  forkpath = strchr(fnonly, '_');
366  if (forkpath != NULL)
367  *forkpath++ = '\0';
368 
369  if (only_filenode && strcmp(only_filenode, fnonly) != 0)
370  /* filenode not to be included */
371  continue;
372 
373  dirsize += st.st_size;
374 
375  /*
376  * No need to work on the file when calculating only the size of
377  * the items in the data folder.
378  */
379  if (!sizeonly)
380  scan_file(fn, segmentno);
381  }
382  else if (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))
383  {
384  /*
385  * If going through the entries of pg_tblspc, we assume to operate
386  * on tablespace locations where only TABLESPACE_VERSION_DIRECTORY
387  * is valid, resolving the linked locations and dive into them
388  * directly.
389  */
390  if (strncmp(PG_TBLSPC_DIR, subdir, strlen(PG_TBLSPC_DIR)) == 0)
391  {
392  char tblspc_path[MAXPGPATH];
393  struct stat tblspc_st;
394 
395  /*
396  * Resolve tablespace location path and check whether
397  * TABLESPACE_VERSION_DIRECTORY exists. Not finding a valid
398  * location is unexpected, since there should be no orphaned
399  * links and no links pointing to something else than a
400  * directory.
401  */
402  snprintf(tblspc_path, sizeof(tblspc_path), "%s/%s/%s",
404 
405  if (lstat(tblspc_path, &tblspc_st) < 0)
406  pg_fatal("could not stat file \"%s\": %m",
407  tblspc_path);
408 
409  /*
410  * Move backwards once as the scan needs to happen for the
411  * contents of TABLESPACE_VERSION_DIRECTORY.
412  */
413  snprintf(tblspc_path, sizeof(tblspc_path), "%s/%s",
414  path, de->d_name);
415 
416  /* Looks like a valid tablespace location */
417  dirsize += scan_directory(tblspc_path,
419  sizeonly);
420  }
421  else
422  {
423  dirsize += scan_directory(path, de->d_name, sizeonly);
424  }
425  }
426  }
427  closedir(dir);
428  return dirsize;
429 }
int closedir(DIR *)
Definition: dirent.c:127
struct dirent * readdir(DIR *)
Definition: dirent.c:78
DIR * opendir(const char *)
Definition: dirent.c:33
#define PG_TEMP_FILES_DIR
Definition: file_utils.h:62
#define PG_TEMP_FILE_PREFIX
Definition: file_utils.h:63
static char * basedir
static void scan_file(const char *fn, int segmentno)
Definition: pg_checksums.c:175
static bool skipfile(const char *fn)
Definition: pg_checksums.c:157
#define MAXPGPATH
#define snprintf
Definition: port.h:238
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:33
Definition: dirent.c:26
Definition: dirent.h:10
char d_name[MAX_PATH]
Definition: dirent.h:15
static void * fn(void *arg)
Definition: thread-alloc.c:119
#define lstat(path, sb)
Definition: win32_port.h:285
#define S_ISDIR(m)
Definition: win32_port.h:325
#define S_ISLNK(m)
Definition: win32_port.h:344
#define S_ISREG(m)
Definition: win32_port.h:328

References basedir, closedir(), dirent::d_name, fn(), lstat, MAXPGPATH, only_filenode, opendir(), pg_fatal, PG_TBLSPC_DIR, PG_TEMP_FILE_PREFIX, PG_TEMP_FILES_DIR, readdir(), S_ISDIR, S_ISLNK, S_ISREG, scan_file(), skipfile(), snprintf, stat::st_mode, stat::st_size, strlcpy(), and TABLESPACE_VERSION_DIRECTORY.

Referenced by main().

◆ scan_file()

static void scan_file ( const char *  fn,
int  segmentno 
)
static

Definition at line 175 of file pg_checksums.c.

176 {
178  PageHeader header = (PageHeader) buf.data;
179  int f;
180  BlockNumber blockno;
181  int flags;
182  int64 blocks_written_in_file = 0;
183 
185  mode == PG_MODE_CHECK);
186 
187  flags = (mode == PG_MODE_ENABLE) ? O_RDWR : O_RDONLY;
188  f = open(fn, PG_BINARY | flags, 0);
189 
190  if (f < 0)
191  pg_fatal("could not open file \"%s\": %m", fn);
192 
193  files_scanned++;
194 
195  for (blockno = 0;; blockno++)
196  {
197  uint16 csum;
198  int r = read(f, buf.data, BLCKSZ);
199 
200  if (r == 0)
201  break;
202  if (r != BLCKSZ)
203  {
204  if (r < 0)
205  pg_fatal("could not read block %u in file \"%s\": %m",
206  blockno, fn);
207  else
208  pg_fatal("could not read block %u in file \"%s\": read %d of %d",
209  blockno, fn, r, BLCKSZ);
210  }
211  blocks_scanned++;
212 
213  /*
214  * Since the file size is counted as total_size for progress status
215  * information, the sizes of all pages including new ones in the file
216  * should be counted as current_size. Otherwise the progress reporting
217  * calculated using those counters may not reach 100%.
218  */
219  current_size += r;
220 
221  /* New pages have no checksum yet */
222  if (PageIsNew(buf.data))
223  continue;
224 
225  csum = pg_checksum_page(buf.data, blockno + segmentno * RELSEG_SIZE);
226  if (mode == PG_MODE_CHECK)
227  {
228  if (csum != header->pd_checksum)
229  {
231  pg_log_error("checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X",
232  fn, blockno, csum, header->pd_checksum);
233  badblocks++;
234  }
235  }
236  else if (mode == PG_MODE_ENABLE)
237  {
238  int w;
239 
240  /*
241  * Do not rewrite if the checksum is already set to the expected
242  * value.
243  */
244  if (header->pd_checksum == csum)
245  continue;
246 
247  blocks_written_in_file++;
248 
249  /* Set checksum in page header */
250  header->pd_checksum = csum;
251 
252  /* Seek back to beginning of block */
253  if (lseek(f, -BLCKSZ, SEEK_CUR) < 0)
254  pg_fatal("seek failed for block %u in file \"%s\": %m", blockno, fn);
255 
256  /* Write block with checksum */
257  w = write(f, buf.data, BLCKSZ);
258  if (w != BLCKSZ)
259  {
260  if (w < 0)
261  pg_fatal("could not write block %u in file \"%s\": %m",
262  blockno, fn);
263  else
264  pg_fatal("could not write block %u in file \"%s\": wrote %d of %d",
265  blockno, fn, w, BLCKSZ);
266  }
267  }
268 
269  if (showprogress)
270  progress_report(false);
271  }
272 
273  if (verbose)
274  {
275  if (mode == PG_MODE_CHECK)
276  pg_log_info("checksums verified in file \"%s\"", fn);
277  if (mode == PG_MODE_ENABLE)
278  pg_log_info("checksums enabled in file \"%s\"", fn);
279  }
280 
281  /* Update write counters if any write activity has happened */
282  if (blocks_written_in_file > 0)
283  {
284  files_written++;
285  blocks_written += blocks_written_in_file;
286  }
287 
288  close(f);
289 }
uint32 BlockNumber
Definition: block.h:31
PageHeaderData * PageHeader
Definition: bufpage.h:173
static bool PageIsNew(Page page)
Definition: bufpage.h:233
unsigned short uint16
Definition: c.h:517
#define PG_BINARY
Definition: c.h:1278
uint16 pg_checksum_page(char *page, BlockNumber blkno)
#define close(a)
Definition: win32.h:12
#define write(a, b, c)
Definition: win32.h:14
#define read(a, b, c)
Definition: win32.h:13
static char * buf
Definition: pg_test_fsync.c:72
uint16 pd_checksum
Definition: bufpage.h:163

References Assert, badblocks, blocks_scanned, blocks_written, buf, close, ControlFile, current_size, ControlFileData::data_checksum_version, files_scanned, files_written, fn(), mode, PageIsNew(), PageHeaderData::pd_checksum, PG_BINARY, pg_checksum_page(), PG_DATA_CHECKSUM_VERSION, pg_fatal, pg_log_error, pg_log_info, PG_MODE_CHECK, PG_MODE_ENABLE, progress_report(), read, showprogress, verbose, and write.

Referenced by scan_directory().

◆ skipfile()

static bool skipfile ( const char *  fn)
static

Definition at line 157 of file pg_checksums.c.

158 {
159  int excludeIdx;
160 
161  for (excludeIdx = 0; skip[excludeIdx].name != NULL; excludeIdx++)
162  {
163  int cmplen = strlen(skip[excludeIdx].name);
164 
165  if (!skip[excludeIdx].match_prefix)
166  cmplen++;
167  if (strncmp(skip[excludeIdx].name, fn, cmplen) == 0)
168  return true;
169  }
170 
171  return false;
172 }
static const struct exclude_list_item skip[]
Definition: pg_checksums.c:107
const char * name
Definition: basebackup.c:139
const char * name

References fn(), exclude_list_item::match_prefix, exclude_list_item::name, name, and skip.

Referenced by scan_directory().

◆ usage()

static void usage ( void  )
static

Definition at line 67 of file pg_checksums.c.

68 {
69  printf(_("%s enables, disables, or verifies data checksums in a PostgreSQL database cluster.\n\n"), progname);
70  printf(_("Usage:\n"));
71  printf(_(" %s [OPTION]... [DATADIR]\n"), progname);
72  printf(_("\nOptions:\n"));
73  printf(_(" [-D, --pgdata=]DATADIR data directory\n"));
74  printf(_(" -c, --check check data checksums (default)\n"));
75  printf(_(" -d, --disable disable data checksums\n"));
76  printf(_(" -e, --enable enable data checksums\n"));
77  printf(_(" -f, --filenode=FILENODE check only relation with specified filenode\n"));
78  printf(_(" -N, --no-sync do not wait for changes to be written safely to disk\n"));
79  printf(_(" -P, --progress show progress information\n"));
80  printf(_(" --sync-method=METHOD set method for syncing files to disk\n"));
81  printf(_(" -v, --verbose output verbose messages\n"));
82  printf(_(" -V, --version output version information, then exit\n"));
83  printf(_(" -?, --help show this help, then exit\n"));
84  printf(_("\nIf no data directory (DATADIR) is specified, "
85  "the environment variable PGDATA\nis used.\n\n"));
86  printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
87  printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
88 }

Referenced by main().

Variable Documentation

◆ badblocks

int64 badblocks = 0
static

Definition at line 39 of file pg_checksums.c.

Referenced by main(), and scan_file().

◆ blocks_scanned

int64 blocks_scanned = 0
static

Definition at line 37 of file pg_checksums.c.

Referenced by main(), and scan_file().

◆ blocks_written

int64 blocks_written = 0
static

Definition at line 38 of file pg_checksums.c.

Referenced by main(), pgstat_slru_flush_cb(), and scan_file().

◆ ControlFile

ControlFileData* ControlFile
static

Definition at line 40 of file pg_checksums.c.

Referenced by main(), and scan_file().

◆ current_size

int64 current_size = 0
static

Definition at line 63 of file pg_checksums.c.

Referenced by ExtendBufferedRelTo(), progress_report(), scan_file(), and unicode_normalize().

◆ do_sync

bool do_sync = true
static

Definition at line 43 of file pg_checksums.c.

Referenced by main().

◆ files_scanned

int64 files_scanned = 0
static

Definition at line 35 of file pg_checksums.c.

Referenced by main(), and scan_file().

◆ files_written

int64 files_written = 0
static

Definition at line 36 of file pg_checksums.c.

Referenced by main(), and scan_file().

◆ last_progress_report

pg_time_t last_progress_report = 0
static

Definition at line 64 of file pg_checksums.c.

Referenced by progress_report().

◆ mode

Definition at line 55 of file pg_checksums.c.

Referenced by _allocAH(), AllocateFile(), be_lo_open(), brinGetTupleForHeapBlock(), BufFileOpenFileSet(), column_privilege_check(), compute_new_xmax_infomask(), create_file_for_extract(), CreateArchive(), dump_variables(), ECPGsetcommit(), ExtendBufferedRelTo(), extract_directory(), FileSetOpen(), from_char_set_mode(), get_mxact_status_for_lock(), GetLockmodeName(), GetMultiXactIdHintBits(), has_any_column_privilege_id(), has_any_column_privilege_id_id(), has_any_column_privilege_id_name(), has_any_column_privilege_name(), has_any_column_privilege_name_id(), has_any_column_privilege_name_name(), has_column_privilege_id_attnum(), has_column_privilege_id_id_attnum(), has_column_privilege_id_id_name(), has_column_privilege_id_name(), has_column_privilege_id_name_attnum(), has_column_privilege_id_name_name(), has_column_privilege_name_attnum(), has_column_privilege_name_id_attnum(), has_column_privilege_name_id_name(), has_column_privilege_name_name(), has_column_privilege_name_name_attnum(), has_column_privilege_name_name_name(), has_database_privilege_id(), has_database_privilege_id_id(), has_database_privilege_id_name(), has_database_privilege_name(), has_database_privilege_name_id(), has_database_privilege_name_name(), has_foreign_data_wrapper_privilege_id(), has_foreign_data_wrapper_privilege_id_id(), has_foreign_data_wrapper_privilege_id_name(), has_foreign_data_wrapper_privilege_name(), has_foreign_data_wrapper_privilege_name_id(), has_foreign_data_wrapper_privilege_name_name(), has_function_privilege_id(), has_function_privilege_id_id(), has_function_privilege_id_name(), has_function_privilege_name(), has_function_privilege_name_id(), has_function_privilege_name_name(), has_language_privilege_id(), has_language_privilege_id_id(), has_language_privilege_id_name(), has_language_privilege_name(), has_language_privilege_name_id(), has_language_privilege_name_name(), has_largeobject_privilege_id(), has_largeobject_privilege_id_id(), has_largeobject_privilege_name_id(), has_schema_privilege_id(), has_schema_privilege_id_id(), has_schema_privilege_id_name(), has_schema_privilege_name(), has_schema_privilege_name_id(), has_schema_privilege_name_name(), has_sequence_privilege_id(), has_sequence_privilege_id_id(), has_sequence_privilege_id_name(), has_sequence_privilege_name(), has_sequence_privilege_name_id(), has_sequence_privilege_name_name(), has_server_privilege_id(), has_server_privilege_id_id(), has_server_privilege_id_name(), has_server_privilege_name(), has_server_privilege_name_id(), has_server_privilege_name_name(), has_table_privilege_id(), has_table_privilege_id_id(), has_table_privilege_id_name(), has_table_privilege_name(), has_table_privilege_name_id(), has_table_privilege_name_name(), has_tablespace_privilege_id(), has_tablespace_privilege_id_id(), has_tablespace_privilege_id_name(), has_tablespace_privilege_name(), has_tablespace_privilege_name_id(), has_tablespace_privilege_name_name(), has_type_privilege_id(), has_type_privilege_id_id(), has_type_privilege_id_name(), has_type_privilege_name(), has_type_privilege_name_id(), has_type_privilege_name_name(), heap_acquire_tuplock(), heap_lock_tuple(), heap_lock_updated_tuple(), heap_lock_updated_tuple_rec(), heapam_tuple_lock(), InitDiscoverCompressFileHandle(), lo_creat(), lo_open(), LockBuffer(), logfile_open(), LWLockAcquire(), LWLockAcquireOrWait(), LWLockAttemptLock(), LWLockConditionalAcquire(), LWLockHeldByMeInMode(), LWLockQueueSelf(), LWLockRelease(), main(), object_aclcheck(), object_aclcheck_ext(), open_direct(), open_none(), open_target_file(), open_write_none(), OpenPipeStream(), parseArchiveFormat(), PathNameOpenTemporaryFile(), pg_attribute_aclcheck(), pg_attribute_aclcheck_all(), pg_attribute_aclcheck_all_ext(), pg_attribute_aclcheck_ext(), pg_class_aclcheck(), pg_class_aclcheck_ext(), pg_has_role_id(), pg_has_role_id_id(), pg_has_role_id_name(), pg_has_role_name(), pg_has_role_name_id(), pg_has_role_name_name(), pg_largeobject_aclcheck_snapshot(), pg_lock_status(), pg_parameter_aclcheck(), pg_role_aclcheck(), pgp_s2k_fill(), pgp_set_s2k_mode(), pgp_set_text_mode(), pgp_set_unicode_mode(), popen_check(), process_pm_shutdown_request(), raw_parser(), ReadBuffer_common(), ReadBufferBI(), ReadBufferExtended(), ReadBufferWithoutRelcache(), scan_file(), SetOutput(), SyncRepQueueInsert(), SyncRepWaitForLSN(), SyncRepWakeQueue(), table_tuple_lock(), TargetPrivilegesCheck(), tarOpen(), test_lockmode_for_conflict(), WaitForWorkers(), whenever_action(), XLogReadBufferExtended(), XLogReadBufferForRedoExtended(), and ZeroAndLockBuffer().

◆ only_filenode

char* only_filenode = NULL
static

Definition at line 42 of file pg_checksums.c.

Referenced by main(), and scan_directory().

◆ progname

const char* progname
static

Definition at line 57 of file pg_checksums.c.

Referenced by main().

◆ showprogress

bool showprogress = false
static

Definition at line 45 of file pg_checksums.c.

Referenced by main(), progress_report(), and scan_file().

◆ skip

const struct exclude_list_item skip[]
static
Initial value:
= {
{"pg_control", false},
{"pg_filenode.map", false},
{"pg_internal.init", true},
{"PG_VERSION", false},
{NULL, false}
}

Definition at line 67 of file pg_checksums.c.

Referenced by array_replace_internal(), DefineVirtualRelation(), dependencies_clauselist_selectivity(), filter_partitions(), heap_hot_search_buffer(), initTrie(), json_build_object_worker(), json_object_agg_transfn_worker(), jsonb_build_object_worker(), jsonb_object_agg_transfn_worker(), skipfile(), and verify_heapam().

◆ sync_method

Definition at line 46 of file pg_checksums.c.

Referenced by main().

◆ total_size

int64 total_size = 0
static

Definition at line 62 of file pg_checksums.c.

Referenced by main(), make_new_segment(), and progress_report().

◆ verbose

bool verbose = false
static

Definition at line 44 of file pg_checksums.c.

Referenced by main(), and scan_file().