Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak in elgglib.php (Trac #1990) #1990

Closed
elgg-gitbot opened this issue Feb 16, 2013 · 9 comments
Closed

Memory leak in elgglib.php (Trac #1990) #1990

elgg-gitbot opened this issue Feb 16, 2013 · 9 comments

Comments

@elgg-gitbot
Copy link

@elgg-gitbot elgg-gitbot commented Feb 16, 2013

Original ticket http://trac.elgg.org/ticket/1990 on 40207296-01-15 by trac user mdupont, assigned to unknown.

Elgg version: 1.6

On a 200+ users on ELGG 1.6.1 website, from time to time the front page became unaccessible and we had a PHP fatal error for memory limit exhausted.

Increasing the PHP memory limit fixed the problem for a while, until the same problem appeared (a few days later) and that we had again to increase the memory limit. At a point we had to allocate hundreds of megabytes for ELGG not to throw an error, and PHP was eating so much memory that it could cause the server to crash.

We tried to ajust Apache, PHP, MySQL and Memcache configuration without success.

The PHP error indicates that the culprit is in engine/lib/elgglib.php at line 1795. Here is the block of code :

                    // [Marcus Povey 20090217 : Now retrieving all datalist values on first load as this saves about 9 queries per page]
                   $result = get_data("SELECT * from {$CONFIG->dbprefix}datalists");
                    if ($result)
                    {
                            foreach ($result as $row)
                            {
                                    $DATALIST_CACHE[$row->name] = $row->value;

                                    // Cache it if memcache is available
                                    if ($datalist_memcache) $datalist_memcache->save($row->name, $row->value);
                            }

                            if (isset($DATALIST_CACHE[$name]))
                                    return $DATALIST_CACHE[$name];
                    }

Just below this block, on line 1808 - 1815 is commented the old version of the code. After uncommenting this block and commenting the one above, ELGG was running again into 64 Mo of PHP memory AND page display was quicker than before. The code is :

                    if ($row = get_data_row("SELECT value from {$CONFIG->dbprefix}datalists where name = '{$name}' limit 1")) {
                            $DATALIST_CACHE[$name] = $row->value;

                            // Cache it if memcache is available
                            if ($datalist_memcache) $datalist_memcache->save($name, $row->value);

                            return $row->value;
                    }

It turns out that saving queries wasn't the best way to increase performance and stability. Since this block of code is still here in 1.7, it should be corrected or reverted back to the old version.

@elgg-gitbot
Copy link
Author

@elgg-gitbot elgg-gitbot commented Feb 16, 2013

brettp wrote on 40207317-03-06

How many entries are in your datalists table?

@elgg-gitbot
Copy link
Author

@elgg-gitbot elgg-gitbot commented Feb 16, 2013

cash wrote on 40209436-01-06

I don't see how hundreds of MBs of data could be in the datalist table...

@elgg-gitbot
Copy link
Author

@elgg-gitbot elgg-gitbot commented Feb 16, 2013

Milestone changed to Unscheduled by cash on 40209436-01-06

@elgg-gitbot
Copy link
Author

@elgg-gitbot elgg-gitbot commented Feb 16, 2013

brettp wrote on 40209674-02-25

Nor I unless some plugin is using it to store data. Unless we get more info in the next few days we can mark this worksforme.

@elgg-gitbot
Copy link
Author

@elgg-gitbot elgg-gitbot commented Feb 16, 2013

trac user mdupont wrote on 40211985-11-05

Hi,

Thanks for your answer. Actually there are tens of thousands of entries in my datalists table, making it weight more than 250MB, of mostly duplicate entries (thousands of crontrigger__, of simplecache__, of view_*?). Why is a new entry created each time and not the existing value updated?

@elgg-gitbot
Copy link
Author

@elgg-gitbot elgg-gitbot commented Feb 16, 2013

trac user mdupont wrote on 40211990-09-23

Additional info : the datalist table is in latin1_swedish encoding and doesn't have an index. Is this normal?

@elgg-gitbot
Copy link
Author

@elgg-gitbot elgg-gitbot commented Feb 16, 2013

trac user mdupont wrote on 40212239-08-23

Update : deleted duplicates in the datalists table (down from 660'000 entries to 26!) and added name as the Primary key. Seems that no more duplicates are created and that ELGG is now fast... I'll wait and see if it remains stable.

No idea why the datalists table was not correct, but the fact that a new entry was created every time a settings was changed (including cron runs) could explain why it was eating more and more memory...

@elgg-gitbot
Copy link
Author

@elgg-gitbot elgg-gitbot commented Feb 16, 2013

cash wrote on 40212987-02-23

Looks like someone must have changed your database schema after Elgg was installed. name is the primary key according to the schema that comes with Elgg.

@elgg-gitbot
Copy link
Author

@elgg-gitbot elgg-gitbot commented Feb 16, 2013

trac user mdupont wrote on 40214684-08-25

Yes, i've reset the database schema following engine/schema/mysql.sql and ever since everything seems to work - no more duplicate keys added. I think I'll never know why and how the schema was modified...

Thanks again for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

1 participant