티스토리 뷰

1. 배경설명

지난 며칠간 사이드프로젝트 DB 컨테이너화 한다고 docker-compose.yml 설정 중에 한글 초기화 데이터 깨짐 현상이 발생했습니다.
찾아보면 해결방법은 나와있는데 원인분석된 포스팅은 없는 것 같아 정리하기위해 본 포스팅 작성을 결정했습니다.
※ 여러 자료를 참고해서 정리한 포스팅이긴 하나 일부 뇌피셜부분도 있으니 참고 바랍니다.

 


 

 

 

2. Default character set 설정과 Command 명령어 추가 시 비교분석 및 결론

Command 없이 Mysql을 생성했을 경우와 Command 명령어 추가 후 Mysql을 생성했을 때, 결과 동일합니다.
이는 아래 예시를 통해 확인 가능하며 실제 테스트를 통한 결과입니다. 

 

1) command 명령 없이 Mysql 생성했을 경우

  • docker-compose.yml
version: '3'
services: # 컨테이너
  db:
    image: mysql
    container_name: mysql-hkidb
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${패스워드}
      MYSQL_DATABASE: ${DB이름}
      TZ: Asia/Seoul
    ports:
      - "3306:3306" #local 포트 : docker 포트
    volumes:
      - ./initSQL/:/docker-entrypoint-initdb.d

 

 

  • Mysql status
    • Server characterset : utf8mb4
    • Db       chracterset   : utf8mb4
    • Client  chracterset   : latin1
    • Conn. chracterset    : latin1

 

 

 

2) command를 추가 후 Mysql을 생성했을 경우

  • 추가한 명령어는 다음과 같습니다.
--character-set-server=utf8mb4 
--collation-server=uft8mb4_unicode_ci

 

 

  • docker-compose.yml
version: '3'
services: # 컨테이너
  db:
    image: mysql
    container_name: mysql-hkidb
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${패스워드}
      MYSQL_DATABASE: ${DB이름}
      TZ: Asia/Seoul
    ports:
      - "3306:3306" #local 포트 : docker 포트
    command:
      - --character-set-server=utf8mb4 # 서버 characterset 설정
      - --collation-server=utf8mb4_unicode_ci # 정렬 설정(문자열 정렬)
    volumes:
      - ./initSQL/:/docker-entrypoint-initdb.d

 

 

  • Mysql status
    • Server characterset : utf8mb4
    • Db       chracterset   : utf8mb4
    • Client  chracterset   : latin1
    • Conn. chracterset    : latin1

 

 

 

 

 

 

따라서,
Mysql 8.0부터 아래 사진과 같이 character_set_server과 collation_server default 값이 변경되었고,
따라서 추가한 Command 명령어는 불필요한 부분으로 생략해도 됩니다.

 

 

 

 

 

MySQL :: New Defaults in MySQL 8.0

MySQL 8.0 comes with improved defaults, aiming at the best out of the box experience possible. Here we describe the changes and why they are made. Introduction Generally speaking, a good default is “the best choice for most users, most of the time”. In

dev.mysql.com

 

 

 

2. 한글 데이터 깨짐 해결방법과 이유 분석

1) 해결방법

결론적으로 Command에 --skip-character-set-client-handshake 명령어를 추가하면 해결됩니다.
제시된 방법 외에 my.cnf 파일을 Mysql 디렉토리에 마운트 시키는 방법도 있으니, 검색을 통해 원하는 방식으로 해결하면 됩니다.

 

  • docker-compose.yml
version: '3'
services: # 컨테이너
    db:
        image: mysql
        container_name: mysql-hkidb
        restart: always
        environment:
            MYSQL_ROOT_PASSWORD: ${패스워드}
            MYSQL_DATABASE: ${DB이름}
            TZ: Asia/Seoul
        ports:
            - "3306:3306"
        command:
            - --skip-character-set-client-handshake
        volumes:
            - ./mysql/initdb.d:/docker-entrypoint-initdb.d

 

  • Mysql status
    • Server characterset : utf8mb4
    • Db       chracterset   : utf8mb4
    • Client  chracterset   : utf8mb4
    • Conn. chracterset    : utf8mb4

 

 

 

2) 분석

위 명령어를 통해 모든 character set이 uft8 mb4로 설정된 것을 볼 수 있는데,
그렇다면 위 명령어가 없을 때 Client와 Connection character set 이 latin1로 설정된 이유는 무엇일까요? 

 

 

2-1) Mysql에서 서부지역 서버에 연결된 클라이언트는 client character set default 값을 latin1으로 설정

 

이해를 돕기 위해 아래 해당글과 설명되어 있는 Mysql 사이트를 첨부했습니다.

These are typical character-set settings for an international-oriented client (notice the use of utf8 Unicode) connected to a server in the West (latin1 is a West Europe character set).

이는 서부(latin1은 서부 유럽 문자 세트)에 있는 서버에 연결된 국제 지향 클라이언트(utf8 유니코드 사용에 유의)에 대한 일반적인 문자 세트 설정입니다.
 

MySQL :: MySQL 8.0 Reference Manual :: A.11 MySQL 8.0 FAQ: MySQL Chinese, Japanese, and Korean Character Sets

The list of CJK character sets may vary depending on your MySQL version. For example, the gb18030 character set is not supported prior to MySQL 5.7.4. However, since the name of the applicable language appears in the DESCRIPTION column for every entry in t

dev.mysql.com

 

 

 

 

 

2-2) 도커에서 리눅스 생성 시 locale 설정을 별도 하지 않아 LC_ALL 값이 공란, 이로 인해 Mysql default 값이 적용.

리눅스 locale 설정

 

 

 

2-3) --skip-character-set-client-handshake 명령어 역할

--skip-character-set-client-handshake : 클라이언트 character set 값을 보낼 때 서버에서 이를 무시하는 명령어입니다.
(여기서 클라이언트에서 보내는 character set은 OS character set 설정값을 보냅니다.)

 

 

The effect of this is that you cannot control the client character set by starting mysqld with --character-set-server=utf8. However, some Asian customers prefer the MySQL 4.0 behavior. To make it possible to retain this behavior, we added a mysqld switch, --character-set-client-handshake, which can be turned off with --skip-character-set-client-handshake. If you start mysqld with --skip-character-set-client-handshake, then, when a client connects, it sends to the server the name of the character set that it wants to use. However, the server ignores this request from the client.

 

이해를 돕기 위해 아래 해당글과 설명되어 있는 Mysql 사이트를 첨부했습니다.

 

MySQL :: MySQL 8.0 Reference Manual :: A.11 MySQL 8.0 FAQ: MySQL Chinese, Japanese, and Korean Character Sets

The list of CJK character sets may vary depending on your MySQL version. For example, the gb18030 character set is not supported prior to MySQL 5.7.4. However, since the name of the applicable language appears in the DESCRIPTION column for every entry in t

dev.mysql.com

 

 


 

 

3. 결론

도커에서 linux 설정 시 locale 설정을 하지 않아 character set 설정이 공란으로 되어있어, client character set 설정이 Mysql에서 설정한 default 값인 latin1으로 설정되었습니다. 
--skip-character-set-client-handshake 명령어로 OS locale 설정을 무시하고 client character set 설정이 server character set을 따라가게 되어 최종적으로 utf8mb4 설정이 적용되었습니다.

 

 

 

이상 정리 끝!

 

'Architecture > Docker' 카테고리의 다른 글

로컬에서 docker로 mysql 이사하기  (0) 2024.01.18
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함