diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml index 42e94971741..2caa84a1253 100644 --- a/doc/src/sgml/protocol.sgml +++ b/doc/src/sgml/protocol.sgml @@ -1434,7 +1434,7 @@ The commands accepted in walsender mode are: - CREATE_REPLICATION_SLOT slot_name { PHYSICAL | LOGICAL output_plugin } + CREATE_REPLICATION_SLOT slot_name { PHYSICAL [ RESERVE_WAL ] | LOGICAL output_plugin } CREATE_REPLICATION_SLOT @@ -1463,6 +1463,17 @@ The commands accepted in walsender mode are: + + + RESERVE_WAL + + + Specify that this physical replication reserves WAL + immediately; otherwise WAL is only reserved upon + connection from a streaming replication client. + + + diff --git a/src/backend/replication/repl_gram.y b/src/backend/replication/repl_gram.y index e9177ca0db6..1b753644223 100644 --- a/src/backend/replication/repl_gram.y +++ b/src/backend/replication/repl_gram.y @@ -76,6 +76,7 @@ Node *replication_parse_result; %token K_PHYSICAL %token K_LOGICAL %token K_SLOT +%token K_RESERVE_WAL %type command %type base_backup start_replication start_logical_replication @@ -88,6 +89,7 @@ Node *replication_parse_result; %type plugin_opt_elem %type plugin_opt_arg %type opt_slot +%type opt_reserve_wal %% @@ -181,13 +183,14 @@ base_backup_opt: ; create_replication_slot: - /* CREATE_REPLICATION_SLOT slot PHYSICAL */ - K_CREATE_REPLICATION_SLOT IDENT K_PHYSICAL + /* CREATE_REPLICATION_SLOT slot PHYSICAL RESERVE_WAL */ + K_CREATE_REPLICATION_SLOT IDENT K_PHYSICAL opt_reserve_wal { CreateReplicationSlotCmd *cmd; cmd = makeNode(CreateReplicationSlotCmd); cmd->kind = REPLICATION_KIND_PHYSICAL; cmd->slotname = $2; + cmd->reserve_wal = $4; $$ = (Node *) cmd; } /* CREATE_REPLICATION_SLOT slot LOGICAL plugin */ @@ -268,6 +271,11 @@ opt_physical: | /* EMPTY */ ; +opt_reserve_wal: + K_RESERVE_WAL { $$ = true; } + | /* EMPTY */ { $$ = false; } + ; + opt_slot: K_SLOT IDENT { $$ = $2; } diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l index 91bac21b06b..126e7d90640 100644 --- a/src/backend/replication/repl_scanner.l +++ b/src/backend/replication/repl_scanner.l @@ -95,6 +95,7 @@ CREATE_REPLICATION_SLOT { return K_CREATE_REPLICATION_SLOT; } DROP_REPLICATION_SLOT { return K_DROP_REPLICATION_SLOT; } TIMELINE_HISTORY { return K_TIMELINE_HISTORY; } PHYSICAL { return K_PHYSICAL; } +RESERVE_WAL { return K_RESERVE_WAL; } LOGICAL { return K_LOGICAL; } SLOT { return K_SLOT; } diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 27de156b1ff..c95fe75a721 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -826,6 +826,14 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) ReplicationSlotPersist(); } + else if (cmd->kind == REPLICATION_KIND_PHYSICAL && cmd->reserve_wal) + { + ReplicationSlotReserveWal(); + + /* Write this slot to disk */ + ReplicationSlotMarkDirty(); + ReplicationSlotSave(); + } slot_name = NameStr(MyReplicationSlot->data.name); snprintf(xpos, sizeof(xpos), "%X/%X", diff --git a/src/include/nodes/replnodes.h b/src/include/nodes/replnodes.h index cac64198508..4e35be6a286 100644 --- a/src/include/nodes/replnodes.h +++ b/src/include/nodes/replnodes.h @@ -55,6 +55,7 @@ typedef struct CreateReplicationSlotCmd char *slotname; ReplicationKind kind; char *plugin; + bool reserve_wal; } CreateReplicationSlotCmd;