@@ -99,6 +99,7 @@ static void pg_switch_wal(PGconn *conn);
99
99
static void pg_stop_backup (pgBackup * backup );
100
100
static int checkpoint_timeout (void );
101
101
102
+ //static void backup_list_file(parray *files, const char *root, )
102
103
static void parse_backup_filelist_filenames (parray * files , const char * root );
103
104
static void write_backup_file_list (parray * files , const char * root );
104
105
static void wait_wal_lsn (XLogRecPtr lsn , bool wait_prev_segment );
@@ -273,7 +274,8 @@ ReceiveFileList(parray* files, PGconn *conn, PGresult *res, int rownum)
273
274
274
275
/* read one file via replication protocol
275
276
* and write it to the destination subdir in 'backup_path' */
276
- static void remote_copy_file (PGconn * conn , pgFile * file )
277
+ static void
278
+ remote_copy_file (PGconn * conn , pgFile * file )
277
279
{
278
280
PGresult * res ;
279
281
char * copybuf = NULL ;
@@ -2095,256 +2097,75 @@ backup_files(void *arg)
2095
2097
static void
2096
2098
parse_backup_filelist_filenames (parray * files , const char * root )
2097
2099
{
2098
- size_t i ;
2099
- Oid unlogged_file_reloid = 0 ;
2100
+ size_t i = 0 ;
2101
+ Oid unlogged_file_reloid = 0 ;
2100
2102
2101
- for (i = 0 ; i < parray_num (files ); i ++ )
2103
+ while (i < parray_num (files ))
2102
2104
{
2103
2105
pgFile * file = (pgFile * ) parray_get (files , i );
2104
2106
char * relative ;
2105
- char filename [MAXPGPATH ];
2106
2107
int sscanf_result ;
2107
2108
2108
2109
relative = GetRelativePath (file -> path , root );
2109
- filename [0 ] = '\0' ;
2110
2110
2111
- elog ( VERBOSE , "-----------------------------------------------------: %s" , relative );
2112
- if ( path_is_prefix_of_path ("global" , relative ))
2111
+ if ( S_ISREG ( file -> mode ) &&
2112
+ path_is_prefix_of_path (PG_TBLSPC_DIR , relative ))
2113
2113
{
2114
- file -> tblspcOid = GLOBALTABLESPACE_OID ;
2115
- sscanf_result = sscanf (relative , "global/%s" , filename );
2116
- elog (VERBOSE , "global sscanf result: %i" , sscanf_result );
2117
- if (strcmp (relative , "global" ) == 0 )
2118
- {
2119
- Assert (S_ISDIR (file -> mode ));
2120
- elog (VERBOSE , "the global itself, filepath %s" , relative );
2121
- file -> is_database = true; /* TODO add an explanation */
2122
- }
2123
- else if (sscanf_result == 1 )
2124
- {
2125
- elog (VERBOSE , "filename %s, filepath %s" , filename , relative );
2126
- }
2127
- }
2128
- else if (path_is_prefix_of_path ("base" , relative ))
2129
- {
2130
- file -> tblspcOid = DEFAULTTABLESPACE_OID ;
2131
- sscanf_result = sscanf (relative , "base/%u/%s" , & (file -> dbOid ), filename );
2132
- elog (VERBOSE , "base sscanf result: %i" , sscanf_result );
2133
- if (strcmp (relative , "base" ) == 0 )
2134
- {
2135
- Assert (S_ISDIR (file -> mode ));
2136
- elog (VERBOSE , "the base itself, filepath %s" , relative );
2137
- }
2138
- else if (sscanf_result == 1 )
2139
- {
2140
- Assert (S_ISDIR (file -> mode ));
2141
- elog (VERBOSE , "dboid %u, filepath %s" , file -> dbOid , relative );
2142
- file -> is_database = true;
2143
- }
2144
- else
2145
- {
2146
- elog (VERBOSE , "dboid %u, filename %s, filepath %s" , file -> dbOid , filename , relative );
2147
- }
2148
- }
2149
- else if (path_is_prefix_of_path (PG_TBLSPC_DIR , relative ))
2150
- {
2151
- char temp_relative_path [MAXPGPATH ];
2152
-
2153
- sscanf_result = sscanf (relative , "pg_tblspc/%u/%s" , & (file -> tblspcOid ), temp_relative_path );
2154
- elog (VERBOSE , "pg_tblspc sscanf result: %i" , sscanf_result );
2155
-
2156
- if (strcmp (relative , "pg_tblspc" ) == 0 )
2157
- {
2158
- Assert (S_ISDIR (file -> mode ));
2159
- elog (VERBOSE , "the pg_tblspc itself, filepath %s" , relative );
2160
- }
2161
- else if (sscanf_result == 1 )
2162
- {
2163
- Assert (S_ISDIR (file -> mode ));
2164
- elog (VERBOSE , "tblspcOid %u, filepath %s" , file -> tblspcOid , relative );
2165
- }
2166
- else
2114
+ /*
2115
+ * Found file in pg_tblspc/tblsOid/TABLESPACE_VERSION_DIRECTORY
2116
+ * Legal only in case of 'pg_compression'
2117
+ */
2118
+ if (strcmp (file -> name , "pg_compression" ) == 0 )
2167
2119
{
2168
- /*continue parsing */
2169
- sscanf_result = sscanf (temp_relative_path + strlen (TABLESPACE_VERSION_DIRECTORY )+ 1 , "%u/%s" ,
2170
- & (file -> dbOid ), filename );
2171
- elog (VERBOSE , "TABLESPACE_VERSION_DIRECTORY sscanf result: %i" , sscanf_result );
2172
-
2173
- if (sscanf_result == -1 )
2174
- {
2175
- elog (VERBOSE , "The TABLESPACE_VERSION_DIRECTORY itself, filepath %s" , relative );
2176
- }
2177
- else if (sscanf_result == 0 )
2178
- {
2179
- /* Found file in pg_tblspc/tblsOid/TABLESPACE_VERSION_DIRECTORY
2180
- Legal only in case of 'pg_compression'
2181
- */
2182
- if (strcmp (file -> name , "pg_compression" ) == 0 )
2183
- {
2184
- elog (VERBOSE , "Found pg_compression file in TABLESPACE_VERSION_DIRECTORY, filepath %s" , relative );
2185
- /*Set every datafile in tablespace as is_cfs */
2186
- set_cfs_datafiles (files , root , relative , i );
2187
- }
2188
- else
2189
- {
2190
- elog (VERBOSE , "Found illegal file in TABLESPACE_VERSION_DIRECTORY, filepath %s" , relative );
2191
- }
2120
+ Oid tblspcOid ;
2121
+ Oid dbOid ;
2122
+ char tmp_rel_path [MAXPGPATH ];
2123
+ /*
2124
+ * Check that the file is located under
2125
+ * TABLESPACE_VERSION_DIRECTORY
2126
+ */
2127
+ sscanf_result = sscanf (relative , PG_TBLSPC_DIR "/%u/%s/%u" ,
2128
+ & tblspcOid , tmp_rel_path , & dbOid );
2192
2129
2193
- }
2194
- else if (sscanf_result == 1 )
2195
- {
2196
- Assert (S_ISDIR (file -> mode ));
2197
- elog (VERBOSE , "dboid %u, filepath %s" , file -> dbOid , relative );
2198
- file -> is_database = true;
2199
- }
2200
- else if (sscanf_result == 2 )
2201
- {
2202
- elog (VERBOSE , "dboid %u, filename %s, filepath %s" , file -> dbOid , filename , relative );
2203
- }
2204
- else
2205
- {
2206
- elog (VERBOSE , "Illegal file filepath %s" , relative );
2207
- }
2130
+ /* Yes, it is */
2131
+ if (sscanf_result == 2 &&
2132
+ strcmp (tmp_rel_path , TABLESPACE_VERSION_DIRECTORY ) == 0 )
2133
+ set_cfs_datafiles (files , root , relative , i );
2208
2134
}
2209
2135
}
2210
- else
2211
- {
2212
- elog (VERBOSE ,"other dir or file, filepath %s" , relative );
2213
- }
2214
2136
2215
- if (strcmp (filename , "ptrack_init" ) == 0 )
2137
+ if (S_ISREG (file -> mode ) && file -> tblspcOid != 0 &&
2138
+ file -> name && file -> name [0 ])
2216
2139
{
2217
- /* Do not backup ptrack_init files */
2218
- pgFileFree (file );
2219
- parray_remove (files , i );
2220
- i -- ;
2221
- continue ;
2222
- }
2223
-
2224
- /* Check files located inside database directories including directory 'global' */
2225
- if (filename [0 ] != '\0' && file -> tblspcOid != 0 )
2226
- {
2227
- if (strcmp (filename , "pg_internal.init" ) == 0 )
2228
- {
2229
- /* Do not pg_internal.init files
2230
- * (they contain some cache entries, so it's fine) */
2231
- pgFileFree (file );
2232
- parray_remove (files , i );
2233
- i -- ;
2234
- continue ;
2235
- }
2236
- else if (filename [0 ] == 't' && isdigit (filename [1 ]))
2237
- {
2238
- elog (VERBOSE , "temp file, filepath %s" , relative );
2239
- /* Do not backup temp files */
2240
- pgFileFree (file );
2241
- parray_remove (files , i );
2242
- i -- ;
2243
- continue ;
2244
- }
2245
- else if (isdigit (filename [0 ]))
2140
+ if (strcmp (file -> forkName , "init" ) == 0 )
2246
2141
{
2247
2142
/*
2248
- * TODO TODO TODO Files of this type can be compressed by cfs .
2249
- * Check that and do not mark them with 'is_datafile' flag .
2143
+ * Do not backup files of unlogged relations .
2144
+ * scan filelist backward and exclude these files .
2250
2145
*/
2251
- char * forkNameptr ;
2252
- char suffix [MAXPGPATH ];
2146
+ int unlogged_file_num = i - 1 ;
2147
+ pgFile * unlogged_file = (pgFile * ) parray_get (files ,
2148
+ unlogged_file_num );
2253
2149
2254
- forkNameptr = strstr (filename , "_" );
2255
- if (forkNameptr != NULL )
2256
- {
2257
- /* auxiliary fork of the relfile */
2258
- sscanf (filename , "%u_%s" , & (file -> relOid ), file -> forkName );
2259
- elog (VERBOSE , "relOid %u, forkName %s, filepath %s" , file -> relOid , file -> forkName , relative );
2260
-
2261
- /* handle unlogged relations */
2262
- if (strcmp (file -> forkName , "init" ) == 0 )
2263
- {
2264
- /*
2265
- * Do not backup files of unlogged relations.
2266
- * scan filelist backward and exclude these files.
2267
- */
2268
- int unlogged_file_num = i - 1 ;
2269
- pgFile * unlogged_file = (pgFile * ) parray_get (files , unlogged_file_num );
2270
-
2271
- unlogged_file_reloid = file -> relOid ;
2272
-
2273
- while (unlogged_file_num >= 0 &&
2274
- (unlogged_file_reloid != 0 ) &&
2275
- (unlogged_file -> relOid == unlogged_file_reloid ))
2276
- {
2277
- unlogged_file -> size = 0 ;
2278
- pgFileFree (unlogged_file );
2279
- parray_remove (files , unlogged_file_num );
2280
- unlogged_file_num -- ;
2281
- i -- ;
2282
- unlogged_file = (pgFile * ) parray_get (files , unlogged_file_num );
2283
- }
2284
- }
2285
- else if (strcmp (file -> forkName , "ptrack" ) == 0 )
2286
- {
2287
- /* Do not backup ptrack files */
2288
- pgFileFree (file );
2289
- parray_remove (files , i );
2290
- i -- ;
2291
- }
2292
- else if ((unlogged_file_reloid != 0 ) &&
2293
- (file -> relOid == unlogged_file_reloid ))
2294
- {
2295
- /* Do not backup forks of unlogged relations */
2296
- pgFileFree (file );
2297
- parray_remove (files , i );
2298
- i -- ;
2299
- }
2300
- continue ;
2301
- }
2150
+ unlogged_file_reloid = file -> relOid ;
2302
2151
2303
- sscanf_result = sscanf (filename , "%u.%d.%s" , & (file -> relOid ), & (file -> segno ), suffix );
2304
- if (sscanf_result == 0 )
2152
+ while (unlogged_file_num >= 0 &&
2153
+ (unlogged_file_reloid != 0 ) &&
2154
+ (unlogged_file -> relOid == unlogged_file_reloid ))
2305
2155
{
2306
- elog (ERROR , "cannot parse filepath %s" , relative );
2307
- }
2308
- else if (sscanf_result == 1 )
2309
- {
2310
- /* first segment of the relfile */
2311
- elog (VERBOSE , "relOid %u, segno %d, filepath %s" , file -> relOid , 0 , relative );
2312
- if (strcmp (relative + strlen (relative ) - strlen ("cfm" ), "cfm" ) == 0 )
2313
- {
2314
- /* reloid.cfm */
2315
- elog (VERBOSE , "Found cfm file %s" , relative );
2316
- }
2317
- else
2318
- {
2319
- elog (VERBOSE , "Found first segment of the relfile %s" , relative );
2320
- file -> is_datafile = true;
2321
- }
2322
- }
2323
- else if (sscanf_result == 2 )
2324
- {
2325
- /* not first segment of the relfile */
2326
- elog (VERBOSE , "relOid %u, segno %d, filepath %s" , file -> relOid , file -> segno , relative );
2327
- file -> is_datafile = true;
2328
- }
2329
- else
2330
- {
2331
- /*
2332
- * some cfs specific file.
2333
- * It is not datafile, because we cannot read it block by block
2334
- */
2335
- elog (VERBOSE , "relOid %u, segno %d, suffix %s, filepath %s" , file -> relOid , file -> segno , suffix , relative );
2336
- }
2156
+ pgFileFree (unlogged_file );
2157
+ parray_remove (files , unlogged_file_num );
2337
2158
2338
- if ((unlogged_file_reloid != 0 ) &&
2339
- (file -> relOid == unlogged_file_reloid ))
2340
- {
2341
- /* Do not backup segments of unlogged files */
2342
- pgFileFree (file );
2343
- parray_remove (files , i );
2159
+ unlogged_file_num -- ;
2344
2160
i -- ;
2161
+
2162
+ unlogged_file = (pgFile * ) parray_get (files ,
2163
+ unlogged_file_num );
2345
2164
}
2346
2165
}
2347
2166
}
2167
+
2168
+ i ++ ;
2348
2169
}
2349
2170
}
2350
2171
@@ -2617,6 +2438,10 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished)
2617
2438
static uint32 prevtimeline = 0 ;
2618
2439
static XLogRecPtr prevpos = InvalidXLogRecPtr ;
2619
2440
2441
+ /* check for interrupt */
2442
+ if (interrupted )
2443
+ elog (ERROR , "Interrupted during backup" );
2444
+
2620
2445
/* we assume that we get called once at the end of each segment */
2621
2446
if (segment_finished )
2622
2447
elog (VERBOSE , _ ("finished segment at %X/%X (timeline %u)" ),
0 commit comments