WordPress Multi-Master DB Replication: Deadlock when updating cron table in wp_options

We’re running WordPress in an environment that features a multi-master DB behind a load-balancer. The error log was filling up with a deadlock error when WP tried to update the cron table in wp_options. We disabled wp-cron altogether but are still seeing the error, so, two questions:

1) What causes the cron table in wp_options to be updated?

Read More

2) It appears to run on every page load. Can this be disabled and a cronjob setup to run it periodically in crontab?

Thanks

Related posts

Leave a Reply

2 comments

  1. WordPress uses wp-cron.php as a means for running scheduled tasks when the user doesn’t have access to or want to setup cronjobs via Unix. This process looks at the scheduled jobs in the cron table in wp_options and if the specified time (or more) has elapsed then the job executes.

    wp-cron.php uses wp-includes/cron.php (the WordPress Cron API) to run scheduled jobs. In cron.php you’ll find a number of functions that update the cron table table, these functions are all around the scheduling of events.

    Any function of WordPress or plugin that requires a scheduled event uses the Cron API to do so. However, the action of scheduling an event (even if it already exists) updates the cron table in wp_options. Even with wp-cron.php totally disabled, these elements of WordPress/the plugin are loading and scheduling their events, trying to update the cron table in the process.

    I’ve not figured-out exactly why the deadlock occurs, other than knowing it must be related to the DB/site config, but I do now know that WordPress is behaving itself.

  2. I’ve run into this same issue — the databases would go out of sync very quickly. Certain plugins made it occur faster (they scheduled lots of cron jobs), but even with them disabled, eventually the errors would block replication.

    I was able to keep replication working by doing two things.

    The first, in my.ini, was to add:

    slave-skip-errors = 1062
    

    This instructs MySql to skip creating entries when a duplicate key already exists. My cluster is set up as active-passive, so in theory, there should be no “real” writes to the passive MySql node unless the active node is down, in which case, there will be no “real” writes to that node. The only stuff that gets written to the passive node is as a result of wp-cron jobs, which (in theory) are also running on the active node.

    The second, in each site’s wp-config.ini, was to add:

    /** disable cron */
    define('DISABLE_WP_CRON', true);
    

    This blocks wp-cron from running at all, so either one of these solutions should work on their own.

    Another option would be to disable wp-cron, but leave the full database syncing in place, and schedule a script to call each site’s wp-cron.php (you’d be accomplishing manually what the wp-cron service does automatically). That way, it will only run on the active node and the data should be synced over to the passive node with no problems.