1 /*-------------------------------------------------------------------------
2  *
3  * walreceiver.h
4  *	  Exports from replication/walreceiverfuncs.c.
5  *
6  * Portions Copyright (c) 2010-2016, PostgreSQL Global Development Group
7  *
8  * src/include/replication/walreceiver.h
9  *
10  *-------------------------------------------------------------------------
11  */
12 #ifndef _WALRECEIVER_H
13 #define _WALRECEIVER_H
14 
15 #include "access/xlog.h"
16 #include "access/xlogdefs.h"
17 #include "fmgr.h"
18 #include "storage/latch.h"
19 #include "storage/spin.h"
20 #include "pgtime.h"
21 
22 /* user-settable parameters */
23 extern int	wal_receiver_status_interval;
24 extern int	wal_receiver_timeout;
25 extern bool hot_standby_feedback;
26 
27 /*
28  * MAXCONNINFO: maximum size of a connection string.
29  *
30  * XXX: Should this move to pg_config_manual.h?
31  */
32 #define MAXCONNINFO		1024
33 
34 /* Can we allow the standby to accept replication connection from another standby? */
35 #define AllowCascadeReplication() (EnableHotStandby && max_wal_senders > 0)
36 
37 /*
38  * Values for WalRcv->walRcvState.
39  */
40 typedef enum
41 {
42 	WALRCV_STOPPED,				/* stopped and mustn't start up again */
43 	WALRCV_STARTING,			/* launched, but the process hasn't
44 								 * initialized yet */
45 	WALRCV_STREAMING,			/* walreceiver is streaming */
46 	WALRCV_WAITING,				/* stopped streaming, waiting for orders */
47 	WALRCV_RESTARTING,			/* asked to restart streaming */
48 	WALRCV_STOPPING				/* requested to stop, but still running */
49 } WalRcvState;
50 
51 /* Shared memory area for management of walreceiver process */
52 typedef struct
53 {
54 	/*
55 	 * PID of currently active walreceiver process, its current state and
56 	 * start time (actually, the time at which it was requested to be
57 	 * started).
58 	 */
59 	pid_t		pid;
60 	WalRcvState walRcvState;
61 	pg_time_t	startTime;
62 
63 	/*
64 	 * receiveStart and receiveStartTLI indicate the first byte position and
65 	 * timeline that will be received. When startup process starts the
66 	 * walreceiver, it sets these to the point where it wants the streaming to
67 	 * begin.
68 	 */
69 	XLogRecPtr	receiveStart;
70 	TimeLineID	receiveStartTLI;
71 
72 	/*
73 	 * receivedUpto-1 is the last byte position that has already been
74 	 * received, and receivedTLI is the timeline it came from.  At the first
75 	 * startup of walreceiver, these are set to receiveStart and
76 	 * receiveStartTLI. After that, walreceiver updates these whenever it
77 	 * flushes the received WAL to disk.
78 	 */
79 	XLogRecPtr	receivedUpto;
80 	TimeLineID	receivedTLI;
81 
82 	/*
83 	 * latestChunkStart is the starting byte position of the current "batch"
84 	 * of received WAL.  It's actually the same as the previous value of
85 	 * receivedUpto before the last flush to disk.  Startup process can use
86 	 * this to detect whether it's keeping up or not.
87 	 */
88 	XLogRecPtr	latestChunkStart;
89 
90 	/*
91 	 * Time of send and receive of any message received.
92 	 */
93 	TimestampTz lastMsgSendTime;
94 	TimestampTz lastMsgReceiptTime;
95 
96 	/*
97 	 * Latest reported end of WAL on the sender
98 	 */
99 	XLogRecPtr	latestWalEnd;
100 	TimestampTz latestWalEndTime;
101 
102 	/*
103 	 * connection string; initially set to connect to the primary, and later
104 	 * clobbered to hide security-sensitive fields.
105 	 */
106 	char		conninfo[MAXCONNINFO];
107 
108 	/*
109 	 * replication slot name; is also used for walreceiver to connect with the
110 	 * primary
111 	 */
112 	char		slotname[NAMEDATALEN];
113 
114 	slock_t		mutex;			/* locks shared variables shown above */
115 
116 	/*
117 	 * force walreceiver reply?  This doesn't need to be locked; memory
118 	 * barriers for ordering are sufficient.
119 	 */
120 	bool		force_reply;
121 
122 	/* set true once conninfo is ready to display (obfuscated pwds etc) */
123 	bool		ready_to_display;
124 
125 	/*
126 	 * Latch used by startup process to wake up walreceiver after telling it
127 	 * where to start streaming (after setting receiveStart and
128 	 * receiveStartTLI), and also to tell it to send apply feedback to the
129 	 * primary whenever specially marked commit records are applied.
130 	 */
131 	Latch		latch;
132 } WalRcvData;
133 
134 extern WalRcvData *WalRcv;
135 
136 /* libpqwalreceiver hooks */
137 typedef void (*walrcv_connect_type) (char *conninfo);
138 extern PGDLLIMPORT walrcv_connect_type walrcv_connect;
139 
140 typedef char *(*walrcv_get_conninfo_type) (void);
141 extern PGDLLIMPORT walrcv_get_conninfo_type walrcv_get_conninfo;
142 
143 typedef void (*walrcv_identify_system_type) (TimeLineID *primary_tli);
144 extern PGDLLIMPORT walrcv_identify_system_type walrcv_identify_system;
145 
146 typedef void (*walrcv_readtimelinehistoryfile_type) (TimeLineID tli, char **filename, char **content, int *size);
147 extern PGDLLIMPORT walrcv_readtimelinehistoryfile_type walrcv_readtimelinehistoryfile;
148 
149 typedef bool (*walrcv_startstreaming_type) (TimeLineID tli, XLogRecPtr startpoint, char *slotname);
150 extern PGDLLIMPORT walrcv_startstreaming_type walrcv_startstreaming;
151 
152 typedef void (*walrcv_endstreaming_type) (TimeLineID *next_tli);
153 extern PGDLLIMPORT walrcv_endstreaming_type walrcv_endstreaming;
154 
155 typedef int (*walrcv_receive_type) (char **buffer, pgsocket *wait_fd);
156 extern PGDLLIMPORT walrcv_receive_type walrcv_receive;
157 
158 typedef void (*walrcv_send_type) (const char *buffer, int nbytes);
159 extern PGDLLIMPORT walrcv_send_type walrcv_send;
160 
161 typedef void (*walrcv_disconnect_type) (void);
162 extern PGDLLIMPORT walrcv_disconnect_type walrcv_disconnect;
163 
164 /* prototypes for functions in walreceiver.c */
165 extern void WalReceiverMain(void) pg_attribute_noreturn();
166 extern Datum pg_stat_get_wal_receiver(PG_FUNCTION_ARGS);
167 
168 /* prototypes for functions in walreceiverfuncs.c */
169 extern Size WalRcvShmemSize(void);
170 extern void WalRcvShmemInit(void);
171 extern void ShutdownWalRcv(void);
172 extern bool WalRcvStreaming(void);
173 extern bool WalRcvRunning(void);
174 extern void RequestXLogStreaming(TimeLineID tli, XLogRecPtr recptr,
175 					 const char *conninfo, const char *slotname);
176 extern XLogRecPtr GetWalRcvWriteRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI);
177 extern int	GetReplicationApplyDelay(void);
178 extern int	GetReplicationTransferLatency(void);
179 extern void WalRcvForceReply(void);
180 
181 #endif   /* _WALRECEIVER_H */
182