버그 재현
ghost 기반의 개인 블로그( 지금 이 블로그 ) 는 linux 상에서 운영되고 있다. 메인 운영체제를 Macos로 바꾼 이후, docker를 활용해서 맥북의 로컬 환경에 완전히 동일한 셋업을 구성해 추후 블로그 테마 개발시 live preview에 활용하려 하였다.
product 환경에 올라가있는 docker container와 서버 내의 두 폴더를 서로 bind 시켜 놓았기에 해당 디렉토리를 복사 및 로컬환경에 붙여넣었고,
이제 로컬환경의 docker container를 실행시킬 시 정상적으로 동작했어야 했으나, mysql container 쪽에서
different lower_case_table_names settings for server ('2') and data dictionary ('0').
에러를 띄우는 문제가 발생하였다
원인
Mysql에서는 테이블 명을 정할 때에 대소문자를 구분할지 말지에 대한 option 값을 줄 수 있는데, 이 대소문자 구분을 할지 말지의 여부가 운영체제마다 달라서 발생하는 문제이다.
lower_case_table_names 필드에는 세 값이 들어갈 수 있는데,
- 0의 경우 대소문자를 구분하는 옵션
- 1의 경우 대소문자를 구분하지 않는 옵션
- 2의 경우 Create 시에는 구분하지만, lookup 시에는 소문자로 일괄 처리.
이제 이 배경지식과 함께 에러 메시지를 다시 확인해보면 명확하게 이해할 수 있게 된다.
different lower_case_table_names settings for server ('2') and data dictionary ('0').
linux -> macos 으로의 마이그레이션을 진행함에 따라서, 대소문자를 구분하는 linux 운영체제와 구분하지 않는 macos 운영체제의 기본 설정이 서로 충돌한 것이다. 이는 macos뿐만 아니라 linux -> windows시에도 해당될 수 있는 사항이다.
해결 방안
이 문제가 까다로워지는 부분은, 0으로 그냥 변경해서 사용할 수 없다는 데에 있다.
If you force this variable to 0 with --lower-case-table-names=0 on a case-insensitive file system and access MyISAM tablenames using different lettercases, index corruption may result.
lower_case_table_names를 macos 등에서 강제로 0으로 지정할 경우, mysql 시스템 내부의 기본 테이블명에 접근하기 힘들어짐에 따라 오류가 발생한다는 경고문이다.
일괄 통일하기
lower_case_table_names 필드를 1으로 일괄 통일하면 제일 간편해진다. 단 일괄 통일할 수 있는가 에 대한 문제가 발생할 수 있다.
lower_case_table_names can only be configured when initializing the server. Changing the lower_case_table_names setting after the server is initialized is prohibited.
서버의 최초 기동시에만 이 값을 변경할 수 있다는 제한사항이 mysql 8.0에 추가됨에 따라, 구버전 Mysql이 아닌 경우 이 방법을 사용하기 어렵다
Macos를 legacy모드로 실행시키기
기존 파일들을 전부 남기고 migration 해야하는 상황이었기 때문에, Linux 쪽에 macos를 맞추는게 제일 적합하다고 판단했다.
나는 macos환경에서 docker를 실행시키는데 Docker desktop을 사용하고 있는데, 이 프로그램의 설정창에서 이 문제를 해결할 수 있는 옵션을 건드릴 수 있다.
docker desktop > settings > General > Choose file sharing...
으로 이동한다.
해당 항목의 기본값이 gRPC FUSE
로 되어있던 것으로 기억하는데, 해당 값을 osxfs (Legacy)
로 변경하고 컨테이너를 다시 실행시키면 된다.
mysql dump 후 옮겨오기
사실 이 문제가 발생하는 근본 원인은
내가 너무 게을러서 mysql에서 제공하는 백업 방법을 사용하지 않았음
에 가깝다.
mysql 안에 적재된 데이터들은 이 문제와 무관하고, 운영체제의 설정에 관련한 문제이기 때문에, mysqldump 명령어를 사용해 데이터만 추출하고 새로 만들어진 docker container 에 다시 불러오기만 하면 정상적으로 동작한다.
나는 뭐 로컬서버 개발 테스트용이기 때문에 그냥 쉽게쉽게 하려고 시도했다.
mysqldump를 사용하여 데이터를 백업뜨고 다시 불러오는 과정은 굳이 이 글에서 다루지는 않도록 하겠다.
결론
localhost:2368 에 프로덕션 서버와 완전히 동일한 데이터를 지닌 블로그의 복제본을 올리는데 성공했다. 해당 블로그의 테마 폴더는 별도의 github repository와 연동되어 있으므로, 이제 로컬 환경에서 커밋을 올리기 전에 변경사항을 한결 더 확인하기 쉬워졌다.
macos는 linux와 그 기반이 비슷할 줄 알았는데, windows와 같은 분류로 묶여서 오류가 발생한다는 부분이 좀 인상깊었고, windows 환경에서는 사실 Ghost-cli를 통해 시도했었기 때문에 이런 부분을 겪어 볼 일이 없었던듯.
docker-compose를 통해 bind를 하고 백업본을 남길 때 항상 이 데이터로 실제로 복구가 될까 하는 의심이 있었는데, 실제로 복구를 성공함을 통해 어느정도 현재의 백업 시스템에 신뢰를 가질 수 있었다.