是否收集了瞬态垃圾?


61

这个问题让我想到wp_options中的瞬态RSS提要不会自动删除吗?

瞬态应该过期并被删除。但是,我看到此处理的唯一方法是当瞬变过期并被请求时,然后在请求期间将其删除。

如果瞬变已过期但之后又没有请求怎么办?从法典中的描述,我认为这意味着某种垃圾回收。现在,我不确定,也找不到执行此操作的任何代码。

那么它将永远永远停留在数据库中吗?


从理论上讲,应在运行cron时将其删除(如果它们已过期)
onetrickpony

1
@雄心勃勃的变形虫是的,我有点提到这个问题。我的意思是-创建瞬态并不假定或保证将要请求它。强调原始问题- 如果我从未得到过,何时以及是否过期的瞬变会被删除?
2011年

1
假设您清理了过期的数据,但是是的,您是对的,在某些情况下,数据永远都不会被删除。就像删除使用瞬态的小部件一样。您应该为此提交票证:)
onetrickpony

1
@Rarst-编写补丁并提交给trac听起来很完美?
MikeSchinkel 2011年

1
相关的追踪
Stephen Harris,

Answers:


45

他们现在是

从WordPress 3.7开始,过期的瞬变将在数据库升级时删除,请参阅#20316


旧答案

如果其他人不能告诉我,那么瞬态似乎根本不是垃圾收集。更糟糕的是,与选项不同,它们不能保证存储在数据库中。因此,没有可靠的方法来获取所有瞬态的列表以检查它们是否到期。

如果使用数据库存储,一些临时代码可以进行垃圾回收:

add_action( 'wp_scheduled_delete', 'delete_expired_db_transients' );

function delete_expired_db_transients() {

    global $wpdb, $_wp_using_ext_object_cache;

    if( $_wp_using_ext_object_cache )
        return;

    $time = isset ( $_SERVER['REQUEST_TIME'] ) ? (int)$_SERVER['REQUEST_TIME'] : time() ;
    $expired = $wpdb->get_col( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout%' AND option_value < {$time};" );

    foreach( $expired as $transient ) {

        $key = str_replace('_transient_timeout_', '', $transient);
        delete_transient($key);
    }
}

$ time = $ _SERVER ['REQUEST_TIME']; 然后在SQL查询中使用$ time-不要这样做。$ _SERVER变量/值应更仔细地处理以防止SQL注入。
hakre 2011年

@hakre hm ...我是从有关PHP性能的演示文稿中挑选出来的,推荐使用time()它而不是会导致错误的代码(执行不是天生的。)。请求时间是由PHP自己设置的,它不是来自用户提供的任何数据。为什么会出现此漏洞?
2011年

@Rarst:我并不是说您不应该使用它,您应该确保已对其进行安全编码以在SQL查询中使用。您应该对来自外部源的每个变量执行此操作。$ _SERVER变量可能未按预期设置,而是由请求用户设置。我只想传播一些好的编码实践。与往常一样,要了解可用性的真实状态,请参阅文档。以PHP 4为例,该变量不存在,可能会被自定义标头或环境变量覆盖-php.net/manual/en/reserved.variables.server.php
hakre 2011年

@hakre已修复(我认为),感谢PHP4提醒btw(我等不及WordPress对它的支持)
Rarst 2011年

在我看来,这看起来好多了;)。我们希望time()和负整数没有问题,它们可以删除所有瞬态,也可以删除偶然性。永远不要相信正在运行的系统:P
hakre 2011年

20

通过重新措辞和重新设置格式,将讨论中的一些评论移到答案中。

基本上,归结为,除非您有一个极端的案例,否则它们实际上并不需要“收集垃圾”。如果您从不获取它们,那么它们是否存在都没关系。

请参阅,默认情况下,瞬态存储在选项表中。在基本安装中,选项表中可能包含100个条目。每个瞬变都会添加两个条目,但是即使您有数千个条目,它们也不会影响站点速度,因为它们不会自动加载。

在启动时,WordPress会将选项加载到内存中,但只会加载启用了自动加载标记的选项。瞬态不了解这一点,因此也不会加载到内存中。只有稍后实际使用的瞬变会产生成本。

从数据库的角度来看,选项表在选项ID和选项名称上都有索引。瞬态总是根据名称(键)加载的,因此对它们的查找始终是对单个唯一键值的简单选择。因此,查找为O(log(n)),并且超快。使用log(n)的Big-O,您必须先进入数百万行,然后才能注意到它。坦白说,查询的建立和删除以及实际数据传输的开销要长得多。通过比较,查询本身的运行时间基本上为零。因此,简单地拥有多余的未使用行不会影响任何事情,但会占用额外的磁盘空间。

