워드프레스 autoload 옵션을 실제로 재보면: 정리 대상은 플러그인 찌꺼기가 아니었다

워드프레스 autoload 옵션을 실제로 재보면: 정리 대상은 플러그인 찌꺼기가 아니었다

워드프레스 속도 이야기가 나오면 자주 등장하는 것이 wp_options 테이블의 autoload 옵션입니다. 쓰지 않는 플러그인이 남긴 찌꺼기가 쌓여 모든 요청을 느리게 만든다는 설명입니다. 그런데 이 조언은 대부분 “정리하십시오”에서 끝나고, 정작 내 사이트의 현재 값이 얼마인지 재는 방법정상 범위가 어느 정도인지는 알려주지 않습니다. 그래서 직접 재봤습니다. 결과는 흔히 지목되는 대상과 달랐습니다.

autoload가 무엇을 뜻하는가

wp_options 테이블에는 사이트 주소, 테마 설정, 플러그인 설정 같은 값이 들어 있습니다. 이 테이블에는 autoload라는 칸이 하나 더 있습니다. 이 칸이 켜져 있는 행은 페이지 요청이 들어올 때마다 워드프레스가 한꺼번에 읽어서 메모리에 올립니다. 필요할 때 하나씩 꺼내 쓰는 것이 아니라, 필요 여부와 무관하게 전부 먼저 읽습니다.

그래서 이 값이 커지면 모든 요청이 조금씩 무거워집니다. 방문자가 보는 글 한 편을 그리는 데 아무 관련이 없는 설정까지 매번 함께 읽히기 때문입니다. 문제는 여기서 ‘크다’의 기준이 잘 알려져 있지 않다는 점입니다.

먼저 재는 방법

정리하기 전에 현재 값을 알아야 합니다. 데이터베이스에 접근할 수 있다면 질의 한 번이면 됩니다.

SELECT COUNT(*), SUM(LENGTH(option_value))
FROM wp_options
WHERE autoload IN ('yes','on');

autoload 칸의 값이 워드프레스 버전에 따라 yeson으로 나뉘어 저장되는 경우가 있어 두 값을 함께 넣었습니다. 한쪽만 넣고 재면 실제보다 작게 나옵니다. 흔히 소개되는 WHERE autoload = 'yes'만 쓰면 최근 설치된 사이트에서 0으로 나오기도 합니다.

큰 것부터 보려면 정렬을 붙입니다.

SELECT option_name, LENGTH(option_value) AS len
FROM wp_options
WHERE autoload IN ('yes','on')
ORDER BY len DESC
LIMIT 15;

WP-CLI를 쓸 수 있는 환경이라면 wp db query에 같은 문장을 넘기면 됩니다. 멀티사이트라면 사이트마다 테이블 접두어가 달라집니다. 두 번째 사이트는 wp_2_options, 세 번째 사이트는 wp_3_options가 됩니다.

실제로 잰 값

플러그인을 많이 쓰지 않는 워드프레스 멀티사이트에서 세 사이트를 각각 재봤습니다.

테이블 전체 옵션 autoload 합계 용량
wp_options 158개 103개 48.7KB
wp_2_options 132개 99개 29.2KB
wp_3_options 131개 101개 28.1KB
사이트별 autoload 합계 용량. wp_options 48.7KB, wp_2_options 29.2KB, wp_3_options 28.1KB
세 사이트 모두 30~50KB 수준으로, 흔히 말하는 위험 기준에 한참 못 미칩니다.

먼저 눈에 띄는 것은 절대량입니다. 세 사이트 모두 30~50KB 수준입니다. autoload 문제를 다루는 글에서 흔히 언급되는 위험 기준은 800KB에서 1MB인데, 여기서는 그 20분의 1도 되지 않습니다. 즉 이 사이트들에는 애초에 정리할 것이 거의 없었습니다.

전체 옵션 중 autoload가 아닌 것도 30개 남짓입니다. 옵션 자체가 130~160개뿐이라는 뜻이고, 이는 플러그인을 적게 쓰는 사이트의 대략적인 기준선으로 삼을 만합니다.

용량의 대부분은 옵션이 아니었다

