Closed (outdated)
Project:
Drupal core
Version:
6.x-dev
Component:
base system
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
28 Aug 2009 at 08:17 UTC
Updated:
2 Mar 2016 at 22:18 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
mikeytown2 commentedhttp://api.drupal.org/api/group/lock/
Comment #2
kenorb commentedWhat about performance?
I see that lock_acquire() using some db queries (db_insert()).
What is the reason of caching something in memory, if it use database anyway.
Comment #3
damien tournoud commentedPressflow already added a lock in variable_initialize(). I think it makes sense.
Comment #4
catchI've ported the pressflow version from http://bazaar.launchpad.net/~pressflow/pressflow/6/annotate/head:/includ... to a core patch.
Main changes vs. HEAD are:
1. When you call variable_set() or variable_del(), it sets a global, which is then checked in drupal_page_footer() to trigger a cache clear - that way if you submit a long system settings form you don't clear the cache for each one at a time.
2. Adds a lock to variable_initialize() on cache misses, using exactly the same pattern as #802446: Cache stampede protection: drupal_render() and page cache.
I didn't do any testing of this beyond checking HEAD would still bootstrap, but I know that nnewton will need to in the next couple of days in an environment where this issue is getting hit.
Also according to twitter, this is the last core patch from Drupal 6 pressflow that hasn't made it into D7, would be great if Drupal 7 pressflow can start from a clean slate.
It might be possible to add a write through cache to this, but I think if we want to add such a thing, we should do it for the page cache first in #762978: Prevent cache stamped for page cache table.
Comment #5
catchComment #6
damien tournoud commentedOk for the lock in variable_initialize(), but the delayed clearing is a really bad idea from a consistency point of view.
Comment #8
catchThese are really two separate patches anyway. Removing the delayed clearing for now. Let's see if that helps the tests at all too.
Comment #9
catchAnd whitespace.
Comment #11
catchThe lock_initialize() causes the single test failure (in lock tests, presumably that's setting global $locks to empty and allowing a lock to be acquired, see if that causes problems elsewhere if we just remove it.
Comment #13
catchlock_initialize() should just take care not to overwrite the global if it's called twice.
Comment #14
damien tournoud commentedAren't you just missing the lock_release() call?
Comment #15
catchI am, but that's not why the test is failing. If you add the lock_release(), but also remove the check from lock_initialize() that test still fails.
Comment #16
damien tournoud commentedPlease move lock_initialize() earlier in the bootstrap (for example in _drupal_bootstrap_variables()). Having variable_initialize() call lock_initialize() feels slightly messy.
Comment #17
catchThat's a better fix, it's only slightly earlier in the bootstrap process so no real bloating, and that means no more need for the isset() check in lock_initialize().
Comment #18
mikeytown2 commentedI know in D6 they moved lock_initialize to the database_init level
http://api.drupal.org/api/function/_drupal_bootstrap/6
#732064: "Call to undefined function lock_acquire", locale module
Where it is right now
http://api.drupal.org/api/function/drupal_bootstrap/7
http://api.drupal.org/api/function/_drupal_bootstrap_page_header/7
Comment #19
damien tournoud commented#17 looks good to me.
Comment #20
nnewton commentedI've been load testing #17 and found an issue. In variable_init, when you hit the lock and re-call the function we arn't passing the $conf array in, so all settings in settings.php are lost. The upshot of this for a high-traffic site is that once you hit the lock, you lose memcache.
I'm continuing testing as under high traffic we are also getting a stampede of the semaphore table, which is problematic and may require a memcache lock.inc over-ride.
Comment #21
damien tournoud commentedOh, d'oh for the first issue. For high traffic sites, of course we will need a memcache (or similar) lock.inc. Something that doesn't require polling would be nice. The default db-based implementation is not designed to scale.
Comment #22
nnewton commentedHere is the version of the patch I'm currently using. Ya, a memcache plugin for the locking framework definitely, but it actually isn't that bad once you fix this.
Comment #23
moshe weitzman commentedWell done. This looks RTBC to me.
As for the memcache version lock.inc - might not be needed once the lock.inc improvements from #802446: Cache stampede protection: drupal_render() and page cache are committed
Comment #24
catchOuch on $conf :(
memcache-lock.inc has a patch here #596908: memcached implementation of D7 locking, I re-rolled it yesterday, but didn't test it and that issue is quite old, but looks pretty far along to me.
Comment #25
dries commentedCommitted to CVS HEAD. Thanks.
Comment #26
dries commentedUpdating status.
Comment #27
mikeytown2 commentedBump this back down to 6.x
Backport from the 7.x patch
Comment #28
achtonSubscribing.
Comment #29
mikeytown2 commented@achton
Can you test the patch #27 and report if it works for you? It helps our 7 web servers a lot.
Comment #30
mikeytown2 commentedBeen using #27 in production for the last 3 months; works very well.
Comment #31
ehudash commentedApplied the patch from #27.
Now I get the same error but for a different table:
Duplicate entry 'variable_init' for key 'PRIMARY' query: INSERT INTO semaphore (name, value, expire)(Using D6 with Boost)
Comment #32
dmendo11 commentedMikey,
I did the samething like #31 and I am getting that error as well. Do we have to delete that and see if it works?
Any help is appreciated.
David
Comment #33
mikeytown2 commentedThis error
Duplicate entry 'variable_init' for key 'PRIMARY' query: INSERT INTO semaphore (name, value, expire)shouldn't be thrown, as the query for inserting that has an@in front of it (lock_acquire()), which should suppress any errors thrown by it (see http://php.net/operators.errorcontrol). In reality this is not the case so lock_acquire appears to have a bug, as it doesn't suppress the race condition error for acquiring a lock; the patch in #27 doesn't have a bug in regards to this error, error is in lock.inc.Comment #34
dmendo11 commentedMikey,
What I did is just install number #27. Do I have to do anything prior to Patch #27 then? Should I do the number #17 or #22 as well?
The reason I am interested is because I would get about 10 to 20 errors in the watchdog page like this:
Thanks for your quick response.
David
Comment #35
mikeytown2 commentedPort from pressflow with some modifications to it from my pressflow fork https://github.com/mikeytown2/6
Comment #37
mikeytown2 commentedComment #38
ehudash commentedThanks mikeytown2
I Applied patch #37...
It solved the original error like expected, but now I get a slightly different error
Is this related, or a whole different issue?
Comment #39
mikeytown2 commented@ehudash
It is a whole different issue. Luckily this is actually a database error you can ignore... odd I know. The code for lock_acquire actually suppresses this error so where is this error being reported?
Comment #40
ehudash commentedI see it in the /admin/reports/dblog under "boost" type:
Is this what you were looking for?
Drupal 6, Boost, NGINX, InnoDB tables (most of them)
EDIT: When boost is set to cache pages even with PHP errors, the error is ignored in the DB log.
Bug in Boost module?
Comment #41
mikeytown2 commentedThere is a bug is in the boost module. It sees the error but doesn't ignore it.
Comment #42
zerolab commentedHi mikeytown2,
thank you for a great patch!
Using it in production on a large site and it works well.
Attaching a patch for Pressflow 6.28.111 (from https://github.com/pressflow/6/pull/37) in case anyone needs it.
Cheers,
Dan
Comment #44
rfayMoving back to "Needs review" for #37 which is the patch in play here for D6, if I read this right.
Comment #45
jainmca4444 commented#11: variable_stampede.patch queued for re-testing.
Comment #46
jainmca4444 commented#27: drupal-561990-D6.patch queued for re-testing.
Comment #47
jcisio commentedReroll.
Comment #49
jcisio commentedPatch 47 failed because it was rerolled against Pressflow.
Comment #50
rfayOne thing I do notice - although #37 solves the stampede problem, I regularly see
In several different contexts, both in core areas and contrib. Anybody else seen this or started to understand it.
Comment #51
jcisio commentedRe #50 I get this, a lot, usually when there is cron. Two traces with this error:
In my guess, it is because of the concurrency between two SELECTs to check for the lock, then two INSERTs in different requests. But it's a separate issue.