在数据库中建立索引是一种深入了解的想法之一,它对实际上尚未了解幕后情况的人们没有意义。数据库是专为从头开始快速进行数据检索而设计的,可以毫无问题地处理这种事情。这是一本不错的书:http : //en.wikipedia.org/wiki/Index_(database

现在,以最明显的方式进行清理(在它们上调用SQL DELETE)实际上并没有从数据库中删除它们。它只是将它们从索引中删除,并将该行标记为“已删除”。同样,这就是数据库的工作方式。要实际清除磁盘空间,您必须继续然后在之后执行OPTIMIZE TABLE,这不是一个快速的操作。这需要时间。可能花了更多时间。总的来说,这可能不足以节省CPU时间。

如果您有某种情况导致连续插入未使用的新瞬态,则需要查找潜在的问题。是什么插入这些瞬变?他们使用的是变更键还是变异键?如果是这样,那么导致此问题的插件或代码基本上应该固定为不这样做。这将更有帮助,因为未正确创建它们的代码也可能没有检索到它们,因此所要做的工作比必须要做的更多。

另一方面,可能会为每个帖子之类的内容创建瞬态。这确实可以完全接受。我自己在SFC中进行此操作,以存储来自Facebook的传入评论。每个帖子都有一个与之关联的潜在瞬变,这意味着每个帖子额外增加两行。如果您有1万条帖子,那么选项表中(最终)将有2万行。这并不坏,也不会很慢,因为同样,就数据库真正关心的而言,100行和20,000行之间的差异很小。全部索引。快得快。子毫秒以下。

当您开始进入数百万行时,我会担心。当选项表的大小增加到几百兆字节以上时,我将非常关注一下。但是总的来说,除了极端情况,这不是问题。对于比拥有数十万个帖子的大型新闻网站这样的小问题来说,这绝对不是问题。对于任何足以解决问题的站点,您都应该使用某种外部对象缓存,在这种情况下,瞬态会自动存储在此处而不是存储在数据库中。


1
注:没有到期瞬变得到autloaded,并没有过期是默认的,所以其中应用程序/插件创建大量的瞬变,而不是设置他们将使用在每一页/后载荷的内存块到期。
webaware

没有理由使用“没有到期的瞬态”,因为它基本上与普通的“ option”相同。
奥托

1
可以,但这是默认设置。因此,许多插件作者都在添加非过期过渡。
webaware

1
好吧,这里的解决方案很简单:不要使用这些插件。他们做错了。暂态不能用作会话,您不应在没有有意义的期限的情况下使用它们,并且它们不应具有突变或更改键。
奥托

2
说7天。如果插件/主题作者想要更大或更小的东西,他们会指定它。如果他们想要自动加载,则不必为到期时间(= infinity)指定0,但这就是他们当前使用expiration参数作为yes / no autoload参数承担双重职责的结果。无论哪种方式,默认到期都不应该导致autoload = yes作为默认值;那只是自找麻烦。
webaware

18

奥托-我再也不同意你。问题在于,最终所有这些瞬变都会使表的大小变得可笑。无需花费数百万行就可以解决。我目前正在处理一个超过13万行的选项表,该表经常挂起。因为value字段是大文本类型,所以即使仅查找“自动加载”行也成为性能的噩梦。这些值字段与其余的行数据分开存储。即使从逻辑上讲它是同一张表的一部分,也必须进行联接才能提取所需的行。现在,由于需要的数据分布在磁盘上的所有位置,因此永久连接是永久的。分析(对MySQL使用jet profiler)已经证明了这一点。

将自动加载添加到群集密钥可能有助于解决此问题。例如,基于自动加载描述(ID ASC)的群集,将允许所有自动加载行首先在磁盘上聚集在一起。甚至我仍然认为您从数据库的角度来看正在承受巨大的压力。

我个人认为该系统的设计很糟糕。选项表似乎已经变成了很多事情的通用工具。如果value字段足够小,可以与该行数据的其余部分包含在同一页上,并且可以有效地对其进行索引,则可以。不幸的是事实并非如此。设计此方法的人需要回到DB101类。


5
是的,但是请考虑一下,当WordPress开发开始时,没有人认为将有成千上万个使用options表作为数据存储插件的插件:)
onetrickpony

@onetrickpony,这就是为什么务必花费时间并正确地做事很重要,无论您是否希望某天很大:)
Mahmoud Al-Qudsi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.