配置定时清理优化wordpress数据库

WordPress易操作、易扩展(插件机制),但不如意之处也有,所以我会趁闲暇之余进行优化,我戏称之“Wordpress归真计划”。自动运维系列其实没有太多可写,无非是自动更新升级、自动清理垃圾(文件+数据)、自动提交代码(版本管理)等几个方面。本次分享wp数据库自动清理优化——删除过期无效数据并优化数据表。该想法源于归真计划中的“Kill Plugins”【注1】,要告别的插件是WP Clean Up,先感谢插件作者@BoLiQuan。

  • 指导思想:将插件做的交给系统自动进行,解放人力。
  • 技术核心:SQL+LinuxCrontab

一、数据清理SQL语句

先说三处需要谨慎清理的:

1、草稿数据

发布体【注2】的草稿数据。注意如果你的习惯不是离线写文章,这一条语句请谨慎考虑使用。

$sql.=“DELETE FROM {$table_prefix}posts WHERE post_status = ‘draft’;”;

2、待审评论

这条语句处理的是待审评论数据,如果wordpress设置了评论审核,那么这一条也要谨慎使用,待审评论不一定是垃圾评论。

$sql.=“DELETE FROM {$table_prefix}comments WHERE comment_approved = ‘0’;”;

3、配置表配置项

options表存储着wp和站长的配置数据,请按照自己的情况书写清理语句,清理之前自己做好表备份,通常这种工作处理一次就够了,不必每次都执行。

比如下面的代码是适合我网站的:清除非当前模板主题的配置项;删除无用插件配置项,比如我已经不用了的LoginLockDown(详见:WordPress扫二维码登录后台功能实现案例—WpQrLogin)、BaiduSubmit(已重写自动推送,并融入主题)、WP Backup。

//query current theme name
$themes = $pdo->query(“select option_value from {$table_prefix}options where option_name=’current_theme’ “)->fetch();
//$theme_name = strtolower($themes[0]);
//clear other themes’ options
$sql.=“DELETE FROM {$table_prefix}options WHERE option_name like ‘%theme_mod_%’ AND option_name<>’theme_mod_{$theme_name}’;”;
//unused plugins option
$sql.=“DELETE FROM {$table_prefix}options WHERE option_name like ‘%loginlockdown%’ ;”;
$sql.=“DELETE FROM {$table_prefix}options WHERE option_name like ‘%baidusubmit%’ ;”;
$sql.=“DELETE FROM {$table_prefix}options WHERE option_name like ‘%backwpup%’; “;

—–分割线—–

4、发布体版本

有多少人写文章是多人协作的?你写文章的时候需要对比上一个版本查看自己做了哪些修改?如果都不是,可以使用下面的语句清理发布版本。

$sql.=“DELETE FROM {$table_prefix}posts WHERE post_type = ‘revision’;”;

5、自动草稿

不多解释,请按需使用。我个人习惯离线撰写文章,在线写的时候倾向于自己手动保存,而且我已经移除了wp自动草稿的功能,所以数据库中所有自动草稿数据都是我不需要的。

$sql.=“DELETE FROM {$table_prefix}posts WHERE post_status = ‘auto-draft’;”;

6、回收站

删除的发布体,以后不用自己手动去后台回收站清空了。

$sql.=“DELETE FROM {$table_prefix}comments WHERE comment_approved = ‘trash’;”;

7、无用的发布体元数据(附加数据)

postmeta表中因发布体删除而遗留下来的数据。比如文章的自定义字段,有些人在设计自定义字段面板的时候没有设计delete,就会产生这样的情况。

$sql.=“DELETE pm FROM {$table_prefix}postmeta pm LEFT JOIN {$table_prefix}posts wp ON wp.ID = pm.post_id WHERE wp.ID IS NULL;”;

8、垃圾评论

$sql.=“DELETE FROM {$table_prefix}comments WHERE comment_approved = ‘spam’;”;

9、无用的评论元数据(附加数据)

删除评论遗留的附加数据或者做过评论优化残留的数据况。大多数wp使用者会有Askimet的数据,这些数据记录有助于插件过滤垃圾评论,可去可留。

$sql.=“DELETE FROM {$table_prefix}commentmeta WHERE comment_id NOT IN (SELECT comment_id FROM {$table_prefix}comments);”;
$sql.=“DELETE FROM {$table_prefix}commentmeta WHERE meta_key IN (‘akismet_history’,’akismet_result’,’akismet_user_result’,’akismet_user’);”;

10、无效的关系数据

