Привет Slack Overflowvians.
Итак, я наткнулся на этот сервер PostgreSQL под управлением 8.3.11 (да, я знаю), который был в заблокированном состоянии с:
ERROR: database is not accepting commands to avoid wraparound data loss in database "postgres"
HINT: Stop the postmaster and use a standalone backend to vacuum that database.
Обычно с этим справляется демон автоматической очистки (autovacuum=on
), но поскольку следующие четыре TOAST (позволяют хранить большие значения полей размером 8 КБ, например хлеб), объект базы данных. Но XID этой базы данных никогда не сбрасывался из-за этих поврежденных объектов базы данных.
Ниже приведен фрагмент вывода при запуске сервера в однопользовательском режиме с правами администратора:
SELECT oid, relname, age(relfrozenxid) FROM pg_class WHERE relkind = 't' ORDER BY age(relfrozenxid) DESC LIMIT 4;
----
1: oid = "2421459" (typeid = 26, len = 4, typmod = -1, byval = t)
2: relname = "pg_toast_2421456" (typeid = 19, len = 64, typmod = -1, byval = f)
3: age = "2146484084" (typeid = 23, len = 4, typmod = -1, byval = t)
----
1: oid = "2421450" (typeid = 26, len = 4, typmod = -1, byval = t)
2: relname = "pg_toast_2421447" (typeid = 19, len = 64, typmod = -1, byval = f)
3: age = "2146484084" (typeid = 23, len = 4, typmod = -1, byval = t)
----
1: oid = "2421435" (typeid = 26, len = 4, typmod = -1, byval = t)
2: relname = "pg_toast_2421432" (typeid = 19, len = 64, typmod = -1, byval = f)
3: age = "2146484084" (typeid = 23, len = 4, typmod = -1, byval = t)
----
1: oid = "2421426" (typeid = 26, len = 4, typmod = -1, byval = t)
2: relname = "pg_toast_2421423" (typeid = 19, len = 64, typmod = -1, byval = f)
3: age = "2146484084" (typeid = 23, len = 4, typmod = -1, byval = t)
Обратите внимание, что возраст значительно превышает vacuum_freeze_min_age
(значение, установленное после успешного VACUUM) на этом сервере и, следовательно, почему он выдает исходные ошибки, указанные выше. Вышеупомянутое было ПОСЛЕ запуска VACUUM FULL
; все остальные таблицы в порядке.
SELECT relfilenode FROM pg_class WHERE oid=2421459;
Итак, когда мы посмотрели на диск (использовали значение pg_class.relfilenode для каждой таблицы выше), файл таблицы всплывающих уведомлений отсутствовал:
$ find /var/lib/pgsql/data/ -type f -name '2421426' | wc -l # Bad toast
0
и когда мы посмотрели на диске индекс тоста
SELECT relfilenode FROM pg_class WHERE (select reltoastidxid FROM pg_class WHERE oid=2421459)
$ find /var/lib/pgsql/data/ -type f -name '2421459' | wc -l # Bad toast's index
0
Затем мы попытались найти таблицу, с которой связана плохая запись всплывающего уведомления:
SELECT * FROM pg_class WHERE reltoastrelid=2421459;
получил 0 результатов для каждой таблицы выше! Нет таблиц для команды VACUUM
для сброса XID этих отношений.
Когда мы проверили таблицу pg_depend и обнаружили, что в этих таблицах TOAST НЕТ ссылок:
SELECT * FROM pg_depend WHERE refobjid IN(2421459,2421450,2421435,2421426)
Вопрос
- Можете ли вы удалить плохую таблицу TOAST и индексы таблицы TOAST из таблицы pg_class (например,
DELETE FROM pg_class where oid=2421459
) - Есть ли какие-либо другие таблицы, из которых нам также нужно удалить отношение?
- Можем ли мы просто создать временную таблицу и связать ее с oid индекса TOAST?
Пример для № 3 выше:
CREATE TABLE adoptedparent (colnameblah char(1));
UPDATE pg_class SET reltoastrelid=2421459 WHERE relname='adoptedparent';
VACUUM FULL VERBOSE adoptedparent
ИЗМЕНИТЬ:
select txid_current()
равно 3094769499, поэтому эти таблицы были давно повреждены. Нам не нужно восстанавливать данные. Мы используем файловую систему ext4 на Linux 2.6.18-238.el5. Мы проверили соответствующие каталоги lost+found/
, и файлов там не было.
database
ориентировано? - person Yzmir Ramirez   schedule 30.09.2015