증상
- 에러 메시지:
pgsql복사ERROR 1396 (HY000) at line 1: Operation CREATE USER failed for 'cheston'@'%'
- 컨테이너 로그:
MySQL 컨테이너 로그에 사용자 생성 에러가 나타남. - 수동으로 MySQL 접속 후:
수동으로 접속해서 drop user 'cheston'@'%'; 명령어를 실행하면 정상적으로 삭제됨.
원인
- Persistent 볼륨에 남은 이전 데이터:
- MySQL 데이터를 저장하는 Docker 볼륨에 이미 'cheston'@'%' 사용자가 생성되어 있었기 때문에, 컨테이너가 재시작될 때 초기화 스크립트에서 다시 사용자를 생성하려고 하면 충돌이 발생함.
- MySQL 기동 타이밍 문제:
- 스크립트가 MySQL 데몬을 시작한 직후에 바로 사용자 관련 명령어를 실행하는 경우, MySQL이 완전히 기동되기 전에 명령이 실행되어 내부 상태가 불안정할 수 있음.
- 이로 인해 DROP USER IF EXISTS 명령이 정상 동작하지 않거나, 이미 존재하는 사용자에 대해 오류가 발생할 가능성이 있음.
- 스크립트 중복 실행 문제:
- 컨테이너가 재시작되거나 초기화 스크립트가 여러 번 실행되면서 이미 존재하는 사용자에 대해 다시 생성 명령이 실행될 때 에러가 발생함.
해결 방안
- Persistent 볼륨 초기화 (데이터 초기화가 가능할 경우):
- 기존 데이터(사용자 정보)를 삭제하고 새로 초기화하는 방법입니다.
bash복사docker-compose down -v docker-compose up -d- 이렇게 하면 새로운 볼륨이 생성되어 MySQL 초기화 스크립트가 깨끗한 상태에서 실행됩니다.
- MySQL 기동 완료 후 스크립트 실행:
- MySQL이 완전히 시작되기 전에 사용자 생성 명령어가 실행되지 않도록, mysqladmin ping 등을 사용하여 MySQL이 준비될 때까지 대기하는 로직을 스크립트에 추가합니다.
- 예를 들어:
bash복사#!/bin/bash service mysql start # 최대 30초간 MySQL 기동 대기 timeout=30 until mysqladmin ping --silent; do sleep 1 timeout=$((timeout - 1)) if [ $timeout -le 0 ]; then echo "MySQL did not start in time." exit 1 fi done if [ -n "${MYSQL_USER}" ]; then mysql -uroot -e "DROP USER IF EXISTS '${MYSQL_USER}'@'%';" mysql -uroot -e "CREATE USER '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';" mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO '${MYSQL_USER}'@'%';" mysql -uroot -e "FLUSH PRIVILEGES;" fi sleep infinity
- 이 방식은 MySQL이 완전히 준비된 후에 사용자 관련 명령어를 실행하여 타이밍 문제를 방지합니다.
- 명령어 안전하게 사용하기:
- MySQL 8.0 이상에서는 CREATE USER IF NOT EXISTS ... 구문을 사용할 수 있으므로, 이를 사용해도 좋습니다.
- 그러나 이미 존재하는 사용자를 명시적으로 제거하는 방식(DROP 후 CREATE)이 보다 명확한 경우도 있습니다.
결론
- 문제 요약:
Persistent 볼륨에 남은 이전 사용자 데이터와 MySQL 기동 타이밍 문제로 인해, 스크립트 내에서 'cheston'@'%' 사용자 삭제 및 재생성이 제대로 처리되지 않아 ERROR 1396 에러가 발생했습니다. - 해결 방법:
- 필요에 따라 기존 볼륨을 초기화하여 깨끗한 상태에서 시작하거나,
- MySQL이 완전히 기동된 후에 사용자 삭제 및 생성 명령어가 실행되도록 스크립트에 대기 로직을 추가하는 방법으로 문제를 해결할 수 있습니다.
수동으로 MySQL 접속 후 사용자를 삭제하면 성공한 것으로 보아, 볼륨의 기존 데이터가 문제였던 것으로 판단됩니다. 이 점과 MySQL 기동 타이밍을 고려하여 스크립트를 개선하면 정상적으로 동작할 것입니다.
반응형
'기초 튼튼 > 시행착오노트' 카테고리의 다른 글
[Selenium] 크롬 드라이버 버전 문제 해결 (0) | 2023.10.28 |
---|---|
[elastic beanstalk 에러 해결] The instance profile aws-elasticbeanstalk-ec2-role associated with the environment does not exist. (0) | 2023.09.09 |
[시행착오노트] AWS RDS 로컬 피시에서 접근하기 (0) | 2023.03.22 |
[시행착오노트] MySQL rank 함수 구현 (0) | 2021.06.18 |
[시행착오노트] pandas 고유값 카운트: value_counts() (0) | 2021.06.17 |