删除发布体或者分类(待确定)以后残留的数据。

$sql.=“DELETE FROM {$table_prefix}term_relationships WHERE object_id NOT IN (SELECT ID FROM {$table_prefix}posts);”;

11、无用的用户元数据(附加数据)

$sql.=“DELETE FROM {$table_prefix}usermeta WHERE user_id NOT IN (SELECT ID FROM {$table_prefix}users);”;

12、订阅消息

$sql.=“DELETE FROM {$table_prefix}options WHERE option_name LIKE ‘_site_transient_browser_%’ OR option_name LIKE ‘_site_transient_timeout_browser_%’ OR option_name LIKE ‘_transient_feed_%’ OR option_name LIKE ‘_transient_timeout_feed_%’;”;

二、数据表优化SQL

原插件中优化工作很简单,仅使用了OPTIMIZE,但对大多数人而言足够了。它对MyISAM/INNODB引擎的数据表还是很有用的,能够删除冗余数据(包括字段和索引),提高表的查询效率。

$result = $pdo->query(‘SHOW TABLE STATUS FROM `’.DB_NAME.’`’)->fetchAll();
foreach($result as $row){
    $sql.= “OPTIMIZE TABLE {$row[‘Name’]};”;
}

注意:所有语句最终会综合到一起依次执行,所以必须有分隔符,即:每一句SQL语句必须要用分号结尾。

三、自动化的实现

小节标题挺高大上,其实就是个定时计划任务+执行脚本。

1、执行脚本PHP

执行脚本的核心就是文章一二节提到的部分,我们再补充一下数据库操作,略做完善后命名(如gznotes.php);

将文件放到wordpress根目录,然后可以利用php命令直接执行,进行首测(注意:非HTTP访问),命令如下:

[/gznotes.com]# php /YourPath/gznotes.php

/**
* Copyright (c) DingLipeng
* Author       : DingLipeng(Daniel Ting)
* Author URI   : http://www.gznotes.com/
* Created Time : 2017-08-12 16:09
*/
//read db config from wp-config.php
$config_str = file_get_contents(dirname(__FILE__).DIRECTORY_SEPARATOR.’wp-config.php’);
preg_match_all(“!define\(\s*’DB_.*\);|\\\$table_prefix.*;!”,$config_str,$res);
foreach ( $res[0] as $re ) {
    eval($re);
}
$pdo = null;
try{
    $pdo = new PDO(“mysql:host=”.DB_HOST.“;dbname=”.DB_NAME,DB_USER,DB_PASSWORD);
} catch (PDOException $exception){
    echo “Connect Failed:”.$exception->getMessage();
    exit();
}
$sql = “”;
//============start sql str=====
    //……
//============sql str end=====
$pdo->exec($sql);
//log completed or affected number of rows
exit(“Succ\n”);

2、定时计划任务Crontab

大多数人用Linux系统的服务器,所以一般都有crontab神器。如果没有请安装(我的是 CentOS 6.8):

[/gznotes.com]# yum –y install vixie-cron

安装完成,记得加入开机启动项

[/gznotes.com]# chkconfig –level 345 crond on

关于crontab使用,引用@蚂蚁快跑 【参考链接1】博文中的几张图片:

WordPress自动运维教程—如何自动清理优化数据库-crontab1

图:Linux Crontab定时计划任务讲解

老规矩,运维放到夜深人静,访客稀少的时候进行,频率方面不用太高,一个周一次就可以,任务形式可以有多种表现,比如可以在/etc/crontab直接书写:

#每周日的凌晨3点

0 3  *  * 0 root /usr/bin/php  /YourPath/gznotes.php >>/YourPath/clean.log

#每隔七天凌晨3点

0 3 */7 * * root /usr/bin/php  /YourPath/gznotes.php >>/YourPath/clean.log

也可以在/etc/cron.weekly中添加执行脚本clean.sh,并赋予执行权限chmod +x  /etc/cron.weekly/wp-cleaner.sh,文件命令如下:

#!/bin/sh

php /YourPath/gznotes.php>>/YourPath/clean.log

#把命令执行的结果追加输出到指定目录下的clean.log文件中

注意:写完后手动执行看下有没有错误,如果像上面命令那样指定了结果输出,那么打开clean.log文件查看执行的结果。

然后,启动crond,查看状态,查看当前用户所有任务列表:

[/gznotes.com]# service crond start

[/gznotes.com]# service crond status

[/gznotes.com]# crontab -l
标签:WordPress 发布于:2019-11-12 16:19:06