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

Commit366c9ec

Browse files
committed
Merge branch 'PGPRO9_6' into PGPROEE9_6
2 parentsfe74a23 +cb87f01 commit366c9ec

File tree

16 files changed

+422
-258
lines changed

16 files changed

+422
-258
lines changed

‎contrib/pg_probackup/backup.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
*
33
* backup.c: backup DB cluster, archived WAL
44
*
5-
* Copyright (c) 2009-2013, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
5+
* Portions Copyright (c) 2009-2013, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
6+
* Portions Copyright (c) 2015-2017, Postgres Professional
67
*
78
*-------------------------------------------------------------------------
89
*/
@@ -403,7 +404,6 @@ do_backup_database(parray *backup_list, bool smooth_checkpoint)
403404
int
404405
do_backup(boolsmooth_checkpoint)
405406
{
406-
intret;
407407
parray*backup_list;
408408
parray*files_database;
409409

@@ -432,12 +432,7 @@ do_backup(bool smooth_checkpoint)
432432
elog(LOG,"----------------------------------------");
433433

434434
/* get exclusive lock of backup catalog */
435-
ret=catalog_lock(true);
436-
if (ret==-1)
437-
elog(ERROR,"cannot lock backup catalog");
438-
elseif (ret==1)
439-
elog(ERROR,
440-
"another pg_probackup is running, skipping this backup");
435+
catalog_lock(true);
441436

442437
/* initialize backup result */
443438
current.status=BACKUP_STATUS_RUNNING;
@@ -508,9 +503,6 @@ do_backup(bool smooth_checkpoint)
508503

509504
pgBackupValidate(&current, false, false);
510505

511-
/* release catalog lock */
512-
catalog_unlock();
513-
514506
return0;
515507
}
516508

‎contrib/pg_probackup/catalog.c

Lines changed: 169 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
*
33
* catalog.c: backup catalog opration
44
*
5-
* Copyright (c) 2009-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
5+
* Portions Copyright (c) 2009-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
6+
* Portions Copyright (c) 2015-2017, Postgres Professional
67
*
78
*-------------------------------------------------------------------------
89
*/
@@ -12,6 +13,7 @@
1213
#include<dirent.h>
1314
#include<fcntl.h>
1415
#include<libgen.h>
16+
#include<signal.h>
1517
#include<sys/file.h>
1618
#include<sys/stat.h>
1719
#include<sys/types.h>
@@ -25,42 +27,185 @@ static pgBackup *read_backup_from_file(const char *path);
2527

2628
#defineBOOL_TO_STR(val)((val) ? "true" : "false")
2729

28-
staticintlock_fd=-1;
30+
staticboolexit_hook_registered= false;
31+
staticcharlock_file[MAXPGPATH];
32+
33+
staticvoid
34+
unlink_lock_atexit(void)
35+
{
36+
intres;
37+
res=unlink(lock_file);
38+
if (res!=0&&res!=ENOENT)
39+
elog(WARNING,"%s: %s",lock_file,strerror(errno));
40+
}
2941

