Bug #50302 memory leak in php calling mysql_real_escape_string
Submitted: 13 Jan 2010 8:51 Modified: 15 Jan 2010 8:02
Reporter: Don Cohen Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:5.0.77 OS:Linux (2.6.18-128.el5)
Assigned to: CPU Architecture:Any

[13 Jan 2010 8:51] Don Cohen
Description:
I don't know whether this is the fault of mysql or php.  I hope someone there has heard of this problem and can tell me something about how to fix it.
I have a test program that simply reads a file and computes the updates that should be sent to the DB - this version does not update the DB at all.  It contains this code:
function f($x){
  return mysql_real_escape_string($x);
  //return $x;
}
When I use it as above I see memory_get_usage() increase by about 10K per record, e.g., it's 10M after 1000 records, whereas switching the comment to the other line it does not increase appreciably - it's 84576 after 1000 records and 83520 after 100,000 records. (The records seem to average about 8KB.)
Of course when I run as above I run out of space long before 100,000 records.
I saw this initially on a centos machine with mysql 5.0.45, PHP 5.1.6.
I did a yum update and still see the problem with mysql 5.0.77.
I do not see the problem on a fedora 11 machine with mysql 5.1.40, PHP 5.2.11.

How to repeat:
run my test program on my test data

Suggested fix:
I hope you can tell me.
[13 Jan 2010 9:43] Sveta Smirnova
Thank you for the report.

I assume your test script not only contains function definition. Please provide example of PHP code which demonstrates the problem: I want to be sure you don't just collect escaped strings (in this case increasing in memory usage is expected).
[13 Jan 2010 17:49] Don Cohen
complete test program demonstrating memory leak

Attachment: test.php (application/octet-stream, text), 2.93 KiB.

[13 Jan 2010 17:52] Don Cohen
The test program is now uploaded.
Note that if I were just collecting the strings, the memory would also increase in the version that does not call mysql_real_escape_string.
[13 Jan 2010 17:59] Don Cohen
While we're at it, here is the output.
The input file, of course is much too big to send.
I wonder whether the problem might appear only for strings of length more than a certain value, like maybe 1KB.  Perhaps these are relatively uncommon as arguments to mysql_real_escape_string and so the bug is not normally observed.
You'll see that the program also shows the length of the longest line so far.
My original guess was that I was running out of space because one line was very long.
$ php -f ./test.php
line 1=8584
line 2=9109
line 3=9120
line 7=9258
line 17=9348
line 23=9476
line 29=9617
line 73=9700
line 184=9752
line 242=9766
line 264=9773
line 290=9791
line 320=9798
line 335=9810
line 990=9816
after 1000 memory=10066264
line 1130=9829
PHP Fatal error:  Allowed memory size of 16777216 bytes exhausted (tried to allocate 5959 bytes) in /root/test.php on line 15
[15 Jan 2010 8:02] Sveta Smirnova
Thank you for the feedback.

> Note that if I were just collecting the strings, the memory would also
> increase in the version that does not call mysql_real_escape_string.

This is not MySQL bug in this case. This is probably not a bug at all too, but ideally string should be destroyed when you reached last "}" in the loop. Please fill PHP bug report.