MySQL 5.7에서 8.0으로 버전을 올려서 최신 DB 환경을 구축했거나 Docker로 MySQL 인스턴스를 새로 띄운 뒤 PHP로 접속을 시도하다가 SQLSTATE[HY000] [2054] 에러를 마주친 적이 있을 것이다. DB 서버는 올바르게 동작하고 접속 정보도 분명 정확한데 PHP 스크립트를 실행하는 즉시 커넥션이 튕겨나간다.
다만 정확한 원인이나 해결책을 모르는 채 php.ini 설정을 무작정 수정하거나 DB 서버를 계속 재부팅하는 경우가 많다.
이번에는 MySQL 8.0의 기본 인증 플러그인 변경 원인이 정확히 뭔지, 왜 PHP PDO 연동에서 오류가 발생하는지, 그리고 운영 환경별로 안전하게 해결하는 방법을 완벽하게 정리해서 소개하겠다.

 

MySQL 8.0 인증 방식 변경 원인과 PDO 오류 구조

MySQL 8.0 버전부터는 보안 강화를 위해 기본 사용자 인증 플러그인이 기존 mysql_native_password에서 caching_sha2_password로 변경되었다. 보안 관점에서는 SHA-256 기반의 비대칭 암호화와 빠른 캐싱을 지원하므로 훨씬 안전하다.
문제는 기존의 PHP PDO extensions(특히 php_pdo_mysql) 및 mysqlnd 드라이버 구버전이 이 새로운 인증 메커니즘을 제대로 처리하지 못한다는 점이다. 클라이언트인 PHP가 DB 서버가 요구하는 SHA-256 인증 교환 방식을 알지 못하니 연결 시도 단계에서 2054 에러를 내뿜으며 끊어진다.

 

caching_sha2_password 접속 오류 해결하는 두 가지 방법

이 문제의 본질은 DB 계정이 사용 중인 인증 플러그인과 PHP 클라이언트가 지원하는 인증 플러그인의 불일치다. 상황에 맞춰 계정 단위로 방식을 바꾸거나 서버 전역 설정을 변경해 해결할 수 있다.

 

방법 1: 특정 계정의 인증 방식을 mysql_native_password로 변경

가장 안전하고 권장되는 방식이다. 전역 보안 설정을 건드리지 않고, PHP 애플리케이션이 사용하는 특정 사용자 계정에만 이전 인증 방식을 적용한다. MySQL 관리자 권한(root)으로 접속한 뒤 다음 SQL 명령을 실행한다.

ALTER USER 'app_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
FLUSH PRIVILEGES;

 

방법 2: MySQL 서버 전역 설정 파일(my.cnf) 수정

개발 환경이나 여러 클라이언트가 동시에 구형 방식을 사용해야 하는 경우에는 서버 기본값을 바꿀 수 있다. /etc/mysql/my.cnf 또는 /etc/my.cnf 파일의 [mysqld] 섹션에 아래 설정을 추가하고 MySQL 서비스를 재시작한다.

[mysqld]
default_authentication_plugin = mysql_native_password

 

실전 예제: PHP PDO 데이터베이스 연결 테스트

인증 방식을 수정한 후 PHP PDO를 통해 안전하게 데이터베이스에 연결하는 실전 코드 구조다.

✗ 잘못된 연동 시도 (caching_sha2_password 미지원 환경에서 기본 계정 연결 시도)

<?php
// 인증 방식 불일치 상태에서 기존 코드 그대로 접속 시도
$dsn = 'mysql:host=127.0.0.1;dbname=production_db;charset=utf8mb4';
$user = 'app_user';
$password = 'secret1234';

$pdo = new PDO($dsn, $user, $password);
// 원인: 서버는 caching_sha2_password를 요구하지만 PHP 드라이버가 응답하지 못해 Fatal Error 발생
?>

결과: Fatal error: Uncaught PDOException: SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client

✓ 올바른 연동 코드 (mysql_native_password 계정 설정 후 PDO 예외 처리)

<?php
$dsn = 'mysql:host=127.0.0.1;dbname=production_db;port=3306;charset=utf8mb4';
$user = 'app_user';
$password = 'secure_password123!';

$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false,
];

try {
    $pdo = new PDO($dsn, $user, $password, $options);
    echo "MySQL 8.0 데이터베이스 연결에 성공했습니다.";
} catch (PDOException $e) {
    error_log("DB 접속 실패 상세: " . $e->getMessage());
    exit("데이터베이스 커넥션에 실패했습니다. 관리자에게 문의하세요.");
}
?>

결과: MySQL 8.0 데이터베이스 연결에 성공했습니다.

 

인증 방식 비교 및 주의사항

두 인증 방식의 명확한 특성을 이해하고 서비스 환경에 맞춰 적용해야 한다.

비교 항목mysql_native_passwordcaching_sha2_password
암호화 알고리즘SHA-1 기반SHA-256 기반
보안 수준보통 (오래된 표준)매우 높음 (강력한 보안)
PHP 구버전 호환성완벽 호환 (PHP 5.x~8.x)PHP 7.4 이상 + OpenSSL 필요
MySQL 8.0 기본값아님 (기존 방식)기본값 (Default)

✗ 서버 전체 보안을 낮추기 위해 my.cnf 전체 설정을 바꾸고 계정을 root 그대로 운영하는 실수.
✓ 애플리케이션 전용 계정을 별도로 분리 생성하고 해당 계정만 mysql_native_password를 지정하여 운영하는 방법.

 

정리 및 마무리

MySQL 8.0 인증 플러그인 설정은 백엔드 서비스의 안정적인 DB 연결을 결정짓는 핵심 요소다. 무심코 넘어가기 쉬운 작은 보안 및 인증 습관이 모여서 서비스의 안정성과 가동률을 만든다는 점을 잊지 말자. 이 글의 인증 방식 변경 명령어와 PHP PDO 연결 코드를 참고해 서버 환경을 재점검하면, 더 이상 DB 접속 에러로 시간을 허비하지 않고 안정적인 서비스 운영 결과를 얻을 수 있을 것이다.