Rozmiar tabeli formularza pamięci podręcznej jest ogromny

13

Rozmiar tabeli pamięci podręcznej wzrósł w zeszłym miesiącu do ponad 10 GB, a ja tymczasowo naprawiłem ją, obcinając. Ostatni raz sprawdziłem, że było to około 1 GB. Za kilka miesięcy znów osiągnie 10 GB. Jak sobie z tym poradzić?

Pamiętaj, że wyłączyłem wszystkie zadania CRON na tej stronie. Jeśli to jest powód, który cron powinien być włączony?

GoodSp33d
źródło

Odpowiedzi:

24

{cache_form}Stół jest trochę śmieszne, i zachowuje się w nieco inny sposób niż innych tabel skrytek.

Jeśli spojrzysz na drupal_flush_all_caches()to, zobaczysz, że {cache_form}nie jest wyczyszczone. Ma to na celu ochronę trwających formularzy przed nuksem.

system_cron()Funkcja ma dbać o przycinanie się stare dane z {cache_form}wraz z innymi tabelami skrytek.

Naprawdę powinieneś uruchomić crona na wszystkich stronach Drupala. Jeśli twój {cache_form}stół jest ginourmous, to założę się, że {watchdog}i twoje też {session}są. Wiele innych modułów prowadzi czynności porządkowe jako część własnych hook_cron()funkcji.

Możesz także zajrzeć do kolejki problemów. Wystąpiły pewne błędy {cache_form}i możesz się z nimi spotkać.

mpdonadio
źródło
Ok, teraz poprawnie ustawiłem crony, ale wciąż widziałem, że wzrosło do 2 GB w ciągu jednego dnia, ale było stałe od tygodnia. Co będzie przechowywane w tych tabelach?
GoodSp33d,
1
{cache_form} ma przesyłane formularze w toku. {watchdog} ma dzienniki, a {session} ma informacje o sesji (stan na użytkownika).
mpdonadio
6

Reguła kciuka: Cron powinien być regularnie uruchamiany w celu zarządzania witryną.

W swoim komentarzu do MPD wspomniałeś, że pomimo konfigurowania crona i regularnego uruchamiania go, twoja tabela cache_form szybko rośnie.

Jednym z takich rozwiązań jest częstsze uruchamianie crona. Mówisz co sześć godzin lub mniej? Jeśli nie możesz sobie na to pozwolić, czytaj dalej.

Alternatywne rozwiązanie:

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

Zainstaluj Elysia Cron, a teraz możesz uruchomić funkcję cron swojego modułu osobno. Możesz zachować częstotliwość cronu Elysia, aby moduł działał co sześć godzin. Aby twój cache_formstół był przycinany co sześć godzin.

Podczas tego procesu przycinania wpisy, które nie są starsze niż 6 godzin, nie zostaną usunięte. Powodem jest to, że jeśli wszystkie wpisy zostaną usunięte, wszelkie formularze przesyłane w momencie usuwania wpisów mogą zachowywać się dziwnie.

Spójrz na kod w https://api.drupal.org/api/drupal/include!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;

Jak czytamy w komentarzu, zakładają, że powinno to być obfite, aw twoim przypadku staje się dla ciebie zbyt obfite. Zatem sztuczka polega na częstszym czyszczeniu tabeli cache_form i zmniejszeniu wartości $ expire do niższej wartości, jeśli chcesz wyczyścić wpisy cache_form częściej niż domyślna wartość 6 sześć godzin, musisz zmienić TTL wpisy cache_form.

Możesz to zrobić, instalując cacheboject, a następnie wdrażając, hook_cacheobject_presavew którym możesz zmienić TTL na 2 lub 3 godziny.

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;
  }
}

Wadą tego podejścia jest to, że jeśli formularze nie zostaną przesłane w ciągu 2 godzin (ustawiona wartość RTL), dane formularza mogą zostać utracone i mogą wystąpić problemy z wygasaniem formularza.

Gokul NK
źródło
1

Kiedy miałem problemy z wydajnością w witrynie, na której pracowałem, natknąłem się na to po naprawieniu buforowania. Możesz przeczytać artykuł tutaj: https://thinktandem.io/blog/2017/11/22/debugging-with-new-relic-blazemeter-strace-more/

Z mojego posta na blogu możesz dodać konfigurację kolejki i crona, a następnie użyć czegoś takiego jak Elysia Cron, aby wszystko działało dobrze:

/**
 * 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();
}
John O
źródło
1

Użyj modułu Safe cache_form Clear .

Pozwoli to najpierw przyciąć stół do rozsądnego rozmiaru, a następnie go utrzymać.

Fragment streszczenia ze strony projektu:

Bezpiecznie usuń ograniczoną liczbę elementów z tabeli cache_form.

Po zainstalowaniu modułu najpierw przycinaj cache_form: uruchom, drush safe-cache-form-clearaż rozmiar tabeli pozostanie spójny, co oznacza, że ​​usunąłeś wszystkie rekordy starsze niż 6 godzin.

Następnie będzie kontynuował działanie na cronie.

Jest to moduł udokumentowany w tym celu przez Acquia dla ich subskrybentów. Strona dokumentacji Acquia zawiera dobre dodatkowe informacje.

Kay V.
źródło