Media Log

mysql4.0 -> 5.0으로 마이그레이션시 euckr 버그

아래 내용에 잘못된 내용이 있어서 수정합니다.

MySQL Euc-Kr 처리 소스를 확인한 결과, MySQL Euckr 테이블에 cp949 확장 코드 저장 가능합니다.

정상적으로 데이터가 저장되어 있는 경우라면, 4.0, 5.0 버전간 euckr 테이블 마이그레이션은 문제없이 수행됩니다.

단, 데이터 가 1byte만 잘린 경우, 이미 유효하지 않은 euckr 혹은 cp949 코드로 저장된 경우에는,

마이그레이션 시 데이터 일부가 truncate 처리됩니다.


기존 버전에서 문제가 있었던 부분은 아래와 같고, 별도 포스트로 다시 정리합니다.

 - Extended euckr (cp949) byte range 체크 오류 (일부 cp949 코드 영역을 invalid character로 처리)

 - 일부 euckr 코드의 mapping rule 누락 (다른 캐릭터셋과의 변환시 에러)

 - http://blog.naver.com/seuis398/70030161347


MySQL 4.0의 euc_kr 테이블을 MySQL 5으로 마이그레이션 하는 경우,

입력 데이터의 캐릭터셋 문제로 인하여, 마이그레이션에 문제가 발생할 수 있다.

euckr 데이터를 euckr로 마이그레이션 하는데 무슨 문제가 생긴다는 것인지 의문이 생길 것이다.

결론부터 얘기하자면, 실제 MySQL 4.0의 euc_kr 테이블에는 cp949 코드가 들어있고,

MySQL 5.0의 euckr 테이블에는 euckr 코드 범위를 벗어나는 cp949 코드를 저장할 수 없기 때문에,

마이그레이션 진행중 "Incorrect String 0xXXXX" 이런 에러 메시지를 만나게 된다.


euckr과 cp949에 대한 세부적인 내용은, 아래 포스트에 따로 정리해 두었다.

http://blog.naver.com/seuis398/70020811274


일차적인 원인은 대부분의 클라이언트 환경인 Windows 플랫폼에서...

실제 euckr이 아닌, euckr을 확장한 cp949(ms949)를 사용하고 있기 때문이다.

윈도우 상에서 입력된 한글 데이터는 euckr이 아닌 cp949 데이터이고,

기존 euckr 코드 범위를 벗어난 확장 cp949 한글 코드도 MySQL 4.0의 euc_kr 테이블에 저장이 된 것이다.

물론 입력 데이터의 캐릭터셋을 체크하지 않은 MySQL 4.0도 이런 상황에 책임이 있다고 할 수 있다.


문제는 MySQL 5에서는 euckr 테이블에 euckr(ksx1001) 영역을 벗어나는 코드를 저장할 수 없다는 것이다.

MySQL 5에서 내부적인 입력 데이터에 대한 캐릭터셋 validation이 구현된 것으로 보인다.


예를 들어보면, "땡"이라는 글자는 euckr(ksx1001)에 코드가 정의되어 있지만,

"ㄸ+ㅒ+ㅇ"으로 조합된 글자는 euckr(ksx1001)에 정의되어 있지 않은 cp949 확장 코드로 정의되어 있다.

(네이버 블로그에서 cp949 코드가 입력되지 않아 "ㄸㅒㅇ"으로 표현하였다.)


아래 예시는 위 cp949 코드로 인하여 MySQL 5버전으로의 마이그레이션 시 에러를 발생시키는 경우이다.


[MySQL 4.0에 저장된 cp949 코드]

오타로 인하여 euckr의 코드 범위를 벗어난, 확장 cp949에 정의된 코드가 입력되어 있다.

사용자 삽입 이미지


위 데이터를 mysqldump --default-character-set=euc_kr 옵션으로 dump받아서,

MySQL 5.0 서버로 restore 하면 아래와 같은 상황이 벌어진다.


[MySQL 5.0으로의 마이그레이션 1 : Strict SQL MODE인 경우]

복구시 해당 문자(0x8BAF) 처리시 Incorrect String 에러가 발생한다.

사용자 삽입 이미지

[MySQL 5.0으로의 마이그레이션 2 : Non-Strict SQL MODE]

에러 없이 restore 가능하지만, 해당 컬럼 데이터가 cp949 코드부터 끝까지 truncate 된다.

사용자 삽입 이미지

MySQL 4.0의 euc_kr 테이블을 MySQL 5로 마이그레이션 하기 위해서는 utf8 테이블로의 변환이 필요하다.

utf8로의 변환은 아래 두가지 방법으로 진행할 수 있다.

1) iconv 툴 등으로 dump script(euckr)를 utf8 데이터로 변환 후 복구

2) 스키마와 데이터를 따로 백업한 후 테이블 생성 스크립트에 "default charset=utf8" 옵션 지정

    데이터 복구시는 euckr 세션으로 연결하여, MySQL이 스스로 캐릭터셋 변환을 수행하도록 처리


* 2번 방법의 경우 ksx1001:1998 에 추가된 두 코드가 변환이 안되므로 유의 (MySQL 버그)