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

Commit8b938d3

Browse files
committed
Refactor more code logic to update the control file
ce6afc6 has begun the refactoring work by plugging pg_rewind into acentral routine to update the control file, and left around two extracopies, with one in xlog.c for the backend and one in pg_resetwal.c. Byadding an extra option to the central routine in controldata_utils.c tocontrol if a flush of the control file needs to be done, it is provingto be straight-forward to make xlog.c and pg_resetwal.c use the centralcode path at the condition of moving the wait event tracking there.Hence, this allows to have only one central code path to update thecontrol file, shaving the code from the duplicates.This refactoring actually fixes a problem in pg_resetwal. Previously,the control file was first removed before being recreated. So if acrash happened between the moment the file was removed and the momentthe file was created, then it would have been possible to not have acontrol file anymore in the database folder.Author: Fabien CoelhoReviewed-by: Michael PaquierDiscussion:https://postgr.es/m/alpine.DEB.2.21.1903170935210.2506@lancre
1 parenta7eadaa commit8b938d3

File tree

5 files changed

+55
-116
lines changed

5 files changed

+55
-116
lines changed

‎src/backend/access/transam/xlog.c

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include"catalog/pg_control.h"
4141
#include"catalog/pg_database.h"
4242
#include"commands/tablespace.h"
43+
#include"common/controldata_utils.h"
4344
#include"miscadmin.h"
4445
#include"pgstat.h"
4546
#include"port/atomics.h"
@@ -4754,51 +4755,14 @@ ReadControlFile(void)
47544755
PGC_INTERNAL,PGC_S_OVERRIDE);
47554756
}
47564757

4758+
/*
4759+
* Utility wrapper to update the control file. Note that the control
4760+
* file gets flushed.
4761+
*/
47574762
void
47584763
UpdateControlFile(void)
47594764
{
4760-
intfd;
4761-
4762-
INIT_CRC32C(ControlFile->crc);
4763-
COMP_CRC32C(ControlFile->crc,
4764-
(char*)ControlFile,
4765-
offsetof(ControlFileData,crc));
4766-
FIN_CRC32C(ControlFile->crc);
4767-
4768-
fd=BasicOpenFile(XLOG_CONTROL_FILE,
4769-
O_RDWR |PG_BINARY);
4770-
if (fd<0)
4771-
ereport(PANIC,
4772-
(errcode_for_file_access(),
4773-
errmsg("could not open file \"%s\": %m",XLOG_CONTROL_FILE)));
4774-
4775-
errno=0;
4776-
pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE);
4777-
if (write(fd,ControlFile,sizeof(ControlFileData))!=sizeof(ControlFileData))
4778-
{
4779-
/* if write didn't set errno, assume problem is no disk space */
4780-
if (errno==0)
4781-
errno=ENOSPC;
4782-
ereport(PANIC,
4783-
(errcode_for_file_access(),
4784-
errmsg("could not write to file \"%s\": %m",
4785-
XLOG_CONTROL_FILE)));
4786-
}
4787-
pgstat_report_wait_end();
4788-
4789-
pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE);
4790-
if (pg_fsync(fd)!=0)
4791-
ereport(PANIC,
4792-
(errcode_for_file_access(),
4793-
errmsg("could not fsync file \"%s\": %m",
4794-
XLOG_CONTROL_FILE)));
4795-
pgstat_report_wait_end();
4796-
4797-
if (close(fd))
4798-
ereport(PANIC,
4799-
(errcode_for_file_access(),
4800-
errmsg("could not close file \"%s\": %m",
4801-
XLOG_CONTROL_FILE)));
4765+
update_controlfile(DataDir,NULL,ControlFile, true);
48024766
}
48034767

