[wp-trac] [WordPress Trac] #26173: DB Upgrade Loop after Automatic Upgrade with db_version change and external object cache
WordPress Trac
noreply at wordpress.org
Tue Nov 26 05:27:00 UTC 2013
#26173: DB Upgrade Loop after Automatic Upgrade with db_version change and external
object cache
-----------------------------+------------------------------
Reporter: DH-Shredder | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Upgrade/Install | Version: 3.7.1
Severity: major | Resolution:
Keywords: needs-patch |
-----------------------------+------------------------------
Comment (by dd32):
Finally tracked this down.. Bit of a hairy one.. so tread carefully, I
might confuse. (for simplicity, db_version = 1 for old, db_version = 2 for
new version)
* The call to update the DB is normally done through a `wp_remote_post(
wp-admin/upgrade.php )` request from the upgrading script.
* On the call to wp-admin/upgrade.php which updates the database,
`WP_INSTALLING` is defined, this causes `update_option(db_version, 2)` to
update the DB only, but not the caches. Once it's finished updating the
DB, it calls `wp_flush_cache()` to clear the object cache.
* In normal circumstances, ie. a Standard manual upgrade, the next
pageload will cause the cache to be re-filled from the DB.
* In the case of a Background Update however, after the DB upgrade step,
we call `update_option()` while `WP_INSTALLING` is NOT defined, this
causes us to update the object cache.
The problem is, that we store all options in one bucket,
`$prefix:options:alloptions` which holds an array of every option in
existence.
At this point, we've got the old data loaded in the cache (db_version =
1), we update another entry in the array ( `auto_core_update_notified` )
and re-set it in the object cache.
So we're overwriting the data in the cache with old data. The solution
appears to be simple, call `wp_cache_flush()` after the call to wp-
admin/upgrade.php takes place.
The root cause is much deeper, and is a bug in the way which we cache
options. We prioritize the `$alloptions` cache above individual caches
(which are only used for non-autoloaded values normally) which means
reproducing this is very easy: Simply have two scripts running at the
same time, and update two different options (both of which are autoloaded
normally, or, one which is a new option) and one will overwrite the other
in the cache.
Will attach a patch shortly.. I can think of ways to bypass it and cause
the problem again.
--
Ticket URL: <http://core.trac.wordpress.org/ticket/26173#comment:3>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software
More information about the wp-trac
mailing list