PostgreSQL Source Code  git master
recovery_gen.h File Reference
#include "libpq-fe.h"
#include "pqexpbuffer.h"
Include dependency graph for recovery_gen.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MINIMUM_VERSION_FOR_RECOVERY_GUC   120000
 

Functions

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

Macro Definition Documentation

◆ MINIMUM_VERSION_FOR_RECOVERY_GUC

#define MINIMUM_VERSION_FOR_RECOVERY_GUC   120000

Definition at line 21 of file recovery_gen.h.

Function Documentation

◆ GenerateRecoveryConfig()

PQExpBuffer GenerateRecoveryConfig ( PGconn pgconn,
const char *  replication_slot 
)

Definition at line 23 of file recovery_gen.c.

24 {
25  PQconninfoOption *connOptions;
26  PQExpBufferData conninfo_buf;
27  char *escaped;
28  PQExpBuffer contents;
29 
30  Assert(pgconn != NULL);
31 
32  contents = createPQExpBuffer();
33  if (!contents)
34  pg_fatal("out of memory");
35 
36  /*
37  * In PostgreSQL 12 and newer versions, standby_mode is gone, replaced by
38  * standby.signal to trigger a standby state at recovery.
39  */
41  appendPQExpBufferStr(contents, "standby_mode = 'on'\n");
42 
43  connOptions = PQconninfo(pgconn);
44  if (connOptions == NULL)
45  pg_fatal("out of memory");
46 
47  initPQExpBuffer(&conninfo_buf);
48  for (PQconninfoOption *opt = connOptions; opt && opt->keyword; opt++)
49  {
50  /* Omit empty settings and those libpqwalreceiver overrides. */
51  if (strcmp(opt->keyword, "replication") == 0 ||
52  strcmp(opt->keyword, "dbname") == 0 ||
53  strcmp(opt->keyword, "fallback_application_name") == 0 ||
54  (opt->val == NULL) ||
55  (opt->val != NULL && opt->val[0] == '\0'))
56  continue;
57 
58  /* Separate key-value pairs with spaces */
59  if (conninfo_buf.len != 0)
60  appendPQExpBufferChar(&conninfo_buf, ' ');
61 
62  /*
63  * Write "keyword=value" pieces, the value string is escaped and/or
64  * quoted if necessary.
65  */
66  appendPQExpBuffer(&conninfo_buf, "%s=", opt->keyword);
67  appendConnStrVal(&conninfo_buf, opt->val);
68  }
69  if (PQExpBufferDataBroken(conninfo_buf))
70  pg_fatal("out of memory");
71 
72  /*
73  * Escape the connection string, so that it can be put in the config file.
74  * Note that this is different from the escaping of individual connection
75  * options above!
76  */
77  escaped = escape_quotes(conninfo_buf.data);
78  termPQExpBuffer(&conninfo_buf);
79  appendPQExpBuffer(contents, "primary_conninfo = '%s'\n", escaped);
80  free(escaped);
81 
82  if (replication_slot)
83  {
84  /* unescaped: ReplicationSlotValidateName allows [a-z0-9_] only */
85  appendPQExpBuffer(contents, "primary_slot_name = '%s'\n",
87  }
88 
89  if (PQExpBufferBroken(contents))
90  pg_fatal("out of memory");
91 
92  PQconninfoFree(connOptions);
93 
94  return contents;
95 }
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6938
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:6781
PQconninfoOption * PQconninfo(PGconn *conn)
Definition: fe-connect.c:6737
#define free(a)
Definition: header.h:65
Assert(fmt[strlen(fmt) - 1] !='\n')
#define pg_fatal(...)
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:144
#define MINIMUM_VERSION_FOR_RECOVERY_GUC
Definition: recovery_gen.h:21
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:545

References appendConnStrVal(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), Assert(), createPQExpBuffer(), PQExpBufferData::data, 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(), and main().

◆ WriteRecoveryConfig()

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

Definition at line 105 of file recovery_gen.c.

106 {
107  char filename[MAXPGPATH];
108  FILE *cf;
109  bool use_recovery_conf;
110 
111  Assert(pgconn != NULL);
112 
113  use_recovery_conf =
115 
116  snprintf(filename, MAXPGPATH, "%s/%s", target_dir,
117  use_recovery_conf ? "recovery.conf" : "postgresql.auto.conf");
118 
119  cf = fopen(filename, use_recovery_conf ? "w" : "a");
120  if (cf == NULL)
121  pg_fatal("could not open file \"%s\": %m", filename);
122 
123  if (fwrite(contents->data, contents->len, 1, cf) != 1)
124  pg_fatal("could not write to file \"%s\": %m", filename);
125 
126  fclose(cf);
127 
128  if (!use_recovery_conf)
129  {
130  snprintf(filename, MAXPGPATH, "%s/%s", target_dir, "standby.signal");
131  cf = fopen(filename, "w");
132  if (cf == NULL)
133  pg_fatal("could not create file \"%s\": %m", filename);
134 
135  fclose(cf);
136  }
137 }
#define MAXPGPATH
static char * filename
Definition: pg_dumpall.c:121
#define snprintf
Definition: port.h:238

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

Referenced by main().