클라우드플레어가 Workers와 SQL 데이터베이스를 연결하는 하이퍼드라이브(Hyperdrive)의 MySQL 지원을 정식 제공한다고 밝혔다. 기존 PostgreSQL 지원에 이어 MySQL 베타에서 발견한 호환성·안정성 문제를 정리한 결과다. 회사는 요청마다 새 연결을 만드는 비용을 줄이기 위해 연결을 유지·공유하고, 선택적으로 쿼리 결과도 캐시한다고 설명했다. 이번 발표의 초점은 특정 쿼리의 속도 경쟁보다 실제 고객 환경에서 드물게 틀린 응답을 내던 경로를 제거한 데 있다.
문자 집합과 초기화 뒤의 상태도 점검
안정화 과정에는 이모지 인코딩 문제도 있었다. 하이퍼드라이브가 협상한 utf8은 utf8mb3 별칭이어서 4바이트 문자를 모두 처리하지 못했고, 회사는 utf8mb4로 바꿨다고 설명했다. MySQL 8.4 문서도 utf8 별칭의 사용 중단 예정 상태와 새 애플리케이션의 utf8mb4 사용을 안내한다. 또한 연결 반환 때 세션을 정리한 뒤에는 서버 기본 문자 집합으로 돌아가는 문제 때문에 다시 utf8mb4를 설정했다. 공식 COM_RESET_CONNECTION 문서는 연결을 닫거나 재인증하지 않고 세션 상태를 정리하는 명령이라고 규정한다. 연결을 재사용한다는 사실만으로 이전 협상 상태가 그대로 남는 것은 아니다.
데이터센터가 같을 때 공유되는 캐시
희귀한 빈 결과 문제는 캐시를 켠 인스턴스에서 관측됐다. 원문에 따르면 Worker와 같은 머신의 Client 노드가 로컬 캐시를 처리하고, 원본 데이터베이스 가까이에 놓인 Endpoint 노드가 연결 풀을 맡는다. 두 노드가 같은 데이터센터에 있으면 동일한 캐시를 이용한다. 서로 저장한 결과를 재사용하는 구조는 같은 쿼리의 왕복을 줄이지만, 어느 쪽에서 읽어도 같은 의미로 해석되는 바이트를 저장해야 한다. 한 노드의 출력이 다른 노드의 입력으로 쓰이는 순간, 내부 표현의 일관성도 캐시의 정확성 조건이 된다.
캐시에는 Worker별 출력 대신 공통 표현 저장
문제는 Client가 Worker에 보낸 변환된 바이트를 그대로 캐시에 넣는 가정이었다. Endpoint는 하이퍼드라이브의 기능 집합으로, Client는 Worker가 기대하는 형식으로 결과를 다뤘으므로 공유 캐시에서 두 표현이 섞였다. 상대 노드가 저장한 값을 읽을 때 필요한 변환을 건너뛰거나 이미 변환한 값을 다시 처리해 빈 결과 또는 대기가 발생할 수 있었다. 회사는 어느 노드가 저장하든 하이퍼드라이브의 기능 집합으로 인코딩한 공통 결과를 넣도록 바꿨다고 설명했다. 해결책은 캐시를 없애는 것이 아니라 캐시 안 표현과 최종 수신자용 표현을 분리하는 것이었다.
결과 행이 같아도 종료 표시가 다르면 읽지 못한다
CLIENT_DEPRECATE_EOF 협상 여부는 열 정의와 행 뒤에서 응답이 끝났음을 표시하는 패킷을 바꾼다. 행 데이터의 내용이 맞더라도 수신자가 기다리는 종료 표시와 다르면 결과가 비어 보이거나 대기할 수 있다. 캐시 값의 정확성에는 자료뿐 아니라 읽는 쪽과의 형식 계약도 들어간다.
수정은 어느 노드든 공통 Hyperdrive 형식으로 캐시에 저장한 뒤 최종 Worker에 보낼 때 필요한 변환을 하는 방향이었다. 저장 형식과 전달 형식을 분리하면 같은 캐시를 읽는 두 노드가 소비자별 가정을 공유하지 않아도 된다. 캐시 키만 맞추는 것으로 해결되지 않았던 이유다.
| 위치 | 맞춰야 하는 계약 |
|---|---|
| 공유 캐시 내부 | 모든 노드가 해석할 공통 Hyperdrive 형식 |
| Worker에 전달 | 해당 MySQL 드라이버가 협상한 형식 |
| 회수한 연결 초기화 | 재설정 후 문자 집합 등 세션 상태 |
Hyperdrive의 버그는 공유 캐시에 같은 결과를 다른 형식으로 기록한 노드 사이에서 발생했다. 공통 저장 형식으로 고친 사례는 기능 협상과 캐시의 경계를 함께 관리해야 함을 보여 준다.
ARCH.B 의견
MySQL의 CLIENT_DEPRECATE_EOF는 결과 집합 종료를 표현하는 방식에 영향을 주는 기능 플래그다. 공식 구현 문서는 이 플래그를 쓰는 클라이언트가 결과 행 뒤에서 EOF 대신 OK 패킷을 기대한다고 설명한다. 하이퍼드라이브와 Worker의 드라이버가 같은 기능을 지원한다고 가정할 수는 없다. 원문은 당시 mysql2 드라이버의 지원 차이 때문에 응답을 변환해야 했다고 밝혔다. 데이터베이스가 반환한 행 자체가 맞더라도, 수신자가 기대하는 경계 표시와 다르면 행을 읽는 방식이 달라질 수 있다는 문제다. 모든 MySQL 클라이언트가 항상 같은 종료 패킷을 쓴다는 설명은 정확하지 않다.
클라우드플레어는 수정 뒤 빈 행 문제가 사라졌고 Client 연결 성공률이 99.99%에 도달했다고 보고했다. 이는 회사가 공개한 운영 지표로, 모든 고객 쿼리의 성공이나 응답 내용의 정확성을 일괄 보장하는 수치로 해석할 수는 없다. 독자에게 더 일반적으로 남는 교훈은 캐시 키가 같다는 사실만으로 저장값의 호환성이 확보되지 않는다는 점이다. 연결 협상과 세션 초기화, 여러 소비자가 공유하는 직렬화 형식을 함께 봐야 한다. 재현 빈도가 낮은 장애에서는 요청 내용뿐 아니라 결과를 만든 노드와 읽은 노드, 적용된 기능 집합까지 연결해 보는 접근이 유용하다.



