キャッシュフォームテーブルのサイズは膨大です


13

キャッシュテーブルのサイズは先月10 GB以上に増加し、切り捨てて一時的に修正しました。前回確認したときは、約1GBでした。したがって、数か月後には再び10GBに達するでしょう。これはどのように対処する必要がありますか?

このサイトですべてのcronジョブを無効にしていることに注意してください。これが理由である場合、どのcronを有効にする必要がありますか?

回答:


24

{cache_form}テーブルには、ちょっと面白いですし、他のキャッシュテーブルと若干異なるように動作します。

あなたが見て取ればdrupal_flush_all_caches()、あなたはそれが表示されます{cache_form}クリアされません。これは、進行中のフォームが破壊されるのを防ぐためです。

このsystem_cron()関数は{cache_form}、他のキャッシュテーブルとともに古いデータを整理します。

本当にすべてのDrupalサイトでcronを実行する必要があります。あなたならば{cache_form}表がginourmousで、その後、私はあなたを賭ける{watchdog}{session}テーブルもあります。他の多くのモジュールは、独自のhook_cron()機能の一部としてハウスキーピングアクティビティを実行します。

また、課題キューを確認することもできます。にはいくつかのバグが{cache_form}あり、あなたはそのうちの1つにぶつかる可能性があります。


さて、cronを適切にセットアップしましたが、それでも1日で2 GBに成長したことがわかりましたが、1週間以来一定でした。これらのテーブルには何が保存されますか?
GoodSp33d

1
{cache_form}には進行中のフォーム送信があります。{watchdog}にはログがあり、{session}にはセッション情報(ユーザーごとの状態)があります。
mpdonadio

6

親指のルール:ウェブサイトの管理のためにCronを定期的に実行する必要があります。

MPDへのコメントで、cronをセットアップして定期的に実行しているにもかかわらず、cache_formテーブルが急速に成長していると述べました。

その解決策の1つは、cronをより頻繁に実行することです。6時間以下ごとに言いますか?あなたがそれを行う余裕がない場合は、さらに読みます。

代替ソリューション:

mymodule_cron() {
    cache_clear_all(NULL, 'cache_form');
}

Elysia Cronをインストールすると、モジュールのcron機能を個別に実行できます。モジュールのElysia cronの頻度を6時間ごとに実行するように保つことができます。したがって、cache_formテーブルは6時間ごとに整理されます。

このプルーニングプロセス中、6時間以上前のエントリは削除されません。その理由は、すべてのエントリが削除されると、エントリを削除するときに送信されているフォームが異常に動作する可能性があるためです。

https://api.drupal.org/api/drupal/includes!form.inc/function/form_set_cache/7のコードを見てください

function form_set_cache($form_build_id, $form, $form_state) {
  // 6 hours cache life time for forms should be plenty.
  $expire = 21600;

コメントが読むように、彼らはそれが十分であるべきだと仮定しており、あなたの場合、それはあなたにとってあまりにも多くなりすぎています。そのため、cache_formテーブルをより頻繁にクリアし、$ expireの値をより低い値に減らすか、cache_formエントリをデフォルト値の6 6時間よりも頻繁にクリアする場合は、TTLを変更する必要がありますcache_formエントリ。

cachebojectをインストールしてhook_cacheobject_presaveから、TTLを2時間または3時間に変更できる範囲内で実装することにより、これを行うことができます。

mymodule_cacheobject_presave()($object, $cid, $bin) {
  // Extend the expiry period for prototype forms used in ajax enabled forms.                                                                  
  $cache_ttl = 1 ; // Change it to any number of hours
  if ($bin == 'cache_form') {
    $object->expire = REQUEST_TIME + $cache_ttl * 3600;
  }
}

このアプローチの欠点の1つは、フォームが2時間以内に送信されない場合(設定したRTL値)、フォームデータが失われ、フォームの期限切れの問題が発生する可能性があることです。



1

作業中のサイトでパフォーマンスの問題が発生していたとき、キャッシュを修正した後にこれに遭遇しました。こちらの記事を読むことができます:https : //thinktandem.io/blog/2017/11/22/debugging-with-new-relic-blazemeter-strace-more/

私のブログ投稿から、キューとcronのセットアップを追加し、Elysia Cronのようなものを使用して、すべてをうまく連携させることができます。

/**
 * Implements hook_cron_queue_info()
 */
function THE MODULE_cron_queue_info() {
  // Set up the worker queue.
  $queues['THE MODULE_queue'] = array(
    'worker callback' => 'THE MODULE_queue_process',
    'time' => 600,
  );
  return $queues;
}

/**
 * Implements hook_cron()
 */
function THE MODULE_cron() {
  // Load up our worker queue.
  $queue = DrupalQueue::get('THE MODULE_queue');

  // Set up the query for expired results.
  $sql = "SELECT cid FROM {cache_form} WHERE expire < :time";
  $query = db_query($sql, array(':time' => REQUEST_TIME));
  $results = $query->fetchAll(PDO::FETCH_ASSOC);

  // Split this into chunks for safety and speed.
  $chunks = array_chunk($results, 5000);
  foreach ($chunks as $chunk) {
    // Add the chunk to the queue worker.
    $queue->createItem($chunk);
  }
}

/**
 * Worker callback defined in hook_cron_queue_info().
 *
 * @param array $data
 *   The array of cids we want to delete.
 */
function THE MODULE_queue_process($data) {
  db_delete('cache_form')
    ->condition('cid', $data, 'IN')
    ->execute();
}

1

Safe cache_form Clearモジュールを使用します。

まず、テーブルを適切なサイズに整理してから、それを維持します。

プロジェクトページからの抜粋要約:

cache_formテーブルから限られた数のアイテムを安全に削除します。

モジュールがインストールされたら、まずcache_form:を整理します。drush safe-cache-form-clearテーブルサイズが一定になるまで実行し、6時間以上経過したすべてのレコードを削除したことを示します。

その後、cronで実行を継続します。

これは、Acquiaが加入者向けにこの目的のために文書化したモジュールです。Acquiaのドキュメントページには、追加情報があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.