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

Commit0ae6e6d

Browse files
committed
Merge branch 'PGPROEE9_6_CFS_385' into PGPROEE9_6
2 parents1a5283c +e6c29f0 commit0ae6e6d

File tree

5 files changed

+86
-26
lines changed

5 files changed

+86
-26
lines changed

‎src/backend/storage/file/cfs.c

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include"utils/resowner_private.h"
5656
#include"postmaster/bgworker.h"
5757

58+
5859
/*
5960
* GUC variable that defines compression level.
6061
* 0 - no compression, 1 - max speed,
@@ -417,15 +418,21 @@ int cfs_msync(FileMap* map)
417418
FileMap*cfs_mmap(intmd)
418419
{
419420
FileMap*map;
421+
if (ftruncate(md,sizeof(FileMap))!=0)
422+
{
423+
return (FileMap*)MAP_FAILED;
424+
}
425+
420426
#ifdefWIN32
421-
HANDLEmh=CreateFileMapping(_get_osfhandle(md),NULL,PAGE_READWRITE,
427+
{
428+
HANDLEmh=CreateFileMapping(_get_osfhandle(md),NULL,PAGE_READWRITE,
422429
0, (DWORD)sizeof(FileMap),NULL);
423-
if (mh==NULL)
424-
return (FileMap*)MAP_FAILED;
425-
426-
map= (FileMap*)MapViewOfFile(mh,FILE_MAP_ALL_ACCESS,0,0,0);
427-
CloseHandle(mh);
430+
if (mh==NULL)
431+
return (FileMap*)MAP_FAILED;
428432

433+
map= (FileMap*)MapViewOfFile(mh,FILE_MAP_ALL_ACCESS,0,0,0);
434+
CloseHandle(mh);
435+
}
429436
if (map==NULL)
430437
return (FileMap*)MAP_FAILED;
431438

@@ -533,17 +540,44 @@ static bool cfs_write_file(int fd, void const* data, uint32 size)
533540
voidcfs_lock_file(FileMap*map,charconst*file_path)
534541
{
535542
longdelay=CFS_LOCK_MIN_TIMEOUT;
543+
intn_attempts=0;
536544

537545
while (true)
538546
{
539547
uint64count=pg_atomic_fetch_add_u32(&map->lock,1);
548+
boolrevokeLock= false;
540549

541550
if (count<CFS_GC_LOCK)
542551
break;
543-
544-
if (InRecovery)
552+
553+
if (InRecovery)
554+
{
555+
revokeLock= true;
556+
}
557+
else
545558
{
546-
/* Uhhh... looks like last GC was interrupted.
559+
if (!pg_atomic_unlocked_test_flag(&cfs_state->gc_started))
560+
{
561+
if (++n_attempts>MAX_LOCK_ATTEMPTS)
562+
{
563+
/* So there is GC lock, but no active GC process during MAX_LOCK_ATTEMPTS.
564+
* Most likely it means that GC is crashed (may be together with other postgres processes or even OS)
565+
* without releasing lock. And for some reasons recovery was not performed and this page left locked.
566+
* We should revoke the the lock to allow access to this segment.
567+
*/
568+
revokeLock= true;
569+
}
570+
}
571+
else
572+
{
573+
n_attempts=0;/* Reset counter of attempts because GC is in progress */
574+
}
575+
}
576+
if (revokeLock
577+
/* use gc_started flag to prevent race condition with other backends and GC */
578+
&&pg_atomic_test_set_flag(&cfs_state->gc_started))
579+
{
580+
/* Ugggh... looks like last GC was interrupted.
547581
* Try to recover the file.
548582
*/
549583
char*map_bck_path=psprintf("%s.cfm.bck",file_path);
@@ -565,18 +599,20 @@ void cfs_lock_file(FileMap* map, char const* file_path)
565599
else
566600
{
567601
/* Presence of backup file means that we still have
568-
* unchanged data and map files. Just remove backup files,
569-
*grab lock and continue processing
602+
* unchanged data and map files. Just remove backup files and
603+
*revoke GC lock.
570604
*/
571605
unlink(file_bck_path);
572606
unlink(map_bck_path);
573607
}
574608

609+
pg_atomic_clear_flag(&cfs_state->gc_started);
610+
count=pg_atomic_fetch_sub_u32(&map->lock,CFS_GC_LOCK);/* revoke GC lock */
611+
Assert((int)count>0);
575612
pfree(file_bck_path);
576613
pfree(map_bck_path);
577614
break;
578-
}
579-
615+
}
580616
pg_atomic_fetch_sub_u32(&map->lock,1);
581617
pg_usleep(delay);
582618
if (delay<CFS_LOCK_MAX_TIMEOUT)

‎src/backend/storage/file/copydir.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ copy_zip_file(char *fromfile, bool from_compressed,
319319
Assert(sep!=NULL);
320320

321321
if ((sscanf(sep+1,"%d.%d%n",&relno,&segno,&n)!=2
322+
&&sscanf(sep+1,"%d_init%n",&relno,&n)!=1
322323
&&sscanf(sep+1,"%d%n",&relno,&n)!=1)
323324
||sep[n+1]!='\0'
324325
||relno<FirstNormalObjectId)
@@ -328,7 +329,7 @@ copy_zip_file(char *fromfile, bool from_compressed,
328329
}
329330

330331
if (to_compressed)
331-
fprintf(stderr,"Compress file %s, relno=%d, sep[n+1]=%s\n",
332+
elog(DEBUG2,"Compress file %s, relno=%d, sep[n+1]=%s\n",
332333
tofile,relno,&sep[n+1]);
333334

334335
/* Open the files */

‎src/backend/storage/file/fd.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,9 +1322,6 @@ PathNameOpenFile(FileName fileName, int fileFlags, int fileMode)
13221322
gotoio_error;
13231323
}
13241324

1325-
if (ftruncate(vfdP->md,sizeof(FileMap))!=0)
1326-
elog(LOG,"OPEN MAP ftruncate FAILED: %d",errno);
1327-
13281325
vfdP->map=cfs_mmap(vfdP->md);
13291326
if (vfdP->map==MAP_FAILED)
13301327
{

‎src/backend/storage/file/reinit.c

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
#include"utils/memutils.h"
2626

2727
staticvoidResetUnloggedRelationsInTablespaceDir(constchar*tsdirname,
28-
intop);
28+
intop,boolcompressed);
2929
staticvoidResetUnloggedRelationsInDbspaceDir(constchar*dbspacedirname,
30-
intop);
30+
intop,boolcompressed);
3131
staticboolparse_filename_for_nontemp_relation(constchar*name,
3232
int*oidchars,ForkNumber*fork);
3333

