Eu tenho uma instância de desenvolvedor Docker PostgreSQL (TimescaleDB) com um mapeamento de volume local do Linux.
version: '3'
services:
dex-timeseriesdb:
image: timescale/timescaledb:latest-pg12
# https://stackoverflow.com/a/56754077/315168
shm_size: 1g
container_name: dex-timeseriesdb
environment:
POSTGRES_USER: postgres
volumes:
- $PWD/data/postgresql:/var/lib/postgresql/data
Após o desligamento não limpo, a instância não inicia mais com FATAL: xlog flush request 0/2CEFA910 is not satisfied --- flushed only to 0/1B48258
erro:
dex-timeseriesdb |
dex-timeseriesdb | PostgreSQL Database directory appears to contain a database; Skipping initialization
dex-timeseriesdb |
dex-timeseriesdb | 2021-06-13 18:50:47.330 UTC [1] LOG: starting PostgreSQL 12.6 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.2.1_pre1) 10.2.1 20201203, 64-bit
dex-timeseriesdb | 2021-06-13 18:50:47.330 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
dex-timeseriesdb | 2021-06-13 18:50:47.330 UTC [1] LOG: listening on IPv6 address "::", port 5432
dex-timeseriesdb | 2021-06-13 18:50:47.336 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
dex-timeseriesdb | 2021-06-13 18:50:47.486 UTC [21] LOG: database system shutdown was interrupted; last known up at 2021-06-13 18:47:35 UTC
dex-timeseriesdb | 2021-06-13 18:50:49.629 UTC [21] LOG: database system was not properly shut down; automatic recovery in progress
dex-timeseriesdb | 2021-06-13 18:50:49.645 UTC [21] LOG: redo starts at 0/1B46C68
dex-timeseriesdb | 2021-06-13 18:50:49.648 UTC [21] LOG: invalid record length at 0/1B48258: wanted 24, got 0
dex-timeseriesdb | 2021-06-13 18:50:49.648 UTC [21] LOG: redo done at 0/1B48220
dex-timeseriesdb | 2021-06-13 18:50:49.697 UTC [21] LOG: request to flush past end of generated WAL; request 0/2CEFA910, currpos 0/1B48258
dex-timeseriesdb | 2021-06-13 18:50:49.697 UTC [21] CONTEXT: writing block 0 of relation base/13455/16573_vm
dex-timeseriesdb | 2021-06-13 18:50:49.697 UTC [21] FATAL: xlog flush request 0/2CEFA910 is not satisfied --- flushed only to 0/1B48258
dex-timeseriesdb | 2021-06-13 18:50:49.697 UTC [21] CONTEXT: writing block 0 of relation base/13455/16573_vm
dex-timeseriesdb | 2021-06-13 18:50:49.701 UTC [1] LOG: startup process (PID 21) exited with exit code 1
dex-timeseriesdb | 2021-06-13 18:50:49.701 UTC [1] LOG: aborting startup due to startup process failure
dex-timeseriesdb | 2021-06-13 18:50:49.744 UTC [1] LOG: database system is shut down
Provavelmente, isso é corrupção de dados devido ao desligamento não limpo do Docker.
Não há nada importante no banco de dados. No entanto, ainda gostaria de saber se é possível recuperar o banco de dados em situações como essa, em vez de reconstruí-lo do zero ou restaurar a partir de um backup.
Eu testei que o mapeamento de volume é gravável dentro da instância do Docker usando shell, então isso não deve ser um problema.
Veja também pergunta semelhante sobre FATAL: solicitação de liberação de xlog, mas erro um pouco diferente .
De acordo com o log fornecido, o problema está relacionado ao arquivo de dados corrompido - o que pode ser causado pelo desligamento incorreto. Um dos arquivos de dados foi corrompido.
A localização do arquivo deve ser
$PGDATA/base/13455/16573_vm
Ação recomendada:
Em primeiro lugar, é importante ter em mente que este erro é sobre as páginas gravadas no diretório de dados, não sobre o fluxo WAL. Isso significa que o objetivo principal aqui, se os dados de uma tabela forem realmente perdidos, é obter uma cópia dos dados do fluxo WAL.
Antes de entrarmos em detalhes sobre como fazer isso, vamos primeiro descobrir qual tabela ou índice é afetado.
Na mensagem de log
invalid page in block 0 of relation base/13455/16573_vm
obtemos as seguintes informações:Isso significa que podemos encontrar a tabela afetada primeiro fazendo o seguinte para localizar o banco de dados correto:
E, em seguida, conectando-se a esse banco de dados e executando o seguinte, o que nos fornece a tabela ou índice afetado:
Se o objeto de banco de dados afetado for um índice, é uma sorte para você - você pode apenas reconstruir o índice para corrigir tudo.
Se o objeto de banco de dados afetado for uma tabela - azar - as opções disponíveis são: