|
11 | 11 |
|
12 | 12 | #include "postgres.h"
|
13 | 13 |
|
| 14 | +#include "access/relation.h" |
| 15 | +#include "access/table.h" |
14 | 16 | #include "catalog/binary_upgrade.h"
|
15 | 17 | #include "catalog/heap.h"
|
16 | 18 | #include "catalog/namespace.h"
|
| 19 | +#include "catalog/pg_subscription_rel.h" |
17 | 20 | #include "catalog/pg_type.h"
|
18 | 21 | #include "commands/extension.h"
|
19 | 22 | #include "miscadmin.h"
|
20 | 23 | #include "replication/logical.h"
|
| 24 | +#include "replication/origin.h" |
| 25 | +#include "replication/worker_internal.h" |
| 26 | +#include "storage/lmgr.h" |
21 | 27 | #include "utils/array.h"
|
22 | 28 | #include "utils/builtins.h"
|
| 29 | +#include "utils/lsyscache.h" |
| 30 | +#include "utils/pg_lsn.h" |
| 31 | +#include "utils/syscache.h" |
23 | 32 |
|
24 | 33 |
|
25 | 34 | #define CHECK_IS_BINARY_UPGRADE \
|
@@ -305,3 +314,100 @@ binary_upgrade_logical_slot_has_caught_up(PG_FUNCTION_ARGS)
|
305 | 314 |
|
306 | 315 | PG_RETURN_BOOL(!found_pending_wal);
|
307 | 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 |
| 325 | +binary_upgrade_add_sub_rel_state(PG_FUNCTION_ARGS) |
| 326 | +{ |
| 327 | + Relation subrel; |
| 328 | + Relation rel; |
| 329 | + Oid subid; |
| 330 | + char *subname; |
| 331 | + Oid relid; |
| 332 | + char relstate; |
| 333 | + XLogRecPtr sublsn; |
| 334 | + |
| 335 | + CHECK_IS_BINARY_UPGRADE; |
| 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 | + |
| 341 | + subname = text_to_cstring(PG_GETARG_TEXT_PP(0)); |
| 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); |
| 357 | + relation_close(rel, AccessShareLock); |
| 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 |
| 369 | +binary_upgrade_replorigin_advance(PG_FUNCTION_ARGS) |
| 370 | +{ |
| 371 | + Relation rel; |
| 372 | + Oid subid; |
| 373 | + char *subname; |
| 374 | + char originname[NAMEDATALEN]; |
| 375 | + RepOriginId node; |
| 376 | + XLogRecPtr remote_commit; |
| 377 | + |
| 378 | + CHECK_IS_BINARY_UPGRADE; |
| 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 | + |
| 387 | + subname = text_to_cstring(PG_GETARG_TEXT_PP(0)); |
| 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); |
| 410 | + table_close(rel, RowExclusiveLock); |
| 411 | + |
| 412 | + PG_RETURN_VOID(); |
| 413 | +} |
0 commit comments