|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2018-06-09 09:57 UTC] luca dot looz92 at gmail dot com
Description:
------------
I was going crazy by investigating a memory issue on our server, php-fpm pools after a couple of days exhausts 16gb of RAM.
By doing a lot of tests with trials and errors i was able to reproduce the issue.
The memory leak happens when using functions like "mysqli_fetch_object" and "mysqli_fetch_array". Doesn't happen with "mysqli_fetch_row".
I'm able to reproduce this by compiling php 7.2.6 from source with just the mysqli module:
./configure --disable-all --with-mysqli
A very strange thing is that if I compile php in debug mode the leak doesn't happen anymore...
./configure --disable-all --enable-debug --with-mysqli
If I put the code in a loop the leak doesn't become bigger so it seems that is limited per script execution by leaking something like 4 bytes for each execution.
To test this I used the Wordpress default database by reading the hello world article.
I have attached the valgrind results with "export ZEND_DONT_UNLOAD_MODULES=1".
Another thing to note is that if set "export USE_ZEND_ALLOC=0" with the non-debug version the leak doesn't happen.
I've seen this issue on 7.2.2, 7.2.5 and 7.2.6.
Test script:
---------------
<?php
$dbh = mysqli_init();
mysqli_real_connect( $dbh, '127.0.0.1', 'root', 'mydbpass');
mysqli_select_db( $dbh, 'dbwpempty' );
$result = mysqli_query( $dbh, "SELECT * FROM wp_posts WHERE ID = 1 LIMIT 1" );
$num_rows = 0;
$last_result = array();
while ( $row = mysqli_fetch_object( $result ) ) {
$last_result[$num_rows] = $row;
$num_rows++;
}
$result->free();
$dbh->close();
?>
valgrind --leak-check=full php mysqlleak.php
Expected result:
----------------
==30485== HEAP SUMMARY:
==30485== in use at exit: 32 bytes in 1 blocks
==30485== total heap usage: 10,515 allocs, 10,514 frees, 1,983,262 bytes allocated
==30485==
==30485== LEAK SUMMARY:
==30485== definitely lost: 0 bytes in 0 blocks
==30485== indirectly lost: 0 bytes in 0 blocks
==30485== possibly lost: 0 bytes in 0 blocks
==30485== still reachable: 32 bytes in 1 blocks
==30485== suppressed: 0 bytes in 0 blocks
Actual result:
--------------
==30483== HEAP SUMMARY:
==30483== in use at exit: 936 bytes in 24 blocks
==30483== total heap usage: 9,275 allocs, 9,251 frees, 1,466,918 bytes allocated
==30483==
==30483== 904 bytes in 23 blocks are definitely lost in loss record 2 of 2
==30483== at 0x4C29C23: malloc (vg_replace_malloc.c:299)
==30483== by 0x5B1198: __zend_malloc (zend_alloc.c:2829)
==30483== by 0x564684: zend_string_alloc (zend_string.h:134)
==30483== by 0x564684: zend_string_init (zend_string.h:170)
==30483== by 0x564684: php_mysqlnd_rset_field_read (mysqlnd_wireprotocol.c:1378)
==30483== by 0x56DA81: mysqlnd_mysqlnd_res_meta_read_metadata_pub (mysqlnd_result_meta.c:76)
==30483== by 0x56A2B6: mysqlnd_mysqlnd_res_read_result_metadata_pub (mysqlnd_result.c:385)
==30483== by 0x56C8D0: mysqlnd_query_read_result_set_header (mysqlnd_result.c:539)
==30483== by 0x55B152: mysqlnd_mysqlnd_conn_data_reap_query_pub (mysqlnd_connection.c:917)
==30483== by 0x55D79E: mysqlnd_mysqlnd_conn_data_query_pub (mysqlnd_connection.c:859)
==30483== by 0x4AA001: zif_mysqli_query (mysqli_nonapi.c:593)
==30483== by 0x671C93: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:617)
==30483== by 0x671C93: execute_ex (zend_vm_execute.h:59734)
==30483== by 0x67A690: zend_execute (zend_vm_execute.h:63760)
==30483== by 0x5D8FC7: zend_execute_scripts (zend.c:1496)
==30483==
==30483== LEAK SUMMARY:
==30483== definitely lost: 904 bytes in 23 blocks
==30483== indirectly lost: 0 bytes in 0 blocks
==30483== possibly lost: 0 bytes in 0 blocks
==30483== still reachable: 32 bytes in 1 blocks
==30483== suppressed: 0 bytes in 0 blocks
==30483== Reachable blocks (those to which a pointer was found) are not shown.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 16:00:01 2025 UTC |
I have this problem in PHP 5.6.40 on Centos 7.6. This simple code triggers it. I just read around 1 million rows from the table and my memory usage is just growing higher and higher. $cnt = 0; $result = mysqli_query($conn,"SELECT `text`,`sms_date`,`to` FROM `sms_data`.`sms_201933`;"); while ($row = mysqli_fetch_object($result)) { if ($cnt%1000) { echo memory_get_usage()." *** \n\n"; } $cnt++; }