postgres sink: a batch is dropped, not retried, when PostgreSQL ends the session (SQLSTATE 57P01/57P02)

Abierto Apto para principiantes
#26,565 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
78/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
postgresql, rust
Área
databases

Línea de trabajo

Empieza en src/sinks/postgres/config.rs, en PostgresRetryLogic::is_retriable_error, que hoy solo reconoce sqlx::Error::Io y PoolTimedOut. Extiende el match para que los errores de sqlx::Error::Database con clase SQLSTATE 08 y códigos 57P01/57P02/57P03 (y opcionalmente 40001/40P01) sean reintentables, y luego añade un test unitario que verifique la clasificación de cada código. Se considera terminado cuando un error de terminación de sesión provoca un reintento en lugar de la línea de registro Non-retriable error; dropping the request, y los tests de reintento existentes siguen pasando.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Version

vector 0.58.0 (x86_64-unknown-linux-musl 2bcad9b 2026-08-26), postgres sink with a disk buffer (batch.max_events: 1000, request.concurrency: 1), PostgreSQL 18.6.

Problem

If PostgreSQL terminates the sink's session while an insert is running, the whole batch is dropped as a non-retriable error. This happens on a fast shutdown of the database (57P01 admin_shutdown), on the crash of any other backend (57P02 crash_shutdown), or on pg_terminate_backend. The disk buffer has already handed the batch to the sink, so it is lost even though the buffer is durable. The next request then fails on DNS or connection errors while the database is down, and those are retried, so everything after the dropped batch is delivered.

Observed when stopping the database container while ingesting 1,000 events/s (one batch exactly missing afterwards, 1,000 events):

ERROR sink{component_kind="sink" component_id=timescaledb component_type=postgres}:request{request_id=665}: vector::sinks::util::retries: Non-retriable error; dropping the request. error=Database error: error returned from database: terminating connection due to administrator command
ERROR ... vector_common::internal_event::service: Service call failed. No retries or retries exhausted. error=Some(Postgres { source: Database(PgDatabaseError { severity: Fatal, code: "57P01", message: "terminating connection due to administrator command", ... routine: Some("ProcessInterrupts") }) }) request_id=665 error_type="request_failed" stage="sending"
ERROR ... vector_common::internal_event::component_events_dropped: Events dropped intentional=false count=1000 reason="Service call failed. No retries or retries exhausted."
WARN  ... request{request_id=666}: vector::sinks::util::retries: Retrying after error. error=Database error: error communicating with database: failed to lookup address information: Try again

Cause

src/sinks/postgres/config.rs, PostgresRetryLogic::is_retriable_error, only matches sqlx::Error::Io(_) | sqlx::Error::PoolTimedOut. Any sqlx::Error::Database, including session-termination errors, is treated as permanent.

Proposal

Treat these SQLSTATEs as retriable:

  • class 08 (connection exception);
  • 57P01, 57P02 and 57P03 (admin_shutdown, crash_shutdown, cannot_connect_now);
  • optionally 40001 and 40P01 (serialization failure, deadlock).

This is no less safe than the Io case already retried. An Io error can arrive after the server committed, so an Io retry can duplicate rows. A 57P0x raised while the statement runs means the transaction was rolled back, so a retry cannot duplicate anything.

Lenguaje dominante
Rust
Estrellas
22.8k
Forks
2.4k
Merge medio
1 d 13 h
PR fusionados (30 d)
273

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de vectordotdev/vector

Todos los issues de vectordotdev/vector

Issues similares

Más issues de Rust

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.