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

Commitce6afc6

Browse files
committed
Add routine able to update the control file to src/common/
This adds a new routine to src/common/ which is compatible with both thefrontend and backend code, able to update the control file's contents.This is now getting used only by pg_rewind, but some upcoming patcheswhich add more control on checksums for offline instances will make useof it. This could also get used more by the backend as xlog.c has itsown flavor of the same logic with some wait events and an additionalflush phase before closing the opened file descriptor, but this is letas separate work.Author: Michael Banck, Michael PaquierReviewed-by: Fabien Coelho, Sergei KornilovDiscussion:https://postgr.es/m/20181221201616.GD4974@nighthawk.caipicrew.dd-dns.de
1 parent1a83a80 commitce6afc6

File tree

3 files changed

+101
-42
lines changed

3 files changed

+101
-42
lines changed

‎src/bin/pg_rewind/pg_rewind.c

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include"access/xlog_internal.h"
2525
#include"catalog/catversion.h"
2626
#include"catalog/pg_control.h"
27+
#include"common/controldata_utils.h"
2728
#include"common/file_perm.h"
2829
#include"common/file_utils.h"
2930
#include"common/restricted_token.h"
@@ -37,7 +38,6 @@ static void createBackupLabel(XLogRecPtr startpoint, TimeLineID starttli,
3738

3839
staticvoiddigestControlFile(ControlFileData*ControlFile,char*source,
3940
size_tsize);
40-
staticvoidupdateControlFile(ControlFileData*ControlFile);
4141
staticvoidsyncTargetDirectory(void);
4242
staticvoidsanityChecks(void);
4343
staticvoidfindCommonAncestorTimeline(XLogRecPtr*recptr,int*tliIndex);
@@ -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-
updateControlFile(&ControlFile_new);
380+
update_controlfile(datadir_target,progname,&ControlFile_new);
381381

382382
pg_log(PG_PROGRESS,"syncing target data directory\n");
383383
syncTargetDirectory();
@@ -666,45 +666,6 @@ digestControlFile(ControlFileData *ControlFile, char *src, size_t size)
666666
checkControlFile(ControlFile);
667667
}
668668

