PostgreSQL Source Code  git master
pg_upgrade_support.c
Go to the documentation of this file.
1 /*
2  * pg_upgrade_support.c
3  *
4  * server-side functions to set backend global variables
5  * to control oid and relfilenumber assignment, and do other special
6  * hacks needed for pg_upgrade.
7  *
8  * Copyright (c) 2010-2024, PostgreSQL Global Development Group
9  * src/backend/utils/adt/pg_upgrade_support.c
10  */
11 
12 #include "postgres.h"
13 
14 #include "access/relation.h"
15 #include "access/table.h"
16 #include "catalog/binary_upgrade.h"
17 #include "catalog/heap.h"
18 #include "catalog/namespace.h"
20 #include "catalog/pg_type.h"
21 #include "commands/extension.h"
22 #include "miscadmin.h"
23 #include "replication/logical.h"
24 #include "replication/origin.h"
26 #include "storage/lmgr.h"
27 #include "utils/array.h"
28 #include "utils/builtins.h"
29 #include "utils/lsyscache.h"
30 #include "utils/pg_lsn.h"
31 
32 
33 #define CHECK_IS_BINARY_UPGRADE \
34 do { \
35  if (!IsBinaryUpgrade) \
36  ereport(ERROR, \
37  (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM), \
38  errmsg("function can only be called when server is in binary upgrade mode"))); \
39 } while (0)
40 
41 Datum
43 {
44  Oid tbspoid = PG_GETARG_OID(0);
45 
48 
50 }
51 
52 Datum
54 {
55  Oid typoid = PG_GETARG_OID(0);
56 
59 
61 }
62 
63 Datum
65 {
66  Oid typoid = PG_GETARG_OID(0);
67 
70 
72 }
73 
74 Datum
76 {
77  Oid typoid = PG_GETARG_OID(0);
78 
81 
83 }
84 
85 Datum
87 {
88  Oid typoid = PG_GETARG_OID(0);
89 
92 
94 }
95 
96 Datum
98 {
99  Oid reloid = PG_GETARG_OID(0);
100 
103 
104  PG_RETURN_VOID();
105 }
106 
107 Datum
109 {
110  RelFileNumber relfilenumber = PG_GETARG_OID(0);
111 
114 
115  PG_RETURN_VOID();
116 }
117 
118 Datum
120 {
121  Oid reloid = PG_GETARG_OID(0);
122 
125 
126  PG_RETURN_VOID();
127 }
128 
129 Datum
131 {
132  RelFileNumber relfilenumber = PG_GETARG_OID(0);
133 
136 
137  PG_RETURN_VOID();
138 }
139 
140 Datum
142 {
143  Oid reloid = PG_GETARG_OID(0);
144 
147 
148  PG_RETURN_VOID();
149 }
150 
151 Datum
153 {
154  RelFileNumber relfilenumber = PG_GETARG_OID(0);
155 
158 
159  PG_RETURN_VOID();
160 }
161 
162 Datum
164 {
165  Oid enumoid = PG_GETARG_OID(0);
166 
169 
170  PG_RETURN_VOID();
171 }
172 
173 Datum
175 {
176  Oid authoid = PG_GETARG_OID(0);
177 
180  PG_RETURN_VOID();
181 }
182 
183 Datum
185 {
186  text *extName;
187  text *schemaName;
188  bool relocatable;
189  text *extVersion;
190  Datum extConfig;
191  Datum extCondition;
192  List *requiredExtensions;
193 
195 
196  /* We must check these things before dereferencing the arguments */
197  if (PG_ARGISNULL(0) ||
198  PG_ARGISNULL(1) ||
199  PG_ARGISNULL(2) ||
200  PG_ARGISNULL(3))
201  elog(ERROR, "null argument to binary_upgrade_create_empty_extension is not allowed");
202 
203  extName = PG_GETARG_TEXT_PP(0);
204  schemaName = PG_GETARG_TEXT_PP(1);
205  relocatable = PG_GETARG_BOOL(2);
206  extVersion = PG_GETARG_TEXT_PP(3);
207 
208  if (PG_ARGISNULL(4))
209  extConfig = PointerGetDatum(NULL);
210  else
211  extConfig = PG_GETARG_DATUM(4);
212 
213  if (PG_ARGISNULL(5))
214  extCondition = PointerGetDatum(NULL);
215  else
216  extCondition = PG_GETARG_DATUM(5);
217 
218  requiredExtensions = NIL;
219  if (!PG_ARGISNULL(6))
220  {
221  ArrayType *textArray = PG_GETARG_ARRAYTYPE_P(6);
222  Datum *textDatums;
223  int ndatums;
224  int i;
225 
226  deconstruct_array_builtin(textArray, TEXTOID, &textDatums, NULL, &ndatums);
227  for (i = 0; i < ndatums; i++)
228  {
229  char *extName = TextDatumGetCString(textDatums[i]);
230  Oid extOid = get_extension_oid(extName, false);
231 
232  requiredExtensions = lappend_oid(requiredExtensions, extOid);
233  }
234  }
235 
237  GetUserId(),
238  get_namespace_oid(text_to_cstring(schemaName), false),
239  relocatable,
240  text_to_cstring(extVersion),
241  extConfig,
242  extCondition,
243  requiredExtensions);
244 
245  PG_RETURN_VOID();
246 }
247 
248 Datum
250 {
251  bool record_init_privs = PG_GETARG_BOOL(0);
252 
254  binary_upgrade_record_init_privs = record_init_privs;
255 
256  PG_RETURN_VOID();
257 }
258 
259 Datum
261 {
262  Oid table_id = PG_GETARG_OID(0);
265  char *cattname = text_to_cstring(attname);
266  char *cvalue = text_to_cstring(value);
267 
269  SetAttrMissing(table_id, cattname, cvalue);
270 
271  PG_RETURN_VOID();
272 }
273 
274 /*
275  * Verify the given slot has already consumed all the WAL changes.
276  *
277  * Returns true if there are no decodable WAL records after the
278  * confirmed_flush_lsn. Otherwise false.
279  *
280  * This is a special purpose function to ensure that the given slot can be
281  * upgraded without data loss.
282  */
283 Datum
285 {
286  Name slot_name;
287  XLogRecPtr end_of_wal;
288  bool found_pending_wal;
289 
291 
292  /*
293  * Binary upgrades only allowed super-user connections so we must have
294  * permission to use replication slots.
295  */
297 
298  slot_name = PG_GETARG_NAME(0);
299 
300  /* Acquire the given slot */
301  ReplicationSlotAcquire(NameStr(*slot_name), true);
302 
304 
305  /* Slots must be valid as otherwise we won't be able to scan the WAL */
307 
308  end_of_wal = GetFlushRecPtr(NULL);
309  found_pending_wal = LogicalReplicationSlotHasPendingWal(end_of_wal);
310 
311  /* Clean up */
313 
314  PG_RETURN_BOOL(!found_pending_wal);
315 }
316 
317 /*
318  * binary_upgrade_add_sub_rel_state
319  *
320  * Add the relation with the specified relation state to pg_subscription_rel
321  * catalog.
322  */
323 Datum
325 {
326  Relation subrel;
327  Relation rel;
328  Oid subid;
329  char *subname;
330  Oid relid;
331  char relstate;
332  XLogRecPtr sublsn;
333 
335 
336  /* We must check these things before dereferencing the arguments */
337  if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2))
338  elog(ERROR, "null argument to binary_upgrade_add_sub_rel_state is not allowed");
339 
341  relid = PG_GETARG_OID(1);
342  relstate = PG_GETARG_CHAR(2);
343  sublsn = PG_ARGISNULL(3) ? InvalidXLogRecPtr : PG_GETARG_LSN(3);
344 
345  subrel = table_open(SubscriptionRelationId, RowExclusiveLock);
346  subid = get_subscription_oid(subname, false);
347  rel = relation_open(relid, AccessShareLock);
348 
349  /*
350  * Since there are no concurrent ALTER/DROP SUBSCRIPTION commands during
351  * the upgrade process, and the apply worker (which builds cache based on
352  * the subscription catalog) is not running, the locks can be released
353  * immediately.
354  */
355  AddSubscriptionRelState(subid, relid, relstate, sublsn, false);
357  table_close(subrel, RowExclusiveLock);
358 
359  PG_RETURN_VOID();
360 }
361 
362 /*
363  * binary_upgrade_replorigin_advance
364  *
365  * Update the remote_lsn for the subscriber's replication origin.
366  */
367 Datum
369 {
370  Relation rel;
371  Oid subid;
372  char *subname;
373  char originname[NAMEDATALEN];
374  RepOriginId node;
375  XLogRecPtr remote_commit;
376 
378 
379  /*
380  * We must ensure a non-NULL subscription name before dereferencing the
381  * arguments.
382  */
383  if (PG_ARGISNULL(0))
384  elog(ERROR, "null argument to binary_upgrade_replorigin_advance is not allowed");
385 
387  remote_commit = PG_ARGISNULL(1) ? InvalidXLogRecPtr : PG_GETARG_LSN(1);
388 
389  rel = table_open(SubscriptionRelationId, RowExclusiveLock);
390  subid = get_subscription_oid(subname, false);
391 
392  ReplicationOriginNameForLogicalRep(subid, InvalidOid, originname, sizeof(originname));
393 
394  /* Lock to prevent the replication origin from vanishing */
395  LockRelationOid(ReplicationOriginRelationId, RowExclusiveLock);
396  node = replorigin_by_name(originname, false);
397 
398  /*
399  * The server will be stopped after setting up the objects in the new
400  * cluster and the origins will be flushed during the shutdown checkpoint.
401  * This will ensure that the latest LSN values for origin will be
402  * available after the upgrade.
403  */
404  replorigin_advance(node, remote_commit, InvalidXLogRecPtr,
405  false /* backward */ ,
406  false /* WAL log */ );
407 
408  UnlockRelationOid(ReplicationOriginRelationId, RowExclusiveLock);
410 
411  PG_RETURN_VOID();
412 }
bool binary_upgrade_record_init_privs
Definition: aclchk.c:110
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
void deconstruct_array_builtin(ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3697
Oid binary_upgrade_next_pg_tablespace_oid
Definition: tablespace.c:87
void ReplicationOriginNameForLogicalRep(Oid suboid, Oid relid, char *originname, Size szoriginname)
Definition: worker.c:426
#define TextDatumGetCString(d)
Definition: builtins.h:98
#define NameStr(name)
Definition: c.h:737
#define Assert(condition)
Definition: c.h:849
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
ObjectAddress InsertExtensionTuple(const char *extName, Oid extOwner, Oid schemaOid, bool relocatable, const char *extVersion, Datum extConfig, Datum extCondition, List *requiredExtensions)
Definition: extension.c:1977
Oid get_extension_oid(const char *extname, bool missing_ok)
Definition: extension.c:158
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_GETARG_CHAR(n)
Definition: fmgr.h:273
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:336
void SetAttrMissing(Oid relid, char *attname, char *value)
Definition: heap.c:2015
RelFileNumber binary_upgrade_next_heap_pg_class_relfilenumber
Definition: heap.c:82
RelFileNumber binary_upgrade_next_toast_pg_class_relfilenumber
Definition: heap.c:83
Oid binary_upgrade_next_toast_pg_class_oid
Definition: heap.c:81
Oid binary_upgrade_next_heap_pg_class_oid
Definition: heap.c:80
RelFileNumber binary_upgrade_next_index_pg_class_relfilenumber
Definition: index.c:85
Oid binary_upgrade_next_index_pg_class_oid
Definition: index.c:84
static struct @160 value
int i
Definition: isn.c:72
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:226
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:107
#define AccessShareLock
Definition: lockdefs.h:36
#define RowExclusiveLock
Definition: lockdefs.h:38
bool LogicalReplicationSlotHasPendingWal(XLogRecPtr end_of_wal)
Definition: logical.c:1979
Oid get_subscription_oid(const char *subname, bool missing_ok)
Definition: lsyscache.c:3675
Oid GetUserId(void)
Definition: miscinit.c:514
bool has_rolreplication(Oid roleid)
Definition: miscinit.c:711
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3535
RepOriginId replorigin_by_name(const char *roname, bool missing_ok)
Definition: origin.c:225
void replorigin_advance(RepOriginId node, XLogRecPtr remote_commit, XLogRecPtr local_commit, bool go_backward, bool wal_log)
Definition: origin.c:892
NameData attname
Definition: pg_attribute.h:41
#define NAMEDATALEN
Oid binary_upgrade_next_pg_enum_oid
Definition: pg_enum.c:36
#define NIL
Definition: pg_list.h:68
#define PG_GETARG_LSN(n)
Definition: pg_lsn.h:33
void AddSubscriptionRelState(Oid subid, Oid relid, char state, XLogRecPtr sublsn, bool retain_lock)
NameData subname
Oid binary_upgrade_next_pg_type_oid
Definition: pg_type.c:41
Datum binary_upgrade_set_next_heap_pg_class_oid(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_next_multirange_pg_type_oid(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_next_pg_enum_oid(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_next_index_pg_class_oid(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_next_array_pg_type_oid(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_next_toast_relfilenode(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_next_pg_authid_oid(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_record_init_privs(PG_FUNCTION_ARGS)
#define CHECK_IS_BINARY_UPGRADE
Datum binary_upgrade_add_sub_rel_state(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_next_multirange_array_pg_type_oid(PG_FUNCTION_ARGS)
Datum binary_upgrade_logical_slot_has_caught_up(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_next_pg_tablespace_oid(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_next_heap_relfilenode(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_next_index_relfilenode(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_missing_value(PG_FUNCTION_ARGS)
Datum binary_upgrade_create_empty_extension(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_next_pg_type_oid(PG_FUNCTION_ARGS)
Datum binary_upgrade_replorigin_advance(PG_FUNCTION_ARGS)
Datum binary_upgrade_set_next_toast_pg_class_oid(PG_FUNCTION_ARGS)
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
Oid RelFileNumber
Definition: relpath.h:25
void ReplicationSlotAcquire(const char *name, bool nowait)
Definition: slot.c:540
ReplicationSlot * MyReplicationSlot
Definition: slot.c:138
void ReplicationSlotRelease(void)
Definition: slot.c:652
@ RS_INVAL_NONE
Definition: slot.h:52
#define SlotIsLogical(slot)
Definition: slot.h:213
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:205
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: relation.c:47
Definition: pg_list.h:54
ReplicationSlotInvalidationCause invalidated
Definition: slot.h:99
ReplicationSlotPersistentData data
Definition: slot.h:181
Definition: c.h:732
Definition: c.h:678
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
Oid binary_upgrade_next_mrng_array_pg_type_oid
Definition: typecmds.c:111
Oid binary_upgrade_next_mrng_pg_type_oid
Definition: typecmds.c:110
Oid binary_upgrade_next_array_pg_type_oid
Definition: typecmds.c:109
Oid binary_upgrade_next_pg_authid_oid
Definition: user.c:70
char * text_to_cstring(const text *t)
Definition: varlena.c:217
XLogRecPtr GetFlushRecPtr(TimeLineID *insertTLI)
Definition: xlog.c:6499
uint16 RepOriginId
Definition: xlogdefs.h:65
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28