3

How do you I go about setting WordPress to a read-only state?

I have a setup that scales slaves instances with read-only database access but I'm seeing a lot of log data where WordPress still tries to write to the database.

update_{post_type}_metadata, set_transient, wpdb... basically stopping anything attempting to write would be ideal. I can easily check to see if I'm on a MASTER instance vs. SLAVE instance so I could modify hooks pretty early.

Trying to short-circuit the update metadata function seems like possibly eliminating one vector, but the rest I fear involve modifying WP Core.

add_filter ( 'update_post_metadata', '__return_false', 99 );

$result = update_post_meta( -1, 'test-key', 'test-value' );

echo $result;

Any suggestions?


HyperDB looks promising as a more long-term solution.

  • As usual ;) I don't get the scenario. If something needs to be written to the DB why would you prevent it? if for example a server identified a comment as spam, why don't you want to mark it as one? – Mark Kaplun Oct 21 '16 at 3:33
  • 2
    It's WordPress at scale. It's fine if you don't get it @MarkKaplun ;) I have read-only databases which cannot be written to... but still log errors when WordPress tries... which is all the time based on OEmbeds, Widgets and other factors non-essential to the end goal of the question. – jgraup Oct 21 '16 at 3:58
  • Rephrasing my question, to use a RO DB you need to know that the software you run will not legitimately try to write to it. transients is easy to avoid with object cache, but why would anything write meta data? this sounds like something important you don't want to just ignore – Mark Kaplun Oct 21 '16 at 4:04
  • I can tell you no issues are being ignored and the plugin related issues are considered off-topic for this forum. – jgraup Oct 21 '16 at 4:12
  • 1
    Having one R/W DB, and then multiple read replicas is the easiest way to scale a database--then you don't have to deal with sharding and all that sort of mess. Most likely, only the front-end will be heavily loaded, so if you can modify your install to have your admin section point to the master, and the front-end to point to the read replicas. – haz Jan 18 '17 at 22:16
6

WordPress doesn't work well in read-only mode. It depends on the database for cache and other tasks.

However, there are a couple of options if you'd still like to proceed.

  1. Set the database user permissions to 'READ ONLY'
  2. Use a function to intercept all db queries. We used this on our theme demo site to prevent db writes.

Function to use:

/**
 * Whitelist "SELECT" and "SHOW FULL COLUMNS" queries.
 */
function my_readonly_filter( $query ) {
  global $wpdb;

  if ( preg_match( '/^\s*select|show full columns\s+/i', $query ) ) {
    return $query;
  }

  // Return arbitrary query for everything else otherwise you get 'empty query' db errors.
  return "SELECT ID from $wpdb->posts LIMIT 1;";
}
add_filter( 'query', 'my_readonly_filter' );
  • Thanks @cowgill. I'll test this out but I think this was close to my initial thought. – jgraup Oct 21 '16 at 3:59
  • Unfortunately for some reason it slows down the website greatly. Not the best for demoing a product. – Maciej Krawczyk Nov 7 '17 at 21:17
  • 1
    Before you use it, make sure to disable WP_CRON. Add define('DISABLE_WP_CRON', true); to wp-config.php The reason why is, that when you disable write access to the database, WordPress will attempt to do cron on each request, causing massive slowdown in admin page load. – Maciej Krawczyk Nov 12 '17 at 15:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.