우당탕탕

MySQL 8.0 업그레이드하면서 깨졌던 쿼리들, 이렇게 해결했어요 본문

Database

MySQL 8.0 업그레이드하면서 깨졌던 쿼리들, 이렇게 해결했어요

모찌모찝 2026. 7. 20. 15:07

저도 처음에 MySQL 8.0으로 업그레이드하고 나서 기존에 잘 작동하던 쿼리가 갑자기 에러를 뿜거나 이상하게 동작해서 한참 고생했어요. 특히 쿼리 하나하나가 왜 깨졌는지, 또 어떻게 고쳐야 하는지 막막하더라고요. 사실 이 부분이 생각보다 복잡한데, 저처럼 처음 입문하는 분들도 이해할 수 있도록 차근차근 설명해볼게요.

이 글에서는 MySQL 8.0 업그레이드 후 가장 많이 깨진 쿼리 사례들과 그것들을 어떻게 고쳤는지, 그리고 배운 점들을 실제 코드 예시와 함께 소개할게요. 초보자 분들도 쉽게 따라할 수 있도록 용어 설명도 꼭 포함했습니다.

개발 환경 / 버전 정보

제가 사용한 버전은 MySQL 5.7에서 MySQL 8.0으로 업그레이드했어요. 운영체제는 Ubuntu 20.04이며, 클라이언트는 DBeaver를 사용했어요.

MySQL 8.0 업그레이드하면서 깨졌던 쿼리들 관련 이미지

MySQL 8.0 업그레이드하면서 깨졌던 쿼리들 관련 정보

MySQL 8.0에서 처음 헷갈렸던 용어들, 저도 그랬어요

사실 데이터베이스 초보자는 'SQL 모드(SQL Mode)'라거나 '문자셋(Character Set)', '콜레이션(Collation)' 같은 용어가 낯설죠. 저도 처음엔 '왜 SQL 모드가 바뀌면 쿼리가 깨져?' 하고 의문이었어요.

간단히 설명하면, SQL 모드는 MySQL이 쿼리를 해석하고 실행하는 방식을 조절하는 설정이에요. 예를 들어, 어떤 SQL 모드는 엄격하게 데이터 타입을 검사해 오류를 내고, 다른 모드는 자동으로 수정해서 넘어가기도 하죠. MySQL 8.0은 기본 SQL 모드가 많이 엄격해져서 5.7에 비해 쿼리가 깨질 가능성이 커졌어요.

깨진 쿼리 1: GROUP BY 에러

가장 많이 부딪힌 문제는 GROUP BY 관련 에러였어요. 예전에는 아래처럼 쿼리 작성해도 문제없었는데 8.0에서는 에러가 나더라고요.

SELECT name, age, COUNT(*) FROM users GROUP BY name;

에러 메시지는 대략 이렇게 나왔어요:

ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'users.age' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

이게 무슨 말이냐면, 8.0부터는 GROUP BY에 포함되지 않은 컬럼을 SELECT에 그냥 쓰면 안 된다는 뜻이에요. 그래서 해결 방법은 다음 중 하나를 선택해야 해요.

  • SELECT에 넣은 컬럼을 전부 GROUP BY에 추가하기
  • age 같은 컬럼을 집계 함수(SUM, MAX 등)로 감싸기
  • SQL 모드에서 only_full_group_by 비활성화하기(권장하지 않음)

저는 첫 번째 방법으로 고쳤어요. 이렇게요:

SELECT name, age, COUNT(*) FROM users GROUP BY name, age;

실행 결과 예상대로 정상 동작했어요.

MySQL 8.0 업그레이드하면서 깨졌던 쿼리들 직접 정리한 자료

MySQL 8.0 업그레이드하면서 깨졌던 쿼리들 관련 정보

깨진 쿼리 2: utf8mb4 인코딩 문제

MySQL 8.0에서는 기본 문자셋이 utf8mb4로 변경됐어요. 이게 뭔지 모르면 혼란스러울 수 있는데, 쉽게 말하면 4바이트 유니코드 문자까지 다 처리하는 인코딩이에요. 그래서 이모지 같은 특수문자도 저장 가능하죠.

문제는 기존 테이블이나 칼럼이 utf8 (3바이트)로 되어 있으면 충돌이 발생하는 경우가 많아요. 특히 인덱스 길이 제한 때문에 인덱스를 다시 만들어야 했습니다.

예를 들어, 이런 에러 메시지가 떴어요:

ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

이때는 테이블 문자셋과 콜레이션을 utf8mb4로 바꾸고, 인덱스 길이도 줄여줘야 해요. 이렇게 쿼리 작성했었어요:

ALTER TABLE my_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

또, varchar 인덱스 길이는 191자 이내로 제한하는 게 안정적이에요.

깨진 쿼리 3: JSON 함수 미지원에서 변경된 점

MySQL 5.7에서 도입한 JSON 데이터 타입과 함수들이 8.0에서 더 진화했는데, 함수 이름이나 동작 방식이 달라져서 쿼리가 깨지는 경우도 있었어요.

