Hi, on my drupal site I am getting duplicate entry errors on the cache table, especially when the site is under heavy load. ie.

Duplicate entry 'menu:0:en' for key 1 query: INSERT INTO cache (cid, data, created, expire, headers) VALUES ('menu:0:en', 'a:3:{s:10"path index\";a:191:{s:16"admin/aggregator\";s:1"2\";s:26"admin/aggregator/edit/feed\";i:-2;s:30"admin/aggregator/edit/category\";i:-3;s:23"admin/aggregator/remove\";i:-4;s:23"admin/aggregator/update\";i:-5;s:21"admin/aggregator/list\";i:-6

It has been suggested that this is caused by a race condition in the cache_set function, which usually has a two step upate of the cache (update, if that fails then insert). My solution to this was to use the MySQL statement INSERT ... ON DUPLICATE KEY UPDATE... as shown below. This eliminates the race condition, without the need for explicit table locking. Alternatively you could use the REPLACE INTO syntax, used in the id generation. Either way, these are DB specific commands, so the cache_set function should probably be moved into the database.{mysql|pgsql}.inc files.

function cache_set($cid, $data, $expire = CACHE_PERMANENT, $headers = NULL) {
$data = db_encode_blob($data);

@db_query("INSERT INTO {cache} (cid, data, created, expire, headers) VALUES ('%s', '%s', %d, %d, '%s') ON DUPLICATE KEY UPDATE data = '%s', created = %d, expire = %d, headers = '%s'", $cid, $data, time(), $expire, $headers, $data, time(), $expire, $headers);
}

I checked with the latest release of Drupal (4.6.5) and this patch still holds.

Comments

Wesley Tanaka’s picture

Status: Active » Closed (duplicate)