* Execute an incoming replication command. * * Returns true if the cmd_string was recognized as WalSender command, false * if not. */
| 1556 | * if not. |
| 1557 | */ |
| 1558 | bool |
| 1559 | exec_replication_command(const char *cmd_string) |
| 1560 | { |
| 1561 | int parse_rc; |
| 1562 | Node *cmd_node; |
| 1563 | const char *cmdtag; |
| 1564 | MemoryContext cmd_context; |
| 1565 | MemoryContext old_context; |
| 1566 | |
| 1567 | /* |
| 1568 | * If WAL sender has been told that shutdown is getting close, switch its |
| 1569 | * status accordingly to handle the next replication commands correctly. |
| 1570 | */ |
| 1571 | if (got_STOPPING) |
| 1572 | WalSndSetState(WALSNDSTATE_STOPPING); |
| 1573 | |
| 1574 | /* |
| 1575 | * Throw error if in stopping mode. We need prevent commands that could |
| 1576 | * generate WAL while the shutdown checkpoint is being written. To be |
| 1577 | * safe, we just prohibit all new commands. |
| 1578 | */ |
| 1579 | if (MyWalSnd->state == WALSNDSTATE_STOPPING) |
| 1580 | ereport(ERROR, |
| 1581 | (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), |
| 1582 | errmsg("cannot execute new commands while WAL sender is in stopping mode"))); |
| 1583 | |
| 1584 | /* |
| 1585 | * CREATE_REPLICATION_SLOT ... LOGICAL exports a snapshot until the next |
| 1586 | * command arrives. Clean up the old stuff if there's anything. |
| 1587 | */ |
| 1588 | SnapBuildClearExportedSnapshot(); |
| 1589 | |
| 1590 | CHECK_FOR_INTERRUPTS(); |
| 1591 | |
| 1592 | /* |
| 1593 | * Prepare to parse and execute the command. |
| 1594 | */ |
| 1595 | cmd_context = AllocSetContextCreate(CurrentMemoryContext, |
| 1596 | "Replication command context", |
| 1597 | ALLOCSET_DEFAULT_SIZES); |
| 1598 | old_context = MemoryContextSwitchTo(cmd_context); |
| 1599 | |
| 1600 | replication_scanner_init(cmd_string); |
| 1601 | |
| 1602 | /* |
| 1603 | * Is it a WalSender command? |
| 1604 | */ |
| 1605 | if (!replication_scanner_is_replication_command()) |
| 1606 | { |
| 1607 | /* Nope; clean up and get out. */ |
| 1608 | replication_scanner_finish(); |
| 1609 | |
| 1610 | MemoryContextSwitchTo(old_context); |
| 1611 | MemoryContextDelete(cmd_context); |
| 1612 | |
| 1613 | /* XXX this is a pretty random place to make this check */ |
| 1614 | if (MyDatabaseId == InvalidOid) |
| 1615 | ereport(ERROR, |
no test coverage detected