PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
recovery_gen.c File Reference
Include dependency graph for recovery_gen.c:

Go to the source code of this file.

Functions

static char * escape_quotes (const char *src)
 
static char * FindDbnameInConnOpts (PQconninfoOption *conn_opts)
 
PQExpBuffer GenerateRecoveryConfig (PGconn *pgconn, const char *replication_slot, char *dbname)
 
void WriteRecoveryConfig (PGconn *pgconn, const char *target_dir, PQExpBuffer contents)
 
char * GetDbnameFromConnectionOptions (const char *connstr)
 

Function Documentation

◆ escape_quotes()

static char * escape_quotes ( const char *  src)
static

Definition at line 164 of file recovery_gen.c.

165{
166 char *result = escape_single_quotes_ascii(src);
167
168 if (!result)
169 pg_fatal("out of memory");
170 return result;
171}
#define pg_fatal(...)
char * escape_single_quotes_ascii(const char *src)
Definition: quotes.c:33

References escape_single_quotes_ascii(), and pg_fatal.

Referenced by GenerateRecoveryConfig().

◆ FindDbnameInConnOpts()

static char * FindDbnameInConnOpts ( PQconninfoOption conn_opts)
static

Definition at line 181 of file recovery_gen.c.

182{
183 for (PQconninfoOption *conn_opt = conn_opts;
184 conn_opt->keyword != NULL;
185 conn_opt++)
186 {
187 if (strcmp(conn_opt->keyword, "dbname") == 0 &&
188 conn_opt->val != NULL && conn_opt->val[0] != '\0')
189 return pg_strdup(conn_opt->val);
190 }
191 return NULL;
192}
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85

References _PQconninfoOption::keyword, and pg_strdup().

Referenced by GetDbnameFromConnectionOptions().

◆ GenerateRecoveryConfig()

PQExpBuffer GenerateRecoveryConfig ( PGconn pgconn,
const char *  replication_slot,
char *  dbname 
)

Definition at line 28 of file recovery_gen.c.

