MySQL 크로스 DB JOIN에서 터지는 두 가지 폭탄
11
MySQL 크로스 DB JOIN에서 터지는 두 가지 폭탄
2026-02-11 ~ 2026-02-20
에피소드 1: Slave DB에서 다른 스키마 접근 불가 (02-11)
발단
스케줄러가 2개 스키마(데이터베이스 안에서 테이블, 뷰 등을 논리적으로 묶어놓은 단위)의 테이블을 JOIN 해야 했다. 사용자 정보는 A 스키마, 활동 기록은 B 스키마.
성능을 위해 읽기 전용 Slave DB(Master DB의 데이터를 복제해서 읽기 요청만 처리하는 보조 DB 서버) 커넥션으로 조회하도록 만들었다. 로컬에서 잘 돌아갔는데 dev에 올리자마자 에러가 났다.
Table 'B_SCHEMA.SOME_TABLE' doesn't exist
원인
Master DB 계정
├── A 스키마 ✅
└── B 스키마 ✅ ← 크로스 스키마 접근 가능
Slave DB 계정
├── A 스키마 ✅
└── B 스키마 ❌ ← 권한 없음!
Slave는 특정 스키마만 복제하고 있거나, 계정에 다른 스키마 접근 권한이 없었다.
해결
Slave 대신 Master 커넥션으로 변경. 한 줄 수정이지만 모르면 한참 헤맨다.
에피소드 2: Collation 불일치로 JOIN 실패 (02-20)
발단
두 테이블을 JOIN 하는 쿼리에서 이런 에러가 떴다:
ERROR 1267: Illegal mix of collations
(utf8mb4_unicode_ci, IMPLICIT) and (utf8mb4_general_ci, IMPLICIT)
Collation이 뭔데?
Collation(콜레이션)은 문자열을 비교하고 정렬할 때 어떤 규칙을 따를지 정하는 설정이다.
'cafe' = 'café' ?
utf8mb4_general_ci → 다르다 (악센트 구분)
utf8mb4_unicode_ci → 같다 (유니코드 표준)
MySQL은 두 컬럼을 비교할 때 같은 collation이어야 한다. 다르면 어느 규칙으로 비교할지 모르니까 에러를 낸다.
원인
SELECT a.user_id, a.name
FROM table_a a
JOIN table_b b ON a.user_id = b.user_id -- 💥 collation 불일치!
같은 DB 안인데도 테이블마다 collation이 달랐다. 테이블을 만든 시기가 다르거나 설정이 달랐던 것. → 레거시(오래되어 유지보수가 어려운 기존 시스템) 프로젝트에서 흔히 발생하는 문제다.
해결
JOIN table_b b ON a.user_id = b.user_id COLLATE utf8mb4_unicode_ci
JOIN 조건에 COLLATE를 명시해서 기준을 통일. 다만 이건 임시 해결이고, 테이블 collation을 아예 통일하는 게 근본 해결이다.
크로스 DB JOIN 체크리스트
| 확인 항목 | 설명 |
|---|---|
| 커넥션 권한 | 이 계정이 대상 스키마에 접근 권한이 있는가? 특히 Slave/읽기전용 계정 |
| Collation 일치 | JOIN 대상 컬럼의 collation이 같은가? |
| 인덱스 영향 | COLLATE를 붙이면 해당 컬럼 인덱스를 못 탈 수 있다 (인덱스: DB가 빠르게 검색하기 위해 만드는 목차 같은 자료구조) |
배운 것
- Slave DB는 Master와 권한이 다를 수 있다. 크로스 스키마 쿼리는 커넥션 권한 확인 필수.
- 같은 DB 안에서도 테이블마다 collation이 다를 수 있다. 특히 레거시에서.
- 로컬에서 되는데 dev/prod에서 안 되는 DB 문제는 대부분 권한이나 설정 차이다.