@@ -103,6 +103,7 @@ static XLogRecPtr wait_wal_lsn(XLogRecPtr lsn, bool is_start_lsn,
103103 bool wait_prev_segment );
104104static void make_pagemap_from_ptrack (parray * files , PGconn * backup_conn );
105105static void * StreamLog (void * arg );
106+ static void IdentifySystem (StreamThreadArg * stream_thread_arg );
106107
107108static void check_external_for_tablespaces (parray * external_list ,
108109 PGconn * backup_conn );
@@ -289,30 +290,10 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo)
289290 instance_config .conn_opt .pgport ,
290291 instance_config .conn_opt .pgdatabase ,
291292 instance_config .conn_opt .pguser );
293+ /* sanity */
294+ IdentifySystem (& stream_thread_arg );
292295
293- if (!CheckServerVersionForStreaming (stream_thread_arg .conn ))
294- {
295- PQfinish (stream_thread_arg .conn );
296- /*
297- * Error message already written in CheckServerVersionForStreaming().
298- * There's no hope of recovering from a version mismatch, so don't
299- * retry.
300- */
301- elog (ERROR , "Cannot continue backup because stream connect has failed." );
302- }
303-
304- /*
305- * Identify server, obtaining start LSN position and current timeline ID
306- * at the same time, necessary if not valid data can be found in the
307- * existing output directory.
308- */
309- if (!RunIdentifySystem (stream_thread_arg .conn , NULL , NULL , NULL , NULL ))
310- {
311- PQfinish (stream_thread_arg .conn );
312- elog (ERROR , "Cannot continue backup because stream connect has failed." );
313- }
314-
315- /* By default there are some error */
296+ /* By default there are some error */
316297 stream_thread_arg .ret = 1 ;
317298 /* we must use startpos as start_lsn from start_backup */
318299 stream_thread_arg .startpos = current .start_lsn ;
@@ -522,7 +503,7 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo)
522503 char pg_control_path [MAXPGPATH ];
523504
524505 snprintf (pg_control_path , sizeof (pg_control_path ), "%s/%s" ,
525- instance_config .pgdata , "global/pg_control" );
506+ instance_config .pgdata , XLOG_CONTROL_FILE );
526507
527508 for (i = 0 ; i < parray_num (backup_files_list ); i ++ )
528509 {
@@ -2529,7 +2510,7 @@ StreamLog(void *arg)
25292510 /*
25302511 * Start the replication
25312512 */
2532- elog (LOG , _ ( "started streaming WAL at %X/%X (timeline %u)" ) ,
2513+ elog (LOG , "started streaming WAL at %X/%X (timeline %u)" ,
25332514 (uint32 ) (stream_arg -> startpos >> 32 ), (uint32 ) stream_arg -> startpos ,
25342515 stream_arg -> starttli );
25352516
@@ -2570,13 +2551,13 @@ StreamLog(void *arg)
25702551#endif
25712552 }
25722553#else
2573- if (ReceiveXlogStream (stream_arg -> conn , stream_arg -> startpos , stream_arg -> starttli , NULL ,
2574- (char * ) stream_arg -> basedir , stop_streaming ,
2575- standby_message_timeout , NULL , false, false) == false)
2554+ if (ReceiveXlogStream (stream_arg -> conn , stream_arg -> startpos , stream_arg -> starttli ,
2555+ NULL , (char * ) stream_arg -> basedir , stop_streaming ,
2556+ standby_message_timeout , NULL , false, false) == false)
25762557 elog (ERROR , "Problem in receivexlog" );
25772558#endif
25782559
2579- elog (LOG , _ ( "finished streaming WAL at %X/%X (timeline %u)" ) ,
2560+ elog (LOG , "finished streaming WAL at %X/%X (timeline %u)" ,
25802561 (uint32 ) (stop_stream_lsn >> 32 ), (uint32 ) stop_stream_lsn , stream_arg -> starttli );
25812562 stream_arg -> ret = 0 ;
25822563
@@ -2744,3 +2725,62 @@ check_external_for_tablespaces(parray *external_list, PGconn *backup_conn)
27442725 }
27452726 }
27462727}
2728+
2729+ /*
2730+ * Run IDENTIFY_SYSTEM through a given connection and
2731+ * check system identifier and timeline are matching
2732+ */
2733+ void
2734+ IdentifySystem (StreamThreadArg * stream_thread_arg )
2735+ {
2736+ PGresult * res ;
2737+
2738+ uint64 stream_conn_sysidentifier = 0 ;
2739+ char * stream_conn_sysidentifier_str ;
2740+ TimeLineID stream_conn_tli = 0 ;
2741+
2742+ if (!CheckServerVersionForStreaming (stream_thread_arg -> conn ))
2743+ {
2744+ PQfinish (stream_thread_arg -> conn );
2745+ /*
2746+ * Error message already written in CheckServerVersionForStreaming().
2747+ * There's no hope of recovering from a version mismatch, so don't
2748+ * retry.
2749+ */
2750+ elog (ERROR , "Cannot continue backup because stream connect has failed." );
2751+ }
2752+
2753+ /*
2754+ * Identify server, obtain server system identifier and timeline
2755+ */
2756+ res = pgut_execute (stream_thread_arg -> conn , "IDENTIFY_SYSTEM" , 0 , NULL );
2757+
2758+ if (PQresultStatus (res ) != PGRES_TUPLES_OK )
2759+ {
2760+ elog (WARNING ,"Could not send replication command \"%s\": %s" ,
2761+ "IDENTIFY_SYSTEM" , PQerrorMessage (stream_thread_arg -> conn ));
2762+ PQfinish (stream_thread_arg -> conn );
2763+ elog (ERROR , "Cannot continue backup because stream connect has failed." );
2764+ }
2765+
2766+ stream_conn_sysidentifier_str = PQgetvalue (res , 0 , 0 );
2767+ stream_conn_tli = atoi (PQgetvalue (res , 0 , 1 ));
2768+
2769+ /* Additional sanity, primary for PG 9.5,
2770+ * where system id can be obtained only via "IDENTIFY SYSTEM"
2771+ */
2772+ if (!parse_uint64 (stream_conn_sysidentifier_str , & stream_conn_sysidentifier , 0 ))
2773+ elog (ERROR , "%s is not system_identifier" , stream_conn_sysidentifier_str );
2774+
2775+ if (stream_conn_sysidentifier != instance_config .system_identifier )
2776+ elog (ERROR , "System identifier mismatch. Connected PostgreSQL instance has system id: "
2777+ "" UINT64_FORMAT ". Expected: " UINT64_FORMAT "." ,
2778+ stream_conn_sysidentifier , instance_config .system_identifier );
2779+
2780+ if (stream_conn_tli != current .tli )
2781+ elog (ERROR , "Timeline identifier mismatch. "
2782+ "Connected PostgreSQL instance has timeline id: %X. Expected: %X." ,
2783+ stream_conn_tli , current .tli );
2784+
2785+ PQclear (res );
2786+ }
0 commit comments