Closed (duplicate)
Project:
Drupal core
Version:
6.x-dev
Component:
database system
Priority:
Normal
Category:
Task
Assigned:
Reporter:
Created:
20 May 2007 at 23:33 UTC
Updated:
21 May 2007 at 01:04 UTC
Currently, the MySQL sequence manager db_next_id() locks the entire table. This is unnecessary, even without transactions. Here's a patch for 5.1, though it will probably not qualify for 5.1's core due to its reliance on MySQL 4's ON DUPLICATE UPDATE. The patch may apply seamlessly to 6.x-dev because only the line numbers change. As an additional benefit to InnoDB users, this will only lock one row of {sequences}. LAST_INSERT_ID is maintained per connection, so the code below functions atomically.
The updated MySQL sequencer:
function db_next_id($name) {
$name = db_prefix_tables($name);
db_query('INSERT INTO {sequences} VALUES ("%s", %d) ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id + 1)', $name, 1);
$id = db_result(db_query('SELECT LAST_INSERT_ID()'));
if ($id == 0) {
$id = 1;
}
return $id;
}
No schema changes are necessary.
| Comment | File | Size | Author |
|---|---|---|---|
| drupal-5.1-sequence.patch | 1.8 KB | david strauss |
Comments
Comment #1
david straussA few pieces of MySQL trivia on why this works:
So, I'm actually using LAST_INSERT_ID() backwards: it's 0 if I insert a row and >=1 if I increment (update) an existing sequence.
Comment #2
davea commentedThis would help InnoDB performance by no longer using the *LOCK TABLES* function and relying on the row-level locking that InnoDB provides.
Otherwise, running Drupal on MySQL database using the InnoDB engine would not reap any benefit in this context.
Comment #3
Crell commentedhttp://drupal.org/node/55516 - Already done and awaiting Dries' pondering.