48044768
/*

‎src/bin/pg_resetwal/pg_resetwal.c

Lines changed: 3 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@
4949
#include"access/multixact.h"
5050
#include"access/xlog.h"
5151
#include"access/xlog_internal.h"
52-
#include"catalog/catversion.h"
53-
#include"catalog/pg_control.h"
52+
#include"common/controldata_utils.h"
5453
#include"common/fe_memutils.h"
5554
#include"common/file_perm.h"
5655
#include"common/restricted_token.h"
@@ -918,18 +917,6 @@ PrintNewControlValues(void)
918917
staticvoid
919918
RewriteControlFile(void)
920919
{
921-
intfd;
922-
charbuffer[PG_CONTROL_FILE_SIZE];/* need not be aligned */
923-
924-
/*
925-
* For good luck, apply the same static assertions as in backend's
926-
* WriteControlFile().
927-
*/
928-
StaticAssertStmt(sizeof(ControlFileData) <=PG_CONTROL_MAX_SAFE_SIZE,
929-
"pg_control is too large for atomic disk writes");
930-
StaticAssertStmt(sizeof(ControlFileData) <=PG_CONTROL_FILE_SIZE,
931-
"sizeof(ControlFileData) exceeds PG_CONTROL_FILE_SIZE");
932-
933920
/*
934921
* Adjust fields as needed to force an empty XLOG starting at
935922
* newXlogSegNo.
@@ -961,53 +948,8 @@ RewriteControlFile(void)
961948
ControlFile.max_prepared_xacts=0;
962949
ControlFile.max_locks_per_xact=64;
963950

964-
/* Contents are protected with a CRC */
965-
INIT_CRC32C(ControlFile.crc);
966-
COMP_CRC32C(ControlFile.crc,
967-
(char*)&ControlFile,
968-
offsetof(ControlFileData,crc));
969-
FIN_CRC32C(ControlFile.crc);
970-
971-
/*
972-
* We write out PG_CONTROL_FILE_SIZE bytes into pg_control, zero-padding
973-
* the excess over sizeof(ControlFileData). This reduces the odds of
974-
* premature-EOF errors when reading pg_control. We'll still fail when we
975-
* check the contents of the file, but hopefully with a more specific
976-
* error than "couldn't read pg_control".
977-
*/
978-
memset(buffer,0,PG_CONTROL_FILE_SIZE);
979-
memcpy(buffer,&ControlFile,sizeof(ControlFileData));
980-
981-
unlink(XLOG_CONTROL_FILE);
982-
983-
fd=open(XLOG_CONTROL_FILE,
984-
O_RDWR |O_CREAT |O_EXCL |PG_BINARY,
985-
pg_file_create_mode);
986-
if (fd<0)
987-
{
988-
fprintf(stderr,_("%s: could not create pg_control file: %s\n"),
989-
progname,strerror(errno));
990-
exit(1);
991-
}
992-
993-
errno=0;
994-
if (write(fd,buffer,PG_CONTROL_FILE_SIZE)!=PG_CONTROL_FILE_SIZE)
995-
{
996-
/* if write didn't set errno, assume problem is no disk space */
997-
if (errno==0)
998-
errno=ENOSPC;
999-
fprintf(stderr,_("%s: could not write pg_control file: %s\n"),
1000-
progname,strerror(errno));
1001-
exit(1);
1002-
}
1003-
1004-
if (fsync(fd)!=0)
1005-
{
1006-
fprintf(stderr,_("%s: fsync error: %s\n"),progname,strerror(errno));
1007-
exit(1);
1008-
}
1009-
1010-
close(fd);
951+
/* The control file gets flushed here. */
952+
update_controlfile(".",progname,&ControlFile, true);
1011953
}
1012954

1013955

‎src/bin/pg_rewind/pg_rewind.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ main(int argc, char **argv)
377377
ControlFile_new.minRecoveryPoint=endrec;
378378
ControlFile_new.minRecoveryPointTLI=endtli;
379379
ControlFile_new.state=DB_IN_ARCHIVE_RECOVERY;
380-
update_controlfile(datadir_target,progname,&ControlFile_new);
380+
update_controlfile(datadir_target,progname,&ControlFile_new,do_sync);
381381

382382
pg_log(PG_PROGRESS,"syncing target data directory\n");
383383
syncTargetDirectory();

‎src/common/controldata_utils.c

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
#include"common/controldata_utils.h"
3030
#include"common/file_perm.h"
3131
#include"port/pg_crc32c.h"
32+
3233
#ifndefFRONTEND
34+
#include"pgstat.h"
3335
#include"storage/fd.h"
3436
#endif
3537

