There appears to be a race condition in the system_theme_data() function.

I was running several concurrent administration windows on my new Drupal-6.3 installation, and one of the loaded pages suddenly showed the following warnings:

user warning: Duplicate entry 'themes/garland/garland.info' for key 1 query: INSERT INTO system (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('garland', 'themes/engines/phptemplate/phptemplate.engine', 'a:13:{s:4:\"name\";s:7:\"Garland\";s:11:\"description\";s:66:\"Tableless, recolorable, multi-column, fluid width theme (default).\";s:7:\"version\";s:3:\"6.3\";s:4:\"core\";s:3:\"6.x\";s:6:\"engine\";s:11:\"phptemplate\";s:11:\"stylesheets\";a:2:{s:3:\"all\";a:1:{s:9:\"style.css\";s:24:\"themes/garland/style.css\";}s:5:\"print\";a:1:{s:9:\"print.css\";s:24:\"themes/garland/print.css\";}}s:7:\"project\";s:6:\"drupal\";s:9:\"datestamp\";s:10:\"1215640509\";s:7:\"regions\";a:5:{s:4:\"left\";s:12:\"Left sidebar\";s:5:\"right\";s:13:\"Right sidebar\";s:7:\"content\";s:7:\"Content\";s:6:\"header\";s:6:\"Header\";s:6:\"footer\";s:6:\"Footer\";}s:8:\"features\";a:10:{i:0;s:20:\"comment_user_picture\";i:1;s:7:\"favicon\";i:2;s:7:\"mission\";i:3;s:4:\"logo\";i:4;s:4:\"name\";i:5;s:17:\"node_user_picture\";i:6;s:6:\"search\";i:7;s:6:\"slogan\";i:8;s:13:\"primary_links\";i:9;s:15:\"secondary_links\";}s:7:\"scripts\";a:1:{s:9:\"script.js\";s:24:\"themes/garland/script.js\";}s:10:\"screenshot\";s:29:\"themes/garland/screenshot.png\";s:3:\"php\";s:5:\"4.3.5\";}', 'theme', 'themes/garland/garland.info', 0, 0, 0) in /var/www/drupal6/modules/system/system.module on line 830.
user warning: Duplicate entry 'themes/bluemarine/bluemarine.info' for key 1 query: INSERT INTO system (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('bluemarine', 'themes/engines/phptemplate/phptemplate.engine', 'a:13:{s:4:\"name\";s:10:\"Bluemarine\";s:11:\"description\";s:66:\"Table-based multi-column theme with a marine and ash color scheme.\";s:7:\"version\";s:3:\"6.3\";s:4:\"core\";s:3:\"6.x\";s:6:\"engine\";s:11:\"phptemplate\";s:7:\"project\";s:6:\"drupal\";s:9:\"datestamp\";s:10:\"1215640509\";s:7:\"regions\";a:5:{s:4:\"left\";s:12:\"Left sidebar\";s:5:\"right\";s:13:\"Right sidebar\";s:7:\"content\";s:7:\"Content\";s:6:\"header\";s:6:\"Header\";s:6:\"footer\";s:6:\"Footer\";}s:8:\"features\";a:10:{i:0;s:20:\"comment_user_picture\";i:1;s:7:\"favicon\";i:2;s:7:\"mission\";i:3;s:4:\"logo\";i:4;s:4:\"name\";i:5;s:17:\"node_user_picture\";i:6;s:6:\"search\";i:7;s:6:\"slogan\";i:8;s:13:\"primary_links\";i:9;s:15:\"secondary_links\";}s:11:\"stylesheets\";a:1:{s:3:\"all\";a:1:{s:9:\"style.css\";s:27:\"themes/bluemarine/style.css\";}}s:7:\"scripts\";a:1:{s:9:\"script.js\";s:27:\"themes/bluemarine/script.js\";}s:10:\"screenshot\";s:32:\"themes/bluemarine/screenshot.png\";s:3:\"php\";s:5:\"4.3.5\";}', 'theme', 'themes/bluemarine/bluemarine.info', 0, 0, 0) in /var/www/drupal6/modules/system/system.module on line 830.
user warning: Duplicate entry 'themes/pushbutton/pushbutton.info' for key 1 query: INSERT INTO system (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('pushbutton', 'themes/engines/phptemplate/phptemplate.engine', 'a:13:{s:4:\"name\";s:10:\"Pushbutton\";s:11:\"description\";s:52:\"Tabled, multi-column theme in blue and orange tones.\";s:7:\"version\";s:3:\"6.3\";s:4:\"core\";s:3:\"6.x\";s:6:\"engine\";s:11:\"phptemplate\";s:7:\"project\";s:6:\"drupal\";s:9:\"datestamp\";s:10:\"1215640509\";s:7:\"regions\";a:5:{s:4:\"left\";s:12:\"Left sidebar\";s:5:\"right\";s:13:\"Right sidebar\";s:7:\"content\";s:7:\"Content\";s:6:\"header\";s:6:\"Header\";s:6:\"footer\";s:6:\"Footer\";}s:8:\"features\";a:10:{i:0;s:20:\"comment_user_picture\";i:1;s:7:\"favicon\";i:2;s:7:\"mission\";i:3;s:4:\"logo\";i:4;s:4:\"name\";i:5;s:17:\"node_user_picture\";i:6;s:6:\"search\";i:7;s:6:\"slogan\";i:8;s:13:\"primary_links\";i:9;s:15:\"secondary_links\";}s:11:\"stylesheets\";a:1:{s:3:\"all\";a:1:{s:9:\"style.css\";s:27:\"themes/pushbutton/style.css\";}}s:7:\"scripts\";a:1:{s:9:\"script.js\";s:27:\"themes/pushbutton/script.js\";}s:10:\"screenshot\";s:32:\"themes/pushbutton/screenshot.png\";s:3:\"php\";s:5:\"4.3.5\";}', 'theme', 'themes/pushbutton/pushbutton.info', 0, 0, 0) in /var/www/drupal6/modules/system/system.module on line 830.
user warning: Duplicate entry 'themes/chameleon/marvin/marvin.info' for key 1 query: INSERT INTO system (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('marvin', '', 'a:13:{s:4:\"name\";s:6:\"Marvin\";s:11:\"description\";s:31:\"Boxy tabled theme in all grays.\";s:7:\"regions\";a:2:{s:4:\"left\";s:12:\"Left sidebar\";s:5:\"right\";s:13:\"Right sidebar\";}s:7:\"version\";s:3:\"6.3\";s:4:\"core\";s:3:\"6.x\";s:10:\"base theme\";s:9:\"chameleon\";s:7:\"project\";s:6:\"drupal\";s:9:\"datestamp\";s:10:\"1215640509\";s:8:\"features\";a:10:{i:0;s:20:\"comment_user_picture\";i:1;s:7:\"favicon\";i:2;s:7:\"mission\";i:3;s:4:\"logo\";i:4;s:4:\"name\";i:5;s:17:\"node_user_picture\";i:6;s:6:\"search\";i:7;s:6:\"slogan\";i:8;s:13:\"primary_links\";i:9;s:15:\"secondary_links\";}s:11:\"stylesheets\";a:1:{s:3:\"all\";a:1:{s:9:\"style.css\";s:33:\"themes/chameleon/marvin/style.css\";}}s:7:\"scripts\";a:1:{s:9:\"script.js\";s:33:\"themes/chameleon/marvin/script.js\";}s:10:\"screenshot\";s:38:\"themes/chameleon/marvin/screenshot.png\";s:3:\"php\";s:5:\"4.3.5\";}', 'theme', 'themes/chameleon/marvin/marvin.info', 0, 0, 0) in /var/www/drupal6/modules/system/system.module on line 830.
user warning: Duplicate entry 'themes/chameleon/chameleon.info' for key 1 query: INSERT INTO system (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('chameleon', 'themes/chameleon/chameleon.theme', 'a:12:{s:4:\"name\";s:9:\"Chameleon\";s:11:\"description\";s:42:\"Minimalist tabled theme with light colors.\";s:7:\"regions\";a:2:{s:4:\"left\";s:12:\"Left sidebar\";s:5:\"right\";s:13:\"Right sidebar\";}s:8:\"features\";a:4:{i:0;s:4:\"logo\";i:1;s:7:\"favicon\";i:2;s:4:\"name\";i:3;s:6:\"slogan\";}s:11:\"stylesheets\";a:1:{s:3:\"all\";a:2:{s:9:\"style.css\";s:26:\"themes/chameleon/style.css\";s:10:\"common.css\";s:27:\"themes/chameleon/common.css\";}}s:7:\"version\";s:3:\"6.3\";s:4:\"core\";s:3:\"6.x\";s:7:\"project\";s:6:\"drupal\";s:9:\"datestamp\";s:10:\"1215640509\";s:7:\"scripts\";a:1:{s:9:\"script.js\";s:26:\"themes/chameleon/script.js\";}s:10:\"screenshot\";s:31:\"themes/chameleon/screenshot.png\";s:3:\"php\";s:5:\"4.3.5\";}', 'theme', 'themes/chameleon/chameleon.info', 0, 0, 0) in /var/www/drupal6/modules/system/system.module on line 830.

Looking at the referenced code, I see the following:

function system_theme_data() {
  // Scan the installation theme .info files and their engines.
  $themes = _system_theme_data();

  // Extract current files from database.
  system_get_files_database($themes, 'theme');

  db_query("DELETE FROM {system} WHERE type = 'theme'");

  foreach ($themes as $theme) {
    if (!isset($theme->owner)) {
      $theme->owner = '';
    }

    db_query("INSERT INTO {system} (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d)", $theme->name, $theme->owner, serialize($theme->inf\
o), 'theme', $theme->filename, isset($theme->status) ? $theme->status : 0, 0, 0);
  }

If two instances of this function are running concurrently, then it is possible for the two DELETE..INSERT cycles to overlap, resulting in the above warning messages.

Clearly, there should be some locking involved to prevent this from happening. Unfortunately, I don't know enough about Drupal locking semantics to suggest a fix.

Thee bug mentioned in #275801: Minor slowdown in _system_theme_data() due to typo may be contributing to the frequency at which the above function is called.

Comments

Damien Tournoud’s picture

Status: Active » Postponed

Well at that time, there is no Drupal locking. I gave a shot at this in http://drupal.org/node/251792, but got no time to push the ball since that time.

I'm marking this as postponed, because looking at the code (the INSERTs are in a tight loop very close to the DELETE) there is nothing we can do until we implement either a transactional framework or a soft locking one.

arhak’s picture

subscribing

Flying Drupalist’s picture

Version: 6.3 » 6.4

subscribing.

Dave Reid’s picture

Also having this issue. Subscribing. This should be fixed with #289369: Deleted modules are not removed from system table. The system table, if it actually needs to be rebuild, should only be rebuilt on occasional actions, like running update.php. Otherwise it should only insert new records in the system table when it 'discovers' newly installed themes and modules. Likewise delete records from the system table when they are deleted from the filesystem.

caole261188’s picture

subscribing

marcusthijm’s picture

I wish I had something proper to say, but "subscribing" is all...

lilou’s picture

Status: Postponed » Closed (duplicate)
Flying Drupalist’s picture

Will there be a patch backported to d6 is the problem is solved?

Dave Reid’s picture

This is actually a duplicate of #147000: Rewrite module_rebuild_cache() and system_theme_data(), where there is a patch ready for testing! It removes the "DELETE/INSERT" logic in system_theme_data and only runs a minimal amount of queries.

pillarsdotnet’s picture

Version: 6.4 » 6.x-dev
Assigned: Unassigned » pillarsdotnet

Working backport of the code in #147000 is at http://drupal.org/node/307756

nonsie’s picture

subscribe

casperl’s picture

banglogic’s picture

Subscribing...

pillarsdotnet’s picture

Instead of subscribing here, please try and/or comment on the patch available at #307756: Backport of #147000: Unify and rewrite module_rebuild_cache() and system_theme_data()