GCP 에서 MySQL 인스턴스를 운영중이었다.
ERROR 1045 (28000): Access denied for user 'user'@'host'
계정도 맞고 비밀번호도 맞다. 리셋하고, 접속 IP 네트워크 재확인하고, 무슨 짓을 해도 접속이 안되어서 한나절을 삽질했는데 어이없게도 드라이버를 MariaDB를 쓰고 있어서 발생한문제였다.
MariaDB는 MySQL의 창업자 중 한 명이 Fork 한 뒤 독립적인 프로젝트로 발전.
따라서 나는 둘이 같은 계열의 DB라고 인지하고 있었던 것 같다.
왜 드라이버가 다르면 접속 조차 안될까?
애초에 내가 드라이버를 정말 정확히 이해하고 있을까?
내가 DB 차이와 장단점을 제대로 파악하고 있는걸까?
즐거운 공부 기회로 승화시켜보자.
차례
1. MySQL vs MariaDB vs PostgreSQL
2. 드라이버란 무엇인가
3. 드라이버의 역할
4. 해결책
1. MySQL vs MariaDB vs PostgreSQL
계보와 탄생 배경

MySQL은 1995년 스웨덴 개발자가 만듦. 10억불에 Sun Microsystems 가 인수했다하며 이후 Oracle이 Sun을 인수하면서 결국 2010년 Oracle 소유가 됐다 (74억불)
MariaDB는 MySQL이 오라클에 인수되면서 Oracle 의 방향성에 반발해 MySQL 개발자가 독립 오픈소스 재단으로 갈라져나온 DB.
재밌는건 MySQL의 My, MariaDB의 Maria 도 딸 이름에서 나왔다고 😊
GCP Cloud SQL 에서는 MySQL을 기본 선택지로 사용하고 있고 AWS에서는 MariaDB 지원뿐 아니라, MySQL 과 호환되면서도 성능이 5배까지 뛰어난 (Postgres 대비 3배까지) Aurora DB 까지 만들어 지원. 스케일/가용성/성능을 AWS 식으로 재설계한 premium-managed-db 상품으로 부가가치를 만드는중.
(클라우드 사업자 입장에서는 제품 수를 늘릴수록 운영비용이 늘어난다. 엔지니어를 타겟으로하는 GCP 와 사업자를 대상으로하는 AWS 의 철학 차이가 여기서도 보인다. 아래 링크는 GCP-AWS 비교글)
28장. GCP VM에 Public Key 분명 올려놨는데 왜 계속 사라짐? AWS에선 이런 일 없었는데 (클라우드 인프
서비스 기업만들때 매출 발생하는 PMF 찾는 것 다음으로 중요한게 운영 즉 인프라가 아닌가 생각한다.심도한 이유가 있는데 그것은 바로... 돈이 나가기 때문. 비용 지출지점이기 때문. IT 기업을
biz-ninza.tistory.com
한편, PostgeSQL은 1986년 UC 버클리 교수 연구실에서 한 프로젝트를 뿌리로 1996년 PostgresSQL로 명명
JSON, 복잡 쿼리, 인덱싱 등은 PostgreSQL 이 강한 경우가 많다. 검색/피드/추천/로그 분석처럼 JSON과 정형데이터가 섞여있으며 쿼리가 복잡해질 서비스에 적합하다.
스토리지 엔진 — "어떻게 데이터를 저장하는가"의 구현체
스토리지 엔진은 데이터를 디스크에 읽고 쓰는 방식 자체를 구현한 소프트웨어 계층이다. 같은 SQL을 실행해도 스토리지 엔진이 다르면 트랜잭션 지원 여부, 락 동작, 인덱스 구조, 복구 방식이 모두 달라진다.
MySQL과 MariaDB는 스토리지 엔진을 플러그인 스타일로 교체할 수 있다. 기본은 InnoDB(트랜잭션, ACID 지원) 이지만 테이블마다 다른 엔진을 같은 서버에서 골라쓸 수 있는 반면, PostgreSQL 은 스토리지 엔진이 하나이며 Extension 기능을 확장하는 방식.
또 동시성제어 (Multi-Version Concurrency Control, MVCC) 방식에서도 좀 차이가 난다는데 글의 주제가 아니므로 이정도까지만 하자.
PostgreSQL 은 복잡쿼리와 인덱싱에서 왜 강해?
PostgreSQL은 쿼리를 실행하기 전에 여러 실행 계획을 시뮬레이션해서 가장 비용이 낮은 계획을 고르는 플래너를 갖고 있다고. 즉, 테이블 전체를 읽을지 인덱스 타고 들어갈지 어떤 순서로 할지를 미리 계산. 또 여러 인덱스 타입과 기능이 잘 되어있어서 단일 쿼리 안에 복잡한 조건-조인/필터/집계/JSON/텍스트검색 등- 이 섞여있어도 스스로 최적화하면서 실행계획을 잘 찾아준다 (카더라)
2. 드라이버란 무엇인가

모두가 알듯이 드라이버는 애플리케이션과 DB 서버 사이의 인터페이스.
DB 클라이언트와 헷갈리면 안됨. DB 클라이언트는 사람이 직접 쿼리 실행하거나 DB 탐색하기 위해 쓰는 CLI/GUI 도구이고, 터미널에서 쓰는 mysql 같은 명령줄 프로그램 혹은 DBeaver 같은 GUI가 그러하다.
이런 DB 클라이언트도 결국 드라이버를 통해 DB 와 직접 통신을 하게 된다.
드라이버는 애플리케이션이 DB와 '통신' 하기위해 사용하는 소프트웨어 컴포넌트.

3. 드라이버의 역할
Java 의 JDBC(Java Database Connectivity)도 인터페이스를 정의한 명세이고 실제 구현은 각 DB 드라이버 (jdbc:mysql://...) 가 담당. 즉, 개발자는 JDBC 인터페이스만 쓰면 되지만 실제 프로토콜 통신, 인증 처리, 데이터 변환을 각 드라이버 구현체가 담당하는 것. CLI클라이언트나 Java 드라이버나 개념적으로 동일하다.
드라이버의 주요 역할은 DB 서버가 이해하는 바이너리 패킷으로 변환해서 TCP로 전송하고 응답을 받는 것이다.
풀어서 나열해보면,
첫째, 프로토콜을 구현하고
둘째, 인증과정을 처리하며
셋째, 데이터타입을 변환하고 (직렬화/역직렬화)
넷째, TLS/SSL 을 처리한다.

유저플로우 관점에서 조금 더 살펴보자.
우선 전제조건.
"DB도 서버다"
[ 첫째, 프로토콜을 구현 ]
결국 DB도 IP/포트로 떠있는 하나의 서버로 바라봐야하고
1) 클라이언트는 서버로 SYN 필드를 보내고
2) 서버는 SYN + ACK로 응답하고
3) 다시 클라이언트는 서버로 ACK 를 보내는 3way handshake 과정이 기본적으로 필요하다.
이렇게 신뢰할 수 있는 TCP 채널 위에서 DB 고유 프로토콜이 시작되는것.

