Situação: Tabela com linhas corrompidas.
Como identificar: Erro ao realizar o dump, select, delete na tabela.
O problema é que quando isto ocorre o PostgreSQL informa que existe um erro e referencia o 'toast value', o que não é nada concreto para uma remoção por DELETE convencional.
Exemplo:
ERROR: missing chunk number 0 for toast value 16983210 in pg_toast_939217
1532317
Então primeiro temos que identificar quais linhas desta tabela estão corrompidas, dai se utiliza o comando na console:
for ((i=0; i<TOTALROWS; i++ )); do psql -U postgres mydb -c "SELECT * FROM public.mytable LIMIT 1 offset $i" >/dev/null || echo $i; done
TOTALROWS: Altere o TOTALROWS pelo número total de linhas da tabelas depois de executar um ANALYZE.
postgres: Role que executará a query, no caso o 'postgres'
mydb: Sua database
mytable: A tabela alvo
Este comando varrerá a tabela linha a linha e pelo retorno você saberá quais linhas estão danificadas, segue exemplo de saída:
ERROR: missing chunk number 0 for toast value 1269808 in pg_toast_93917
162558
ERROR: missing chunk number 0 for toast value 1269810 in pg_toast_93917
162559
No caso acima sabemos agora que as linhas 162558 e 162559 estão corrompidas.
Um DELETE não funcionará, não se iluda. Primeiro é necessário obter o CTID das linhas, pra quem quer ai vai a explicação do que é o CTID: http://www.postgresql.org/docs/8.4/static/datatype-oid.html
Então o próximo passo é obter este valor para ai sim fazer o DELETE, mas sugiro antes fazer um backup da tabela sem as linhas corrompidas:
CREATE TABLE mytable_bkp1 AS SELECT * FROM mytable LIMIT 162558;
CREATE TABLE mytable_bkp2 AS SELECT * FROM mytable OFFSET 162559;
Agora vamos ao CID:
SELECT CTID FROM mytable LIMIT 2 OFFSET 162558;
Agora sim, vamos remover as crianças e salvar o mundo:
DELETE FROM mytable WHERE CTID IN(SELECT CTID FROM mytable LIMIT 2 OFFSET 162558);
Tabela salva, todo mundo feliz. E sim, você perdeu as linhas deletadas!
E quando o erro parece ser causado apenas quando uma coluna específica está envolvida no comando SQL, alguma sugestão?
ResponderExcluirExemplo: Select * from tabela -> QL Error [XX000]: ERROR: missing chunk number 0 for toast value 184711 in pg_toast_2619
Ai fui testando coluna por coluna no select: Select column1 from tabela, e etc..
apenas quando uma coluna específica está envolvida que apresenta erro (para qualquer linha)