@@ -71,7 +71,7 @@ ResetUnloggedRelations(int op)
7171
/*
7272
* First process unlogged files in pg_default ($PGDATA/base)
7373
*/
74-
ResetUnloggedRelationsInTablespaceDir("base",op);
74+
ResetUnloggedRelationsInTablespaceDir("base",op, false);
7575

7676
/*
7777
* Cycle through directories for all non-default tablespaces.
@@ -80,13 +80,25 @@ ResetUnloggedRelations(int op)
8080

8181
while ((spc_de=ReadDir(spc_dir,"pg_tblspc"))!=NULL)
8282
{
83+
FILE*compressionFile;
84+
8385
if (strcmp(spc_de->d_name,".")==0||
8486
strcmp(spc_de->d_name,"..")==0)
8587
continue;
8688

89+
snprintf(temp_path,sizeof(temp_path),"pg_tblspc/%s/%s/pg_compression",
90+
spc_de->d_name,TABLESPACE_VERSION_DIRECTORY);
91+
92+
compressionFile=fopen(temp_path,"r");
93+
if (compressionFile)
94+
{
95+
fclose(compressionFile);
96+
}
97+
8798
snprintf(temp_path,sizeof(temp_path),"pg_tblspc/%s/%s",
8899
spc_de->d_name,TABLESPACE_VERSION_DIRECTORY);
89-
ResetUnloggedRelationsInTablespaceDir(temp_path,op);
100+
101+
ResetUnloggedRelationsInTablespaceDir(temp_path,op,compressionFile!=NULL);
90102
}
91103

92104
FreeDir(spc_dir);
@@ -100,7 +112,7 @@ ResetUnloggedRelations(int op)
100112

101113
/* Process one tablespace directory for ResetUnloggedRelations */
102114
staticvoid
103-
ResetUnloggedRelationsInTablespaceDir(constchar*tsdirname,intop)
115+
ResetUnloggedRelationsInTablespaceDir(constchar*tsdirname,intop,boolcompressed)
104116
{
105117
DIR*ts_dir;
106118
structdirent*de;
@@ -133,15 +145,15 @@ ResetUnloggedRelationsInTablespaceDir(const char *tsdirname, int op)
133145

134146
snprintf(dbspace_path,sizeof(dbspace_path),"%s/%s",
135147
tsdirname,de->d_name);
136-
ResetUnloggedRelationsInDbspaceDir(dbspace_path,op);
148+
ResetUnloggedRelationsInDbspaceDir(dbspace_path,op,compressed);
137149
}
138150

139151
FreeDir(ts_dir);
140152
}
141153

142154
/* Process one per-dbspace directory for ResetUnloggedRelations */
143155
staticvoid
144-
ResetUnloggedRelationsInDbspaceDir(constchar*dbspacedirname,intop)
156+
ResetUnloggedRelationsInDbspaceDir(constchar*dbspacedirname,intop,boolcompressed)
145157
{
146158
DIR*dbspace_dir;
147159
structdirent*de;
@@ -332,8 +344,13 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op)
332344
strlen(forkNames[INIT_FORKNUM]));
333345

334346
/* OK, we're ready to perform the actual copy. */
335-
elog(DEBUG2,"copying %s to %s",srcpath,dstpath);
336-
copy_file(srcpath,dstpath);
347+
if (compressed) {
348+
elog(DEBUG2,"copying %s to %s with compression",srcpath,dstpath);
349+
copy_zip_file(srcpath, false,dstpath, true);
350+
}else {
351+
elog(DEBUG2,"copying %s to %s",srcpath,dstpath);
352+
copy_file(srcpath,dstpath);
353+
}
337354
}
338355

339356
FreeDir(dbspace_dir);

‎src/include/storage/cfs.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@
1515
#defineCFS_DISABLE_TIMEOUT 1000/* milliseconds */
1616
#defineCFS_ESTIMATE_PROBES 10
1717

18+
/*
19+
* Maximal number of attempts backend should perform to lock file segment.
20+
* If during all this attempts gc_started flag is not set (it means that no GC is active at this moment),
21+
* then it means that for some reasons GC process was crashed (may be together with other postgres processes or even OS)
22+
* without releasing lock. And for some reasons recovery was not performed and this page left locked. Цe should revoke this lock
23+
* to allow access to this database segment.
24+
*/
25+
#defineMAX_LOCK_ATTEMPTS 100
26+
1827
/* Maximal size of buffer for compressing (size) bytes where (size) is equal to PostgreSQL page size.
1928
* Some compression algorithms requires to provide buffer large enough for worst case and immediately returns error is buffer is not enough.
2029
* Accurate calculation of required buffer size is not needed here and doubling buffer size works for all used compression algorithms. */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp