B. PostgreSQL commit с потерянным ACK¶
Тип материала: учебный архитектурный сценарий. Не описывает систему конкретной компании. Все операции, IDs и числа ниже — HYPOTHETICAL.
Проверка источников: 2026-11-02. Интеграционный fault test этого сценария — NOT_RUN; documented behavior и предлагаемый recovery не считаются выполненным испытанием.
Normal flow¶
Клиент отправляет операцию с устойчивым operation_id, а PG 17 атомарно сохраняет request hash, проводки и ответ. Суммы — minor units. Для локальной durability предполагаются корректные fsync/WAL и synchronous_commit; failover durability задаётся отдельно. Успех сервера и получение success клиентом — разные события.
Иллюстративная схема нормального пути:
flowchart LR
C[Stable command ID] --> D[Authoritative transaction]
D --> P[Postings and saved response]
P --> A[Client receives ACK]
Failure timeline¶
sequenceDiagram
participant C as Client
participant D as PostgreSQL
C->>D: Command op1
D->>D: Durable COMMIT op1
D--xC: ACK lost
Note over C: Timeout means UNKNOWN
C->>D: Retry same op1 and hash
D-->>C: Original committed response
Состояние систем после отказа¶
| Участник | Durable состояние | Неопределённость / проверка |
|---|---|---|
| PostgreSQL | Может быть committed op1 | Обрыв возможен и до commit: нужен lookup/guard |
| Client | Не получил ответ | Нельзя считать failed или создавать op2 |
| External systems | Могли увидеть outbox event | Сверить по op1 после failover |
Retry и replay¶
Новый request использует тот же ID и payload. Если первая transaction ещё исполняется, retry может ждать unique key/row lock; отсутствие строки в раннем SELECT не разрешает обойти constraint. Читать только async replica опасно: она может ещё не видеть committed op1.
Обнаружение проблемы¶
Рост ambiguous responses, client retries и unique conflicts, долгие sessions/locks, несовпадение client status и authoritative operation table. После promotion нужен анализ WAL gap: stale standby может потерять подтверждённую запись.
Recovery protocol¶
- Назначить operation статус unresolved, сохранить request evidence.
- Читать authoritative DB и повторять ту же guarded команду, ограничивая deadline.
- Вернуть сохранённый ответ, если identity/hash совпадают; конфликт изолировать.
- Если failover изменил durable history, сверить provider/ledger/outbox evidence до нового эффекта.
- Не проводить компенсацию только потому, что клиент получил timeout.
Гарантии и trade-offs¶
Unique operation record и effect в одной transaction обеспечивают единственный результат при сохранной DB history. ACK uncertainty устраняется lookup/retry protocol, а не transport retries сами по себе. Не проверены реальные сетевые drops, PG failover и synchronous replication. Дополнительные lookups и unresolved workflow увеличивают latency.
Практическая проверка¶
PG concurrency lab задаёт independent sessions. Для lost ACK требуется test proxy/failpoint, который обрывает именно ответ после durable evidence; произвольный kill client не доказывает, где был commit.
Источники и версии¶
- PostgreSQL asynchronous commit — 17.
- PostgreSQL isolation — 17.
- PostgreSQL standby — 17.