이번에 게임 서버와 MySQL 통신 간 패킷을 확인해볼 일이 생겼다.
분명 사내에서 구축한 인프라 세팅대로면, 문제 없이 동작하는 게임 서버와 MySQL DB인데,
퍼블리셔에서 구축하셨을 때에는 게임서버에서 유저 접속 처리가 안되는 문제가 보고되었다.
문제는... 이런 증상에 대한 원인을 찾기 위해서는, 범위를 줄여 나가야 한다는 점인데,
그게 생각보다 협조가 쉽지 않을때가 많다. 요청을 보내고 받고 해야 해서 속도도 느리고.
퍼블리셔 인프라팀에서 물론 기본적인 네트워크 설정 테스트는 진행해 주셨지만,
(게임서버와 MySQL DB서버간 통신 및 쿼리 테스트)
MySQL DB가 응답을 어떻게 주었는지, 이걸 게임서버가 해석해서 다음 쿼리를 보냈는지,
이것저것 알고 싶어서 패킷 캡쳐를 요청드렸다.
이번 기회에 MySQL의 패킷 구조와 쿼리-응답 패킷에 대해 살펴보게 되었고, 내용을 정리해 보았다.
MySQL 서버로 쿼리를 날리게 되면, 기본적으로 `COM_QUERY` 라는 타입의 패킷을 보내게 된다.
위와 같은 구조로 데이터를 전송하게 되는데,
예시로 바이트에서 앞 4바이트는 헤더이다.
저렇게 COM_QUERY를 보내게 되면 MySQL으로부터 응답을 받게 되는데,
다음 네 종류 중 하나를 받게 된다.
- ERR
쿼리가 실패한 것을 의미하는 패킷이다.
이 패킷에 담긴 메시지를 통해, 어떤 문제가 있었는지 바로 확인할 수 있다.
- OK
쿼리가 성공하게 되면 서버는 OK 패킷을 보내게 되고,
최신 MySQL에 와서는 EOF 패킷이 deprecated 되고 OK를 쓰도록 대체되었다.
- LOCAL INFILE
LOAD LOCAL INFILE 쿼리를 통해서 파일을 MySQL 서버로 보낼 수 있는데,
( 게임 서버 로그 처리하기 — 불여우의 전직 이야기 (tistory.com) )
이 때 클라이언트에게 로컬 파일을 요청하는 의미의 패킷이 되겠다.
- RESULT SET
쿼리가 데이터를 반환하게 된다면 이 타입으로 리턴되고, 이는 다음 구조를 가진다.
이러한 구조로 되어있다는 것을 알면, 네트워크 TCP 헤더 뒤의 payload 패킷을 분석해서 확인할 수 있다.
다만, WireShark같은 도구를 사용하게 되면, 3306같은 알려진 포트인 경우,
WireShark 가 위 패킷 구조 데이터대로 해석해서 바로 상세한 SQL 쿼리 내용을 보여준다!
그래서 나는 우리 게임서버와 MySQL간의 유저 인증단 통신 패킷캡처를 퍼블리셔에 공유드렸고,
퍼블리셔 또한 게임서버의 패킷캡쳐를 공유해 주셨다.
아직 내용이 완벽히 되기 전이고, DB Proxy가 없이 접속했을 때 문제 없다는 것이 확인된 상황이라,
내용이 확실해 지면 이에 대한 내용도 적어볼 생각이다.
'연구한 이야기 > 문제 해결 이야기' 카테고리의 다른 글
MySQL "Not Supported" 에러와 handshake (0) | 2024.05.30 |
---|---|
클라이언트 IP를 '잘' 가져오자 (0) | 2024.04.21 |
서버 로그가 누락되고 있어요..! (0) | 2024.03.31 |
alpine리눅스와 stat (0) | 2024.03.24 |
mysql connect 시에 timezone 관련해서 에러가 나요! (2) | 2024.03.02 |