흥미로운 것은 그다음입니다. 큰 것부터 정렬해 보니 두 번째 사이트는 이렇게 나왔습니다.

_transient_wp_core_block_css_files      22748
wp_2_user_roles                          3133
cron                                     1520
theme_mods_kadence                       1200
_transient_wp_styles_for_blocks           870
_transient_health-check-site-status        40
ping_sites                                 27
siteurl                                    17

맨 위 항목 하나가 22,748바이트입니다. autoload 전체 29.2KB 중 76%를 이 한 줄이 차지했습니다. 나머지 98개를 다 합쳐도 7KB가 되지 않습니다. 세 번째 사이트도 28.1KB 중 23.1KB가 같은 항목이었습니다.

그런데 이 이름은 플러그인 찌꺼기가 아닙니다. _transient_로 시작하는 것은 워드프레스가 스스로 만드는 임시 저장값이고, wp_core_block_css_files코어가 블록 스타일 파일 목록을 캐시해 둔 것입니다. 즉 지목해야 할 대상이 ‘예전에 지운 플러그인’이 아니라 워드프레스 자신이었습니다.

지워 보고 확인한 것

임시 저장값은 지워도 안전합니다. 필요하면 다시 만들어지도록 설계된 값이기 때문입니다. 그래서 실제로 지우고 앞뒤를 재봤습니다.

시점 autoload 건수 합계 용량
삭제 전 99개 29.2KB
삭제 직후 98개 7.0KB
글 목록·본문 요청 후 98개 7.0KB
트랜지언트 삭제 전후 autoload 용량. 29.2KB에서 7.0KB로 줄고 요청 후에도 그대로
한 줄을 지웠을 뿐인데 모든 요청이 읽는 양이 4분의 1 아래로 줄었습니다.

한 줄을 지웠을 뿐인데 모든 요청이 읽어야 할 양이 29.2KB에서 7.0KB로 줄었습니다. 여기까지는 예상한 결과입니다.

다시 생기지 않았다는 점이 더 중요하다

예상과 달랐던 것은 그다음입니다. 임시 저장값이니 페이지를 몇 번 열면 곧바로 되살아날 것이라 보고 글 목록과 본문을 차례로 요청했습니다. 둘 다 정상 응답이었는데도 값은 되살아나지 않았고 7.0KB 그대로였습니다.

이 결과가 알려주는 것이 있습니다. 이 목록은 방문자에게 글을 보여주는 과정에서 만들어지는 값이 아니라는 뜻입니다. 편집기처럼 블록 스타일 전체를 다뤄야 하는 화면에서 만들어지고, 한번 만들어진 뒤에는 방문자 요청마다 읽히기만 합니다. 관리자 화면에서 한 번 생긴 22KB를 그 뒤의 모든 방문자가 나눠 부담하는 구조였습니다.

그래서 이 값은 ‘지워도 금방 돌아오니 의미 없는 청소’가 아닙니다. 다만 편집기를 다시 열면 언젠가 다시 생깁니다. 한 번 지우고 끝나는 작업이 아니라 가끔 다시 재봐야 하는 항목으로 보는 편이 맞습니다.

오브젝트 캐시가 있으면 이야기가 달라진다

여기까지가 데이터베이스 이야기인데, 한 가지 조건을 빼놓으면 판단이 어긋납니다. 외부 오브젝트 캐시를 쓰고 있는지 여부입니다.

레디스나 멤캐시드 같은 외부 캐시가 연결돼 있으면 옵션은 첫 요청에서 한 번 읽힌 뒤 메모리에 남습니다. 그다음부터는 데이터베이스를 건드리지 않으므로 autoload 용량이 조금 커도 체감 차이가 작습니다. 반대로 외부 캐시가 없으면 요청마다 이 테이블을 다시 읽습니다. 같은 30KB라도 부담이 전혀 다릅니다.

확인은 한 줄이면 됩니다.

wp eval 'var_dump( wp_using_ext_object_cache() );'

또는 wp-content 폴더에 object-cache.php라는 파일이 있는지 보면 됩니다. 이 파일이 있으면 외부 캐시를 쓰는 구성입니다. 앞서 잰 사이트에서는 결과가 ‘아니오’였습니다. 즉 autoload 값이 방문마다 실제로 읽히는 환경이었고, 그래서 22KB를 덜어낸 것이 의미가 있었습니다.

