Closed (duplicate)
Project:
Drupal core
Version:
9.5.x-dev
Component:
database system
Priority:
Normal
Category:
Task
Assigned:
Reporter:
Created:
13 Jan 2007 at 10:28 UTC
Updated:
27 Aug 2023 at 19:31 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
killes@www.drop.org commentedHere's the install file that you need.
Comment #2
killes@www.drop.org commentedFor people using the mysql query cache this patch should be a huge improvement. Untill now queries involving the users table are basically not cached by the query cache as the users table changes all the time and any cached queries involving this table are discarded...
Comment #3
chx commentedVery nice trick.
Comment #4
dries commentedI don't get it. Do we have performance benchmarks?
Comment #5
chx commentedBenchmarking this is quite hard. However, not invalidating the query cache for users is obviously a benefit.
Comment #6
killes@www.drop.org commentedbenchmarks:
Comment #7
m3avrck commentedGerhard, awesome!
Correct me if I'm wrong but I don't see any reason why this should wait for 6.x, would be a nice performance benefit for 5.x.
Comment #8
chx commentedWhy this should wait for D6? Because today is the Drupal 5 release date and this would need a database upgrade which is a particularly bad idea past RC...
Comment #9
gerhard killesreiter commentedI think it would make sense to move the "login" field also to the users_access table (and rename that table). Currently, a user logging in blocks other users from getting a new page or loading a node or ...
Comment #10
killes@www.drop.org commentedprofile module uses the access flag.
Comment #11
Caleb G2 commentedsubscribed
Comment #12
moshe weitzman commentednice patch. subscribing
Comment #13
webchickWicked; this has bugged me for a LONG time.
Comment #14
kbahey commentedOn the mailing list, I expressed that I am ambivalent about this.
Updating the access field only happens in session.inc, and hence no one else is affected. That is good.
On the other hand, any module that wants to print out the last access time for a user will now have a penalty of an extra join for a 1:1 relationship. Breaking a 1:1 relationship into a different table is often against normalization, and usually proves problematic down the road.
Here are the modules affected by this are:
./buddylist/buddylist.module
./devel/devel.module
./erp/erp_home/erp_home.module
./evaluation/evaluation.module
./hof/hof.module
./im/im.module
./inactive_user/inactive_user.module
./knosos/node_access/node_access.module
./og2list/og2list.module
./print/print.module
./profile-ng/profile.module
./syndication/syndication.module
./user_list/user_list.module
./welcome/welcome_demosite.inc
If everyone else decides to go with this patch, then you need to modify this part too in user.module, and add an extra join for the who is new block.
Setting this to needs work for the above query.
Comment #15
moshe weitzman commented@kbahey - there isn't much question about this rightness of this patch. the current situation penalizes everyone so that the handful of modules that you mention can avoid a JOIN.
Comment #16
kbahey commentedPoint taken.
Other alternatives:
Has the users table been converted into InnoDB on drupal.org?
Perhaps playing with various locking mechanisms with it being InnoDB may alleviate the problem, since only one row at a time need to be locked when updated.
Details here http://dev.mysql.com/doc/refman/5.0/en/innodb-lock-modes.html
Comment #17
killes@www.drop.org commentedOk, I've updated the patch to fix the "Who's online" query and also remove access from the "default user fields" somewhere else.
kbahey: The list you retrieved seems to have an error, eg og2list does not use the access info.
Next step is to also move the login info. The login field is only used during the password retrieval operation. Seems reasonable to do a user_load there.
Comment #18
killes@www.drop.org commentedThe changes to move the login field are almost too small to mention. user_load is already executed everywhere.
Comment #19
killes@www.drop.org commentedHere's the updated users.install file. Needs some pgsql love.
Comment #20
killes@www.drop.org commentedImproved user.install file, complete with pgsql and some mysql beautifications thanks to sammys.
Comment #21
kbahey commentedHere is an updated list of modules.
./affiliate/affiliate.module
./buddylist/buddylist.module
./devel/devel.module
./erp/erp_home/erp_home.module
./hof/hof.module
./im/im.module
./inactive_user/inactive_user.module
./print/print.module
./profile-ng/profile.module
./syndication/syndication.module
./tasks/tasks.module
./user_list/user_list.module
Here is the command used:
$ cd HEAD/contributions/modules
$ find . -name "*.module" -exec grep "{users}" {} /dev/null \; | grep -w access |awk -F: '{print $1}' | sort -u
Comment #22
matt westgate commentedThis is interesting. We don't explicitly lock the users table so I don't understand the write lock problem. Perhaps this is an internal MySQL thing I don't know about?
I benchmarked this patch locally and didn't see any performance improvements, but I only benchmarked as a single user with (ab -n 50 -c 5 -C cookie_value localhost). My benchmark only really shows there's not a performance degradation for low-traffic sites, really.
Comment #23
killes@www.drop.org commentedhttp://dev.mysql.com/doc/refman/5.0/en/internal-locking.html
2.
When a lock is released, the lock is made available to the threads in the write lock queue and then to the threads in the read lock queue. This means that if you have many updates for a table, SELECT statements wait until there are no more updates.
Emphasis mine.
Comment #24
matt westgate commentedThanks for the reference material. I tested the patch differently now and can confirm the LOCK contention. I'm using a slightly different patch, one with the login table still a part of the users table. Moving the login column is such a small performance gain compared to the access column that I prefer to keep it with the rest of its sibling data.
Before the patch (using ab -n 50 -c 5)
After the patch:
Comment #25
killes@www.drop.org commentedMatt, try to login/out a few times during your test run. I believe oving user.login to the other table is worth it.
Comment #26
BioALIEN commentedSubscribing.
Comment #27
matt westgate commentedI had chance to revisit this patch and cleaned some things up. Should be ready for another review now. I added in the system.install table changes and merged the user.install updates to a single function. I also added documentation and a little bug fix to user.module.
Comment #28
matt westgate commentedAnd the user install file.
Comment #29
matt westgate commentedKilles found an error in my last patch. Let's try this one.
Comment #30
moshe weitzman commentedi read through the patch and looks good. i think this comment is still valid and should remain.:
"// TODO: this can be an expensive query. Perhaps only execute it every x minutes. Requires investigation into cache expiration."
These two queries are the only writes that we perform on a typical page view. We should aim to get rid of them. Especially the one for access time. I would think that if we write that once every 5 minutes it is enough. As it says, we just have to work through cache expire stuff.
anyway, i am arguing about a comment which is obviously quite minor. nice work.
Comment #31
m3avrck commentedThis patch is ready to go, anything holding up for 6.x commit?
Comment #32
moshe weitzman commentedi tested this. rtbc.
fyi, you can create diffs including new files with fakeadd.sh
Comment #33
gábor hojtsyDries, I bet the drupal.org infrastructure team will be able to provide numbers probably, if the above is not convincing.
Comment #34
dries commentedIs it me, or isn't there an upgrade path? Where is the users_access table created?
Comment #35
killes@www.drop.org commentedDries: http://drupal.org/node/109037#comment-220774
#28
Comment #36
m3avrck commentedbumping, this should still be fine, although it probably needs a reroll
Comment #37
jvandyk commentedRerolled. Moved things to user.schema since that is where we define schemas now. user.install is a new file and provides an update path.
Comment #38
killes@www.drop.org commentedI've been thinking that this patch might not be needed if we make InnoDB the recommended MySQL engine for bigger Drupal installs.
However, I think I was wrong there:
1) Drupal.org runs an earlier version of this patch where only the access column got moved, not the login column.
2) In the slow query log there are instances of the update for the login column being slow, but none for the access table:
### 38 Queries
### Taking 16 to 51 seconds to complete
UPDATE users SET login = XXX WHERE uid = XXX;
So, regardless of SQL engine this patch is a good idea.
Comment #39
moshe weitzman commentedFYI, I have patch in which signficantly reduces writes into users.access. see http://drupal.org/node/40545
Comment #40
moshe weitzman commentedmy patch got in - http://drupal.org/node/40545. i am tempted to mark this won't fix. we are now not writing into this field very often. at leats, we should postpone ot D7 IMO and see if this is needed after some real world experience. if someone agrees, please change the issue.
Comment #41
dries commentedGiven that Moshe's patch went in, I'd like to see us re-evaluate the need for this patch. Moshe's patch should help both MyISAM as InnoDB users, and is likely to buy us more cycles than killes' patch.
Seeing that updating the login timestamp can be that slow, makes me wonder though. The strange part is that only 38 queries (out of hundreds of similar queries?) were slow -- that doesn't seem like consistent behavior. Are these queries slow day after day or was it a one time observation?
All in all, it's probably best to focus our time on more pressing performance patches, and to re-evaluate this patch during the Drupal 7 development cycle.
Comment #42
dharamgollapudi commentedSubscribing...
Comment #43
moshe weitzman commentedi think killes agrees thats this patch is no longer desireable for D6 and beyond. if i'm wrong, please reopen.
Comment #44
killes@www.drop.org commentedI quite disagree. The patch that went in is an ugly band-aid, not much more than a hack.
Comment #45
catchkilles brought this patch up again on irc. It'd be cleaner to normalize this information properly I think, and we're firmly into Drupal 7 now.
Comment #46
moshe weitzman commentedAvoiding a write query on every page is hardly a hack or a band-aid. Personally, I think a new table just adds a join for little benefit. But feel free try to get this in. I won't block it.
Comment #47
drubage commentedIs there any solution to this problem for 5? We have a lot of users/nodes/pageviews and are seeing long wait times for users table (and sessions table) related UPDATES. Since there is an update to the users table for latest access time on each page load I am wondering if this lockout problem is in fact the biggest contributor to database lag. Thanks!
-Drew
Comment #48
catchMoving to D8.
Comment #49
valthebaldComment #62
roderik#1835496: Factor {users_field_data}.access out of the table and entity caches is a duplicate. It's newer but has a better issue summary (this one is outdated since comment ~#41), so closing this one.