Answers:
该{cache_form}
表有点有趣,并且其行为与其他缓存表略有不同。
如果您看一看,drupal_flush_all_caches()
您会发现它{cache_form}
没有被清除。这是为了防止进行中的表单被破坏。
该system_cron()
函数确实会从{cache_form}
其他缓存表中删除旧数据。
您确实应该在所有Drupal网站上运行cron。如果{cache_form}
表是ginourmous,那么我敢打赌,你{watchdog}
和{session}
表是也。许多其他模块将管家活动作为其自身hook_cron()
功能的一部分。
您可能还想在问题队列中四处寻找。出现了一些错误{cache_form}
,您可能会遇到一个错误。
经验法则:Cron应该定期运行以整理您的网站。
您在对MPD的评论中提到,尽管设置了cron并定期运行它们,您的cache_form表仍在快速增长。
一种解决方案是更频繁地运行cron。每六个小时或更短时间说一次?如果您负担不起,请继续阅读。
替代解决方案:
mymodule_cron() {
cache_clear_all(NULL, 'cache_form');
}
安装Elysia Cron,现在您可以单独运行模块的cron功能。您可以保持Elysia cron的频率,以使模块每六个小时运行一次。这样您的cache_form
表每六个小时被修剪一次。
在此修剪过程中,不会删除不超过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;
}
}
这种方法的一个缺点是,如果未在2小时(您设置的RTL值)内提交表单,则表单数据可能会丢失,并且您可能会遇到一些表单过期问题。
作为解决此问题的方法,我创建了模块https://www.drupal.org/project/session_cache_form
当我在工作的网站上遇到性能问题时,我在修复缓存后就遇到了这个问题。您可以在这里阅读文章: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();
}
它将使您首先将表修剪到合理的大小,然后进行维护。
项目页面的摘要:
从cache_form表中安全地删除有限数量的项目。
安装模块后,请首先修剪cache_form:,drush safe-cache-form-clear
直到表大小保持一致为止,这表明您已删除所有6个小时以上的记录。
然后它将继续在cron上运行。
这是Acquia为此目的为其订户记录的模块。Acquia文档页面提供了很好的附加信息。