3042
/*
31-
* Lock of the catalog with pg_probackup.conf file and return 0.
32-
* If the lock is held by another one, return 1 immediately.
43+
* Create a lockfile.
3344
*/
3445
int
3546
catalog_lock(boolcheck_catalog)
3647
{
37-
intret;
38-
charid_path[MAXPGPATH];
39-
40-
join_path_components(id_path,backup_path,BACKUP_CATALOG_CONF_FILE);
41-
lock_fd=open(id_path,O_RDWR);
42-
if (lock_fd==-1)
43-
elog(errno==ENOENT ?ERROR :ERROR,
44-
"cannot open file \"%s\": %s",id_path,strerror(errno));
45-
#ifdef__IBMC__
46-
ret=lockf(lock_fd,LOCK_EX |LOCK_NB,0);/* non-blocking */
48+
intfd;
49+
charbuffer[MAXPGPATH*2+256];
50+
intntries;
51+
intlen;
52+
intencoded_pid;
53+
pid_tmy_pid,
54+
my_p_pid;
55+
56+
join_path_components(lock_file,backup_path,BACKUP_CATALOG_PID);
57+
58+
/*
59+
* If the PID in the lockfile is our own PID or our parent's or
60+
* grandparent's PID, then the file must be stale (probably left over from
61+
* a previous system boot cycle). We need to check this because of the
62+
* likelihood that a reboot will assign exactly the same PID as we had in
63+
* the previous reboot, or one that's only one or two counts larger and
64+
* hence the lockfile's PID now refers to an ancestor shell process. We
65+
* allow pg_ctl to pass down its parent shell PID (our grandparent PID)
66+
* via the environment variable PG_GRANDPARENT_PID; this is so that
67+
* launching the postmaster via pg_ctl can be just as reliable as
68+
* launching it directly. There is no provision for detecting
69+
* further-removed ancestor processes, but if the init script is written
70+
* carefully then all but the immediate parent shell will be root-owned
71+
* processes and so the kill test will fail with EPERM. Note that we
72+
* cannot get a false negative this way, because an existing postmaster
73+
* would surely never launch a competing postmaster or pg_ctl process
74+
* directly.
75+
*/
76+
my_pid=getpid();
77+
#ifndefWIN32
78+
my_p_pid=getppid();
4779
#else
48-
ret=flock(lock_fd,LOCK_EX |LOCK_NB);/* non-blocking */
80+
81+
/*
82+
* Windows hasn't got getppid(), but doesn't need it since it's not using
83+
* real kill() either...
84+
*/
85+
my_p_pid=0;
4986
#endif
50-
if (ret==-1)
87+
88+
/*
89+
* We need a loop here because of race conditions. But don't loop forever
90+
* (for example, a non-writable $backup_path directory might cause a failure
91+
* that won't go away). 100 tries seems like plenty.
92+
*/
93+
for (ntries=0;;ntries++)
5194
{
52-
if (errno==EWOULDBLOCK)
95+
/*
96+
* Try to create the lock file --- O_EXCL makes this atomic.
97+
*
98+
* Think not to make the file protection weaker than 0600. See
99+
* comments below.
100+
*/
101+
fd=open(lock_file,O_RDWR |O_CREAT |O_EXCL,0600);
102+
if (fd >=0)
103+
break;/* Success; exit the retry loop */
104+
105+
/*
106+
* Couldn't create the pid file. Probably it already exists.
107+
*/
108+
if ((errno!=EEXIST&&errno!=EACCES)||ntries>100)
109+
elog(ERROR,"could not create lock file \"%s\": %s",
110+
lock_file,strerror(errno));
111+
112+
/*
113+
* Read the file to get the old owner's PID. Note race condition
114+
* here: file might have been deleted since we tried to create it.
115+
*/
116+
fd=open(lock_file,O_RDONLY,0600);
117+
if (fd<0)
53118
{
54-
close(lock_fd);
55-
return1;
119+
if (errno==ENOENT)
120+
continue;/* race condition; try again */
121+
elog(ERROR,"could not open lock file \"%s\": %s",
122+
lock_file,strerror(errno));
56123
}
57-
else
124+
if ((len=read(fd,buffer,sizeof(buffer)-1))<0)
125+
elog(ERROR,"could not read lock file \"%s\": %s",
126+
lock_file,strerror(errno));
127+
close(fd);
128+
129+
if (len==0)
130+
elog(ERROR,"lock file \"%s\" is empty",lock_file);
131+
132+
buffer[len]='\0';
133+
encoded_pid=atoi(buffer);
134+
135+
if (encoded_pid <=0)
136+
elog(ERROR,"bogus data in lock file \"%s\": \"%s\"",
137+
lock_file,buffer);
138+
139+
/*
140+
* Check to see if the other process still exists
141+
*
142+
* Per discussion above, my_pid, my_p_pid can be
143+
* ignored as false matches.
144+
*
145+
* Normally kill() will fail with ESRCH if the given PID doesn't
146+
* exist.
147+
*/
148+
if (encoded_pid!=my_pid&&encoded_pid!=my_p_pid)
58149
{
59-
interrno_tmp=errno;
60-
close(lock_fd);
61-
elog(ERROR,"cannot lock file \"%s\": %s",id_path,
62-
strerror(errno_tmp));
150+
if (kill(encoded_pid,0)==0||
151+
(errno!=ESRCH&&errno!=EPERM))
152+
elog(ERROR,"lock file \"%s\" already exists",lock_file);
63153
}
154+
155+
/*
156+
* Looks like nobody's home. Unlink the file and try again to create
157+
* it. Need a loop because of possible race condition against other
158+
* would-be creators.
159+
*/
160+
if (unlink(lock_file)<0)
161+
elog(ERROR,"could not remove old lock file \"%s\": %s",
162+
lock_file,strerror(errno));
163+
}
164+
165+
/*
166+
* Successfully created the file, now fill it.
167+
*/
168+
snprintf(buffer,sizeof(buffer),"%d\n",my_pid);
169+
170+
errno=0;
171+
if (write(fd,buffer,strlen(buffer))!=strlen(buffer))
172+
{
173+
intsave_errno=errno;
174+
175+
close(fd);
176+
unlink(lock_file);
177+
/* if write didn't set errno, assume problem is no disk space */
178+
errno=save_errno ?save_errno :ENOSPC;
179+
elog(ERROR,"could not write lock file \"%s\": %s",
180+
lock_file,strerror(errno));
181+
}
182+
if (fsync(fd)!=0)
183+
{
184+
intsave_errno=errno;
185+
186+
close(fd);
187+
unlink(lock_file);
188+
errno=save_errno;
189+
elog(ERROR,"could not write lock file \"%s\": %s",
190+
lock_file,strerror(errno));
191+
}
192+
if (close(fd)!=0)
193+
{
194+
intsave_errno=errno;
195+
196+
unlink(lock_file);
197+
errno=save_errno;
198+
elog(ERROR,"could not write lock file \"%s\": %s",
199+
lock_file,strerror(errno));
200+
}
201+
202+
/*
203+
* Arrange to unlink the lock file(s) at proc_exit.
204+
*/
205+
if (!exit_hook_registered)
206+
{
207+
atexit(unlink_lock_atexit);
208+
exit_hook_registered= true;
64209
}
65210

66211
if (check_catalog)
@@ -79,16 +224,6 @@ catalog_lock(bool check_catalog)
79224
return0;
80225
}
81226

82-
/*
83-
* Release catalog lock.
84-
*/
85-
void
86-
catalog_unlock(void)
87-
{
88-
close(lock_fd);
89-
lock_fd=-1;
90-
}
91-
92227
/*
93228
* Create a pgBackup which taken at timestamp.
94229
* If no backup matches, return NULL.

‎contrib/pg_probackup/data.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
*
33
* data.c: data parsing pages
44
*
5-
* Copyright (c) 2009-2013, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
5+
* Portions Copyright (c) 2009-2013, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
6+
* Portions Copyright (c) 2015-2017, Postgres Professional
67
*
78
*-------------------------------------------------------------------------
89
*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp