Найти тему
Будни одинэсника | 1С

Как исправить ошибку 1С: "XX000: ERROR: missing chunk number 0 for toast value 36011983 in pg_toast_44022"?

Оглавление

Есть база 1С, работает на Postgres SQL. В один момент перестал выполняться бэкап. В логах появилась ошибка "ERROR: missing chunk number 0 for toast value 36011983 in pg_toast_44022".

В этой статье расскажу по этапам, как удалось ее победить.

🔥 Для начала важное замечание!

Перед выполнением любых действий на рабочей базе сделайте резервную копию.

Если бэкап не выполняется стандартными способами, то обязательно скопируйте полностью каталог "DATA".

Я буду рассматривать решение вопроса на PostgresSQL for Windows. Каталог data по умолчанию расположен по такому пути: "C:\Program Files\PostgreSQL\11.5-19.1C\data"

🔴 Что произошло?

В один момент Postgres SQL престал выполнять резервное копирование и отваливался с ошибкой, попытался решить проблему следующими способами:

  • Тестирование базы средствами СУБД;
  • Реиндексация проблемной таблицы средствами СУБД;
  • Выгрузка базы средствами 1С;
  • Тестирование и исправление средствами 1С;
  • Добавление новых объектов метаданных в конфигураторе 1С и реструктуризация БД;

По итогу все время выходит одна и та же ошибка: "ERROR: missing chunk number 0 for toast value 36011983 in pg_toast_44022".

🟢 Решение проблемы!

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

Ошибка ссылается на таблицу pg_toast_44022. Это служебная таблица (тост), нужно определить с какой конкретно таблицей БД она связана.

Для начала зайдем в консоль psql. Откроем Командную строку (cmd.exe) и введем команду: 'psql -U postgres -d BASE', где postgres - имя пользователя СУБД, BASE имя нашей базы. После ввода нужно будет ввести пароль пользователя postgres.

Запуск консоли psql
Запуск консоли psql

Для определения реальной таблицы выполним команду: 'select 44022::regclass;', где 44022 это суффикс из таблицы pg_toast_44022.

-3

В итоге получили таблицу _commonsettings. Это таблица, где хранятся настройки пользователей 1С. Это уже хорошо.

Попробовал очистить настройки пользователей в 1С, но опять та же ошибка 😡

2. Решил очистить эту таблицу средствами СУБД. В этой таблице не хранятся критичные данные, только пользовательские настройки. Не очень хорошо, но как вариант нужно попробовать.

Выполнил команду полной очистки таблицы: 'delete from _commonsettings;'.

Все прошло хорошо, после этого база заработала. Бекап выполняется, как средствами 1С так и СУБД. Бинго!

3. Решил покопаться и все-таки не очищать всю таблицу, а найти битую запись.

Для начала решил выяснить сколько записей в этой таблице, команда: 'select count(*) from _commonsettings;'. Оказалось не так много, всего — 819.

-4

Далее, попробовал сделать полную выборку: 'select * from _commonsettings;' По итогу опять ошибка.

-5

Хорошо, буду выбирать партиями по 100 записей: 'select * from _commonsettings limit 100;'. Нормально, процесс пошел. Прерывать пролистывание строк можно комбинацией CTRL+C.

-6

Каждый раз увеличивал количество строк и собственно подбором пришел к тому, что битая строка оказалась под номером 441. На ней ошибка, а на 440 все проходит хорошо.

-7

Чтобы удалить конкретную запись нужно как-то ее отобрать по какому-то признаку. Для этого сначала посмотрим за структуру данных, выполним команду: 'select * from _commonsettings limit 1 offset 441;'. Получим одну запись. В данным случае мы получаем запись с номером 440, которая не битая. В команде указано 441, так как нумерация для оператора offset начинается с 0. Если выполнить команду с offset 440 (441 по счету строка, так ка нумерация с 0), выйдет ошибка.

Нас пока это устроит. Если посмотреть на данные в строке, то единственное более менее нормальное поле, по которому можно сделать отбор это "_version", у этого поля обычное значение, которое можно подставить в отбор.

-8

Но теперь нужно, получить значение поля "_version" у битой строки. Выбор данных всех полей для строки не проходит попробую получить только данные поля "_version": 'select _version from _commonsettings limit 1 offset 440;'. Все получилось!

-9

В итоге после проверки всех полей оказалось, что ошибка была в поле "_settingsdata", таблицы "_commonsettings" в строке 441. Не знаю, что там "испортилось", но думаю без этой строки мы проживем. Буду удалять!

Выполняю команду: 'delete from _commonsettings where _version='\\xaab78a1716b220d64abbbfd1b7579914';'. Обратите внимание, значение, которое мы получали выше было с одним слешем "\", а в отборе нужно поставить два "\\" для экранирования.

-10

После этого ошибка везде пропала!

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

Смотрите еще статьи по теме: