우당탕탕

MySQL 8.0 업그레이드 후 깨진 쿼리, 저는 이렇게 해결했어요 본문

Database

MySQL 8.0 업그레이드 후 깨진 쿼리, 저는 이렇게 해결했어요

모찌모찝 2026. 6. 19. 10:05

MySQL 8.0으로 업그레이드할 때 쿼리가 갑자기 안 돌아가서 정말 고생했어요. 기존에는 아무 문제 없던 게 어느 순간 에러만 나고, 당황스럽더라고요. 이번에 직접 겪으면서 어떤 부분이 문제였는지, 그리고 어떻게 고쳤는지 정리해 봤어요.

이 글에서는 MySQL 8.0 업그레이드 이후 깨진 쿼리 유형들을 사례별로 다루고, 제가 직접 시도해본 해결법과 흔히들 하는 방법들을 비교해 드릴게요. 실제 실행 결과도 포함해서, 비슷한 문제 겪으실 분들께 정확한 도움이 될 겁니다.

개발 환경 / 버전 정보

제가 사용한 환경은 MySQL 5.7에서 MySQL 8.0.33으로 업그레이드했습니다. OS는 Ubuntu 22.04이고, 테스트는 Workbench 8.0과 CLI에서 했어요.

업그레이드 후 깨진 쿼리 유형과 해결법 비교

사실 MySQL 8에서는 기본 설정과 기능의 변화가 꽤 많아서 쿼리가 깨질 가능성이 높아요. 제가 겪은 대표적인 사례를 크게 3가지로 나눠 봤어요. 그리고 다른 개발자들 사례와도 비교하면서 차이점을 표로 정리했습니다.

문제 유형 저의 해결법 다른 사례 해결법 결과 차이
예약어로 인한 쿼리 오류 컬럼명에 백틱(`) 강제 적용 컬럼명 변경하거나 별칭 사용 저는 수정 최소화로 빠르게 해결, 다른 사례는 스키마 영향
JSON 함수 변경에 따른 오류 함수명과 인자 재검토 후 수정 라이브러리 의존으로 대체 직접 수정이 빠르지만 코드량 늘어남
GROUP BY 엄격 모드에 걸림 SQL_MODE에서 ONLY_FULL_GROUP_BY 제거 쿼리 전면 재작성 저는 임시방편, 다른 사례는 장기 해결책

1. 예약어 문제, 백틱으로 쉽게 해결한 경험

사실 이 부분이 가장 간단해 보이지만, 막상 실제 쿼리에선 많이들 놓치더라고요. MySQL 8.0에서 새로 예약어가 추가돼서 기존 쿼리가 에러가 났던 상황인데요, 저는 그냥 컬럼명에 `를 무조건 씌워서 해결했어요.

-- 깨졌던 쿼리 예시
SELECT select, from, where FROM my_table WHERE where = 'test';

-- 예약어라 에러 발생

-- 해결: 백틱 적용
SELECT `select`, `from`, `where` FROM `my_table` WHERE `where` = 'test';

이렇게 하니까 아무 문제 없이 바로 실행되더라고요. 다른 사람들은 컬럼명 자체를 아예 바꾸거나, 별칭을 썼던데 스키마를 건드리지 않고 쿼리만 바꾸는 게 시간도 덜 들고 마음도 편했어요.

2. JSON 함수 변경, 직접 수정 vs 라이브러리 의존

그런데 여기서 많이 틀리는 부분이 JSON 관련 함수였어요. 8.0에서 JSON 관련 함수 이름이나 동작이 바뀐 게 꽤 있거든요. 예전 쿼리에서 사용하던 함수가 없어져서 실행 에러가 났는데, 저는 함수 이름과 파라미터를 직접 변경했어요.

-- 5.7 버전
SELECT JSON_EXTRACT(data, '$.name') FROM my_table;

-- 8.0 변경 후
SELECT JSON_UNQUOTE(JSON_EXTRACT(data, '$.name')) FROM my_table;

경우에 따라서는 JSON_UNQUOTE를 써줘야 했고, JSON_ARRAYAGG 같은 함수는 동작이 더 엄격해졌더라고요. 다른 사례에서는 아예 외부 라이브러리를 쓰면서 JSON을 미리 처리하는 쪽으로 풀던데, 저는 쿼리 안에서 최대한 처리하는 게 편했어요. 다만 코드가 좀 복잡해졌다는 단점이 있었습니다.

3. GROUP BY 엄격 모드, sql_mode 조정으로 임시 방편 썼어요

가장 난감했던 부분인데, MySQL 8.0부터 기본으로 ONLY_FULL_GROUP_BY가 활성화돼서 기존 GROUP BY 쿼리가 깨졌어요. 저는 이걸 바로 고치기 애매해서 sql_mode에서 해당 옵션만 제거해서 해결했는데요.

-- 현재 모드 확인
SELECT @@sql_mode;

-- 제거해서 임시방편
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

이렇게 하면 기존 쿼리가 다시 실행되긴 하는데, 다른 분들은 쿼리를 아예 재작성해서 그룹핑 기준을 명확히 하는 방법을 추천하더라고요. 장기적으로는 그게 맞는 방법이라 생각하지만, 급할 땐 sql_mode 조정도 괜찮은 선택입니다.

실행 결과 직접 보여드릴게요

간단한 테스트 테이블을 만들어서 위 3가지 문제를 각각 실험해봤어요.

CREATE TABLE my_table (
  `select` VARCHAR(20),
  `from` VARCHAR(20),
  `where` VARCHAR(20),
  data JSON
);

INSERT INTO my_table VALUES
('a', 'b', 'c', '{"name":"kim"}'),
('x', 'y', 'z', '{"name":"lee"}');

-- 백틱 적용 쿼리
SELECT `select`, `from`, `where` FROM my_table WHERE `where` = 'c';

-- JSON 함수 수정 쿼리
SELECT JSON_UNQUOTE(JSON_EXTRACT(data, '$.name')) AS name FROM my_table;

-- GROUP BY 테스트
SELECT `select`, COUNT(*) AS cnt FROM my_table GROUP BY `select`;

위 쿼리들은 모두 MySQL 8.0 환경에서 오류 없이 실행되었어요. 만약 백틱을 빼거나 json 함수 수정을 안 했다면 에러가 나거나 결과가 빈 값이 되었을 겁니다.

여기서 막혔던 부분과 해결 과정

막상 시도할 때는 단순해 보여도 정말 에러 메시지가 난해했어요. 예를 들어, JSON_EXTRACT가 null을 반환한다거나, ONLY_FULL_GROUP_BY 관련 에러가 뜨면 왜 그런지 한참 헤맸거든요.

ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column

이 에러가 왜 나는지 공식 문서랑 커뮤니티 검색으로 겨우 알았고, 결국 sql_mode부터 점검하는 게 우선순위라는 사실을 깨달았어요.

심화: MySQL 8.0 업그레이드 시 주의할 점들

사실 여기에 적은 문제 말고도 여러 가지가 있는데요, 몇 가지 팁을 드리자면 이렇게 하면 좋아요.

  • 업그레이드 전에 mysql_upgrade를 꼭 돌릴 것
  • SQL_MODE 기본값 확인 후 프로젝트에 맞게 세팅 변경하기
  • JSON, 시간 관련 함수들이 바뀌었으니 테스트 케이스 만들어두기
  • 기존 쿼리에서 예약어인지 미리 점검하는 도구 활용 권장
  • 가능하면 로컬 환경에서 먼저 8.0 쿼리 호환성 테스트 수행

자주 물어보시는 것들

Q. mysql_upgrade를 안 하면 어떤 문제가 생기나요?

A. 테이블 구조나 인덱스가 8.0에 맞게 업데이트되지 않아서 쿼리 실행 시 오류가 발생하거나 데이터 무결성 문제가 생길 수 있어요. 업그레이드 과정에서 꼭 선행하세요.

Q. ONLY_FULL_GROUP_BY 옵션을 빼면 정말 안 좋은가요?

A. 엄격한 그룹핑 검사를 무시하기 때문에 쿼리가 모호한 결과를 낼 수 있어요. 임시로 해결하려면 괜찮지만, 가능하면 쿼리를 논리적으로 다시 짜는 게 맞습니다.

MySQL 8.0 업그레이드하면서 깨졌던 쿼리들을 직접 고쳐 보니, 원인을 정확히 파악하고 환경에 맞는 대응을 하는 게 가장 중요하다는 걸 알게 됐어요. 예약어 문제, JSON 함수 변경, GROUP BY 모드 이 세 가지는 거의 필수 점검 사항이라 보시면 돼요. 앞으로 업그레이드할 때는 이런 부분부터 챙기시면 시행착오가 훨씬 줄어들 겁니다.

Comments