LINUX.ORG.RU

Прошу помощи в починке базы PostgreSQL

 ,


1

1

Нужна помощь специалистов. Сам не силен в постгри.

Исходные данные - база engine виртуальной машины HostedEngine гипервизора Ovirt.
Предыстория - была проблема с фс и покорежилась база.
ФС починил, сделал полную реиндексацию стандартными средствами (reindexdb -a)
и в общем и целом заработало, но теперь не проходит бэкап базы - валится с ошибкой:

pg_dump -w -U engine -h localhost -p 5432  engine -E UTF8 --disable-dollar-quoting --disable-triggers --format=custom
pg_dump: Dumping the contents of table "audit_log" failed: PQgetResult() failed.
pg_dump: Error message from server: ERROR:  missing chunk number 0 for toast value 43790352 in pg_toast_16457

Что делал.

Номер раз.

reindexdb -a # проходит без ошибок
/bin/engine-vacuum -f -t audit_log
vacuumdb: vacuuming of table "audit_log" in database "engine" failed: ERROR:  missing chunk number 0 
for toast value 43790352 in pg_toast_16457
Номер два.
su postgres
bash-4.2$ psql -d engine
psql (9.2.23)
Type "help" for help.

engine=# REINDEX table  pg_toast.pg_toast_16457;
REINDEX
engine=# REINDEX table audit_log;
REINDEX
engine=# VACUUM ANALYZE pg_toast.pg_toast_16457;
VACUUM
engine=# VACUUM FULL pg_toast.pg_toast_16457;
VACUUM
engine=# VACUUM ANALYZE audit_log;
VACUUM
engine=# VACUUM FULL audit_log;
ERROR:  missing chunk number 0 for toast value 43790352 in pg_toast_16457
Номер три.
su postgres
bash-4.2$ for ((i=0; i<4647; i++)); do psql engine -c "SELECT * FROM audit_log LIMIT 1 OFFSET $i" > /dev/null || echo $i; done

ERROR:  missing chunk number 0 for toast value 43790352 in pg_toast_16457
486
ERROR:  missing chunk number 0 for toast value 43790344 in pg_toast_16457
587
ERROR:  unexpected chunk number 2 (expected 0) for toast value 43790354 in pg_toast_16457
640
psql -d engine

engine=# select table_name, column_name from information_schema.columns where table_name='audit_log';
 table_name |     column_name     
------------+---------------------
 audit_log  | audit_log_id
 audit_log  | user_id
 audit_log  | user_name
.......

engine=# SELECT audit_log_id FROM audit_log LIMIT 1 OFFSET 486;
 audit_log_id 
--------------
        33790
(1 row)
engine=# delete from audit_log where audit_log_id='33790';
DELETE 1
engine=# SELECT audit_log_id FROM audit_log LIMIT 1 OFFSET 587;
 audit_log_id 
--------------
        33898
(1 row)
engine=# delete from audit_log where audit_log_id='33898';
DELETE 1
engine=# SELECT audit_log_id FROM audit_log LIMIT 1 OFFSET 640;
 audit_log_id 
--------------
        33953
(1 row)
engine=# delete from audit_log where audit_log_id='33953';
DELETE 1

engine=# VACUUM FULL audit_log;
ERROR:  missing chunk number 0 for toast value 43790352 in pg_toast_16457
Вот тут фантазия иссякла. Единственное, есть идея синхронизировать данные таблицы audit_log из предыдущего бэкапа,
но не знаю как правильно это сделать. Есть бэкап всей базы за 17.10.17.

Пробовал в single mode запускать базу и потом делать вакуум всей базы? Или это боевая база?
Из вариантов еще могу предложить попробовать слить реплику базы, и, если процесс пройдет успешно, то перенести нагрузку на реплику, запустив ее мастером.

v9lij ★★★★★ ()

Попробуй сделать дамп выкинув из него проблемную таблицу (--exclude-table) и с audit_log разобраться отдельно.

ya-betmen ★★★★★ ()
Ответ на: комментарий от v9lij

Single...хммм. Не уверен, что это хорошая идея.
Как то стремно экспериментировать на проде. Да, это боевая база. Как правильно сделать репликацию? Реплику сделать прямо на той же машине?

bearpuh ()
Ответ на: комментарий от bearpuh

Ну на той или на другой - разницы нет. Через pg_basebackup сделай копию да стартани новую базу в режиме мастера, а там уже проверяй свои запросы, которые падают на больной базе. Если всё ок, то спланируй миграцию, сделать это можно с минимальным даунтаймом.

v9lij ★★★★★ ()
Ответ на: комментарий от ya-betmen

Вряд ли у него одна битая таблица, просто она первая попадается при бекапе. Почти наверняка, если ее убрать, то посыпятся следующие.

v9lij ★★★★★ ()
Ответ на: комментарий от ya-betmen

Без проблемной таблицы бэкап сливается без ошибок, но весит он раз в 6 меньше чем полный.

