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 #include "utils/syscache.h"
32 
33 
34 #define CHECK_IS_BINARY_UPGRADE \
35 do { \
36  if (!IsBinaryUpgrade) \
37  ereport(ERROR, \
38  (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM), \
39  errmsg("function can only be called when server is in binary upgrade mode"))); \
40 } while (0)
41 
42 Datum
44 {
45  Oid tbspoid = PG_GETARG_OID(0);
46 
49 
51 }
52 
53 Datum
55 {
56  Oid typoid = PG_GETARG_OID(0);
57 
60 
62 }
63 
64 Datum
66 {
67  Oid typoid = PG_GETARG_OID(0);
68 
71 
73 }
74 
75 Datum
77 {
78  Oid typoid = PG_GETARG_OID(0);
79 
82 
84 }
85 
86 Datum
88 {
89  Oid typoid = PG_GETARG_OID(0);
90 
93 
95 }
96 
97 Datum
99 {
100  Oid reloid = PG_GETARG_OID(0);
101 
104 
105  PG_RETURN_VOID();
106 }
107 
108 Datum
110 {
111  RelFileNumber relfilenumber = PG_GETARG_OID(0);
112 
115 
116  PG_RETURN_VOID();
117 }
118 
119 Datum
121 {
122  Oid reloid = PG_GETARG_OID(0);
123 
126 
127  PG_RETURN_VOID();
128 }
129 
130 Datum
132 {
133  RelFileNumber relfilenumber = PG_GETARG_OID(0);
134 
137 
138  PG_RETURN_VOID();
139 }
140 
141 Datum
143 {
144  Oid reloid = PG_GETARG_OID(0);
145 
148 
149  PG_RETURN_VOID();
150 }
151 
152 Datum
154 {
155  RelFileNumber relfilenumber = PG_GETARG_OID(0);
156 
159 
160  PG_RETURN_VOID();
161 }
162 
163 Datum
165 {
166  Oid enumoid = PG_GETARG_OID(0);
167 
170 
171  PG_RETURN_VOID();
172 }
173 
174 Datum
176 {
177  Oid authoid = PG_GETARG_OID(0);
178 
181  PG_RETURN_VOID();
182 }
183 
184 Datum
186 {
187  text *extName;
188  text *schemaName;
189  bool relocatable;
190  text *extVersion;
191  Datum extConfig;
192  Datum extCondition;
193  List *requiredExtensions;
194 
196 
197  /* We must check these things before dereferencing the arguments */
198  if (PG_ARGISNULL(0) ||
199  PG_ARGISNULL(1) ||
200  PG_ARGISNULL(2) ||
201  PG_ARGISNULL(3))
202  elog(ERROR, "null argument to binary_upgrade_create_empty_extension is not allowed");
203 
204  extName = PG_GETARG_TEXT_PP(0);
205  schemaName = PG_GETARG_TEXT_PP(1);
206  relocatable = PG_GETARG_BOOL(2);
207  extVersion = PG_GETARG_TEXT_PP(3);
208 
209  if (PG_ARGISNULL(4))
210  extConfig = PointerGetDatum(NULL);
211  else
212  extConfig = PG_GETARG_DATUM(4);
213 
214  if (PG_ARGISNULL(5))
215  extCondition = PointerGetDatum(NULL);
216  else
217  extCondition = PG_GETARG_DATUM(5);
218 
219  requiredExtensions = NIL;
220  if (!PG_ARGISNULL(6))
221  {
222  ArrayType *textArray = PG_GETARG_ARRAYTYPE_P(6);
223  Datum *textDatums;
224  int ndatums;
225  int i;
226 
227  deconstruct_array_builtin(textArray, TEXTOID, &textDatums, NULL, &ndatums);
228  for (i = 0; i < ndatums; i++)
229  {
230  char *extName = TextDatumGetCString(textDatums[i]);
231  Oid extOid = get_extension_oid(extName, false);
232 
233  requiredExtensions = lappend_oid(requiredExtensions, extOid);
234  }
235  }
236 
238  GetUserId(),
239  get_namespace_oid(text_to_cstring(schemaName), false),
240  relocatable,
241  text_to_cstring(extVersion),
242  extConfig,
243  extCondition,
244  requiredExtensions);
245 
246  PG_RETURN_VOID();
247 }
248 
249 Datum
251 {
252  bool record_init_privs = PG_GETARG_BOOL(0);
253 
255  binary_upgrade_record_init_privs = record_init_privs;
256 
257  PG_RETURN_VOID();
258 }
259 
260 Datum
262 {
263  Oid table_id = PG_GETARG_OID(0);
266  char *cattname = text_to_cstring(attname);
267  char *cvalue = text_to_cstring(value);
268 
270  SetAttrMissing(table_id, cattname, cvalue);
271 
272  PG_RETURN_VOID();
273 }
274 
275 /*
276  * Verify the given slot has already consumed all the WAL changes.
277  *
278  * Returns true if there are no decodable WAL records after the
279  * confirmed_flush_lsn. Otherwise false.
280  *
281  * This is a special purpose function to ensure that the given slot can be
282  * upgraded without data loss.
283  */
284 Datum
286 {
287  Name slot_name;
288  XLogRecPtr end_of_wal;
289  bool found_pending_wal;
290 
292 
293  /*
294  * Binary upgrades only allowed super-user connections so we must have
295  * permission to use replication slots.
296  */
298 
299  slot_name = PG_GETARG_NAME(0);
300 
301  /* Acquire the given slot */
302  ReplicationSlotAcquire(NameStr(*slot_name), true);
303 
305 
306  /* Slots must be valid as otherwise we won't be able to scan the WAL */
308 
309  end_of_wal = GetFlushRecPtr(NULL);
310  found_pending_wal = LogicalReplicationSlotHasPendingWal(end_of_wal);
311 
312  /* Clean up */
314 
315  PG_RETURN_BOOL(!found_pending_wal);
316 }
317 
318 /*
319  * binary_upgrade_add_sub_rel_state
320  *
321  * Add the relation with the specified relation state to pg_subscription_rel
322  * catalog.
323  */
324 Datum
326 {
327  Relation subrel;
328  Relation rel;
329  Oid subid;
330  char *subname;
331  Oid relid;
332  char relstate;
333  XLogRecPtr sublsn;
334 
336 
337  /* We must check these things before dereferencing the arguments */
338  if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2))
339  elog(ERROR, "null argument to binary_upgrade_add_sub_rel_state is not allowed");
340 
342  relid = PG_GETARG_OID(1);
343  relstate = PG_GETARG_CHAR(2);
344  sublsn = PG_ARGISNULL(3) ? InvalidXLogRecPtr : PG_GETARG_LSN(3);
345 
346  subrel = table_open(SubscriptionRelationId, RowExclusiveLock);
347  subid = get_subscription_oid(subname, false);
348  rel = relation_open(relid, AccessShareLock);
349 
350  /*
351  * Since there are no concurrent ALTER/DROP SUBSCRIPTION commands during
352  * the upgrade process, and the apply worker (which builds cache based on
353  * the subscription catalog) is not running, the locks can be released
354  * immediately.
355  */
356  AddSubscriptionRelState(subid, relid, relstate, sublsn, false);
358  table_close(subrel, RowExclusiveLock);
359 
360  PG_RETURN_VOID();
361 }
362 
363 /*
364  * binary_upgrade_replorigin_advance
365  *
366  * Update the remote_lsn for the subscriber's replication origin.
367  */
368 Datum
370 {
371  Relation rel;
372  Oid subid;
373  char *subname;
374  char originname[NAMEDATALEN];
375  RepOriginId node;
376  XLogRecPtr remote_commit;
377 
379 
380  /*
381  * We must ensure a non-NULL subscription name before dereferencing the
382  * arguments.
383  */
384  if (PG_ARGISNULL(0))
385  elog(ERROR, "null argument to binary_upgrade_replorigin_advance is not allowed");
386 
388  remote_commit = PG_ARGISNULL(1) ? InvalidXLogRecPtr : PG_GETARG_LSN(1);
389 
390  rel = table_open(SubscriptionRelationId, RowExclusiveLock);
391  subid = get_subscription_oid(subname, false);
392 
393  ReplicationOriginNameForLogicalRep(subid, InvalidOid, originname, sizeof(originname));
394 
395  /* Lock to prevent the replication origin from vanishing */
396  LockRelationOid(ReplicationOriginRelationId, RowExclusiveLock);
397  node = replorigin_by_name(originname, false);
398 
399  /*
400  * The server will be stopped after setting up the objects in the new
401  * cluster and the origins will be flushed during the shutdown checkpoint.
402  * This will ensure that the latest LSN values for origin will be
403  * available after the upgrade.
404  */
405  replorigin_advance(node, remote_commit, InvalidXLogRecPtr,
406  false /* backward */ ,
407  false /* WAL log */ );
408 
409  UnlockRelationOid(ReplicationOriginRelationId, RowExclusiveLock);
411 
412  PG_RETURN_VOID();
413 }
bool binary_upgrade_record_init_privs
Definition: aclchk.c:109
#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:3678
Oid binary_upgrade_next_pg_tablespace_oid
Definition: tablespace.c:87
Oid binary_upgrade_next_pg_authid_oid
Definition: user.c:70
void ReplicationOriginNameForLogicalRep(Oid suboid, Oid relid, char *originname, Size szoriginname)
Definition: worker.c:428
#define TextDatumGetCString(d)
Definition: builtins.h:98
#define NameStr(name)
Definition: c.h:746
#define Assert(condition)
Definition: c.h:858
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
ObjectAddress InsertExtensionTuple(const char *extName, Oid extOwner, Oid schemaOid, bool relocatable, const char *extVersion, Datum extConfig, Datum extCondition, List *requiredExtensions)
Definition: extension.c:1866
Oid get_extension_oid(const char *extname, bool missing_ok)
Definition: extension.c:145
#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:2005
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 @155 value
int i
Definition: isn.c:73
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:227
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:108
#define AccessShareLock
Definition: lockdefs.h:36
#define RowExclusiveLock
Definition: lockdefs.h:38
bool LogicalReplicationSlotHasPendingWal(XLogRecPtr end_of_wal)
Definition: logical.c:1978
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:3520
RepOriginId replorigin_by_name(const char *roname, bool missing_ok)
Definition: origin.c:221
void replorigin_advance(RepOriginId node, XLogRecPtr remote_commit, XLogRecPtr local_commit, bool go_backward, bool wal_log)
Definition: origin.c:888
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:49
#define SlotIsLogical(slot)
Definition: slot.h:210
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:96
ReplicationSlotPersistentData data
Definition: slot.h:178
Definition: c.h:741
Definition: c.h:687
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
char * text_to_cstring(const text *t)
Definition: varlena.c:217
XLogRecPtr GetFlushRecPtr(TimeLineID *insertTLI)
Definition: xlog.c:6455
uint16 RepOriginId
Definition: xlogdefs.h:65
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28