@@ -1109,9 +1109,7 @@ backup_cleanup(bool fatal, void *userdata)
1109
1109
}
1110
1110
}
1111
1111
1112
- /*
1113
- * Count bytes in file
1114
- */
1112
+ /* Count bytes in file */
1115
1113
static long
1116
1114
file_size (const char * file )
1117
1115
{
@@ -1120,8 +1118,8 @@ file_size(const char *file)
1120
1118
1121
1119
if (!f )
1122
1120
{
1123
- fprintf ( stderr , _ ( "%s : could not open file \"%s\" for reading: %s\n") ,
1124
- progname , file , strerror (errno ));
1121
+ elog ( ERROR , "pg_probackup : could not open file \"%s\" for reading: %s\n" ,
1122
+ file , strerror (errno ));
1125
1123
return -1 ;
1126
1124
}
1127
1125
fseek (f , 0 , SEEK_END );
@@ -1130,6 +1128,55 @@ file_size(const char *file)
1130
1128
return r ;
1131
1129
}
1132
1130
1131
+ bool
1132
+ backup_compressed_file_partially (pgFile * file , void * arg , size_t * skip_size )
1133
+ {
1134
+ bool result = false;
1135
+ pgFile * prev_file = NULL ;
1136
+ size_t current_file_size ;
1137
+ backup_files_args * arguments = (backup_files_args * ) arg ;
1138
+
1139
+ if (arguments -> prev_files )
1140
+ {
1141
+ pgFile * * p = (pgFile * * ) parray_bsearch (arguments -> prev_files ,
1142
+ file , pgFileComparePath );
1143
+ if (p )
1144
+ prev_file = * p ;
1145
+
1146
+ elog (NOTICE , "file '%s' generation: prev %d, now %d" ,
1147
+ file -> path , prev_file -> generation , file -> generation );
1148
+
1149
+ /* If file's gc generation has changed since last backup, just copy it*/
1150
+ if (prev_file
1151
+ && prev_file -> generation == file -> generation )
1152
+ {
1153
+ current_file_size = file_size (file -> path );
1154
+
1155
+ elog (NOTICE , "prev->write_size %lu, current_file_size %lu" ,
1156
+ prev_file -> write_size , current_file_size );
1157
+
1158
+ if (prev_file -> write_size == BYTES_INVALID )
1159
+ return false;
1160
+
1161
+ * skip_size = prev_file -> write_size ;
1162
+
1163
+ if (current_file_size >= prev_file -> write_size )
1164
+ {
1165
+ elog (NOTICE , "Backup part of the file. %s : %lu" ,
1166
+ file -> path , current_file_size - * skip_size );
1167
+ result = true;
1168
+ }
1169
+ else
1170
+ elog (ERROR , "Something went wrong. current_file_size %lu, prev %lu" ,
1171
+ current_file_size , prev_file -> write_size );
1172
+ }
1173
+ else
1174
+ elog (NOTICE , "Copy full file. Generations are different" );
1175
+ }
1176
+
1177
+ return result ;
1178
+ }
1179
+
1133
1180
/*
1134
1181
* Take differential backup at page level.
1135
1182
*/
@@ -1138,6 +1185,7 @@ backup_files(void *arg)
1138
1185
{
1139
1186
int i ;
1140
1187
struct timeval tv ;
1188
+
1141
1189
backup_files_args * arguments = (backup_files_args * ) arg ;
1142
1190
1143
1191
gettimeofday (& tv , NULL );
@@ -1239,52 +1287,15 @@ backup_files(void *arg)
1239
1287
continue ;
1240
1288
}
1241
1289
}
1242
- else
1290
+ else if ( is_compressed_data_file ( file , arguments -> files ))
1243
1291
{
1244
- /* Check first if the file is a cfs relation's segment */
1245
- bool is_cfs_relation_segment = false;
1246
- pgFile tmp_file ;
1247
- pgFile * * pre_search_file ;
1248
- pgFile * prev_file = NULL ;
1249
-
1250
- tmp_file .path = psprintf ("%s.cfm" , file -> path );
1251
- pre_search_file = (pgFile * * ) parray_bsearch (arguments -> files , & tmp_file , pgFileComparePath );
1252
- if (pre_search_file != NULL )
1253
- {
1254
- /* Now check if it's generation has changed since last backup */
1255
- if (arguments -> prev_files )
1256
- {
1257
- pgFile * * p = (pgFile * * ) parray_bsearch (arguments -> prev_files , file , pgFileComparePath );
1258
- if (p )
1259
- prev_file = * p ;
1260
- elog (NOTICE , "file '%s' is a cfs relation's segment generation prev %d, now %d" ,
1261
- file -> path , prev_file -> generation , file -> generation );
1262
-
1263
- if (prev_file && prev_file -> generation == file -> generation )
1264
- {
1265
- elog (NOTICE , "prev->write_size %lu, file_size %lu" , prev_file -> write_size , file_size (file -> path ));
1266
- if (prev_file -> write_size == file_size (file -> path ))
1267
- {
1268
- elog (NOTICE , "File hasn't changed since last backup. Don't copy at all" );
1269
- is_cfs_relation_segment = true;
1270
- }
1271
- else
1272
- {
1273
- elog (NOTICE , "Backup part of the file. %s" , file -> path );
1274
- is_cfs_relation_segment = true;
1275
- }
1276
- }
1277
- }
1278
- }
1279
- pg_free (tmp_file .path );
1280
-
1281
-
1282
- if (is_cfs_relation_segment )
1292
+ size_t skip_size = 0 ;
1293
+ if (backup_compressed_file_partially (file , arguments , & skip_size ))
1283
1294
{
1284
1295
/* backup cfs segment partly */
1285
1296
if (!copy_file_partly (arguments -> from_root ,
1286
1297
arguments -> to_root ,
1287
- file , prev_file -> write_size ))
1298
+ file , skip_size ))
1288
1299
{
1289
1300
/* record as skipped file in file_xxx.txt */
1290
1301
file -> write_size = BYTES_INVALID ;
@@ -1302,6 +1313,15 @@ backup_files(void *arg)
1302
1313
continue ;
1303
1314
}
1304
1315
}
1316
+ else if (!copy_file (arguments -> from_root ,
1317
+ arguments -> to_root ,
1318
+ file ))
1319
+ {
1320
+ /* record as skipped file in file_xxx.txt */
1321
+ file -> write_size = BYTES_INVALID ;
1322
+ elog (LOG , "skip" );
1323
+ continue ;
1324
+ }
1305
1325
1306
1326
elog (LOG , "copied %lu" , (unsigned long ) file -> write_size );
1307
1327
}
@@ -1377,30 +1397,23 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
1377
1397
tmp_file .path [path_len - 7 ] = '\0' ;
1378
1398
1379
1399
pre_search_file = (pgFile * * ) parray_bsearch (list_file , & tmp_file , pgFileComparePath );
1380
- /* Use another scheme for compressed files */
1381
- pgFile map_file ;
1382
- pgFile * * map_search_file ;
1383
- map_file .path = pg_strdup (file -> path );
1384
- if (segno > 0 )
1385
- sprintf (map_file .path + path_len - 7 , ".%d.cfm" , segno );
1386
- else
1387
- sprintf (map_file .path + path_len - 7 , ".cfm" );
1388
- map_search_file = (pgFile * * ) parray_bsearch (list_file , & map_file , pgFileComparePath );
1389
1400
1390
- if (pre_search_file != NULL
1391
- && map_search_file == NULL )
1401
+ if (is_compressed_data_file (& tmp_file , list_file ))
1402
+ {
1403
+ elog (NOTICE , "file %s is compressed, don't remove it from list" , tmp_file .path );
1404
+ pg_free (tmp_file .path );
1405
+ break ;
1406
+ }
1407
+
1408
+ if (pre_search_file != NULL )
1392
1409
{
1393
1410
search_file = * pre_search_file ;
1394
1411
search_file -> ptrack_path = pg_strdup (file -> path );
1395
1412
search_file -> segno = segno ;
1396
- }
1397
- else
1398
- {
1413
+ } else {
1399
1414
pg_free (tmp_file .path );
1400
- pg_free (map_file .path );
1401
1415
break ;
1402
1416
}
1403
- pg_free (map_file .path );
1404
1417
pg_free (tmp_file .path );
1405
1418
segno ++ ;
1406
1419
}
@@ -1453,9 +1466,6 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
1453
1466
}
1454
1467
1455
1468
/* mark cfs relations as not data */
1456
- /* TODO
1457
- * Don't mark cfs relations as not_datafile?
1458
- * We can use similar code to check if the file is compressed */
1459
1469
for (i = 0 ; i < (int ) parray_num (list_file ); i ++ )
1460
1470
{
1461
1471
pgFile * file = (pgFile * ) parray_get (list_file , i );
@@ -1467,7 +1477,8 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
1467
1477
pgFile tmp_file ;
1468
1478
tmp_file .path = pg_strdup (file -> path );
1469
1479
tmp_file .path [path_len - 4 ] = '\0' ;
1470
- pre_search_file = (pgFile * * ) parray_bsearch (list_file , & tmp_file , pgFileComparePath );
1480
+ pre_search_file = (pgFile * * ) parray_bsearch (list_file ,
1481
+ & tmp_file , pgFileComparePath );
1471
1482
if (pre_search_file != NULL )
1472
1483
{
1473
1484
FileMap * map ;
@@ -1483,13 +1494,9 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
1483
1494
break ;
1484
1495
}
1485
1496
1486
- (* pre_search_file )-> last_backup_write_size = map -> last_backup_write_size ;
1487
1497
(* pre_search_file )-> generation = map -> generation ;
1488
1498
(* pre_search_file )-> is_datafile = false;
1489
- map -> last_backup_write_size = map -> physSize ;
1490
1499
1491
- if (cfs_msync (map ) < 0 )
1492
- elog (LOG , "add_files(). CFS failed to sync map %s: %m" , file -> path );
1493
1500
if (cfs_munmap (map ) < 0 )
1494
1501
elog (LOG , "add_files(). CFS failed to unmap file %s: %m" , file -> path );
1495
1502
if (close (md ) < 0 )
@@ -1799,12 +1806,3 @@ int cfs_munmap(FileMap* map)
1799
1806
return munmap (map , sizeof (FileMap ));
1800
1807
#endif
1801
1808
}
1802
-
1803
- int cfs_msync (FileMap * map )
1804
- {
1805
- #ifdef WIN32
1806
- return FlushViewOfFile (map , sizeof (FileMap )) ? 0 : -1 ;
1807
- #else
1808
- return msync (map , sizeof (FileMap ), MS_SYNC );
1809
- #endif
1810
- }
0 commit comments