[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