자기 칸보다 긴 페이지 주소
이 글의 내용
2026년 8월 9일, 카운터 그림 스무 개가 그려지지 않았습니다. 잘못 그려진 것도, 느리게 그려진 것도 아니고 — 카운터가 있어야 할 자리에 방문자는 아무것도 받지 못했습니다.
원인은 255자를 넘는 페이지 주소였습니다. 이제 기록하는 시점에 잘라 내며, 카운터 그림은 전달받은 주소의 길이에 더는 좌우되지 않습니다.
사슬
방문이 어느 페이지에 닿았는지를 담는 칸은 varchar(255)입니다. 주소가 그보다 길게 들어왔습니다. 삽입은 SQLSTATE 22001로 실패했고, 칸에 비해 데이터가 너무 길다는 뜻이며, 이 코드에서는 그것이 예외를 일으켰습니다.
그리고 통계 기록은 그림을 그리기 전에 일어납니다. 그래서 예외는 통계 한 줄만 잃은 것이 아닙니다. 요청을 중단시켰고, 그 요청이 바로 카운터 그림을 만드는 요청이었습니다. 긴 주소를 가진 페이지는 모든 방문자에 대해 소리 없이 자기 카운터를 망가뜨렸습니다.
긴 주소는 별난 것이 아닙니다. 경로가 겹겹인 갤러리, 광고 플랫폼이 붙인 추적 매개변수 열두 개가 달린 가게, 검색 결과 페이지 — 어느 것이나 애쓰지 않아도 255자를 넘깁니다.
고친 방법, 그리고 고르지 않은 방법
이제 주소는 삽입 전에 칸 너비에 맞추어 잘립니다. 아주 긴 URL에서 스무 자가 페이지 목록에서 사라지고, 그 밖에는 아무것도 달라지지 않습니다.
다른 길은 칸을 넓히는 것이었습니다. 물리쳤습니다. 넘을 수 없는 너비는 없고, 더 큰 숫자를 고르는 것은 같은 실패를 더 멀리, 도착했을 때 알아보기 더 어려운 곳으로 미룰 뿐입니다. 실패하는 방식이 드물어지는 것이 아니라 치명적이기를 그쳐야 합니다.
삽입을 try/catch로 감쌌어도 눈에 보이는 증상은 사라졌을 테고, 그편이 더 나빴을 것입니다. 카운터는 그려지고, 줄은 소리 없이 사라지고, 페이지 목록에는 가장 복잡한 주소를 가진 페이지가 영원히, 어느 기록에도 남지 않은 채 빠져 있었을 것입니다.
가져갈 만한 두 가지
바깥에서 온 입력은 맞기를 바랄 것이 아니라 칸 너비에 맞추어 잘라야 합니다. 바깥에서 오는 모든 것 — 주소, 참조, 사용자 에이전트, 제목 — 은 남이 정한 만큼 길고, 데이터베이스는 그에 대해 거부라는 방식으로 의견을 냅니다.
실패의 하류에 무엇이 더 있는지 알아 두십시오. 이것은 통계 서비스에서 일어난 통계 결함이었고, 눈에 보인 피해는 사라진 그림이었습니다. 기록과 그리기는 한 요청을 나누어 썼습니다. 코드 어디에도 둘이 묶여 있다는 말이 없었고, 삽입 실패가 그림까지 데려간다고 경고하는 것도 없었습니다.
하루 스무 개의 망가진 그림은 적은 수입니다. 전혀 다른 것을 찾다가 로그를 읽던 중에 발견했고, 이런 것은 보통 그렇게 발견되며, 로그를 계속 읽어야 하는 까닭이 그것입니다.