【问题标题】:Wordpress Multi-Master DB Replication: Deadlock when updating cron table in wp_optionsWordpress 多主数据库复制:更新 wp_options 中的 cron 表时出现死锁
【发布时间】:2013-03-04 12:00:02
【问题描述】:
我们在负载均衡器后面具有多主数据库的环境中运行 Wordpress。当 WP 尝试更新 wp_options 中的 cron 表时,错误日志充满了死锁错误。我们完全禁用了 wp-cron,但仍然看到错误,所以,有两个问题:
1) wp_options 中的 cron 表被更新的原因是什么?
2) 它似乎在每次页面加载时运行。是否可以禁用此功能并设置 cronjob 以在 crontab 中定期运行它?
谢谢
【问题讨论】:
标签:
wordpress
cron
innodb
deadlock
database-replication
【解决方案1】:
当用户无法访问或想要通过 Unix 设置 cronjobs 时,Wordpress 使用 wp-cron.php 作为运行计划任务的一种方式。此过程查看 wp_options 中 cron 表中的计划作业,如果指定的时间(或更长时间)已过,则作业执行。
wp-cron.php 使用 wp-includes/cron.php(Wordpress Cron API)来运行预定的作业。在 cron.php 中你会发现许多更新 cron 表的函数,这些函数都围绕着事件的调度。
任何需要预定事件的 Wordpress 或插件功能都使用 Cron API 来执行此操作。但是,调度事件的操作(即使它已经存在)会更新 wp_options 中的 cron 表。即使 wp-cron.php 完全禁用,Wordpress/插件的这些元素仍在加载和安排它们的事件,试图更新进程中的 cron 表。
除了知道它一定与数据库/站点配置相关之外,我还没有弄清楚死锁发生的确切原因,但我现在知道 Wordpress 的行为本身。
【解决方案2】:
我也遇到过同样的问题——数据库很快就会不同步。某些插件使它发生得更快(他们安排了大量的 cron 作业),但即使禁用它们,最终错误也会阻止复制。
我能够通过做两件事来保持复制工作。
首先,在 my.ini 中添加:
slave-skip-errors = 1062
当重复键已经存在时,这指示 MySql 跳过创建条目。我的集群设置为主动-被动,因此理论上,除非主动节点关闭,否则不应有“真实”写入被动 MySql 节点,在这种情况下,不会有“真实”写入该节点。写入被动节点的唯一内容是 wp-cron 作业的结果,该作业(理论上)也在主动节点上运行。
第二个,在每个站点的 wp-config.ini 中,添加:
/** disable cron */
define('DISABLE_WP_CRON', true);
这会阻止 wp-cron 运行,因此这些解决方案中的任何一个都应该独立运行。
另一个选项是禁用 wp-cron,但保留完整的数据库同步,并安排一个脚本来调用每个站点的 wp-cron.php(您将手动完成 wp-cron 服务自动执行的操作)。这样,它只会在主动节点上运行,并且数据应该可以毫无问题地同步到被动节点。