@@ -99,6 +99,7 @@ static void pg_switch_wal(PGconn *conn);
9999static void pg_stop_backup (pgBackup * backup );
100100static int checkpoint_timeout (void );
101101
102+ //static void backup_list_file(parray *files, const char *root, )
102103static void parse_backup_filelist_filenames (parray * files , const char * root );
103104static void write_backup_file_list (parray * files , const char * root );
104105static void wait_wal_lsn (XLogRecPtr lsn , bool wait_prev_segment );
@@ -273,7 +274,8 @@ ReceiveFileList(parray* files, PGconn *conn, PGresult *res, int rownum)
273274
274275/* read one file via replication protocol
275276 * 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 )
277279{
278280 PGresult * res ;
279281 char * copybuf = NULL ;
@@ -2095,256 +2097,75 @@ backup_files(void *arg)
20952097static void
20962098parse_backup_filelist_filenames (parray * files , const char * root )
20972099{
2098- size_t i ;
2099- Oid unlogged_file_reloid = 0 ;
2100+ size_t i = 0 ;
2101+ Oid unlogged_file_reloid = 0 ;
21002102
2101- for (i = 0 ; i < parray_num (files ); i ++ )
2103+ while (i < parray_num (files ))
21022104 {
21032105 pgFile * file = (pgFile * ) parray_get (files , i );
21042106 char * relative ;
2105- char filename [MAXPGPATH ];
21062107 int sscanf_result ;
21072108
21082109 relative = GetRelativePath (file -> path , root );
2109- filename [0 ] = '\0' ;
21102110
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 ))
21132113 {
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 )
21672119 {
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 );
21922129
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 );
22082134 }
22092135 }
2210- else
2211- {
2212- elog (VERBOSE ,"other dir or file, filepath %s" , relative );
2213- }
22142136
2215- if (strcmp (filename , "ptrack_init" ) == 0 )
2137+ if (S_ISREG (file -> mode ) && file -> tblspcOid != 0 &&
2138+ file -> name && file -> name [0 ])
22162139 {
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 )
22462141 {
22472142 /*
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 .
22502145 */
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 );
22532149
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 ;
23022151
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 ))
23052155 {
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 );
23372158
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 -- ;
23442160 i -- ;
2161+
2162+ unlogged_file = (pgFile * ) parray_get (files ,
2163+ unlogged_file_num );
23452164 }
23462165 }
23472166 }
2167+
2168+ i ++ ;
23482169 }
23492170}
23502171
@@ -2617,6 +2438,10 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished)
26172438 static uint32 prevtimeline = 0 ;
26182439 static XLogRecPtr prevpos = InvalidXLogRecPtr ;
26192440
2441+ /* check for interrupt */
2442+ if (interrupted )
2443+ elog (ERROR , "Interrupted during backup" );
2444+
26202445 /* we assume that we get called once at the end of each segment */
26212446 if (segment_finished )
26222447 elog (VERBOSE , _ ("finished segment at %X/%X (timeline %u)" ),
0 commit comments