[wp-trac] [WordPress Trac] #25623: The design of update_option etc makes race conditions likely to happen

WordPress Trac noreply at wordpress.org
Thu Oct 17 17:11:45 UTC 2013


#25623: The design of update_option etc makes race conditions likely to happen
--------------------------+-----------------------------
 Reporter:  joehoyle      |      Owner:
     Type:  defect (bug)  |     Status:  new
 Priority:  normal        |  Milestone:  Awaiting Review
Component:  Cache         |    Version:
 Severity:  normal        |   Keywords:  dev-feedback
--------------------------+-----------------------------
 After spending a few hours chasing a nasty race condition bug in
 production today, I thought it would be good to discuss the design of the
 `$alloptions` object caching and how it can lead to data loss very easily
 when using any persistent object caching.

 1. Thread A: Loads options from cache
 1. Thread B: Loads options from cache
 1. Thread A: Updates options to cache
 1. Thread B: Updates options to cache, which includes the "outdated"
 option loaded in step 2

 This is not a new problem, and was discussed in some part in #17519.

 With most persistent object caching plugins, this is not a problem limited
 to options, as they use an internal (in memory) cache which is used before
 going to the cache backend (such as memcached) - this means get / updating
 anything into the cache will not propagate between threads as each thread
 has potentially already populated it's internal cache tool of now stale
 data.

 The "fix" for that scenario is to not use internal cache pools, so query
 memcached directly (aside: this is too slow so not really a solution).

 However, options is a much worse case, because a single cache key
 `alloptions` is used. So updating a single option, pushes all (potentially
 stale) options back to the cache store. To draw a parallel with MySQL,
 this would be like the MySQL query in `update_option` pushing every option
 in memory back to the db.

 As for a persistent object caching plugin fixing this internally - I don't
 see how it could with maintaining the use of an internal cache -- it's not
 so bad with updating a `post_meta` key for example, as the "race
 condition" scenario can only mess up that single post meta entry - with
 options, a race condition can lead to a lot data loss.

 Having said that - what is the "solution" here? Presumably the options are
 cached as one large array for performance reasons so it's one cache get /
 set from memcached / apc etc to load everything in. I am not sure how much
 of an impact that really has - would having a single cache key for each
 option make things much worse?

 Has anyone else come up against this much before? I know I have run into
 in a lot of api drriven stuff, as writes can often happen in concurrent
 running threads.

--
Ticket URL: <http://core.trac.wordpress.org/ticket/25623>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software


More information about the wp-trac mailing list