@@ -935,7 +935,7 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
935
935
uint32 second_pass_bytes = 0 ;
936
936
inode_t * * inodes = (inode_t * * )palloc (RELSEG_SIZE * sizeof (inode_t * ));
937
937
bool remove_backups = true;
938
- bool second_pass_whole = false ;
938
+ int second_pass_whole = 0 ;
939
939
int n_pages , n_pages1 ;
940
940
TimestampTz startTime , secondTime , endTime ;
941
941
long secs , secs2 ;
@@ -984,13 +984,16 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
984
984
goto Cleanup ;
985
985
}
986
986
987
+ cfs_state -> gc_stat .processedFiles += 1 ;
988
+ cfs_gc_processed_segments += 1 ;
989
+
987
990
/* temporary lock file for fetching map snapshot */
988
991
cfs_gc_lock (lock );
989
992
990
993
/* Reread variables after locking file */
991
994
virtSize = pg_atomic_read_u32 (& map -> hdr .virtSize );
992
995
n_pages = virtSize / BLCKSZ ;
993
-
996
+ retry :
994
997
for (i = 0 ; i < n_pages ; i ++ )
995
998
{
996
999
newMap -> inodes [i ] = map -> inodes [i ];
@@ -1000,9 +1003,6 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
1000
1003
/* may unlock until second phase */
1001
1004
cfs_gc_unlock (lock );
1002
1005
1003
- cfs_state -> gc_stat .processedFiles += 1 ;
1004
- cfs_gc_processed_segments += 1 ;
1005
-
1006
1006
if (!cfs_copy_inodes (inodes , n_pages , fd , fd2 , & writeback , & newSize ,
1007
1007
file_path , file_bck_path ))
1008
1008
goto Cleanup ;
@@ -1028,6 +1028,8 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
1028
1028
n_pages1 = n_pages ;
1029
1029
virtSize = pg_atomic_read_u32 (& map -> hdr .virtSize );
1030
1030
n_pages = virtSize / BLCKSZ ;
1031
+ second_pass = 0 ;
1032
+ second_pass_bytes = 0 ;
1031
1033
1032
1034
for (i = 0 ; i < n_pages ; i ++ )
1033
1035
{
@@ -1048,16 +1050,13 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
1048
1050
second_pass ++ ;
1049
1051
}
1050
1052
1051
- if (n_pages1 > n_pages )
1053
+ /* if file were truncated (vacuum???), clean a bit */
1054
+ for (i = n_pages ; i < n_pages1 ; i ++ )
1052
1055
{
1053
- /* if file were truncated (vacuum???), clean a bit */
1054
- for (i = n_pages ; i < n_pages1 ; i ++ )
1055
- {
1056
- inode_t nnode = newMap -> inodes [i ];
1057
- if (CFS_INODE_SIZE (nnode ) != 0 ) {
1058
- newUsed -= CFS_INODE_SIZE (nnode );
1059
- newMap -> inodes [i ] = CFS_INODE (0 , 0 );
1060
- }
1056
+ inode_t nnode = newMap -> inodes [i ];
1057
+ if (CFS_INODE_SIZE (nnode ) != 0 ) {
1058
+ newUsed -= CFS_INODE_SIZE (nnode );
1059
+ newMap -> inodes [i ] = CFS_INODE (0 , 0 );
1061
1060
}
1062
1061
}
1063
1062
@@ -1069,10 +1068,16 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
1069
1068
newUsed = 0 ;
1070
1069
newSize = 0 ;
1071
1070
writeback = 0 ;
1072
- second_pass_whole = true ;
1071
+ second_pass_whole ++ ;
1073
1072
rc = lseek (fd2 , 0 , SEEK_SET );
1074
1073
Assert (rc == 0 );
1075
1074
memset (newMap -> inodes , 0 , sizeof (newMap -> inodes ));
1075
+ elog (LOG , "CFS: retry %d whole gc file %s" , second_pass_whole ,
1076
+ file_path );
1077
+ if (second_pass_whole == 1 )
1078
+ {
1079
+ goto retry ;
1080
+ }
1076
1081
for (i = 0 ; i < n_pages ; i ++ )
1077
1082
{
1078
1083
newMap -> inodes [i ] = map -> inodes [i ];
@@ -1089,7 +1094,7 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
1089
1094
1090
1095
pg_flush_data (fd2 , writeback , newSize );
1091
1096
1092
- if (second_pass_whole )
1097
+ if (second_pass_whole != 0 )
1093
1098
{
1094
1099
/* truncate file to copied size */
1095
1100
if (ftruncate (fd2 , newSize ))
0 commit comments