한편, DB는 모두 자기만의 바이너리/텍스트 프로토콜 규격을 갖으며 드라이버는 이 규격대로 패킷을 구성하고 파싱한다.
- 예: “첫 1바이트는 패킷 타입, 다음 3바이트는 길이, 다음 N바이트는 페이로드” 같은 규칙.
이렇게 SQL 문자열을 네트워크에 실을 수 있는 구조체/바이트 시퀀스로 바꾸는 것

한편 MySQL 과 MariaDB는 프로토콜까지는 거의 동일하게 맞춰져 있어서 일단 통신까지는 된 것
[ 둘째, 인증과정을 처리 ]
프로토콜이 시작되어 물리적인 채널이 열렸다면 인증절차가 시작된다.
서버가 TCP 위에서 인증 프로토콜을 제시하면 클라이언트는 해당 방식대로 패스워드를 암호화해서 보낸다.
인증 프로토콜 자체가 안맞아서 로그인이 실패.

📌 MySQL - caching_sha2_password
이전 기본값이었던 mysql_native_password는 비밀번호의 SHA1 해시를 저장하고 인증에 사용. SHA1은 충돌 공격에 취약하다는 게 알려진 알고리즘이라고 (카더라) MySQL 8.0은 더 강한 SHA-256 기반의 caching_sha2_password를 기본으로 채택했으며 이는 비밀번호 검증도 캐싱되면서 성능적인 이득을 가져간다.

