9

I'm posting this in case someone else is looking for the same solution, seeing as I just wasted two days on this bullshit.

I have a cron job that updates the database using a very large file once a day, using the following code:

if (($handle = fopen(dirname(__FILE__) . '/uncompressed', "r")) !== FALSE) 
{
    while (($data = fgets($handle)) !== FALSE) 
    {
        $thisline = json_decode($data, true);
        $this->regen($thisline);
    }
    fclose($handle);
}

This is in a Codeigniter controller that's only used for cron jobs. The $this->regen function runs through a bunch of different checks and stores the right information from the line in the database. The file itself is over 300MB of JSONs separated by newlines.

The problem: it would only process about 20,000 lines before the whole thing ran out of memory.

1 Answers1

14

I spent hours troubleshooting this and got nothing obvious. I'm using fgets, I have $query->free_result() in the right places. It didn't help. So then I started checking a loop of about 100 lines, and watched the output of memory_get_usage(). I finally narrowed it down to the Codeigniter Active Record class - every call to the class caused the memory usage to increase by a tiny amount.

Then I found this thread on Ellislabs and I got the answer. CI Active Record saves queries so that if you want to, you can build a query in multiple functions. (I am not even going to go into how dumb it is to have that switched on by default.)

Go to /config/database.php and add

$db['default']['save_queries'] = FALSE;

to the end of the file. Then make sure you build and execute queries using Active Record in a single function. If you need to switch it off just for one case, use

$this->db->save_queries = FALSE;

in the constructor or wherever you need to put it.

  • While I didn't find this answer until I knew what to search for, at work there's been a server that handled a whole lot of API calls and ran out of RAM just about immediately, bouncing against its limit and getting its processes killed... this turned out to be almost the entire problem. There's a lot about CI that makes me shake my head, but this one cost us enough time and hair-pulling that it's probably right at the top. – kungphu Mar 03 '16 at 06:32
  • An absolute life saver!! This did it! Thank you! – John Erck Oct 19 '17 at 23:05
  • wtf!? removing save_queries removed all our memory leaks – Farzher Jan 12 '18 at 01:40