WordPressで構築されたサイトがあって、毎日未明にデータベースを自動定時バックアップしているのだが、ふとバックアップされているファイルを確認してみたところ、異常に大きいサイズになっている事を発見した。

最大のファイルは は935MB(約1GB)もある。異常に大きい。バックアップの実行にも、5分近くを要しているようだ。
普通に投稿するだけでは、絶対にこんなサイズにはならないはずだ。
何がこんなに大きいのだろう。
phpMyAdminでテーブルの一覧を確認してみる。

「wp_options」のサイズが、なんと 8.8GB になっている。
レコード数も、phpMyAdminで正しく表示できない(マイナス表示)ほど大きくなってしまっているようだ。
なんだこれは。
更にテーブルの中を開いてみる。

「_transient_timeout_feed_~」「_transient_feed_~」「_transient_timeout_feed_mod_~」「_transient_feed_mod_~」というレコードがずらりと並んでいる。
なんだこれは。
このサイトにアクセスしたり、リロードする度に、どんどんレコードが増えていく。
私自身は「wp_options」にレコードを書き込んむ処理を組み込んだ覚えはない。
どの処理がレコードを追加しているのだろう。
よくみると、増加していくレコードの名称の中に「feed」とある。
このサイトの WordPress に組み込んだプログラムで、「feed」には見覚えがある。
このサイトでは、他のサイトのRSSフィードを読み込んで自身のページに表示するプログラムがあり、WordPress の fetch_feed() を使用している。
おそらくこれだろうとアタリを付けて、この処理をコメントアウトした上で、リロードしてみる。
レコードは増加しない。これだ!
しかし、fetch_feed() の引数はURLのみで、動作を制御するオプションはなく、マニュアルを読んでも「wp_options」への書き込みを抑止するような設定などは見当たらない。
どうすればよいのだ。
「_transient_timeout_」「削除」といったキーワードでググると、このようなデータを削除するプラグインが存在しているようだ。
Delete Expired Transients
Clean Options
※ただし、おそらく削除できる機能があると思われるけれど、私自身はこれらを試していません。
これらのプラグインを導入する事も考えtが、実は対象となるサイトは多数あるし、今後の WordPress のアップデートの事を考えると、できるだけプラグインは導入したくない。
どうしようか迷ったのだが、これらのレコードは、ひたすら追加されるのみで、古いレコードが使われる事はないようなので、古いレコードを自動削除するプログラムを作成し、定期的に実行する事にした。
しかし、ここでまた問題が発生した。
「wp_options」には、レコードの生成日時を記録するフィールドが無い。
どうするか。
う~ん、と悩んで、「wp_options.option_id」を使用する事にした。
まず「wp_options.option_id」の最大値を取得した上で、最新の数百レコードを残して、それより小さい値のレコードを削除する。
つまり、こうだ。
DELETE
FROM
wp_options
WHERE
(option_id < ((SELECT MAX(options_id) FROM wp_options) - 200))
AND
(
(option_name LIKE '_transient_timeout_feed_%')
OR
(option_name LIKE '_transient_feed_%')
OR
(option_name LIKE '_transient_timeout_feed_mod_%')
OR
(option_name LIKE '_transient_feed_mod_%')
)
「_mod_」の条件は、冗長な意味のない記述だけど、とりあえず、気にしない。
このSQLを、WordPressデータベースのプリフィックスごと、データベースごとに処理する様にし、cronで定期的に実行するようにする。
準備したプログラムを実行した上でバックアップを実行、バックアップされたファイルを確認する。

よし、普通のサイズになった。
バックアップに要する時間も数秒~十数秒程度になった。
これでヨシ。