backend/Spring

[오류] Docker 환경에서 MySQL 컨테이너 사용 시 테이블 중복 생성 되는 오류

dzaaling 2025. 6. 23. 20:09
반응형

안녕하세요! 

 

프로젝트를 진행하다가 데이터베이스에 테이블이 중복 생성된 오류를 발견하였고 해결한 것을 남겨두고 학습 하려고 합니다! 

 

""" 오류 발생 

스프링 부트를 사용하여 캘린더를 만드는 프로젝트를 진행중이었는데, 

데이터베이스와 매핑하는 방법을 MyBatis 사용 하다가, Jpa 로 갈아타는 중에 문제가 생겼습니다. 

분명 엔티티에 @Table로 기존 데이터베이스 테이블 이름과 대소문자가 모두 동일 하였는데 데이터베이스 조회시 

의도와 다른 테이블이 하나 더 생성되어 이슈가 발생한건데요.. 

 

MySQL은 테이블 이름의 대소문자 구분 여부를 사용자 운영체제(OS)에 따라 다르다고 합니다. 

추가적으로 MySQL에서 설정한 자체 설정값 또한 영향을 받는다고 하는데요.. 

 

보통 Docker를 사용해서 mysql 이미지를 다운 받고 나서 컨테이너를 올릴 때 명령어가 

docker run -d --name {컨테이너이름} -e MYSQL_ROOT_PASSWORD={비밀번호} -p 3306:3306 mysql:8.0

이렇게 컨테이너를 올리고는 합니다. 이렇게 기본적으로 설정하고 나면 windows, Linux, mac 에서 설정이 달라지는 부분들이 있는데 그 중 오늘 살펴볼 것은 테이블 이름을 구분할 때 대소문자를 구분 하냐 안하냐를 살펴보겠습니다. 

 

lower-case-table-names 라는 옵션인데

| Linux 환경에서는 기본 값이 0 입니다.

| windows 환경에서는 기본 값이 1 입니다.

| Mac 환경에서는 기본 값이 2 입니다. 

 

0이면 대소문자를 구분하고, 1이면 테이블 이름을 소문자로 통일해서 처리합니다. 2는 저장은 원래 이름으로 하되, 비교는 소문자로 합니다. 

 

저처럼 윈도우 사용자가 도커를 사용해서 MySQL 을 사용할 경우 기본 값이 0으로 설정됩니다. 윈도우 사용자도 따라서 도커를 사용해서 MySQL을 사용하게 되면 OS가 Linux로 설정되어 0인 값이 세팅이 됩니다. 

 

데이터베이스 쿼리문에서 show variables like 'lower_case_table_names' 를 실행 해보면 값이 나오는데 프로젝트 환경에 맞추어서 값을 변경 해주면 됩니다. 

 

오류 해결 """

Docker 환경에서 MySQL 컨테이너를 이미 올려서 사용 중 이라면 안타깝게도 컨테이너를 수정할 수 없습니다. 

 

첫 번째 이유는 Docker 의 불변성 원칙이 있고 컨테이너는 생성 시점의 설정이 고정 됩니다. 

두 번째 이유는 MySQL 8.0의 제약인데 lower_case_table_names는 데이터베이스 초기화 후 변경이 불가능합니다. 

세 번째 이유는 Docker Inspect 는 정보 조회만 가능하고, 수정은 불가능합니다 이 또한 첫 번째 이유와 비슷합니다. 

 

그래서 컨테이너 생생 시점에 값을 설정해주어야 하는데 아래 백업 받는 것과 같이 설명 하겠습니다 

 

따라서 기존 데이터베이스를 삭제 하고 다시 해야 한다는 말인데, 데이터들을 다 날리거나 ? 백업을 해야 합니다 ! 

저는 백업을 받기로 결정 했고, 백업 하는 방법과 백업 파일을 받는 과정을 남겨두겠습니다 ! 

 

cmd 창을 열어서 진행 해주시면 되겠습니다. 

#1. 기존 데이터 백업 
docker exec {컨테이너이름} mysqldump -u root -p -alll databases > backup.sql

#2. 기존 컨테이너 중지 및 제거 
docker stop {컨테이너이름}
docker rm {컨테이너이름}

#3. 새 컨테이너 생성(같은 포트)
docker run -d --name {컨테이너이름} -e MYSQL_ROOT_PASSWORD={비밀번호} -p 3306:3306 mysql:8.0 --lower-case-table-names=1

#4. 데이터터 복원 
docker exec -i {컨테이너이름} mysql -u root -p{비밀번호 여기서는 -p1234 처럼 바로 붙여서 작성} < backup.sql

3번과 같이 컨테이너를 생성할 때 lower 옵션값을 설정해주어야 합니다. 

 

여기서 mysql 이미지를 다시 다운 받을 필요는 없습니다~! 

 

 

 

728x90
반응형