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

Commit43c9790

Browse files
committed
Try to handle torn reads of pg_control in frontend.
Some of our src/bin tools read the control file without any kind ofinterlocking against concurrent writes from the server. At least ext4and ntfs can expose partially modified contents when you do that.For now, we'll try to tolerate this by retrying up to 10 times if thechecksum doesn't match, until we get two reads in a row with the samebad checksum. This is not guaranteed to reach the right conclusion, butit seems very likely to. Thanks to Tom Lane for this suggestion.Various ideas for interlocking or atomicity were considered toocomplicated, unportable or expensive given the lack of field reports,but remain open for future reconsideration.Back-patch as far as 12. It doesn't seem like a good idea to put aheuristic change for a very rare problem into the final release of 11.Reviewed-by: Anton A. Melnikov <aamelnikov@inbox.ru>Reviewed-by: David Steele <david@pgmasters.net>Reviewed-by: Michael Paquier <michael@paquier.xyz>Discussion:https://postgr.es/m/20221123014224.xisi44byq3cf5psi%40awork3.anarazel.de
1 parent637e86e commit43c9790

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

‎src/common/controldata_utils.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,22 @@ get_controlfile(const char *DataDir, bool *crc_ok_p)
5555
charControlFilePath[MAXPGPATH];
5656
pg_crc32ccrc;
5757
intr;
58+
#ifdefFRONTEND
59+
pg_crc32clast_crc;
60+
intretries=0;
61+
#endif
5862

5963
AssertArg(crc_ok_p);
6064

6165
ControlFile=palloc(sizeof(ControlFileData));
6266
snprintf(ControlFilePath,MAXPGPATH,"%s/global/pg_control",DataDir);
6367

68+
#ifdefFRONTEND
69+
INIT_CRC32C(last_crc);
70+
71+
retry:
72+
#endif
73+
6474
#ifndefFRONTEND
6575
if ((fd=OpenTransientFile(ControlFilePath,O_RDONLY |PG_BINARY))==-1)
6676
ereport(ERROR,
@@ -128,6 +138,26 @@ get_controlfile(const char *DataDir, bool *crc_ok_p)
128138

129139
*crc_ok_p=EQ_CRC32C(crc,ControlFile->crc);
130140

141+
#ifdefFRONTEND
142+
143+
/*
144+
* If the server was writing at the same time, it is possible that we read
145+
* partially updated contents on some systems. If the CRC doesn't match,
146+
* retry a limited number of times until we compute the same bad CRC twice
147+
* in a row with a short sleep in between. Then the failure is unlikely
148+
* to be due to a concurrent write.
149+
*/
150+
if (!*crc_ok_p&&
151+
(retries==0|| !EQ_CRC32C(crc,last_crc))&&
152+
retries<10)
153+
{
154+
retries++;
155+
last_crc=crc;
156+
pg_usleep(10000);
157+
gotoretry;
158+
}
159+
#endif
160+
131161
/* Make sure the control file is valid byte order. */
132162
if (ControlFile->pg_control_version %65536==0&&
133163
ControlFile->pg_control_version /65536!=0)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp