Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit280e5f1

Browse files
committed
Add progress reporting to pg_checksums
This adds a new option to pg_checksums called -P/--progress, showingevery second some information about the computation state of anoperation for --check and --enable (--disable only updates the controlfile and is quick). This requires a pre-scan of the data folder so asthe total size of checksummable items can be calculated, and then itgets compared to the amount processed.Similarly to what is done for pg_rewind and pg_basebackup, theinformation printed in the progress report consists of the currentamount of data computed and the total amount of data to compute. Thiscould be extended later on.Author: Michael Banck, Bernd HelmleReviewed-by: Fabien Coelho, Michael PaquierDiscussion:https://postgr.es/m/1535719851.1286.17.camel@credativ.de
1 parent475861b commit280e5f1

File tree

2 files changed

+117
-8
lines changed

2 files changed

+117
-8
lines changed

‎doc/src/sgml/ref/pg_checksums.sgml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,17 @@ PostgreSQL documentation
135135
</listitem>
136136
</varlistentry>
137137

138+
<varlistentry>
139+
<term><option>-P</option></term>
140+
<term><option>--progress</option></term>
141+
<listitem>
142+
<para>
143+
Enable progress reporting. Turning this on will deliver a progress
144+
report while checking or enabling checksums.
145+
</para>
146+
</listitem>
147+
</varlistentry>
148+
138149
<varlistentry>
139150
<term><option>-V</option></term>
140151
<term><option>--version</option></term>

‎src/bin/pg_checksums/pg_checksums.c

Lines changed: 106 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include"postgres_fe.h"
1616

1717
#include<dirent.h>
18+
#include<time.h>
1819
#include<sys/stat.h>
1920
#include<unistd.h>
2021

@@ -38,6 +39,7 @@ static ControlFileData *ControlFile;
3839
staticchar*only_relfilenode=NULL;
3940
staticbooldo_sync= true;
4041
staticboolverbose= false;
42+
staticboolshowprogress= false;
4143

4244
typedefenum
4345
{
@@ -60,6 +62,13 @@ static PgChecksumMode mode = PG_MODE_CHECK;
6062

6163
staticconstchar*progname;
6264

65+
/*
66+
* Progress status information.
67+
*/
68+
int64total_size=0;
69+
int64current_size=0;
70+
staticpg_time_tlast_progress_report=0;
71+
6372
staticvoid
6473
usage(void)
6574
{
@@ -72,6 +81,7 @@ usage(void)
7281
printf(_(" -d, --disable disable data checksums\n"));
7382
printf(_(" -e, --enable enable data checksums\n"));
7483
printf(_(" -N, --no-sync do not wait for changes to be written safely to disk\n"));
84+
printf(_(" -P, --progress show progress information\n"));
7585
printf(_(" -v, --verbose output verbose messages\n"));
7686
printf(_(" -r RELFILENODE check only relation with specified relfilenode\n"));
7787
printf(_(" -V, --version output version information, then exit\n"));
@@ -98,6 +108,52 @@ static const char *const skip[] = {
98108
NULL,
99109
};
100110

111+
/*
112+
* Report current progress status. Parts borrowed from
113+
* src/bin/pg_basebackup.c.
114+
*/
115+
staticvoid
116+
progress_report(boolforce)
117+
{
118+
intpercent;
119+
chartotal_size_str[32];
120+
charcurrent_size_str[32];
121+
pg_time_tnow;
122+
123+
Assert(showprogress);
124+
125+
now=time(NULL);
126+
if (now==last_progress_report&& !force)
127+
return;/* Max once per second */
128+
129+
/* Save current time */
130+
last_progress_report=now;
131+
132+
/* Adjust total size if current_size is larger */
133+
if (current_size>total_size)
134+
total_size=current_size;
135+
136+
/* Calculate current percentage of size done */
137+
percent=total_size ? (int) ((current_size)*100 /total_size) :0;
138+
139+
snprintf(total_size_str,sizeof(total_size_str),INT64_FORMAT,
140+
total_size / (1024*1024));
141+
snprintf(current_size_str,sizeof(current_size_str),INT64_FORMAT,
142+
current_size / (1024*1024));
143+
144+
/*
145+
* Separate step to keep platform-dependent format code out of
146+
* translatable strings. And we only test for INT64_FORMAT availability
147+
* in snprintf, not fprintf.
148+
*/
149+
fprintf(stderr,"%*s/%s MB (%d%%) computed",
150+
(int)strlen(current_size_str),current_size_str,total_size_str,
151+
percent);
152+
153+
/* Stay on the same line if reporting to a terminal */
154+
fprintf(stderr,isatty(fileno(stderr)) ?"\r" :"\n");
155+
}
156+
101157
staticbool
102158
skipfile(constchar*fn)
103159
{
@@ -153,6 +209,7 @@ scan_file(const char *fn, BlockNumber segmentno)
153209
continue;
154210

155211
csum=pg_checksum_page(buf.data,blockno+segmentno*RELSEG_SIZE);
212+
current_size+=r;
156213
if (mode==PG_MODE_CHECK)
157214
{
158215
if (csum!=header->pd_checksum)
@@ -183,6 +240,9 @@ scan_file(const char *fn, BlockNumber segmentno)
183240
exit(1);
184241
}
185242
}
243+
244+
if (showprogress)
245+
progress_report(false);
186246
}
187247

188248
if (verbose)
@@ -196,9 +256,17 @@ scan_file(const char *fn, BlockNumber segmentno)
196256
close(f);
197257
}
198258

199-
staticvoid
200-
scan_directory(constchar*basedir,constchar*subdir)
259+
/*
260+
* Scan the given directory for items which can be checksummed and
261+
* operate on each one of them. If "sizeonly" is true, the size of
262+
* all the items which have checksums is computed and returned back
263+
* to the caller without operating on the files. This is used to compile
264+
* the total size of the data directory for progress reports.
265+
*/
266+
staticint64
267+
scan_directory(constchar*basedir,constchar*subdir,boolsizeonly)
201268
{
269+
int64dirsize=0;
202270
charpath[MAXPGPATH];
203271
DIR*dir;
204272
structdirent*de;
@@ -275,16 +343,24 @@ scan_directory(const char *basedir, const char *subdir)
275343
/* Relfilenode not to be included */
276344
continue;
277345

278-
scan_file(fn,segmentno);
346+
dirsize+=st.st_size;
347+
348+
/*
349+
* No need to work on the file when calculating only the size of
350+
* the items in the data folder.
351+
*/
352+
if (!sizeonly)
353+
scan_file(fn,segmentno);
279354
}
280355
#ifndefWIN32
281356
elseif (S_ISDIR(st.st_mode)||S_ISLNK(st.st_mode))
282357
#else
283358
elseif (S_ISDIR(st.st_mode)||pgwin32_is_junction(fn))
284359
#endif
285-
scan_directory(path,de->d_name);
360+
dirsize+=scan_directory(path,de->d_name,sizeonly);
286361
}
287362
closedir(dir);
363+
returndirsize;
288364
}
289365

290366
int
@@ -296,6 +372,7 @@ main(int argc, char *argv[])
296372
{"disable",no_argument,NULL,'d'},
297373
{"enable",no_argument,NULL,'e'},
298374
{"no-sync",no_argument,NULL,'N'},
375+
{"progress",no_argument,NULL,'P'},
299376
{"verbose",no_argument,NULL,'v'},
300377
{NULL,0,NULL,0}
301378
};
@@ -323,7 +400,7 @@ main(int argc, char *argv[])
323400
}
324401
}
325402

326-
while ((c=getopt_long(argc,argv,"cD:deNr:v",long_options,&option_index))!=-1)
403+
while ((c=getopt_long(argc,argv,"cD:deNPr:v",long_options,&option_index))!=-1)
327404
{
328405
switch (c)
329406
{
@@ -353,6 +430,9 @@ main(int argc, char *argv[])
353430
}
354431
only_relfilenode=pstrdup(optarg);
355432
break;
433+
case'P':
434+
showprogress= true;
435+
break;
356436
default:
357437
fprintf(stderr,_("Try \"%s --help\" for more information.\n"),progname);
358438
exit(1);
@@ -447,9 +527,27 @@ main(int argc, char *argv[])
447527
/* Operate on all files if checking or enabling checksums */
448528
if (mode==PG_MODE_CHECK||mode==PG_MODE_ENABLE)
449529
{
450-
scan_directory(DataDir,"global");
451-
scan_directory(DataDir,"base");
452-
scan_directory(DataDir,"pg_tblspc");
530+
/*
531+
* If progress status information is requested, we need to scan the
532+
* directory tree twice: once to know how much total data needs to be
533+
* processed and once to do the real work.
534+
*/
535+
if (showprogress)
536+
{
537+
total_size=scan_directory(DataDir,"global", true);
538+
total_size+=scan_directory(DataDir,"base", true);
539+
total_size+=scan_directory(DataDir,"pg_tblspc", true);
540+
}
541+
542+
(void)scan_directory(DataDir,"global", false);
543+
(void)scan_directory(DataDir,"base", false);
544+
(void)scan_directory(DataDir,"pg_tblspc", false);
545+
546+
if (showprogress)
547+
{
548+
progress_report(true);
549+
fprintf(stderr,"\n");/* Need to move to next line */
550+
}
453551

454552
printf(_("Checksum operation completed\n"));
455553
printf(_("Files scanned: %s\n"),psprintf(INT64_FORMAT,files));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp