WordPress.org

Make WordPress Core

Opened 11 years ago

Closed 11 years ago

#3726 closed defect (bug) (fixed)

wp_list_categories() goes berzerk on default install with object cache enabled

Reported by: markjaquith Owned by:
Milestone: 2.1.1 Priority: highest omg bbq
Severity: major Version: 2.1
Component: Template Keywords:
Focuses: Cc:

Description

  • New install of WP 2.1
  • Published 4 posts in "Uncategorized" category.
  • define('ENABLE_CACHE', true); in wp-config.php
  • Load the front page

First run (non-cached) gives me:

<li class="categories"><h2>Categories</h2><ul>	<li><a href="http://txfx.net/wp22/?cat=1" title="View all posts filed under Uncategorized">Uncategorized</a> (4)
</li>
</ul></li>

Perfect.

Second run (cached), gives me:

<li class="categories"><h2>Categories</h2><ul>
	<ul class="children">
		<ul class="children">
			<ul class="children">
				<ul class="children">
					<ul class="children">
						<ul class="children">
							<ul class="children">

								<ul class="children">
									<ul class="children">
										<ul class="children">
											<ul class="children">
												<ul class="children">
													<ul class="children">
														<ul class="children">
															<ul class="children">
																<ul class="children">

																	<ul class="children">
																		<ul class="children">
																			<ul class="children">
																				<ul class="children">
																					<ul class="children">
																						<ul class="children">
																							<ul class="children">
																								<ul class="children">
																									<ul class="children">

																										<ul class="children">
</ul>

That ain't right.

Attachments (2)

wp_list_categories.png (15.3 KB) - added by markjaquith 11 years ago.
screenshot of result
kill_references_when_caching_objects.diff (826 bytes) - added by markjaquith 11 years ago.

Download all attachments as: .zip

Change History (9)

@markjaquith
11 years ago

screenshot of result

#1 @charleshooper
11 years ago

I can't seem to confirm this... any other steps you may have missed?

Not that I don't think you know what version you were running but I couldn't help but notice the directory being labeled "wp22" (just checking ;))

#2 @markjaquith
11 years ago

I did a svn switch to /branches/2.1/ before reporting.

In order for the cache to be enabled, your wp-contents directory needs to be writable (it should create a /cache/ directory).

In any case, I discovered the issue. get_category() tries to store an array of object references into the cache. The cache doesn't like this, and stores a blank string instead. So you get a blank string on the way out.

Looking around the web, it seems like good old serialize/unserialize is the sure way to make sure you don't have any references. Patch adds that to the appropriate cache functions.

#3 @markjaquith
11 years ago

  • Resolution set to fixed
  • Status changed from new to closed

(In [4855]) Introduce Notoptions and Alloptions caching, so that all options (and previously attempted Notoptions) are read from the cache in one go. Should reduce cache misses to zero or close to it. fixes #3726

#4 @markjaquith
11 years ago

  • Milestone changed from 2.1.1 to 2.2

To explain this a bit:

  • Two pseudo-options are stored in the object cache (just there, not in the DB)
  • 'notoptions' stores all attempted non-options so that the DB isn't accessed more than once trying to load these options that don't exist
  • 'alloptions' stores all autoloaded options. The first time any option is queried, 'alloptions' will be populated (either from the DB, or from a persistent object cache). If the option is in there (likely, most options are autoloaded), it'll be read from there. So you just have one cache read for all your autoloaded options.
  • Non-autoloaded options revert to the options cache as before (one item per cache entry).
  • Since the loading of the autoloaded options is used by get_option(), people using alternative object caches will no longer see individual queries for each option on the first load (i.e. with an empty object cache)

All of this should be transparent. As long as you use get_option(), add_option(), update_option(), and delete_option(), it should be like nothing ever happened.

This should reduce cache misses to zero (or close to it), and it should reduce redundant queries.

#5 @markjaquith
11 years ago

(In [4856]) make sure nothing going into the object cache is being passed by reference. fixes #3726

#6 @markjaquith
11 years ago

  • Milestone changed from 2.2 to 2.1.1
  • Resolution fixed deleted
  • Status changed from closed to reopened

argh... wrong ticket for the comments 2 and 3 ones above this.

#7 @markjaquith
11 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

(In [4857]) make sure nothing going into the object cache is being passed by reference. fixes #3726

Note: See TracTickets for help on using tickets.