Резервная копия была создана из базы данных в кодировке UTF-8 с использованием pg_dump
. Резервная копия находится в tar
формат.
Затем я создал новую базу данных на другом сервере с той же версией PostgreSQL (8.2.4), используя эту команду:
createdb -E utf8 db1
При беге pg_restore
Я получаю следующую ошибку:
pg_restore: [archiver (db)] Error from TOC entry 1667; 0 14758638 TABLE DATA table1 db1
pg_restore: [archiver (db)] COPY failed: ERROR: invalid byte sequence for encoding "UTF8": 0xc520
Исходная база данных больше не доступна.
Как мне восстановить эти данные или найти последовательность байтов, из-за которой возникла проблема?
Я решил эту проблему, выполнив следующие действия:
pg_restore -f db1.sql-v db1.tar
Затем я удалил все из db1.sql
файл, за исключением table1
скопировать команду. Потом побежал:
psql -d db1 < db1.sql
Это дало мне точный номер строки в файле, где произошла ошибка. Затем я открыл файл, удалил проблемный символ и повторно запустил сценарий.
Старые версии Postgres позволяли вводить недопустимые последовательности байтов в базу данных. Об этом было примечание и предложенное исправление в недавнем Release Note:
У некоторых пользователей возникают проблемы с загрузкой данных UTF-8 в 8.1.X. Это связано с тем, что предыдущие версии позволяли вводить недопустимые последовательности байтов UTF-8 в базу данных, а этот выпуск правильно принимает только допустимые последовательности UTF-8. Один из способов исправить файл дампа - запустить команду iconv -c -f UTF-8 -t UTF-8 -o cleanfile.sql dumpfile.sql. Параметр -c удаляет недопустимые последовательности символов. Сравнение двух файлов покажет недопустимые последовательности. iconv считывает весь входной файл в память, поэтому может потребоваться использовать split, чтобы разбить дамп на несколько файлов меньшего размера для обработки.
Если база данных не очень большая или сложная, может быть проще найти проблемный текст в исходной базе данных и исправить его перед созданием нового дампа. Причиной может быть поле, введенное пользователем или содержащее данные, импортированные из других источников.
Этот небольшой сценарий Perl может вас спасти: Восстановление поврежденных документов, содержащих UTF-8 и ISO-8859-1
Перенаправьте вывод скрипта в новый файл. Все недопустимые символы должны быть заменены их правильным воплощением UTF-8. Сценарий также считывает входные данные построчно, поэтому ему не нужно слишком много памяти.
Вероятно, это та же проблема, что и у меня когда-то при переходе с 7,4 на 8,2 дБ. Я использовал инструкции по этому поводу веб-статья решить проблему. Это предполагает, что у вас все еще есть доступ к исходной базе данных. В противном случае вы, вероятно, можете восстановить его в более старой версии Postgresql и попробовать эту процедуру.