예를 들어, 5.7에서 쓰던 JSON_KEYS() 함수가 8.0에서는 내부 동작이 조금 바뀐 것 같아요. 제가 겪은 증상은 이 함수 결과에 인덱싱하는 쿼리가 갑자기 느려지거나 에러가 나는 경우였죠.

해결책은 쿼리를 재작성해서 JSON_EXTRACT 함수 등을 적절히 활용하는 거였어요. 간단한 예시를 보여드릴게요.

-- 기존 쿼리
SELECT JSON_KEYS(data) FROM my_json_table;

-- 8.0에 맞게 변환
SELECT JSON_KEYS(data) AS keys FROM my_json_table;

좀 더 복잡한 경우에는 JSON_TABLE 함수를 활용해서 JSON 데이터를 테이블처럼 변환해 쿼리하는 방식이 추천돼요.

MySQL 8.0 업그레이드하면서 깨졌던 쿼리들 참고 사진

MySQL 8.0 업그레이드하면서 깨졌던 쿼리들 관련 정보

깨진 쿼리 4: 날짜/시간 함수 차이

MySQL 8.0에서는 날짜와 시간을 처리하는 함수가 좀 바뀌었는데, 특히 STR_TO_DATE 함수 같은 포맷 지정자에서 미묘한 차이가 있었어요.

예전엔 '%Y-%m-%d %H:%i:%s' 같은 포맷을 그대로 썼는데, 8.0에서 일부 포맷 지정자가 엄격해져서 에러가 났어요. 특히 12시간제(Hour 01~12)와 24시간제(Hour 00~23)를 구분하는 부분에서 혼란이 있었죠.

해결 방법은 포맷을 정확하게 맞추거나, 쿼리에서 시간 부분을 24시간제로 맞추는 거였어요.

SELECT STR_TO_DATE('2024-04-25 23:15:00', '%Y-%m-%d %H:%i:%s');

이렇게 하면 8.0에서도 잘 작동해요.

여기서 삽질했던 부분들

진짜 한참 삽질했던 게 있었는데요, 바로 ONLY_FULL_GROUP_BY 모드를 끄는 방법을 모르던 때였어요. 여러 설정 파일과 콘솔에서 모드를 바꿔보면서 왜 안 될까 한참 헤맨 기억이 나요.

-- 현재 SQL 모드 확인
SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;

-- ONLY_FULL_GROUP_BY 모드 제거 예시
SET GLOBAL sql_mode=(SELECT REPLACE(@@GLOBAL.sql_mode,'ONLY_FULL_GROUP_BY',''));
SET SESSION sql_mode=(SELECT REPLACE(@@SESSION.sql_mode,'ONLY_FULL_GROUP_BY',''));

제가 놓친 건, 모드를 바꾸고 나서 MySQL을 재시작하거나 세션을 새로 열지 않으면 반영 안된다는 점이었어요. 그리고 글로벌과 세션 모드가 다를 수 있다는 것도 주의해야 해요.

심화: 업그레이드 전 체크리스트 저는 이렇게 만들었어요

사실 업그레이드하면서 미리 준비해두면 훨씬 덜 고생하겠더라고요. 그래서 다음과 같은 점검 리스트를 만들어서 적용했어요.

  • 기존 데이터베이스 백업
  • SQL 모드 확인 및 필요한 설정 변경
  • 테이블 문자셋 및 콜레이션 변경 계획 수립
  • 자주 쓰는 쿼리 테스트 및 수정
  • 애플리케이션에서 사용하는 드라이버 버전 확인

이런 작업을 미리하면 업그레이드 후 쿼리 깨짐을 최소화할 수 있어요.

자주 물어보시는 것들

Q. SQL 모드를 왜 바꾸면 쿼리가 깨지나요?

A. SQL 모드는 MySQL 서버가 쿼리를 검사하는 규칙이에요. 엄격한 모드는 문법과 데이터 무결성을 더 철저하게 확인해서, 예전에는 넘어갔던 일부 애매한 쿼리를 오류로 바꿔버릴 수 있거든요.

Q. 업그레이드 후 기존 데이터에 영향은 없나요?

A. 데이터 자체에는 문제가 없지만, 문자셋 변경 시 인덱스 재생성이나 데이터 변환 작업이 필요해서 시간이 걸릴 수 있어요. 또 애플리케이션 쪽 쿼리가 문제 될 수 있으니 테스트가 필수입니다.

Q. JSON 함수는 5.7 쿼리 그대로 써도 되나요?

A. 대부분은 되지만, 8.0에서 함수가 추가되거나 변경된 부분이 있어 쿼리를 검토하고 테스트해보는 게 좋아요.

MySQL 8.0 업그레이드하면서 깨졌던 쿼리들을 단계별로 살펴보니, 처음에는 복잡하게 느껴져도 차근차근 원인을 찾고 하나씩 고쳐야 하더라고요. 저는 이렇게 직접 부딪히며 경험한 덕분에 한층 더 MySQL에 익숙해졌어요. 여러분도 비슷한 문제 만나면 당황하지 말고, SQL 모드부터 문자셋, 함수 차이까지 차근히 점검해서 해결해 보세요.

Comments