30{
31 PQconninfoOption *connOptions;
32 PQExpBufferData conninfo_buf;
33 char *escaped;
34 PQExpBuffer contents;
35
36 Assert(pgconn != NULL);
37
38 contents = createPQExpBuffer();
39 if (!contents)
40 pg_fatal("out of memory");
41
42 /*
43 * In PostgreSQL 12 and newer versions, standby_mode is gone, replaced by
44 * standby.signal to trigger a standby state at recovery.
45 */
47 appendPQExpBufferStr(contents, "standby_mode = 'on'\n");
48
49 connOptions = PQconninfo(pgconn);
50 if (connOptions == NULL)
51 pg_fatal("out of memory");
52
53 initPQExpBuffer(&conninfo_buf);
54 for (PQconninfoOption *opt = connOptions; opt && opt->keyword; opt++)
55 {
56 /* Omit empty settings and those libpqwalreceiver overrides. */
57 if (strcmp(opt->keyword, "replication") == 0 ||
58 strcmp(opt->keyword, "dbname") == 0 ||
59 strcmp(opt->keyword, "fallback_application_name") == 0 ||
60 (opt->val == NULL) ||
61 (opt->val != NULL && opt->val[0] == '\0'))
62 continue;
63
64 /* Separate key-value pairs with spaces */
65 if (conninfo_buf.len != 0)
66 appendPQExpBufferChar(&conninfo_buf, ' ');
67
68 /*
69 * Write "keyword=value" pieces, the value string is escaped and/or
70 * quoted if necessary.
71 */
72 appendPQExpBuffer(&conninfo_buf, "%s=", opt->keyword);
73 appendConnStrVal(&conninfo_buf, opt->val);
74 }
75
76 if (dbname)
77 {
78 /*
79 * If dbname is specified in the connection, append the dbname. This
80 * will be used later for logical replication slot synchronization.
81 */
82 if (conninfo_buf.len != 0)
83 appendPQExpBufferChar(&conninfo_buf, ' ');
84
85 appendPQExpBuffer(&conninfo_buf, "%s=", "dbname");
86 appendConnStrVal(&conninfo_buf, dbname);
87 }
88
89 if (PQExpBufferDataBroken(conninfo_buf))
90 pg_fatal("out of memory");
91
92 /*
93 * Escape the connection string, so that it can be put in the config file.
94 * Note that this is different from the escaping of individual connection
95 * options above!
96 */
97 escaped = escape_quotes(conninfo_buf.data);
98 termPQExpBuffer(&conninfo_buf);
99 appendPQExpBuffer(contents, "primary_conninfo = '%s'\n", escaped);
100 free(escaped);
101
103 {
104 /* unescaped: ReplicationSlotValidateName allows [a-z0-9_] only */
105 appendPQExpBuffer(contents, "primary_slot_name = '%s'\n",
107 }
108
109 if (PQExpBufferBroken(contents))
110 pg_fatal("out of memory");
111
112 PQconninfoFree(connOptions);
113
114 return contents;
115}
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:7543
PQconninfoOption * PQconninfo(PGconn *conn)
Definition: fe-connect.c:7324
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:7368
Assert(PointerIsAligned(start, uint64))
#define free(a)
Definition: header.h:65
static char * replication_slot
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
static char * escape_quotes(const char *src)
Definition: recovery_gen.c:164
#define MINIMUM_VERSION_FOR_RECOVERY_GUC
Definition: recovery_gen.h:21
char * dbname
Definition: streamutil.c:49
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:698

References appendConnStrVal(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), Assert(), createPQExpBuffer(), PQExpBufferData::data, dbname, escape_quotes(), free, initPQExpBuffer(), _PQconninfoOption::keyword, PQExpBufferData::len, MINIMUM_VERSION_FOR_RECOVERY_GUC, pg_fatal, PQconninfo(), PQconninfoFree(), PQExpBufferBroken, PQExpBufferDataBroken, PQserverVersion(), replication_slot, and termPQExpBuffer().

Referenced by BaseBackup(), main(), and setup_recovery().

◆ GetDbnameFromConnectionOptions()

char * GetDbnameFromConnectionOptions ( const char *  connstr)

Definition at line 204 of file recovery_gen.c.

205{
206 PQconninfoOption *conn_opts;
207 char *err_msg = NULL;
208 char *dbname;
209
210 /* First try to get the dbname from connection string. */
211 if (connstr)
212 {
213 conn_opts = PQconninfoParse(connstr, &err_msg);
214 if (conn_opts == NULL)
215 pg_fatal("%s", err_msg);
216
217 dbname = FindDbnameInConnOpts(conn_opts);
218
219 PQconninfoFree(conn_opts);
220 if (dbname)
221 return dbname;
222 }
223
224 /*
225 * Next try to get the dbname from default values that are available from
226 * the environment.
227 */
228 conn_opts = PQconndefaults();
229 if (conn_opts == NULL)
230 pg_fatal("out of memory");
231
232 dbname = FindDbnameInConnOpts(conn_opts);
233
234 PQconninfoFree(conn_opts);
235 return dbname;
236}
PQconninfoOption * PQconninfoParse(const char *conninfo, char **errmsg)
Definition: fe-connect.c:6084
PQconninfoOption * PQconndefaults(void)
Definition: fe-connect.c:2127
static char * connstr
Definition: pg_dumpall.c:88
static char * FindDbnameInConnOpts(PQconninfoOption *conn_opts)
Definition: recovery_gen.c:181

References connstr, dbname, FindDbnameInConnOpts(), pg_fatal, PQconndefaults(), PQconninfoFree(), and PQconninfoParse().

Referenced by BaseBackup(), and main().

◆ WriteRecoveryConfig()

void WriteRecoveryConfig ( PGconn pgconn,
const char *  target_dir,
PQExpBuffer  contents 
)

Definition at line 125 of file recovery_gen.c.

126{
127 char filename[MAXPGPATH];
128 FILE *cf;
129 bool use_recovery_conf;
130
131 Assert(pgconn != NULL);
132
133 use_recovery_conf =
135
136 snprintf(filename, MAXPGPATH, "%s/%s", target_dir,
137 use_recovery_conf ? "recovery.conf" : "postgresql.auto.conf");
138
139 cf = fopen(filename, use_recovery_conf ? "w" : "a");
140 if (cf == NULL)
141 pg_fatal("could not open file \"%s\": %m", filename);
142
143 if (fwrite(contents->data, contents->len, 1, cf) != 1)
144 pg_fatal("could not write to file \"%s\": %m", filename);
145
146 fclose(cf);
147
148 if (!use_recovery_conf)
149 {
150 snprintf(filename, MAXPGPATH, "%s/%s", target_dir, "standby.signal");
151 cf = fopen(filename, "w");
152 if (cf == NULL)
153 pg_fatal("could not create file \"%s\": %m", filename);
154
155 fclose(cf);
156 }
157}
#define MAXPGPATH
static char * filename
Definition: pg_dumpall.c:123
#define snprintf
Definition: port.h:239

References Assert(), PQExpBufferData::data, filename, PQExpBufferData::len, MAXPGPATH, MINIMUM_VERSION_FOR_RECOVERY_GUC, pg_fatal, PQserverVersion(), and snprintf.

Referenced by main(), and setup_recovery().