bearpuh ()
Ответ на: комментарий от v9lij

Но ведь лучше проверить простой вариант, вдруг повезло и покоцаны только пара таблиц.

ya-betmen ★★★★★ ()
Ответ на: комментарий от bearpuh

весит он раз в 6 меньше чем полный

Судя по всему там логи вход/выход или что-то подобное, поэтому их много. Выгрузи из неё данными запросом и залей на развернутый бакап.

ya-betmen ★★★★★ ()
Ответ на: комментарий от bearpuh

Реплику сделать прямо на той же машине?

ИМХО, лучше на другой.

ЗЫ Для этих штук имею отдельный ноут, потому как были случаи потери базы, которую потом приходилось из файловой системы выкусывать побайтно и всенощно. Делаю реплику и тут же лью на болванку.

Deleted ()
Последнее исправление: rht (всего исправлений: 1)
Ответ на: комментарий от ya-betmen

Судя по всему там логи вход/выход или что-то подобное, поэтому их много.

Я тоже на это надеюсь. Попробую выгрузить в файл.

Выгрузи из неё данными запросом и залей на развернутый бакап.

Без понятия как это сделать.

bearpuh ()
Ответ на: комментарий от v9lij

Через pg_basebackup сделай копию да стартани новую базу в режиме мастера.

Я так понимаю, что сначала нужно разрешить реплику в pg_hba.conf?

bearpuh ()
Ответ на: комментарий от ya-betmen

Не получается скопировать данные из проблемной таблицы - та же ошибка.

bearpuh ()
Ответ на: комментарий от bearpuh

Разрешаешь реплику в pg_hba, релоадишь мастер, запускаешь накатку реплики. Затем делаешь то, о чем говорили ранее.

v9lij ★★★★★ ()
Ответ на: комментарий от ya-betmen

Итак новая информация.
Выяснил, что ошибка проявляется при обращении только к одной колонке таблицы, а именно call_stack.

engine=# SELECT call_stack FROM audit_log LIMIT 1 OFFSET 587;
ERROR:  missing chunk number 0 for toast value 43790344 in pg_toast_16457
engine=# SELECT call_stack FROM audit_log LIMIT 1 OFFSET 596;
ERROR:  missing chunk number 0 for toast value 43790362 in pg_toast_16457
engine=# SELECT call_stack FROM audit_log LIMIT 1 OFFSET 640;
ERROR:  unexpected chunk number 2 (expected 0) for toast value 43790354 in pg_toast_16457

Глянул в непроблемных строках - значение данного поля - пустая строка.

engine=# SELECT call_stack FROM audit_log LIMIT 1 OFFSET 12;
 call_stack 
------------
 
(1 row)
Может просто перезаписать значения данного поля в проблемных строках? Поможите правильно составить запрос.

bearpuh ()
Ответ на: комментарий от ya-betmen

Данные проблемной таблицы выгрузил в файл кроме одного столбца.

bearpuh ()

Что за ФС, какие-то хитрые опции монтирования пробовали ?

bdfy ★★★★★ ()
Ответ на: комментарий от bdfy

Да нет - ext4 поверх GlusterFS, которая в свою очередь на xfs поверх ThinProvisioning LVM. ))))))
В общем и целом я виноват. Как в анекдоте -
- У меня вчера друг сервер «уронил»
- Он что хакер???
- Да не - просто м@$ак.

bearpuh ()
Ответ на: комментарий от bearpuh

Короче перезаписал все строки колонки call_stack и все заработало.

UPDATE audit_log SET call_stack=null;
Всем спасибо!

bearpuh ()
Ответ на: комментарий от bearpuh

Тогда отмечай как решенную. Кстати часть затертых данных ты можешь из дампа восстановить ( Есть бэкап всей базы за 17.10.17.).

ya-betmen ★★★★★ ()
Ответ на: комментарий от bearpuh

на всякий случай: в такой ситуации, нужно врубить в конфиге zero_damaged_pages. естественно предварительно сделав бекап того что есть.

drsm ()
Последнее исправление: drsm (всего исправлений: 1)
Ответ на: комментарий от ya-betmen

Я уже глянул - там ничего ценного нет. Оставлю так.
Данная таблица в текущем моменте - статусы всех процессов и задач, состояний гостевых машин и виртуалок и т.д., но в прошлом всего лишь лог.

bearpuh ()
Ответ на: комментарий от drsm

Почитал. Ни в коем случае этого делать не стоит с данной базой.

bearpuh ()
Ответ на: комментарий от bearpuh

Подскажите пожалуйста, это полная комманда «UPDATE audit_log SET call_stack=null;? Запускаю у себя „UPDATE audit_log SET call_stack=null; и получаю результат: ERROR: relation „audit_log“ does not exist LINE 1: UPDATE audit_log SET call_stack=null; ^ SQL-состояние: 42P01 Символ: 8

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.