|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2014-10-28 12:48 UTC] tomas at slax dot org
Description:
------------
When PHP is compiled with mysqlnd (default), it has a problem with freeing memory, as I will demonstrate in test script. If PHP is compiled with libmysqlclient, the problem does not occur.
Compiling PHP with mysqlnd causes the test script to work INCORRECTLY:
./configure \
--with-mysql-sock=/var/run/mysql/mysql.sock \
--with-mysql \
--with-mysqli
# note that mysqlnd is enabled by default. It's like: --with-mysqli=mysqlnd
Compile PHP with libmysqlclient to fix the memory allocation problem:
./configure \
--with-mysql-sock=/var/run/mysql/mysql.sock \
--with-mysql=/usr \
--with-mysqli=/usr/bin/mysql_config \
# note that this fixes the problem
I expect you to fix bug in PHP's mysqlnd driver so it properly free()s the memory!!
Thank you very much !!!
This error is there since PHP 5.4.x and is there even now with PHP 5.6.x
Test script:
---------------
<?php
echo "First, connect to database test...\n";
$link=mysqli_connect("localhost",'root','rrr','test');
echo "Create temporary table with lots of rows...\n";
$ok=mysqli_query($link,"CREATE TEMPORARY TABLE tbl123 LIKE mysql.user");
if (!$ok) die();
for ($i=0;$i<6000; $i++)
{
mysqli_query($link,"INSERT IGNORE INTO tbl123 SET host='x".$i."'");
}
echo "Get all rows from database\n";
$result=mysqli_query($link,"SELECT * FROM tbl123");
while($row=mysqli_fetch_row($result))
{
echo "Mem used: ".number_format(memory_get_usage()/1024,1,'.','')." KB\n";
}
// expected result: memory usage still the same
// libmysqlclient result: memory usage still the same
// mysqlnd result: memory usage increases with each row!! :(
// and if it reaches php memory limit, the script dies :(
?>
Expected result:
----------------
I expect that PHP doesn't use more than, say, 512KB while processing 6000 rows from database as shown in the example. I expect the test script to print constant memory usage, as like:
Mem used: 228.7 KB
Mem used: 228.7 KB
Mem used: 228.7 KB
Mem used: 228.7 KB
Mem used: 228.7 KB
Mem used: 228.7 KB
Mem used: 228.7 KB
Mem used: 228.7 KB
Mem used: 228.7 KB
(still the same)
Actual result:
--------------
When using mysqlnd (compiled with mysqlnd by default), it increases memory usage with every row, this is very bad:
Mem used: 14040.2 KB
Mem used: 14042.1 KB
Mem used: 14044.1 KB
Mem used: 14046.1 KB
Mem used: 14048.0 KB
Mem used: 14050.0 KB
Mem used: 14052.0 KB
Mem used: 14054.0 KB
Mem used: 14055.9 KB
Mem used: 14057.9 KB
Mem used: 14059.9 KB
Mem used: 14061.8 KB
Mem used: 14063.8 KB
Mem used: 14065.8 KB
(still bigger, this is WRONG)
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Oct 27 08:00:01 2025 UTC |
I tried using massif. Here are the results: ------------------------------------------------------------------ Command: ./php /root/php-bug.php # mysqlnd Massif arguments: (none) ms_print arguments: massif.out.32672 ------------------------------------------------------------------ MB 140.2^ # | :@:# | ::::@:# | :::::::@:# | ::@: :::::@:# | ::::::@: :::::@:# | ::::: :::@: :::::@:# | ::::::::: :::@: :::::@:# | :::: : ::::: :::@: :::::@:# | ::: :: : ::::: :::@: :::::@:# | ::@@::: :: : ::::: :::@: :::::@:# | :::::@ ::: :: : ::::: :::@: :::::@:# | ::::: ::@ ::: :: : ::::: :::@: :::::@:# | ::::: :: ::@ ::: :: : ::::: :::@: :::::@:# | :::: ::: :: ::@ ::: :: : ::::: :::@: :::::@:# | ::::: :: ::: :: ::@ ::: :: : ::::: :::@: :::::@:# | :::: : :: ::: :: ::@ ::: :: : ::::: :::@: :::::@:# | :::: : :: ::: :: ::@ ::: :: : ::::: :::@: :::::@:# | :::: : :: ::: :: ::@ ::: :: : ::::: :::@: :::::@:# | @:::: : :: ::: :: ::@ ::: :: : ::::: :::@: :::::@:# 0 +--------------------------------------------------------->Gi ------------------------------------------------------------------ Command: php php-bug.php # libmysqlclient Massif arguments: (none) ms_print arguments: massif.out.32610 ------------------------------------------------------------------ MB 29.85^ #::::: ::::::@:::::::::@::::::::@:::::: :::: | #::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | #::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | #::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | #::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | :#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | :#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | :#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | ::#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | ::#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | ::#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | ::#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | :::#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | :::#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | :::#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | ::::#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | ::::#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: | ::::#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: |:::::::::::#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: |: :::::#::::::::::::@:::::: ::@:::: :::@::::::@::::@:::: 0 +--------------------------------------------------------->Gi You would expect that the charts will be the same. But you can see both charts are different. The first one shows that memory usage increases and is not freed when using mysqlnd. The other chart shows that memory usage is constant when using libmysqlclient. Furthermore, when the script is processed with PHP with libmysqlclient, it finishes properly for all rows (I used 60000 rows). But when PHP with mysqlnd is used, the script doesn't finish. It fails with this error: PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 1024 bytes) in /root/php-bug.php on line 18 Do you need another proof that there is a memory bug in PHP?