@@ -144,13 +146,14 @@ get_controlfile(const char *DataDir, const char *progname, bool *crc_ok_p)
144146
* update_controlfile()
145147
*
146148
* Update controlfile values with the contents given by caller. The
147-
* contents to write are included in "ControlFile". Note that it is up
148-
* to the caller to fsync the updated file, and to properly lock
149-
* ControlFileLock when calling this routine in the backend.
149+
* contents to write are included in "ControlFile". "do_sync" can be
150+
* optionally used to flush the updated control file. Note that it is up
151+
* to the caller to properly lock ControlFileLock when calling this
152+
* routine in the backend.
150153
*/
151154
void
152155
update_controlfile(constchar*DataDir,constchar*progname,
153-
ControlFileData*ControlFile)
156+
ControlFileData*ControlFile,booldo_sync)
154157
{
155158
intfd;
156159
charbuffer[PG_CONTROL_FILE_SIZE];
@@ -182,7 +185,12 @@ update_controlfile(const char *DataDir, const char *progname,
182185
snprintf(ControlFilePath,sizeof(ControlFilePath),"%s/%s",DataDir,XLOG_CONTROL_FILE);
183186

184187
#ifndefFRONTEND
185-
if ((fd=OpenTransientFile(ControlFilePath,O_WRONLY |PG_BINARY))==-1)
188+
189+
/*
190+
* All errors issue a PANIC, so no need to use OpenTransientFile() and to
191+
* worry about file descriptor leaks.
192+
*/
193+
if ((fd=BasicOpenFile(ControlFilePath,O_RDWR |PG_BINARY))<0)
186194
ereport(PANIC,
187195
(errcode_for_file_access(),
188196
errmsg("could not open file \"%s\": %m",
@@ -198,6 +206,9 @@ update_controlfile(const char *DataDir, const char *progname,
198206
#endif
199207

200208
errno=0;
209+
#ifndefFRONTEND
210+
pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE);
211+
#endif
201212
if (write(fd,buffer,PG_CONTROL_FILE_SIZE)!=PG_CONTROL_FILE_SIZE)
202213
{
203214
/* if write didn't set errno, assume problem is no disk space */
@@ -215,19 +226,41 @@ update_controlfile(const char *DataDir, const char *progname,
215226
exit(EXIT_FAILURE);
216227
#endif
217228
}
229+
#ifndefFRONTEND
230+
pgstat_report_wait_end();
231+
#endif
218232

233+
if (do_sync)
234+
{
235+
#ifndefFRONTEND
236+
pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE);
237+
if (pg_fsync(fd)!=0)
238+
ereport(PANIC,
239+
(errcode_for_file_access(),
240+
errmsg("could not fsync file \"%s\": %m",
241+
ControlFilePath)));
242+
pgstat_report_wait_end();
243+
#else
244+
if (fsync(fd)!=0)
245+
{
246+
fprintf(stderr,_("%s: could not fsync file \"%s\": %s\n"),
247+
progname,ControlFilePath,strerror(errno));
248+
exit(EXIT_FAILURE);
249+
}
250+
#endif
251+
}
252+
253+
if (close(fd)<0)
254+
{
219255
#ifndefFRONTEND
220-
if (CloseTransientFile(fd))
221256
ereport(PANIC,
222257
(errcode_for_file_access(),
223258
errmsg("could not close file \"%s\": %m",
224259
ControlFilePath)));
225260
#else
226-
if (close(fd)<0)
227-
{
228261
fprintf(stderr,_("%s: could not close file \"%s\": %s\n"),
229262
progname,ControlFilePath,strerror(errno));
230263
exit(EXIT_FAILURE);
231-
}
232264
#endif
265+
}
233266
}

‎src/include/common/controldata_utils.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
#include"catalog/pg_control.h"
1414

1515
externControlFileData*get_controlfile(constchar*DataDir,
16-
constchar*progname,
17-
bool*crc_ok_p);
16+
constchar*progname,
17+
bool*crc_ok_p);
1818
externvoidupdate_controlfile(constchar*DataDir,constchar*progname,
19-
ControlFileData*ControlFile);
19+
ControlFileData*ControlFile,booldo_sync);
2020

2121
#endif/* COMMON_CONTROLDATA_UTILS_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp