목록으로

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가 빠르게 검색하기 위해 만드는 목차 같은 자료구조)

배운 것

  1. Slave DB는 Master와 권한이 다를 수 있다. 크로스 스키마 쿼리는 커넥션 권한 확인 필수.
  2. 같은 DB 안에서도 테이블마다 collation이 다를 수 있다. 특히 레거시에서.
  3. 로컬에서 되는데 dev/prod에서 안 되는 DB 문제는 대부분 권한이나 설정 차이다.
MySQL 크로스 DB JOIN에서 터지는 두 가지 폭탄 | KYUDORI