58 #define PG_TEMP_FILES_DIR "pgsql_tmp" 59 #define PG_TEMP_FILE_PREFIX "pgsql_tmp" 75 printf(
_(
"%s enables, disables, or verifies data checksums in a PostgreSQL database cluster.\n\n"),
progname);
79 printf(
_(
" [-D, --pgdata=]DATADIR data directory\n"));
80 printf(
_(
" -c, --check check data checksums (default)\n"));
81 printf(
_(
" -d, --disable disable data checksums\n"));
82 printf(
_(
" -e, --enable enable data checksums\n"));
83 printf(
_(
" -f, --filenode=FILENODE check only relation with specified filenode\n"));
84 printf(
_(
" -N, --no-sync do not wait for changes to be written safely to disk\n"));
85 printf(
_(
" -P, --progress show progress information\n"));
86 printf(
_(
" -v, --verbose output verbose messages\n"));
87 printf(
_(
" -V, --version output version information, then exit\n"));
88 printf(
_(
" -?, --help show this help, then exit\n"));
89 printf(
_(
"\nIf no data directory (DATADIR) is specified, " 90 "the environment variable PGDATA\nis used.\n\n"));
91 printf(
_(
"Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
92 printf(
_(
"%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
113 {
"pg_control",
false},
114 {
"pg_filenode.map",
false},
115 {
"pg_internal.init",
true},
116 {
"PG_VERSION",
false},
118 {
"config_exec_params",
true},
131 char total_size_str[32];
132 char current_size_str[32];
161 fprintf(stderr,
_(
"%*s/%s MB (%d%%) computed"),
162 (
int) strlen(current_size_str), current_size_str, total_size_str,
169 fputc((!finished && isatty(fileno(stderr))) ?
'\r' :
'\n', stderr);
177 for (excludeIdx = 0; skip[excludeIdx].
name != NULL; excludeIdx++)
179 int cmplen = strlen(skip[excludeIdx].
name);
183 if (strncmp(skip[excludeIdx].name, fn, cmplen) == 0)
213 for (blockno = 0;; blockno++)
223 pg_log_error(
"could not read block %u in file \"%s\": %m",
226 pg_log_error(
"could not read block %u in file \"%s\": read %d of %d",
227 blockno, fn, r, BLCKSZ);
250 pg_log_error(
"checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X",
263 if (lseek(f, -BLCKSZ, SEEK_CUR) < 0)
265 pg_log_error(
"seek failed for block %u in file \"%s\": %m", blockno, fn);
274 pg_log_error(
"could not write block %u in file \"%s\": %m",
277 pg_log_error(
"could not write block %u in file \"%s\": wrote %d of %d",
278 blockno, fn, w, BLCKSZ);
290 pg_log_info(
"checksums verified in file \"%s\"", fn);
292 pg_log_info(
"checksums enabled in file \"%s\"", fn);
313 snprintf(path,
sizeof(path),
"%s/%s", basedir, subdir);
317 pg_log_error(
"could not open directory \"%s\": %m", path);
320 while ((de =
readdir(dir)) != NULL)
325 if (strcmp(de->
d_name,
".") == 0 ||
326 strcmp(de->
d_name,
"..") == 0)
342 if (
lstat(fn, &st) < 0)
364 segmentpath = strchr(fnonly,
'.');
365 if (segmentpath != NULL)
367 *segmentpath++ =
'\0';
368 segmentno = atoi(segmentpath);
371 pg_log_error(
"invalid segment number %d in file name \"%s\"",
377 forkpath = strchr(fnonly,
'_');
378 if (forkpath != NULL)
406 if (strncmp(
"pg_tblspc", subdir, strlen(
"pg_tblspc")) == 0)
409 struct stat tblspc_st;
418 snprintf(tblspc_path,
sizeof(tblspc_path),
"%s/%s/%s",
421 if (
lstat(tblspc_path, &tblspc_st) < 0)
432 snprintf(tblspc_path,
sizeof(tblspc_path),
"%s/%s",
453 static struct option long_options[] = {
476 if (strcmp(argv[1],
"--help") == 0 || strcmp(argv[1],
"-?") == 0)
481 if (strcmp(argv[1],
"--version") == 0 || strcmp(argv[1],
"-V") == 0)
483 puts(
"pg_checksums (PostgreSQL) " PG_VERSION);
488 while ((c =
getopt_long(argc, argv,
"cD:deNPf:v", long_options, &option_index)) != -1)
532 DataDir = getenv(
"PGDATA");
546 pg_log_error(
"too many command-line arguments (first is \"%s\")",
548 fprintf(stderr,
_(
"Try \"%s --help\" for more information.\n"),
556 pg_log_error(
"option -f/--filenode can only be used with --check");
557 fprintf(stderr,
_(
"Try \"%s --help\" for more information.\n"),
572 pg_log_error(
"cluster is not compatible with this version of pg_checksums");
576 if (ControlFile->
blcksz != BLCKSZ)
579 fprintf(stderr,
_(
"The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.\n"),
580 ControlFile->
blcksz, BLCKSZ);
599 pg_log_error(
"data checksums are not enabled in cluster");
606 pg_log_error(
"data checksums are already disabled in cluster");
613 pg_log_error(
"data checksums are already enabled in cluster");
639 printf(
_(
"Checksum operation completed\n"));
665 fsync_pgdata(DataDir, PG_VERSION_NUM);
674 printf(
_(
"Checksums enabled in cluster\n"));
676 printf(
_(
"Checksums disabled in cluster\n"));
static PgChecksumMode mode
static const char * progname
const char * get_progname(const char *argv0)
#define pg_log_error(...)
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
char * pstrdup(const char *in)
void pg_logging_init(const char *argv0)
char * psprintf(const char *fmt,...)
static ControlFileData * ControlFile
static const struct exclude_list_item skip[]
#define PG_TEMP_FILES_DIR
#define PG_CONTROL_VERSION
uint32 pg_control_version
int main(int argc, char *argv[])
void update_controlfile(const char *DataDir, ControlFileData *ControlFile, bool do_sync)
#define required_argument
#define PG_TEMP_FILE_PREFIX
DIR * opendir(const char *)
uint32 data_checksum_version
#define TABLESPACE_VERSION_DIRECTORY
static int64 scan_directory(const char *basedir, const char *subdir, bool sizeonly)
#define PG_TEXTDOMAIN(domain)
static void * fn(void *arg)
size_t strlcpy(char *dst, const char *src, size_t siz)
PageHeaderData * PageHeader
#define Assert(condition)
static pg_time_t last_progress_report
ControlFileData * get_controlfile(const char *DataDir, bool *crc_ok_p)
static void scan_file(const char *fn, BlockNumber segmentno)
struct dirent * readdir(DIR *)
static void header(const char *fmt,...) pg_attribute_printf(1
static void progress_report(bool finished)
static char * only_filenode
#define PG_DATA_CHECKSUM_VERSION
void set_pglocale_pgservice(const char *argv0, const char *app)
uint16 pg_checksum_page(char *page, BlockNumber blkno)
Datum now(PG_FUNCTION_ARGS)
static bool skipfile(const char *fn)
bool pgwin32_is_junction(const char *path)