WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 3 years ago

#15548 closed defect (bug) (fixed)

Cache inconsistencies between get_option and get_blog_option

Reported by: mwidmann Owned by:
Milestone: 3.5 Priority: normal
Severity: normal Version: 3.0.1
Component: Multisite Keywords: caching memcache has-patch
Focuses: Cc:

Description

When an option is updated for a blog update_option calls wp_cache_set to update the cache for that option.

The problem comes when the option is accessed through get_blog_option from another site. There the cache never gets updated (unless the caching - in our case memcached - is recycled.

Steps to reproduce, I'm updating the admin_email, so be sure to change it back afterwards:

echo "fetching using get_blog_option<br>";
echo get_blog_option( 6, 'admin_email' );

switch_to_blog( 6 );
echo "<br>fetching using get_option before update<br>";
echo get_option( 'admin_email' );
echo "<br>updating...<br>";
update_option( 'admin_email', 'new-value@email.com' );
echo "<br>fetching using get_option after update<br>";
echo get_option( 'admin_email' );
restore_current_blog();

echo "<br>fetching using get_blog_option after uptdate<br>";
echo get_blog_option( 6, 'admin_email' );

The output will look like something similar to this:

fetching using get_blog_option
old-value@email.com
fetching using get_option before update
new-value@email.com
updating...

fetching using get_option after update
new-value@email.com
fetching using get_blog_option after uptdate
old-value@email.com

If no caching is enabled than - of course - this issue doesn't come up as the value is always fetched form the database.

The best solution most probably would be to modify the either hook into update_option and delete_option actions from ms-blogs.php and then update or delete the value based on the given option.

Change History (9)

comment:1 @mwidmann4 years ago

Here's a way around this limitation, I load it from a mu-plugin.

add_action( 'update_option', 'vmh_update_option', 11, 3 );
add_action( 'delete_option', 'vmh_delete_option', 11, 2 );

function vmh_update_option( $option, $oldvalue, $newvalue ) {
	global $blog_id;

	if ( is_multisite() ) {
		$key = $blog_id."-".$option."-blog_option";
		$value = wp_cache_get( $key, "site-options" );
		if ( FALSE !== $value ) {
			wp_cache_set( $key, $newvalue, "site-options" );
		}
	}
}
function vmh_delete_option( $option, $oldvalue ) {
	global $blog_id;

	if ( is_multisite() ) {
		$key = $blog_id."-".$option."-blog_option";
		wp_cache_delete( $key, "site-options" );
	}
}

comment:2 @scribu4 years ago

Related: #14992

comment:3 @markjaquith4 years ago

  • Milestone changed from Awaiting Review to Future Release
  • Type changed from defect (bug) to enhancement

comment:4 @SergeyBiryukov3 years ago

  • Keywords changed from caching, memcache to caching memcache

Closed #19822 as a duplicate. Has a patch: ticket:19822:patch.diff.

comment:5 @mohanjith3 years ago

  • Cc moha@… added
  • Type changed from enhancement to defect (bug)

comment:6 @uglyrobot3 years ago

  • Cc aaron@… added
  • Keywords has-patch added
  • Version changed from 3.0.1 to 3.3.1

comment:7 @SergeyBiryukov3 years ago

  • Version changed from 3.3.1 to 3.0.1

Version number indicates when the bug was initially introduced/reported.

comment:8 @scribu3 years ago

  • Milestone changed from Future Release to 3.5

This should be fixed as of [21357].

comment:9 @scribu3 years ago

  • Resolution set to fixed
  • Status changed from new to closed
Note: See TracTickets for help on using tickets.