순서를 정하자면 이렇습니다. 외부 캐시가 없는 저사양 서버라면 autoload를 확인할 가치가 있습니다. 이미 외부 캐시를 쓰고 있다면 우선순위가 낮습니다. 같은 조언이라도 환경에 따라 효과가 다르다는 점이 이 항목의 핵심입니다.

멀티사이트라면 볼 곳이 하나 더 있다

멀티사이트에는 사이트별 options 테이블 외에 네트워크 전체가 쓰는 wp_sitemeta 테이블이 따로 있습니다. autoload를 점검할 때 이 테이블은 대개 빠집니다. 이름이 다르기 때문에 검색해서 찾은 SQL을 그대로 쓰면 아예 보이지 않습니다.

같은 방식으로 재봤습니다.

항목 건수 용량
wp_sitemeta 전체 54개 83.7KB
그중 임시 저장값 14개 82.0KB

전체의 98%가 임시 저장값입니다. 가장 큰 것은 다음 두 개였습니다.

_site_transient_available_translations        49804
_site_transient_wp_theme_files_patterns-...   30181

첫 번째는 워드프레스가 내려받을 수 있는 번역 목록이고, 두 번째는 테마가 제공하는 패턴 목록입니다. 둘 다 관리 화면에서 필요한 정보이지 방문자에게 글을 보여주는 데 필요한 값이 아닙니다. 사이트별 테이블에서 확인한 것과 같은 성격입니다.

이 테이블의 값은 사이트별 옵션과 읽히는 조건이 달라서 곧바로 요청 속도로 이어진다고 단정하기는 어렵습니다. 다만 임시 저장값이 쌓이는 자리가 한 곳 더 있다는 사실 자체는 알아 둘 필요가 있습니다. 사이트별 테이블만 아무리 깨끗하게 관리해도 이쪽은 그대로 남습니다.

그렇다면 무엇을 정리해야 하는가

재본 결과를 종합하면 정리 대상의 우선순위가 흔한 조언과 달라집니다.

항목 어떻게 할 것인가 이유
_transient_로 시작하는 큰 값 지워도 된다 필요하면 다시 만들어진다
지운 플러그인이 남긴 옵션 확인 후 지운다 다시 만들어지지 않는다
cron 건드리지 않는다 예약 작업 목록이다
user_roles, siteurl, home 건드리지 않는다 지우면 사이트가 멈춘다
이름을 알 수 없는 작은 값 그대로 둔다 얻는 것이 없고 위험만 있다

지운 플러그인이 남긴 옵션을 찾을 때는 이름의 앞부분을 단서로 삼습니다. 대개 플러그인 이름이나 그 약자가 접두어로 붙습니다. 다만 이름만 보고 판단하지 말고, 지금 설치된 플러그인 목록과 대조한 뒤에 지워야 합니다. 이름이 비슷해도 현재 쓰이는 값일 수 있습니다.

지우기 전에 해당 행을 따로 적어 두면 되돌리기 쉽습니다. 옵션은 이름과 값의 쌍이므로, 문제가 생겼을 때 같은 이름으로 같은 값을 다시 넣으면 원래 상태로 돌아갑니다.

정리하면

autoload 정리는 해볼 만한 작업이지만, 재보지 않고 시작하면 엉뚱한 것을 지우게 됩니다. 실제로 재보니 이 사이트들에서는 전체가 30KB 수준이라 문제 자체가 없었고, 그중에서도 대부분을 차지한 것은 플러그인 찌꺼기가 아니라 코어가 만든 임시 저장값 하나였습니다.

순서는 이렇게 잡는 편이 안전합니다. 먼저 SUM(LENGTH(option_value))로 전체 크기를 확인하고, 수백 KB 이하라면 여기서 멈춥니다. 그 이상이라면 큰 것부터 열 개만 확인하고, _transient_부터 처리한 뒤, 남는 것 중 지금 쓰지 않는 플러그인의 옵션만 골라 냅니다. 목록의 개수가 아니라 용량이 기준이라는 점만 기억하면 대부분의 판단이 쉬워집니다.

Similar Posts

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다