WordPress.org

Make WordPress Core

Opened 4 years ago

Last modified 2 years ago

#27935 new defect (bug)

Multisite get_site_option() does not cache empty string values in "SITE_ID:notoptions"

Reported by: doublesharp Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 3.7
Component: Options, Meta APIs Keywords: reporter-feedback close
Focuses: multisite Cc:

Description

In a multisite configuration the get_site_option() function in wp-includes/option.php does not cache meta_keys with meta_values of empty strings resulting in a database query being run on every request. Checking for a meta_value matching an empty string to trigger an entry into the notoptions cache will correct this behavior.

from:

if ( is_object( $row ) )

to:

if ( is_object( $row ) && $row->meta_value !== '' )

Attachments (1)

option.php.patch (668 bytes) - added by doublesharp 4 years ago.
cache empty meta_values in notoptions

Download all attachments as: .zip

Change History (8)

@doublesharp
4 years ago

cache empty meta_values in notoptions

#1 @doublesharp
4 years ago

  • Severity changed from normal to major

Bumping to major as this significantly impacts performance in my testing - once the cache is primed on my test site, depending on active plugins, approximately 30% of the database calls on a page are for meta_keys which exist but have an blank value, executed on every request as they cannot be cached.

#2 @doublesharp
4 years ago

  • Keywords has-patch dev-feedback added

#3 follow-up: @Denis-de-Bernardy
4 years ago

  • Keywords reporter-feedback added; has-patch removed
  • Version changed from 3.7 to trunk

Empty string is a valid value for an option. Why should it get cached in "notoptions"?

#4 in reply to: ↑ 3 @doublesharp
4 years ago

That's probably true, however it's not being cached properly by wp_cache_set() so the query is run on every request when the value is an empty string. I'll do more testing in case it's specific to my setup using memcache, but in any event the result should end up somewhere in a cache so it's not making unnecessary calls to the database although my suggestion might not be the proper way to go about it.

#5 @helen
4 years ago

  • Version changed from trunk to 3.7

#6 @jeremyfelt
3 years ago

  • Focuses multisite added

#7 @jeremyfelt
2 years ago

  • Keywords close added; dev-feedback removed
  • Severity changed from major to normal

I can't currently reproduce this with the PECL Memcache extension and the Memcached object cache drop-in.

  • Set an option in wp_sitemeta with a meta_key of testkey and a meta_value of an empty string.
  • Restart the memcached service to clear cache.
  • Use the following to test (with a couple var_dump()s watching for the cache hit):
wp> get_network_option( 1, 'testkey' );
string(10) "cache miss"
string(0) ""
wp> get_network_option( 1, 'testkey' );
string(9) "cache hit"
string(0) ""

The first get_network_option() call retrieved the empty string from the database and stored the value in cache as expected using wp_cache_set(). The second retrieved the value from cache using wp_cache_get().

I don't see anything in the code that would be treating an empty string differently. I imagine this could differ based on the object cache being used.

Happy to explore this further if steps can be provided to reproduce. Otherwise it seems like it may be related to the object cache drop-in being used.

Note: See TracTickets for help on using tickets.