서버는 저장된 SHA256 해시와 nonce로 같은 계산을 해서 비교한다. 비밀번호 원문이 네트워크로 전송되지 않는다. "caching"이라는 이름은 서버가 인증 결과를 잠시 캐시해서 반복 접속 시 RSA 교환 없이 빠르게 처리하는 최적화에서 나왔다. 처음 접속 시 암호화 채널이 없으면 RSA 공개키 교환이 필요하고, MariaDB 드라이버는 이 RSA 교환도 구현하지 않는다.
*RSA 공개키 교환: 서버는 공개키와 비공개키 한 쌍을 가지며, 공개키는 모두에게 배포. 공개키로 암호화한 데이터만 서버의 비공개키로 복화한다는 기본적인 사실. RSA는 특정 단어의 약자가 아닌 1977년 이 암호체계를 개발한 세 명의 이니셜 첫글자 모음. 참고로 전세계 대부분 인터넷 뱅킹은 이러한 방식을 사용하며 미국은 AES 라는 표준 암호화 알고리즘을 사용)
RSA 방식 흐름 (참고)
- 서버가 인증서(= 서버의 공개키가 들어 있음)를 클라이언트에게 보냄.
- 클라이언트가 랜덤한 비밀값(pre-master secret)을 하나 생성.
- 이 비밀값을 서버의 공개키로 암호화해서 서버에게 전송.
- 서버는 자기 비공개키로 이 값을 복호화.
- 이제 클라이언트와 서버 둘 다 같은 비밀값을 공유하게 되고, 이걸 기반으로 대칭키(세션키)를 만들어서 이후 통신은 대칭키로 빠르게 암호화.
인터넷 위에서 누가 엿들어도, 공개키로 암호화된 pre-master secret을 복호화할 수 있는 건 비공개키 가진 서버뿐.
그래서 대칭키를 안전하게 합의할 수 있고, 그다음부터는 대칭키(AES 등)로 빠르게 암호화 통신을 진행.
📌 MariaDB - ed25519 (혹은 mysql_native_password)
ed25519는 GCP VM 공개키에서 언뜻 봤던 계열인데 SSH 키 포맷에서 자주 볼 수 있는 일종의 서명 알고리즘이라고 한다.
ed25519 플러그인은 인증 방식이 근본적으로 다르다. 비밀번호 해시를 주고받는 게 아니라, 공개키 암호학 기반의 서명(signature)으로 인증한다. ed25519는 "Edwards-curve Digital Signature Algorithm on Curve25519". Bernstein이 설계한 타원곡선 암호 알고리즘으로, 빠르고 안전하다. GCP VM에 SSH 접속할 때 ssh-keygen -t ed25519로 생성하는 키가 바로 이 알고리즘이다. 개인키-공개키 쌍을 만들고, 서버에 공개키를 등록하고, 인증 시 개인키로 서명해서 신원을 증명하는 방식이 SSH와 동일하다.
MariaDB 드라이버에서는 caching_sha2_password 를 구현하지 않아, MySQL 서버에는 접속할 수 없었던 것.
실제 비밀번호가 맞아도 인증 프로토콜 자체가 안 맞아서 로그인에 실패한 것이다.
[ 셋째, 데이터타입을 변환 (직렬화/역직렬화) ]
테이블 칼럼을 INT, VARCHAR(255) 등으로 정의한다해도 네트워크로 오가는 것은 결국 바이트 배열이다.
DB는 결과를 바이너리/텍스트 프로토콜에 맞춰 '바이트 덩어리' 를 보낸다.
드라이버는 이 바이트들을 언어의 타입으로 다시 복원한다.
- 예: 2025-01-01 10:00:00 → Java의 LocalDateTime, JS의 Date
이 때 DB가 네트워크 전송용 바이트로 바꾸는 것을 직렬화(serialize), 바이트를 언어/객체 타입으로 되돌리는 역직렬화(deserialize) 과정이 일어난다.

