MySQL을 설치하고 처음 접속하려는데 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)가 뜨면서 접속이 안 되는 경험을 해봤을 것이다. 또는 잘 쓰던 서버에서 어느 날 갑자기 같은 에러가 발생해서 당황한 적도 있을 것이다.
다만 대부분의 개발자들은 검색해서 나오는 명령어를 무작정 복사해 실행하다가 오히려 상황을 더 꼬이게 만든다. 비밀번호 문제인지, 권한 문제인지, 인증 플러그인 문제인지 원인부터 정확히 파악해야 올바른 해결책을 적용할 수 있다.
이번에는 MySQL ERROR 1045가 정확히 무엇인지, 왜 발생하는지, 그리고 상황별로 어떻게 해결하는지 완벽하게 정리해서 소개하겠다.
ERROR 1045는 MySQL 서버가 클라이언트의 인증(Authentication)을 거부했을 때 발생하는 에러다. 쉽게 말해 "너 누군지 모르겠으니 들어올 수 없다"는 뜻이다.
에러 메시지를 분해해보면 이렇다.
| 부분 | 의미 |
|---|---|
| ERROR 1045 | MySQL 에러 코드 (인증 실패) |
| (28000) | SQLSTATE 코드 (접근 거부 계열) |
| user 'root'@'localhost' | 접속 시도한 사용자명과 호스트 |
| using password: YES / NO | 비밀번호를 보냈는지 여부 |
using password: YES면 비밀번호를 보냈지만 틀렸다는 뜻이고, using password: NO면 비밀번호를 아예 안 보냈다는 뜻이다. 이 차이만 알아도 원인의 절반은 좁혀진다.
ERROR 1045가 발생하는 원인은 크게 다섯 가지로 나뉜다.
| 원인 | 설명 | 빈도 |
|---|---|---|
| 비밀번호 오타/분실 | 단순히 비밀번호를 잘못 입력하거나 잊어버린 경우 | 매우 높음 |
| 사용자 미존재 | 해당 user@host 조합의 계정이 MySQL에 없는 경우 | 높음 |
| 호스트 불일치 | 'root'@'localhost'와 'root'@'127.0.0.1'은 MySQL에서 별개 계정 | 중간 |
| 인증 플러그인 문제 | MySQL 8.0의 caching_sha2_password를 구 클라이언트가 지원 못 하는 경우 | 중간 |
| 권한 테이블 손상/미갱신 | FLUSH PRIVILEGES를 안 했거나 mysql.user 테이블이 손상된 경우 | 낮음 |
비밀번호를 알고 있는데도 에러가 나면, 접속 명령어부터 확인하자.
✗ 잘못된 접속 (비밀번호 사이에 공백이 들어감)
# -p 뒤에 공백이 있으면 비밀번호가 아니라 데이터베이스명으로 인식된다
mysql -u root -p mypassword
위 명령은 비밀번호 없이 접속을 시도하면서, 'mypassword'라는 이름의 데이터베이스에 접속하려는 것으로 해석된다. 결국 using password: NO 에러가 뜬다.
✓ 올바른 접속 (-p 뒤에 공백 없이 바로 비밀번호 입력, 또는 -p만 쓰고 프롬프트에서 입력)
# 방법 1: -p 뒤에 공백 없이 바로 비밀번호
mysql -u root -pmypassword
# 방법 2: -p만 쓰고 Enter 후 비밀번호 입력 (보안상 권장)
mysql -u root -p
Enter password: ********
방법 2가 터미널 히스토리에 비밀번호가 남지 않아서 보안상 훨씬 안전하다.
root 비밀번호를 완전히 잊어버렸다면, MySQL을 인증 건너뛰기 모드로 재시작해서 비밀번호를 재설정해야 한다.
Step 1: MySQL 서비스 중지
# CentOS / RHEL
sudo systemctl stop mysqld
# Ubuntu / Debian
sudo systemctl stop mysql
Step 2: 안전 모드로 MySQL 시작
sudo mysqld_safe --skip-grant-tables --skip-networking &
--skip-grant-tables는 인증 없이 접속을 허용하고, --skip-networking은 외부 네트워크 접속을 차단해서 보안 위험을 줄인다. 반드시 둘 다 써야 한다.
Step 3: root로 접속 후 비밀번호 변경
-- 비밀번호 없이 접속
mysql -u root
-- MySQL 5.7 이상
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY '새비밀번호여기입력';
-- MySQL 5.6 이하 (ALTER USER 미지원)
FLUSH PRIVILEGES;
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('새비밀번호여기입력');
Step 4: 안전 모드 종료 후 정상 재시작
# 안전 모드 프로세스 종료
sudo kill $(cat /var/run/mysqld/mysqld.pid)
# 정상 시작
sudo systemctl start mysqld
이후 mysql -u root -p로 새 비밀번호를 입력하면 정상 접속된다.
MySQL 8.0부터 기본 인증 플러그인이 caching_sha2_password로 바뀌었다. PHP 구버전이나 오래된 MySQL 클라이언트는 이 방식을 지원하지 못해서 ERROR 1045가 발생할 수 있다.
✗ 현상: PHP에서 mysqli_connect 호출 시 Access denied 발생 (MySQL CLI에서는 잘 됨)
✓ 해결: 해당 사용자의 인증 플러그인을 변경
-- 현재 사용자의 인증 플러그인 확인
SELECT user, host, plugin FROM mysql.user WHERE user = 'root';
-- caching_sha2_password → mysql_native_password 로 변경
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '비밀번호';
FLUSH PRIVILEGES;
또는 MySQL 설정 파일(/etc/my.cnf 또는 /etc/mysql/mysql.conf.d/mysqld.cnf)에 전역으로 기본 인증 방식을 지정할 수도 있다.
[mysqld]
default_authentication_plugin=mysql_native_password
설정 변경 후 MySQL을 재시작하면 이후 생성되는 모든 사용자에게 적용된다.
MySQL에서 'root'@'localhost'와 'root'@'127.0.0.1'은 완전히 다른 계정이다. localhost는 유닉스 소켓으로, 127.0.0.1은 TCP/IP로 접속한다.
-- 현재 존재하는 모든 사용자와 호스트 조합 확인
SELECT user, host FROM mysql.user ORDER BY user, host;
-- 필요하면 127.0.0.1용 계정도 별도로 생성
CREATE USER 'root'@'127.0.0.1' IDENTIFIED BY '비밀번호';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION;
FLUSH PRIVILEGES;
PHP의 mysqli_connect에서 호스트를 localhost로 쓸 때와 127.0.0.1로 쓸 때 접속 방식이 다르다는 점을 반드시 기억해야 한다.
| 실수 | 문제점 | 올바른 방법 |
|---|---|---|
| my.cnf에 skip-grant-tables를 넣고 운영 | 누구나 인증 없이 DB에 접속 가능 — 치명적 보안 구멍 | 비밀번호 재설정 후 반드시 해당 옵션 제거하고 재시작 |
| FLUSH PRIVILEGES 누락 | GRANT/ALTER USER 후 권한 캐시가 갱신되지 않아 변경이 즉시 반영 안 됨 | 권한 변경 쿼리 실행 후 반드시 FLUSH PRIVILEGES 실행 |
| root에 빈 비밀번호 사용 | 외부 노출 시 DB 전체가 탈취될 수 있음 | 최소 12자 이상, 영문+숫자+특수문자 조합 비밀번호 설정 |
| 모든 앱에서 root 계정 사용 | 하나의 앱이 뚫리면 전체 DB가 위험 | 앱마다 별도 사용자 생성 후 필요한 DB에만 권한 부여 |
ERROR 1045 해결 흐름을 한눈에 정리하면 다음과 같다.
| 상황 | 확인 사항 | 해결 방법 |
|---|---|---|
| using password: NO | -p 옵션이 제대로 붙었는지 | -p 뒤 공백 없이 비밀번호 입력 또는 -p만 입력 후 프롬프트에서 입력 |
| using password: YES | 비밀번호가 맞는지 | 비밀번호 확인, 모르면 안전 모드로 재설정 |
| CLI는 되고 PHP는 안 됨 | 인증 플러그인 확인 | mysql_native_password로 변경 |
| localhost는 되고 127.0.0.1은 안 됨 | 호스트별 계정 존재 여부 | 해당 호스트용 계정 생성 |
MySQL ERROR 1045는 단순한 비밀번호 오류부터 인증 플러그인 불일치까지 원인이 다양하기 때문에, 에러 메시지를 정확히 읽는 습관이 무엇보다 중요하다. using password 부분과 user@host 부분만 제대로 확인해도 원인의 80%는 특정할 수 있다. 이 글의 상황별 해결 방법을 참고해 자신의 케이스에 맞는 해결책을 적용하면, 더 이상 ERROR 1045에 시간을 낭비하는 일은 없을 것이다.