WordPress

太多revisions导致编辑文章很慢

今天遇到一个案例,网站安装了Elementor,其它插件有十几个,某些页面有时候能打开,有时候会报数据库错误。本以为是elementor导致的性能问题,但并非所有页面都慢。切换到默认编辑器,发现revisons有点多。

太多revisions导致编辑文章很慢

太多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精确控制。

留言

您的电子邮箱地址不会被公开。 必填项已用*标注