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-2023, PostgreSQL Global Development Group
9  * src/backend/utils/adt/pg_upgrade_support.c
10  */
11 
12 #include "postgres.h"
13 
14 #include "catalog/binary_upgrade.h"
15 #include "catalog/heap.h"
16 #include "catalog/namespace.h"
17 #include "catalog/pg_type.h"
18 #include "commands/extension.h"
19 #include "miscadmin.h"
20 #include "replication/logical.h"
21 #include "utils/array.h"
22 #include "utils/builtins.h"
23 
24 
25 #define CHECK_IS_BINARY_UPGRADE \
26 do { \
27  if (!IsBinaryUpgrade) \
28  ereport(ERROR, \
29  (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM), \
30  errmsg("function can only be called when server is in binary upgrade mode"))); \
31 } while (0)
32 
33 Datum
35 {
36  Oid tbspoid = PG_GETARG_OID(0);
37 
40 
42 }
43 
44 Datum
46 {
47  Oid typoid = PG_GETARG_OID(0);
48 
51 
53 }
54 
55 Datum
57 {
58  Oid typoid = PG_GETARG_OID(0);
59 
62 
64 }
65 
66 Datum
68 {
69  Oid typoid = PG_GETARG_OID(0);
70 
73 
75 }
76 
77 Datum
79 {
80  Oid typoid = PG_GETARG_OID(0);
81 
84 
86 }
87 
88 Datum
90 {
91  Oid reloid = PG_GETARG_OID(0);
92 
95 
97 }
98 
99 Datum
101 {
102  RelFileNumber relfilenumber = PG_GETARG_OID(0);
103 
106 
107  PG_RETURN_VOID();
108 }
109 
110 Datum
112 {
113  Oid reloid = PG_GETARG_OID(0);
114 
117 
118  PG_RETURN_VOID();
119 }
120 
121 Datum
123 {
124  RelFileNumber relfilenumber = PG_GETARG_OID(0);
125 
128 
129  PG_RETURN_VOID();
130 }
131 
132 Datum
134 {
135  Oid reloid = PG_GETARG_OID(0);
136 
139 
140  PG_RETURN_VOID();
141 }
142 
143 Datum
145 {
146  RelFileNumber relfilenumber = PG_GETARG_OID(0);
147 
150 
151  PG_RETURN_VOID();
152 }
153 
154 Datum
156 {
157  Oid enumoid = PG_GETARG_OID(0);
158 
161 
162  PG_RETURN_VOID();
163 }
164 
165 Datum
167 {
168  Oid authoid = PG_GETARG_OID(0);
169 
172  PG_RETURN_VOID();
173 }
174 
175 Datum
177 {
178  text *extName;
179  text *schemaName;
180  bool relocatable;
181  text *extVersion;
182  Datum extConfig;
183  Datum extCondition;
184  List *requiredExtensions;
185 
187 
188  /* We must check these things before dereferencing the arguments */
189  if (PG_ARGISNULL(0) ||
190  PG_ARGISNULL(1) ||
191  PG_ARGISNULL(2) ||
192  PG_ARGISNULL(3))
193  elog(ERROR, "null argument to binary_upgrade_create_empty_extension is not allowed");
194 
195  extName = PG_GETARG_TEXT_PP(0);
196  schemaName = PG_GETARG_TEXT_PP(1);
197  relocatable = PG_GETARG_BOOL(2);
198  extVersion = PG_GETARG_TEXT_PP(3);
199 
200  if (PG_ARGISNULL(4))
201  extConfig = PointerGetDatum(NULL);
202  else
203  extConfig = PG_GETARG_DATUM(4);
204 
205  if (PG_ARGISNULL(5))
206  extCondition = PointerGetDatum(NULL);
207  else
208  extCondition = PG_GETARG_DATUM(5);
209 
210  requiredExtensions = NIL;
211  if (!PG_ARGISNULL(6))
212  {
213  ArrayType *textArray = PG_GETARG_ARRAYTYPE_P(6);
214  Datum *textDatums;
215  int ndatums;
216  int i;
217 
218  deconstruct_array_builtin(textArray, TEXTOID, &textDatums, NULL, &ndatums);
219  for (i = 0; i < ndatums; i++)
220  {
221  char *extName = TextDatumGetCString(textDatums[i]);
222  Oid extOid = get_extension_oid(extName, false);
223 
224  requiredExtensions = lappend_oid(requiredExtensions, extOid);
225  }
226  }
227 
229  GetUserId(),
230  get_namespace_oid(text_to_cstring(schemaName), false),
231  relocatable,
232  text_to_cstring(extVersion),
233  extConfig,
234  extCondition,
235  requiredExtensions);
236 
237  PG_RETURN_VOID();
238 }
239 
240 Datum
242 {
243  bool record_init_privs = PG_GETARG_BOOL(0);
244 
246  binary_upgrade_record_init_privs = record_init_privs;
247 
248  PG_RETURN_VOID();
249 }
250 
251 Datum
253 {
254  Oid table_id = PG_GETARG_OID(0);
257  char *cattname = text_to_cstring(attname);
258  char *cvalue = text_to_cstring(value);
259 
261  SetAttrMissing(table_id, cattname, cvalue);
262 
263  PG_RETURN_VOID();
264 }
265 
266 /*
267  * Verify the given slot has already consumed all the WAL changes.
268  *
269  * Returns true if there are no decodable WAL records after the
270  * confirmed_flush_lsn. Otherwise false.
271  *
272  * This is a special purpose function to ensure that the given slot can be
273  * upgraded without data loss.
274  */
275 Datum
277 {
278  Name slot_name;
279  XLogRecPtr end_of_wal;
280  bool found_pending_wal;
281 
283 
284  /* We must check before dereferencing the argument */
285  if (PG_ARGISNULL(0))
286  elog(ERROR, "null argument to binary_upgrade_validate_wal_records is not allowed");
287 
289 
290  slot_name = PG_GETARG_NAME(0);
291 
292  /* Acquire the given slot */
293  ReplicationSlotAcquire(NameStr(*slot_name), true);
294 
296 
297  /* Slots must be valid as otherwise we won't be able to scan the WAL */
299 
300  end_of_wal = GetFlushRecPtr(NULL);
301  found_pending_wal = LogicalReplicationSlotHasPendingWal(end_of_wal);
302 
303  /* Clean up */
305 
306  PG_RETURN_BOOL(!found_pending_wal);
307 }
bool binary_upgrade_record_init_privs
Definition: aclchk.c:126
#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:3679
Oid binary_upgrade_next_pg_tablespace_oid
Definition: tablespace.c:93
Oid binary_upgrade_next_pg_authid_oid
Definition: user.c:71
#define TextDatumGetCString(d)
Definition: builtins.h:95
#define NameStr(name)
Definition: c.h:735
#define ERROR
Definition: elog.h:39
ObjectAddress InsertExtensionTuple(const char *extName, Oid extOwner, Oid schemaOid, bool relocatable, const char *extVersion, Datum extConfig, Datum extCondition, List *requiredExtensions)
Definition: extension.c:1865
Oid get_extension_oid(const char *extname, bool missing_ok)
Definition: extension.c:144
#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_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:1990
RelFileNumber binary_upgrade_next_heap_pg_class_relfilenumber
Definition: heap.c:81
RelFileNumber binary_upgrade_next_toast_pg_class_relfilenumber
Definition: heap.c:82
Oid binary_upgrade_next_toast_pg_class_oid
Definition: heap.c:80
Oid binary_upgrade_next_heap_pg_class_oid
Definition: heap.c:79
RelFileNumber binary_upgrade_next_index_pg_class_relfilenumber
Definition: index.c:90
Oid binary_upgrade_next_index_pg_class_oid
Definition: index.c:89
static struct @148 value
int i
Definition: isn.c:73
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend_oid(List *list, Oid datum)
Definition: list.c:374
bool LogicalReplicationSlotHasPendingWal(XLogRecPtr end_of_wal)
Definition: logical.c:1961
Oid GetUserId(void)
Definition: miscinit.c:508
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3502
NameData attname
Definition: pg_attribute.h:41
Oid binary_upgrade_next_pg_enum_oid
Definition: pg_enum.c:36
#define NIL
Definition: pg_list.h:68
Oid binary_upgrade_next_pg_type_oid
Definition: pg_type.c:42
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_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_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
unsigned int Oid
Definition: postgres_ext.h:31
Oid RelFileNumber
Definition: relpath.h:25
void ReplicationSlotAcquire(const char *name, bool nowait)
Definition: slot.c:452
ReplicationSlot * MyReplicationSlot
Definition: slot.c:99
void CheckSlotPermissions(void)
Definition: slot.c:1188
void ReplicationSlotRelease(void)
Definition: slot.c:559
@ RS_INVAL_NONE
Definition: slot.h:46
#define SlotIsLogical(slot)
Definition: slot.h:191
Definition: pg_list.h:54
ReplicationSlotInvalidationCause invalidated
Definition: slot.h:91
ReplicationSlotPersistentData data
Definition: slot.h:162
Definition: c.h:730
Definition: c.h:676
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:6202
uint64 XLogRecPtr
Definition: xlogdefs.h:21