今天遇到一个案例,网站安装了Elementor,其它插件有十几个,某些页面有时候能打开,有时候会报数据库错误。本以为是elementor导致的性能问题,但并非所有页面都慢。切换到默认编辑器,发现revisons有点多。
太多post revisions会导致性能问题
出问题的页面的共同点是revisions非常多,至少有400+,后台编辑页面加载不出来时会报数据库错误。
WP Database error: Commands out of sync:...
这个错误有误导性,会让你认为问题出在缓存或者数据库上,即使禁用所有插件,切换到默认主题也无法修复。也可能是资源不足?
但看到revisions的数量后,恍然大悟。加载页面时会进行revisons查询,如下图所示。
update_meta_cache()
对应的查询里,IN后面的一串ID是post revisions的ID,想象一下有五百多个是什么场景,本地测试直接挂机,在线服务器还好,数据库性能强劲,但也比较耗时。
WordPress Post Revisions的数量限制是多少?
默认是没有限制,看源代码就知道。如果没有定义 WP_POST_REVISIONS
这个常量,那$num
是-1,就是没限制。通过wp_revisions_to_keep
这个filter,可以给每篇post设定不同的revision数量限制。
function wp_revisions_to_keep( $post ) {
$num = WP_POST_REVISIONS;
if ( true === $num ) {
$num = -1;
} else {
$num = (int) $num;
}
if ( ! post_type_supports( $post->post_type, 'revisions' ) ) {
$num = 0;
}
/**
* Filters the number of revisions to save for the given post.
*
* Overrides the value of WP_POST_REVISIONS.
*
* @since 3.6.0
*
* @param int $num Number of revisions to store.
* @param WP_Post $post Post object.
*/
$num = apply_filters( 'wp_revisions_to_keep', $num, $post );
/**
* Filters the number of revisions to save for the given post by its post type.
*
* Overrides both the value of WP_POST_REVISIONS and the {@see 'wp_revisions_to_keep'} filter.
*
* The dynamic portion of the hook name, `$post->post_type`, refers to
* the post type slug.
*
* @since 5.8.0
*
* @param int $num Number of revisions to store.
* @param WP_Post $post Post object.
*/
$num = apply_filters( "wp_{$post->post_type}_revisions_to_keep", $num, $post );
return (int) $num;
}
写博客不会遇到这个问题,但做公司网站,你的页面结构基本不变,内容经常更新,随着时间的流逝就会搞出一大堆revisions,你的wp_posts表里可能一半以上的记录是revisions,服务器的数据库性能不够强就会严重影响性能,这时候,建议安装WP-Optimize – Cache, Clean, Compress插件,清除revisions,并在wp-config.php
里定义revisions的数量限制。
define( 'WP_POST_REVISIONS', 10 );
如果用不到这个功能,禁了就行。
define('WP_POST_REVISIONS', false );
或者用WP Revisions Control精确控制。