[ 넷째, TLS/SSL 을 처리한다 ]
드라이버는 연결 옵션에서 useSSL=true, sslmode=require 같은 설정을 읽고, TLS 핸드쉐이크를 수행하도록 소켓을 감싸거나 DB가 요구하는 SSL 버전이나 옵션을 맞춰주는 역할도 수행한다고.
이후 DB 패킷들은 모두 TLS로 암호화된 스트림에서 오가게 되는 것.
JDBC 예: jdbc:sqlserver://...;sslProtocol=TLS 같은 옵션으로 TLS 사용을 지정하는 것도 같은 맥락
4. 해결책
당연히 올바른 클라이언트/드라이버를 쓰면 된다.
그러나 MySQL 계정의 인증 플러그인을 caching_sha2_password 가 아니라 mysql_native_password 로 바꾸면 가능은 하겠다.

5. 고찰
에러 메세지상 비밀번호 틀림 문제로 밖에 생각을 하지 않았으나, 실제 원인은 인증 플로그인 불일치 문제였다.
에러 로그에 의존하지 않고 전체적인 아키텍쳐과 통신 흐름을 머리속에 집어 넣는게 기본이다.
ERROR 1045 (28000): Access denied for user 'user'@'host'
또한 생각해보면 클라우드 관리형 DB는 메이저 버전 업그레이드를 주기적으로 안내하거나 자동 적용한다. MySQL 5.7 → 8.0 업그레이드 순간 기본 인증 플러그인이 바뀐다.
즉 어느 날 운영 서버에서 로그인이 갑자기 안 될 수 있다. 드라이버 버전과 서버 버전 호환성을 사전에 파악하고 관리하는 것이 실력자로 가는 길일 것.
한편 비밀번호 해시를 전송하지 않는 서명 기반 인증(ed25519)이 미래이고, SSH가 이미 그 방식을 30년 넘게 써왔으며 DB 인증도 같은 방향으로 수렴하고 있다. GCP VM 공개키와 MariaDB ed25519 인증이 같은 알고리즘을 쓰는 것은 우연이 아니라고 생각되고 추후 기회가 되면 이 부분을 좀 더 탐구해볼 일이 있을 것으로 예상된다.
✍️
아무리 AI가 판례분석부터 변론서까지 다 작성이 가능해도, 실제 재판에서는 변호사를 쓸 수 밖에 없듯.
프로그래밍도 실제 프로덕션이 되고 돈이 오가는 비지니스 상황에서는 누군가는 의사결정을 내리고 책임져야하며 그것이 나의 역할이라고 믿는다.
좋은 삽질이었다.
'[개발일지] > CS 스터디 플랫폼' 카테고리의 다른 글
| ch9. 스프린트5 종료, 두드려라 그러면 열릴 것이니 (4) | 2026.06.02 |
|---|---|
| 32장. BFF를 지금 왜 써요... Are you insane? (클라우드 인프라 정복기 5) (1) | 2026.01.28 |
| 31장. Next.js 기반 웹을 AWS 에서 Vercel 으로 이전시 고려할점 10가지 (클라우드 인프라 정복기 4) (0) | 2026.01.28 |
| 30장. 왜 요즘은 다 버셀 버셀 할까 (클라우드 인프라 정복기 3) (1) | 2026.01.25 |
| 29장. AWS에서 인스턴스 삭제 협박을 받다 (클라우드 인프라 정복기 2) (1) | 2026.01.23 |