Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP and Mongo - findOne() causes memory exhaustion

Tags:

php

mongodb

My PHP memory_limit is 64M (which is pretty high to start with)

I have a MongoCollection::findOne() called in my PHP code where I "find one" by MongoId. It works in most cases. However in some cases, it causes PHP to go over the memory_limit of 64M.

The data record in Mongo is at max, 3.5MB because Mongo does not allow more than 4MB.

When I run, memory_get_usage() before calling findOne(), its only about 4MB. So findOne() seems to have consumed the other 60MB+. Is this a memory leak or is there a design flaw in the way I store in Mongo?

My PHP Mongo driver is the latest 1.26

like image 627
Subrat Basnet Avatar asked Dec 06 '11 06:12

Subrat Basnet


4 Answers

It would be helpful if you could post the exact code that you are running. It is most likely your code, but there is a chance that it could be a bug with the Mongo PHP drivers. The latest version of the drivers (1.2.9) seems to be a step backwards from previous versions. I myself found a bug in the driver that causes php to segfault on connection timeouts :o In a conversation that I had with a 10gen developer it was revealed to me that the php drivers are the least mature of all the languages, but I was told that they just hired a php developer so the drivers should be getting some love soon.

like image 57
Jake Avatar answered Nov 18 '22 19:11

Jake


Knowing that Mongo looks up by strict hashing, and that the lookup sequence for any given ID is limited, there is absolutely no way this could be Mongo's doing.

If you are using a MongoID then you should be sure that the ID is valid. Because a MongoID is the resolved hash for the given record.

This might be the problem. Or I might be entirely wrong.

like image 23
Milad Naseri Avatar answered Nov 18 '22 20:11

Milad Naseri


I don't know too much about your specific case; however, that has happened to me a number of times using mysql and cakephp. I've never used mongo with php though. Try the following:

A) Have you set up any indexes in your DB?
B) You can increase your memory limit through php.ini, mine is usually set around 256mb.
C) It could be the case that your associations have caused a bunch of objects to be created. I doubt your query is causing the 60mb to fill up, but rather some recursive chaos due to associations. Try unbinding associations before calling your query.
D) Turn off all associations and slowly work your way up.

I know mongo is supposed to eliminate the need for complex queries. Perhaps this is more of a language/library issue?

Hope this helps!

like image 37
Parris Avatar answered Nov 18 '22 20:11

Parris


Try the db.<your collection>.validate() command on the respective collection from the shell.
Try a db.<your collection>.reIndex() call on the collection.
Try dropping all indexes and recreating them on that collection (even all collections; won't hurt anything).
Try db.repairDatabase() from the shell.

Also, from your PHP code, try the same criteria as a find() and see if you get memory corruption.

like image 45
ZagNut Avatar answered Nov 18 '22 19:11

ZagNut