소스 데이터베이스가 UTF8로 인코딩 된 경우 복원시 UTF8 유효하지 않은 바이트 시퀀스 복사 오류를 해결하는 방법은 무엇입니까?


17

PostgreSQL 8.2.x 데이터베이스를 다른 서버로 마이그레이션하는 작업이 제공되었습니다. 이를 위해 pgAdmin 1.12.2 (우분투 11.04)와 사용자 정의 / 압축 형식 (.backup) 및 UTF8 인코딩을 사용하여 백업 및 복원을 사용하고 있습니다.

원래 데이터베이스는 다음과 같이 UTF8입니다.

-- Database: favela

-- DROP DATABASE favela;

CREATE DATABASE favela
  WITH OWNER = favela
       ENCODING = 'UTF8'
       TABLESPACE = favela
       CONNECTION LIMIT = -1;

대상 서버에서 이와 같은 데이터베이스를 만들고 있습니다. 그러나 복원 옵션을 사용하여 .backup 파일에서 데이터베이스를 복원하면 다음과 같은 오류가 발생합니다.

pg_restore: restoring data for table "arena"
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 2173; 0 35500 TABLE DATA arena favela
pg_restore: [archiver (db)] COPY failed: ERROR:  invalid byte sequence for encoding "UTF8": 0xe3a709
HINT:  This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
CONTEXT:  COPY arena, line 62

실제로이 오류가 발생한 레코드를 확인할 때 일부 vartext 필드에는 ç (예 : "caça"와 같이 포르투갈어로 사용)와 같은 발음 구별 부호 문자가 있으며 레코드의 텍스트에서 수동으로 문자를 제거하면 다음 레코드로 전달됩니다. 복사에 오류가 있으면이 테이블에 데이터 삽입을 중지합니다. 그리고 나는 이것을 달성하기 위해 하나씩 수동으로 교체하고 싶지 않습니다.

그러나 UTF8에서는 이런 종류의 문제가 없어야하기 때문에 다소 이상합니다.

나는 그들이 처음에 어떻게 거기에 도착했는지 모른다. 데이터베이스를 마이그레이션하는 중이며 데이터베이스가 LATIN1과 비슷하고 UTF8로 잘못 변경되었다고 가정합니다.

테이블 / 데이터베이스에 잘못된 UTF8 시퀀스가 ​​있는지 확인하는 방법이 있습니까? 또는이 문자를 UFT8로 강제 변환하거나 다시 변환하여 복원을 실행할 때 아무런 문제가 발생하지 않습니까?

미리 감사드립니다.

답변:


8

인터넷을 조사 해보니 이것이 일반적인 문제라는 것을 알았습니다. 일반적인 해결책은 일반 텍스트 형식 덤프를 사용하고 iconv를 통해 인코딩하여 정정하는 것입니다.

여기 에 더 자세한 정보가 있습니다.


iconv를 사용하여 유효하지 않은 기호를 버리고 UTF-32로 변환 한 다음 다시 UTF-8로 변환하면 UTF-8에서 UTF-8 로의 변환이 모든 잘못된 코드 포인트를 포착하지는 않습니다. (예 : 고아 대리모)
Jasen

7

"처음에 그들이 어떻게 도착했는지 모르겠다"

8.4에서 오류가 발생하더라도 여기에 설명 된대로 발생할 수 있습니다 .

텍스트 유형 (예 : text, varchar (10) 등)으로 테이블을 만들면 8 진 이스케이프를 사용하여 해당 필드에 잘못된 바이트 시퀀스를 삽입 할 수 있습니다.

예를 들어 UTF8로 인코딩 된 데이터베이스가있는 경우 다음을 수행 할 수 있습니다.

=> 테이블 만들기 foo (t TEXT);

=> foo 값에 삽입 (E '\ 377');

이제 테이블을 복사하면 결과 파일을 다시 복사 할 수 없습니다. 즉, pg_dump 백업을 복원 할 수 없습니다. 데이터를 다시 가져올 수있는 유일한 방법은 해당 값을 다시 탈출하는 것입니다.

우수한 블로그 에는 일반적인 문제와이를 해결하는 몇 가지 방법에 대한 좋은 게시물이 있습니다.


1

유닉스 / 리눅스 환경에서 사용되는 기본 인코딩 일 가능성이 높습니다. 현재 어떤 인코딩이 기본 인코딩인지 확인하려면 다음을 실행하십시오.

$ echo $LANG
en_US

이 경우 복사 명령이 사용하는 UTF-8 인코딩이 아니라는 것을 분명히 알 수 있습니다.

이 문제를 해결하기 위해 예제에서 LANG 변수를 다음과 같이 설정했습니다.

$ export LANG=en_US.UTF-8

참고 : 현재 세션에서만 사용할 수 있습니다. ~ / .bashrc 또는 유사 항목에 추가하여 향후 셸 세션을 시작할 때 사용할 수있게하십시오.

참고


1

유효한 텍스트 (예 : 중국어 문자)를 다른 문자로 변환 할 수 있으므로 일반 텍스트 덤프에서 iconv를 맹목적으로 실행하지 않는 것이 좋습니다. 아래 명령을 실행하여 유효하지 않은 UTF8 문자를 찾는 것이 좋습니다.

grep -naxv '.*' plain_text_dump.sql

그런 다음 특정 데이터에서 iconv를 실행하십시오. 자세한 설명은이 문서를 확인하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.