이 글은 Bugzilla 2.x 버전에서 3.x 버전으로 업그레이드 하면서 제가 직접 겪은,
MySQL DB의
UTF-8 character encoding 지원 특성과 관련된 문제 및 해결 방법을 기록한 것이기 때문에 일부 틀리거나 부족한 내용이 있을 수도 있습니다. 그러니 그런 부분이 발견되더라도 양해해주시고 덧글이나 메일로 지적 부탁 드리겠습니다. ;)
-------
대부분의 S/W 개발 회사들은 어떤 형태로든
Bug Tracking System을 운영할 겁니다. 저희 팀도 체계적인 버그 추적 및 해결, 사후 이력 관리 등을 위해서 bug tracking system을 운영하고 있습니다.
팀이 막 만들어졌던 초기에는 단순히
Excel sheet를 이용해서 문제들을 정리하고 관리했지만, 시간이 지나고 팀이 조금씩 제대로 된 모습을 갖추어 나가면서 Excel sheet를 이용하는 단순한 방법이 협업이나 검색, 사후 이력 관리 등의 여러가지 측면에서 문제가 많다는 것을 몸으로 직접 느끼게 되었습니다. 그래서 처음으로 사용하게 된 것이
Bugzilla였습니다. 비록 지금은
Mantis BT로 다시 옮겨간 상태지만, Bugzilla는 그 나름의 막강한 기능을 가지고 있는 좋은 Bug Tracking System임에 틀림없습니다.
근래에 이 Bugzilla의 3.0 버전이 발표되었습니다. 제 경우, 3.0 RC1 버전이 발표되었을 때 기존에 사용 중이던 2.x 버전에서 업그레이드를 시도했는데, Perl 기반이다 보니 각종 패키지들 설치하는 것부터 쉬운 일이 아니더군요. 그나마 설치 스크립트가 친절하게 필요한 내용을 안내해주었기 때문에 시간이 좀 걸리기는 해도 성공적으로 업그레이드를 마칠 수가 있었습니다.
문제는 그 다음이었습니다. 두근거리는 마음으로 업그레이드 된 Bugzilla에 접속했는데, 아니 이게 무슨 낭패?! 이전에 등록한 버그 내용의 한글이 몽땅 다 깨져보이는 것입니다. 분명 character encoding은 2.x에서도 3.0 RC1에서도 UTF-8으로 동일하게 지정이 되어 있었고, MySQL DB도 UTF-8 encoding을 사용하도록 설정이 되어 있었는데 말이죠. Bugzilla 3.0 RC1의 자체 문제인가 해서 새 문제를 등록해보았더니 새로 등록한 문제는 한글이 제대로 잘 보였습니다. 결국 encoding을 다루는 방식이 2.x와 3.x에서 차이가 생긴 것이 원인일 것이라는 추측은 가능했지만, 당장 어떻게 해볼 도리가 없었습니다.
급한 마음에 우선 Bugzilla 2.x 버전으로 되돌리는 작업을 진행했지만, 업그레이드 되어 버린 Perl 패키지와 2.x 버전의 Bugzilla가 호환이 되지 않아서 그것 조차 마음 대로 되지 않았습니다. 결국 팀원들에게 Bugzilla 사망(?) 소식을 전할 수 밖에 없었습니다. 그나마 다행이었던 것은 당시 이미 Mantis BT로 옮겨간 상황이었기 때문에 현재 진행되고 있는 작업에는 큰 지장이 없었다는 점이었습니다. 하지만, 지난 프로젝트의 버그 이력을 몽땅 날려 먹는 큰 실수를 한 셈이었죠.
2 주쯤 지난 후, Mantis BT 때문에 MySQL DB를 좀 손보다가 문득 아이디어가 떠올랐습니다. 정확하게는 틀어진 encoding을 바로 잡을 방법이었죠. Bugzilla 2.x에서 만들어진 DB 내용이 Bugzilla 3.x에서 깨져 보이는 이유를 알아낸 것입니다.
Bugzilla 2.x에서는 MySQL DB에 query를 넘길 때 UTF-8 encoding을 위한 지시자(
MySQL 4.x의 경우 'set names utf-8', MySQL 5.x의 경우 'set names utf8')를 넘겨주지 않고 있었고, 3.0 RC1 이후에는 MySQL DB 특성에 맞추어서 UTF-8 encoding 지시자를 넘겨주도록 수정된 것입니다.(
이것은 DB 내용을 dump 해보면 확실하게 알 수 있습니다. Bugzilla 2.x에서 작성된 내용은 dump된 SQL script에서 한글이 깨져보입니다. 그러나 3.0 RC1 이후 버전에서 작성된 내용은 한글이 제대로 잘 보입니다.) 결국 따지고 보면 Bugzilla 3.0 RC1에 와서 제대로 된 DB query를 사용하도록 개선된 것입니다.
문제의 원인을 알았으니 수정을 할 방법도 찾을 수 있었습니다. 해결 방법은 다음과 같습니다. (
아래 내용은 MySQL 5.0.x 기준입니다. MySQL 4.x 버전을 사용하신다면 character encoding 부분을 해당 버전에 맞게 고쳐주시면 됩니다. latin1을 latin-1으로, utf8을 utf-8으로...)
- mysqldump를 사용해서 Bugzilla 2.x에서 만들어진 DB 내용을 dump 하되, --default-character-set=latin1 옵션을 주어 강제로 Latin-1(iso-8859-1) encoding으로 SQL script를 만들어 냅니다.
- dump된 SQL script를 편집기에서 UTF-8 encoding 형식으로 열어 보면 한글 부분이 드디어 깨지지 않고 제대로 보이는 것을 확인하실 수 있습니다.
- SQL script 내용에서 'SET NAMES latin1'이란 부분을 찾아서 'SET NAMES utf8'으로 수정해준 뒤 저장합니다.
- 만약을 위해서 기존 Bugzilla DB를 백업해둔 후 drop 시키고, 새로 create 하여 조금 전에 수정한 SQL script를 실행해줍니다.
- 자, 이제 Bugzilla 3.x에서 한글이 깨지지 않고 제대로 잘 보이는 감동스런 장면을 직접 확인하기만 하면 됩니다. ;)
여기까지가 약 3 주간에 걸친 제 모험 이야기의 끝입니다. 이번 모험을 통해 좋은 공부를 할 수 있어서 즐거웠고, 무엇보다도 팀원들의 피땀으로 만들어진 프로젝트 버그 이력을 되살릴 수 있었던 것이 가장 기뻤습니다. :)
덧.MySQL DB에서 UTF-8 형식으로 DB를 생성하고, 프로그램에서 UTF-8 사용을 위한 지시자(
MySQL 4.x의 경우 'set names utf-8', MySQL 5.x의 경우 'set names utf8')를 넘겨주지 않으면, MySQL은 넘어온 문자열을 Latin-1 encoding 문자열로 간주하게 됩니다. 그래서 1 byte 단위로 끊은 각각의 문자를 다시 UTF-8 encoding으로 변환한 이후 DB에 넣게 되는 것입니다. UTF-8 encoding은 가변 byte 형식이라서 변환된 문자는 1 byte를 넘을 수도 있고, 이 때문에 필드의 원래 길이보다 짧은 문자열이 insert 실패하는 경우도 발생하게 됩니다.