Issue Details (XML | Word | Printable)

Key: MDL-16641
Type: Improvement Improvement
Status: Reopened Reopened
Priority: Major Major
Assignee: Petr Skoda
Reporter: Wen Hao Chuang
Votes: 5
Watchers: 8
Operations

Add/Edit UI Mockup to this issue
If you were logged in you would be able to see more operations.
Moodle

Remove all attempts to cast sesskey to BINARY as it was causing MySQL to ignore the preferred index, resulting in slow response time

Created: 24/Sep/08 12:51 AM   Updated: 21/Oct/09 04:17 PM
Return to search
Component/s: Lib, Performance
Affects Version/s: 1.8, 1.8.1, 1.8.2, 1.8.3, 1.8.4, 1.8.5, 1.8.6, 1.8.7, 1.8.8, 1.9, 1.9.1, 1.9.2, 1.9.3, 1.9.4
Fix Version/s: 1.9.7

Issue Links:
Relates
 

Database: MySQL
Participants: Dakota Duff, Elvedin Trnjanin, Martin Dougiamas, Petr Skoda and Wen Hao Chuang
Security Level: None
Difficulty: Easy
Resolved date: 06/Jan/09
Affected Branches: MOODLE_18_STABLE, MOODLE_19_STABLE
Fixed Branches: MOODLE_19_STABLE


 Description  « Hide
Our team (at SFSU) talked to the MySQL support (we have subscribed to their enterprise level support) and they suggested that we look into the codes and remove all attempts to cast sesskey to BINARY, as it will cause MySQL to ignore the preferred index and not use an index at all, resulting in slow response time. So we dig into the codes and did the following changes

in /lib/adodb/session/adodb-session.php (and adodb-session2.php in the same directory)

replace

$binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';

to

$binary = $conn->dataProvider === 'mysql' ? '' : '';

This has dramatically improved the performance on our production site. However, would like to hear people's opinion about this change (also emailed Martin D, Martin L, and the author of ADODB already, but haven't heard back from them yet). Maybe the core could consider this change too. Also see the discussion thread that our system administrator Taylor posted here for more details:

http://moodle.org/mod/forum/discuss.php?d=106108

 All   Comments   Change History   Version Control      Sort Order: Ascending order - Click to sort in descending order
Petr Skoda added a comment - 24/Sep/08 02:06 AM
The database-session code will be fully rewritten in 2.0, unfortunately the current session code using adodb has several known problems

Petr Skoda added a comment - 06/Jan/09 06:47 AM
the adodb session code is not used anymore in 2.0 - thanks for the report

Martin Dougiamas added a comment - 24/Mar/09 09:51 PM
Petr, is there any actual problem with just implementing this fix in 1.9? (removing the binary cast)

It seems to work for a lot of people using 1.9.


Elvedin Trnjanin added a comment - 25/Mar/09 02:44 AM
Works in 1.8 with no issues as well. Can it be fixed for those that will need to use 1.8 for a bit longer?

Wen Hao Chuang added a comment - 25/Mar/09 02:59 AM
I hope people don't mind that I extend the "affects version/s" to include 1.8 as well. Instead of just listing out 1.8, I listed 1.8.x ~ 1.9.x just so that when people use JIRA's filter they could still find this ticket - NOT that I'm trying to make this bug looks really important/scary across many versions! Martin or Petr if I should just list "affects version/s" as 1.8 and 1.9 in the future (for generic 1.8.x and 1.9.x bugs), please let me know. Thanks!

Petr Skoda added a comment - 25/Mar/09 04:27 AM
the problem here is that it just "seems" to work, but in fact it does not work much
When people use db sessions in 1.9 or earlier they sometimes get weird errors and various seemingly unrelated problems, I do think we should not recommend db sessions at all yet

Wen Hao Chuang added a comment - 25/Mar/09 06:22 AM
Oh boy... Petr when you said that "it just seems to work but in fact it does not work much," are you implying that there are still a lot of potential problems with dbsessons? Could you please elaborate this a little bit more? So if moodle core team will not recommend db sessions at all yet, is there any work-around or alternatives for people who are running large/busy 1.9.x sites (or sites built on cluster of servers)? Thanks!

By the way I did notice the MDL-17754 and have added myself to the watch list. I have also quickly updated the moodle doc sessions to reflect your comments. Please feel free to edit this page:

http://docs.moodle.org/en/sessions


Petr Skoda added a comment - 25/Mar/09 07:44 AM
Oh boy...
It is not my fault, I just discovered the problem and tried to fix it in HEAD. Frankly I do not know how to solve it on 1.9.x sites.

All our code expects sessions to be locked properly - see http://php.net/manual/en/function.session-write-close.php If it is not locked it can not work as expected because concurrent http requests start overriding session or undoing session changes.

Long ago somebody implemented db session support in Moodle using incomplete session code from adodb, at that time we did not store that much critical data in session, but now we cache user access data, group access, role switching and many other critical data there. I can not tell you exactly what and when may go wrong, it may or may not work.

I can not stop anybody using db sessions, all I say is that it should not be supported because it is not reliable and we can not fix it in 1.9.x. Even in 2.0 it might be a big problem to implement it somehow for Oracle and MSSQL and it may be slow/expensive for pgsql adn mysql.

more info:
http://www.mysqlperformanceblog.com/2007/03/27/php-sessions-files-vs-database-based/

We could just remove the binary, but I would personally prefer if somebody found out why it was added there originally, maybe it has some purpose


Dakota Duff added a comment - 18/Aug/09 06:05 AM
We we experiencing outrageous CPU usage on our database server for one of our busier sites and I noticed that queries to the mdl_sessions2 table were frequently waiting locks to clear which led me here. It also led me to this page:

– QUOTE –
http://dev.mysql.com/doc/refman/5.0/en/charset-binary-op.html

OK but the problem is that with binary, the index cannot be used :
mysql> explain select prod_name, prod_id from products where binary prod_name = 'Hype Beau';

The solution is to apply the binary operator to the constant, then the index is used :
mysql> select prod_name, prod_id from products where prod_name = binary 'Hype Beau';
– END QUOTE –

This particular mdl_sessions2 table had about 10K rows, so not having indexes was killing us.

I did a find & replace of '$binary sesskey = ' to 'sesskey = $binary ' in /lib/adodb/session/adodb_session.php and /lib/adodb/session/adodb_session2.php and our DB server's CPU usage dropped from an average of about 100-160% to about 20-30%.