[wp-trac] [WordPress Trac] #31245: Replace alloptions with a key cache

WordPress Trac noreply at wordpress.org
Thu Dec 10 18:30:28 UTC 2015


#31245: Replace alloptions with a key cache
-----------------------------------------------+---------------------------
 Reporter:  rmccue                             |       Owner:  rmccue
     Type:  enhancement                        |      Status:  assigned
 Priority:  normal                             |   Milestone:  Future
Component:  Options, Meta APIs                 |  Release
 Severity:  normal                             |     Version:
 Keywords:  has-patch needs-testing 4.4-early  |  Resolution:
                                               |     Focuses:  performance
-----------------------------------------------+---------------------------

Comment (by jeremyclarke):

 @joehoyle Don't want to give up on this ticket but willing to rename
 it/migrate it elsewhere since I agree with you that the current title
 "Replace alloptions with a key cache" isn't the right approach.

 Joe what do you think of solving this by clearing the {{{alloptions}}}
 cache at the right times (triggering a reload from the db) rather than
 micro-managing the fields that were just changed?

 In our testing it has proved very effective at avoiding the race condition
 entirely. When a process saves an autoloaded option we run
 {{{wp_cache_delete('alloptions', 'options');}}} and the next time an
 option is fetched WP does the single query to reload them (including any
 changes made by other processes).

 Specifically this solution solves the reproduction steps laid out by
 @tollmanz (Thanks so much for that BTW, made our testing much easier!).

 Here is a filter that solves the problem for us and relies only on what's
 already in core:

 {{{
 /**
  * Deletes the alloptions cache value whenever an option is modified.
  *
  * This code triggers a cache delete even when non-autoloaded options are
 saved because
  * we don't have easy access to check if the option is autoload=1 or not
  *
  * Ideally this should be done in core itself, only when alloptions needs
 to be updated.
  */
  function gv_redis_object_cache_delete_alloptions() {
         wp_cache_delete('alloptions', 'options');
  }
  add_action('added_option', 'gv_redis_object_cache_delete_alloptions');
  add_action('deleted_option', 'gv_redis_object_cache_delete_alloptions');
  add_action('updated_option', 'gv_redis_object_cache_delete_alloptions');
 }}}

 For anyone suffering from the WSOD bug like we were this is probably a
 worthwhile solution, but as stated in the phpdoc, it's not at all ideal
 and will result in resetting the {{{alloptions}}} cache more often than
 necessary.

 Core would be in a MUCH better position to solve this directly while
 handling the {{{alloptions}}} cache and knowing whether the option being
 saved is autoloaded or not.

 It can also be fixed at the {{{object-cache.php}}} level, which is the
 solution we're currently using. By adding a filter on the SET command in
 our Redis object cache we can run {{{wp_cache_delete('alloptions',
 'options');}}} only when the actual {{{alloptions}}} cache is updated.
 This seems insane/ironic but works very well to fix this problem and seems
 unlikely to cause any serious performance problems.

 '''Quick note on stupid plugins'''

 FWIW for anyone experiencing problems related to {{{alloptions}}} I
 recommend doing an audit of the ongoing actions taken by your object
 cache. I added logging to our {{{object-cache.php}}} and found several
 plugin features (some by me, some from repo) that were triggering option
 changes on every pageload for foolish reasons. Cleaning up these
 noisy/constant updates will probably make a huge difference to the
 incidence of {{[alloptions}}} bugs and obviously reduce the overall load
 on your system.

--
Ticket URL: <https://core.trac.wordpress.org/ticket/31245#comment:26>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list