[PHP-CVS] cvs: php-src(PHP_5_3) /ext/mysqlnd mysqlnd_debug.c mysqlnd_result.c
andrey Tue Jun 16 13:07:14 2009 UTC Modified files: (Branch: PHP_5_3) /php-src/ext/mysqlndmysqlnd_debug.c mysqlnd_result.c Log: MFH: Memory usage optimisation. mysqlnd is not libmysql. mysqlnd does use the Zend allocator, which means that is easier to hit memory_limit if you have big stored (buffered) result sets. Before with libmysql you won't hit memory_limit because libmysql uses libc's allocator and nothing is checked. Now, with mysqlnd the situation is stricter and it is easier to hit memory_limit. We try to optimize for big result sets. If a result set is larger than 10 rows we will start freeing some data to keep memory usage after 10 rows constant. This will help in the cases where a buffered result set is scrolled forward only and just only once, or mysqlnd will need to decode data from the network buffers again - yes, it is a trade-off between CPU time and memory size. The best for big result sets is of course using unbuffered queries - for comparison : 3 Million rows with buffered take at least 180MB, with buffered you will stay at 3MB, and unbuffered will be just 7-8% slower. http://cvs.php.net/viewvc.cgi/php-src/ext/mysqlnd/mysqlnd_debug.c?r1=1.1.2.16r2=1.1.2.17diff_format=u Index: php-src/ext/mysqlnd/mysqlnd_debug.c diff -u php-src/ext/mysqlnd/mysqlnd_debug.c:1.1.2.16 php-src/ext/mysqlnd/mysqlnd_debug.c:1.1.2.17 --- php-src/ext/mysqlnd/mysqlnd_debug.c:1.1.2.16Thu May 28 11:47:48 2009 +++ php-src/ext/mysqlnd/mysqlnd_debug.c Tue Jun 16 13:07:14 2009 @@ -18,7 +18,7 @@ +--+ */ -/* $Id: mysqlnd_debug.c,v 1.1.2.16 2009/05/28 11:47:48 andrey Exp $ */ +/* $Id: mysqlnd_debug.c,v 1.1.2.17 2009/06/16 13:07:14 andrey Exp $ */ #include php.h #include mysqlnd.h @@ -830,6 +830,9 @@ void _mysqlnd_efree(void *ptr MYSQLND_MEM_D) { DBG_ENTER(mysqlnd_efree_name); + if (!ptr) { + DBG_VOID_RETURN; + } #ifdef MYSQLND_THREADED if (MYSQLND_G(thread_id) != tsrm_thread_id()) { DBG_RETURN(_mysqlnd_pefree(ptr, 1 TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)); http://cvs.php.net/viewvc.cgi/php-src/ext/mysqlnd/mysqlnd_result.c?r1=1.4.2.30r2=1.4.2.31diff_format=u Index: php-src/ext/mysqlnd/mysqlnd_result.c diff -u php-src/ext/mysqlnd/mysqlnd_result.c:1.4.2.30 php-src/ext/mysqlnd/mysqlnd_result.c:1.4.2.31 --- php-src/ext/mysqlnd/mysqlnd_result.c:1.4.2.30 Tue Jun 16 09:15:38 2009 +++ php-src/ext/mysqlnd/mysqlnd_result.cTue Jun 16 13:07:14 2009 @@ -18,7 +18,7 @@ +--+ */ -/* $Id: mysqlnd_result.c,v 1.4.2.30 2009/06/16 09:15:38 andrey Exp $ */ +/* $Id: mysqlnd_result.c,v 1.4.2.31 2009/06/16 13:07:14 andrey Exp $ */ #include php.h #include mysqlnd.h #include mysqlnd_wireprotocol.h @@ -30,6 +30,9 @@ #include mysqlnd_debug.h #include ext/standard/basic_functions.h +#define START_FREEING_AFTER_X_ROWS 10 +static void mysqlnd_buffered_free_previous_row(MYSQLND_RES *result, int which TSRMLS_DC); + #define MYSQLND_SILENT #ifdef MYSQLND_THREADED @@ -101,11 +104,18 @@ unsigned int field_count = result-meta-field_count; unsigned int row_count = result-stored_data-row_count; DBG_ENTER(mysqlnd_res_initialize_result_set_rest); + DBG_INF_FMT(before heap=%lu real=%lu, zend_memory_usage(FALSE TSRMLS_CC), zend_memory_usage(TRUE TSRMLS_CC)); if (!data_cursor || row_count == result-stored_data-initialized_rows) { DBG_VOID_RETURN; } while ((data_cursor - data_begin) (row_count * field_count)) { + if (START_FREEING_AFTER_X_ROWS ((data_cursor - data_begin) / result-field_count)) { + zval **orig_data_cursor = result-stored_data-data_cursor; + result-stored_data-data_cursor = data_cursor; + mysqlnd_buffered_free_previous_row(result, START_FREEING_AFTER_X_ROWS TSRMLS_CC); + result-stored_data-data_cursor = orig_data_cursor; + } if (NULL == data_cursor[0]) { result-stored_data-initialized_rows++; result-m.row_decoder( @@ -130,6 +140,7 @@ } data_cursor += field_count; } + DBG_INF_FMT(after heap=%lu real=%lu, zend_memory_usage(FALSE TSRMLS_CC), zend_memory_usage(TRUE TSRMLS_CC)); DBG_VOID_RETURN; } /* }}} */ @@ -186,6 +197,53 @@ /* }}} */ +/* {{{ mysqlnd_buffered_free_previous_row */ +static +void mysqlnd_buffered_free_previous_row(MYSQLND_RES *result, int which TSRMLS_DC) +{ + MYSQLND_RES_BUFFERED * set = result-stored_data; + + DBG_ENTER(mysqlnd_buffered_free_previous_row); + + if (!set) { + DBG_VOID_RETURN; + } + + DBG_INF_FMT(which=%d result-field_count=%d data=%p
[PHP-CVS] cvs: php-src(PHP_5_3) /ext/mysqlnd mysqlnd_debug.c mysqlnd_result.c mysqlnd_wireprotocol.c mysqlnd_wireprotocol.h
andrey Wed Feb 20 15:18:18 2008 UTC Modified files: (Branch: PHP_5_3) /php-src/ext/mysqlndmysqlnd_debug.c mysqlnd_result.c mysqlnd_wireprotocol.c mysqlnd_wireprotocol.h Log: Fix memory leak http://cvs.php.net/viewvc.cgi/php-src/ext/mysqlnd/mysqlnd_debug.c?r1=1.1.2.7r2=1.1.2.8diff_format=u Index: php-src/ext/mysqlnd/mysqlnd_debug.c diff -u php-src/ext/mysqlnd/mysqlnd_debug.c:1.1.2.7 php-src/ext/mysqlnd/mysqlnd_debug.c:1.1.2.8 --- php-src/ext/mysqlnd/mysqlnd_debug.c:1.1.2.7 Thu Feb 14 15:20:49 2008 +++ php-src/ext/mysqlnd/mysqlnd_debug.c Wed Feb 20 15:18:17 2008 @@ -18,7 +18,7 @@ +--+ */ -/* $Id: mysqlnd_debug.c,v 1.1.2.7 2008/02/14 15:20:49 andrey Exp $ */ +/* $Id: mysqlnd_debug.c,v 1.1.2.8 2008/02/20 15:18:17 andrey Exp $ */ #include php.h #include mysqlnd.h @@ -303,7 +303,9 @@ unsigned int line, const char * const file, char * func_name, uint func_name_len) { +#ifdef MYSQLND_THREADED MYSQLND_ZTS(self); +#endif if ((self-flags MYSQLND_DEBUG_DUMP_TRACE) == 0 || self-file_name == NULL) { return FALSE; } @@ -349,8 +351,9 @@ const char * const file) { char *func_name; +#ifdef MYSQLND_THREADED MYSQLND_ZTS(self); - +#endif if ((self-flags MYSQLND_DEBUG_DUMP_TRACE) == 0 || self-file_name == NULL) { return PASS; } http://cvs.php.net/viewvc.cgi/php-src/ext/mysqlnd/mysqlnd_result.c?r1=1.4.2.15r2=1.4.2.16diff_format=u Index: php-src/ext/mysqlnd/mysqlnd_result.c diff -u php-src/ext/mysqlnd/mysqlnd_result.c:1.4.2.15 php-src/ext/mysqlnd/mysqlnd_result.c:1.4.2.16 --- php-src/ext/mysqlnd/mysqlnd_result.c:1.4.2.15 Thu Feb 14 12:49:30 2008 +++ php-src/ext/mysqlnd/mysqlnd_result.cWed Feb 20 15:18:17 2008 @@ -18,7 +18,7 @@ +--+ */ -/* $Id: mysqlnd_result.c,v 1.4.2.15 2008/02/14 12:49:30 andrey Exp $ */ +/* $Id: mysqlnd_result.c,v 1.4.2.16 2008/02/20 15:18:17 andrey Exp $ */ #include php.h #include mysqlnd.h #include mysqlnd_wireprotocol.h @@ -336,6 +336,12 @@ result-lengths = NULL; } + if (result-row_packet) { + DBG_INF(Freeing packet); + PACKET_FREE(result-row_packet); + result-row_packet = NULL; + } + DBG_VOID_RETURN; } /* }}} */ @@ -349,12 +355,6 @@ result-m.free_result_buffers(result TSRMLS_CC); - if (result-row_packet) { - DBG_INF(Freeing packet); - PACKET_FREE(result-row_packet); - result-row_packet = NULL; - } - if (result-meta) { result-meta-m-free_metadata(result-meta, FALSE TSRMLS_CC); result-meta = NULL; http://cvs.php.net/viewvc.cgi/php-src/ext/mysqlnd/mysqlnd_wireprotocol.c?r1=1.4.2.10r2=1.4.2.11diff_format=u Index: php-src/ext/mysqlnd/mysqlnd_wireprotocol.c diff -u php-src/ext/mysqlnd/mysqlnd_wireprotocol.c:1.4.2.10 php-src/ext/mysqlnd/mysqlnd_wireprotocol.c:1.4.2.11 --- php-src/ext/mysqlnd/mysqlnd_wireprotocol.c:1.4.2.10 Thu Feb 14 14:50:21 2008 +++ php-src/ext/mysqlnd/mysqlnd_wireprotocol.c Wed Feb 20 15:18:17 2008 @@ -1672,11 +1672,13 @@ static void php_mysqlnd_rowp_free_mem(void *_packet, zend_bool alloca TSRMLS_DC) { + DBG_ENTER(php_mysqlnd_rowp_free_mem); php_mysql_packet_row *p= (php_mysql_packet_row *) _packet; if (p-row_buffer) { p-row_buffer-free_chunk(p-row_buffer, TRUE TSRMLS_CC); p-row_buffer = NULL; } + DBG_INF_FMT(alloca=%d persistent=%d, (int)alloca, (int)p-header.persistent); /* Don't free packet-fields : - normal queries - store_result() | fetch_row_unbuffered() will transfer @@ -1687,6 +1689,7 @@ if (!alloca) { mnd_pefree(p, p-header.persistent); } + DBG_VOID_RETURN; } /* }}} */ http://cvs.php.net/viewvc.cgi/php-src/ext/mysqlnd/mysqlnd_wireprotocol.h?r1=1.4.2.8r2=1.4.2.9diff_format=u Index: php-src/ext/mysqlnd/mysqlnd_wireprotocol.h diff -u php-src/ext/mysqlnd/mysqlnd_wireprotocol.h:1.4.2.8 php-src/ext/mysqlnd/mysqlnd_wireprotocol.h:1.4.2.9 --- php-src/ext/mysqlnd/mysqlnd_wireprotocol.h:1.4.2.8 Thu Feb 14 12:49:30 2008 +++ php-src/ext/mysqlnd/mysqlnd_wireprotocol.h Wed Feb 20 15:18:17 2008 @@ -18,7 +18,7 @@ +--+ */ -/* $Id: mysqlnd_wireprotocol.h,v 1.4.2.8 2008/02/14 12:49:30 andrey Exp $ */ +/* $Id: mysqlnd_wireprotocol.h,v 1.4.2.9 2008/02/20 15:18:17 andrey Exp $ */ #ifndef