669-
/*
670-
* Update the target's control file.
671-
*/
672-
staticvoid
673-
updateControlFile(ControlFileData*ControlFile)
674-
{
675-
charbuffer[PG_CONTROL_FILE_SIZE];
676-
677-
/*
678-
* For good luck, apply the same static assertions as in backend's
679-
* WriteControlFile().
680-
*/
681-
StaticAssertStmt(sizeof(ControlFileData) <=PG_CONTROL_MAX_SAFE_SIZE,
682-
"pg_control is too large for atomic disk writes");
683-
StaticAssertStmt(sizeof(ControlFileData) <=PG_CONTROL_FILE_SIZE,
684-
"sizeof(ControlFileData) exceeds PG_CONTROL_FILE_SIZE");
685-
686-
/* Recalculate CRC of control file */
687-
INIT_CRC32C(ControlFile->crc);
688-
COMP_CRC32C(ControlFile->crc,
689-
(char*)ControlFile,
690-
offsetof(ControlFileData,crc));
691-
FIN_CRC32C(ControlFile->crc);
692-
693-
/*
694-
* Write out PG_CONTROL_FILE_SIZE bytes into pg_control by zero-padding
695-
* the excess over sizeof(ControlFileData), to avoid premature EOF related
696-
* errors when reading it.
697-
*/
698-
memset(buffer,0,PG_CONTROL_FILE_SIZE);
699-
memcpy(buffer,ControlFile,sizeof(ControlFileData));
700-
701-
open_target_file("global/pg_control", false);
702-
703-
write_target_range(buffer,0,PG_CONTROL_FILE_SIZE);
704-
705-
close_target_file();
706-
}
707-
708669
/*
709670
* Sync target data directory to ensure that modifications are safely on disk.
710671
*

‎src/common/controldata_utils.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
#include<sys/stat.h>
2525
#include<fcntl.h>
2626

27+
#include"access/xlog_internal.h"
2728
#include"catalog/pg_control.h"
2829
#include"common/controldata_utils.h"
30+
#include"common/file_perm.h"
2931
#include"port/pg_crc32c.h"
3032
#ifndefFRONTEND
3133
#include"storage/fd.h"
@@ -137,3 +139,95 @@ get_controlfile(const char *DataDir, const char *progname, bool *crc_ok_p)
137139

138140
returnControlFile;
139141
}
142+
143+
/*
144+
* update_controlfile()
145+
*
146+
* 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.
150+
*/
151+
void
152+
update_controlfile(constchar*DataDir,constchar*progname,
153+
ControlFileData*ControlFile)
154+
{
155+
intfd;
156+
charbuffer[PG_CONTROL_FILE_SIZE];
157+
charControlFilePath[MAXPGPATH];
158+
159+
/*
160+
* Apply the same static assertions as in backend's WriteControlFile().
161+
*/
162+
StaticAssertStmt(sizeof(ControlFileData) <=PG_CONTROL_MAX_SAFE_SIZE,
163+
"pg_control is too large for atomic disk writes");
164+
StaticAssertStmt(sizeof(ControlFileData) <=PG_CONTROL_FILE_SIZE,
165+
"sizeof(ControlFileData) exceeds PG_CONTROL_FILE_SIZE");
166+
167+
/* Recalculate CRC of control file */
168+
INIT_CRC32C(ControlFile->crc);
169+
COMP_CRC32C(ControlFile->crc,
170+
(char*)ControlFile,
171+
offsetof(ControlFileData,crc));
172+
FIN_CRC32C(ControlFile->crc);
173+
174+
/*
175+
* Write out PG_CONTROL_FILE_SIZE bytes into pg_control by zero-padding
176+
* the excess over sizeof(ControlFileData), to avoid premature EOF related
177+
* errors when reading it.
178+
*/
179+
memset(buffer,0,PG_CONTROL_FILE_SIZE);
180+
memcpy(buffer,ControlFile,sizeof(ControlFileData));
181+
182+
snprintf(ControlFilePath,sizeof(ControlFilePath),"%s/%s",DataDir,XLOG_CONTROL_FILE);
183+
184+
#ifndefFRONTEND
185+
if ((fd=OpenTransientFile(ControlFilePath,O_WRONLY |PG_BINARY))==-1)
186+
ereport(PANIC,
187+
(errcode_for_file_access(),
188+
errmsg("could not open file \"%s\": %m",
189+
ControlFilePath)));
190+
#else
191+
if ((fd=open(ControlFilePath,O_WRONLY |PG_BINARY,
192+
pg_file_create_mode))==-1)
193+
{
194+
fprintf(stderr,_("%s: could not open file \"%s\": %s\n"),
195+
progname,ControlFilePath,strerror(errno));
196+
exit(EXIT_FAILURE);
197+
}
198+
#endif
199+
200+
errno=0;
201+
if (write(fd,buffer,PG_CONTROL_FILE_SIZE)!=PG_CONTROL_FILE_SIZE)
202+
{
203+
/* if write didn't set errno, assume problem is no disk space */
204+
if (errno==0)
205+
errno=ENOSPC;
206+
207+
#ifndefFRONTEND
208+
ereport(PANIC,
209+
(errcode_for_file_access(),
210+
errmsg("could not write file \"%s\": %m",
211+
ControlFilePath)));
212+
#else
213+
fprintf(stderr,_("%s: could not write \"%s\": %s\n"),
214+
progname,ControlFilePath,strerror(errno));
215+
exit(EXIT_FAILURE);
216+
#endif
217+
}
218+
219+
#ifndefFRONTEND
220+
if (CloseTransientFile(fd))
221+
ereport(PANIC,
222+
(errcode_for_file_access(),
223+
errmsg("could not close file \"%s\": %m",
224+
ControlFilePath)));
225+
#else
226+
if (close(fd)<0)
227+
{
228+
fprintf(stderr,_("%s: could not close file \"%s\": %s\n"),
229+
progname,ControlFilePath,strerror(errno));
230+
exit(EXIT_FAILURE);
231+
}
232+
#endif
233+
}

‎src/include/common/controldata_utils.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212

1313
#include"catalog/pg_control.h"
1414

15-
externControlFileData*get_controlfile(constchar*DataDir,constchar*progname,bool*crc_ok_p);
15+
externControlFileData*get_controlfile(constchar*DataDir,
16+
constchar*progname,
17+
bool*crc_ok_p);
18+
externvoidupdate_controlfile(constchar*DataDir,constchar*progname,
19+
ControlFileData*ControlFile);
1620

1721
#endif/* COMMON_CONTROLDATA_UTILS_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp