Hello,
I often host clients which have "bad" PHP/SQL code ; as for example
a "select *" + mysql_row_nums on a 200Mo table just to count lines...
So I add a little patch to throw a warning in case the result of mysql_query
is larger than a specified limit.
I use the setting "mysql.min_stored_data_before_warn" in php.ini, and the
result is :
[30-Mar-2008 04:39:56] PHP Warning: mysql_query() [<a
href='function.mysql-query'>function.mysql-query</a>]: Your query use
too much memory (202636 o) in /path/to/script.php on line 8
This patch seem "usefull" for me as PHP does not report the queries's memory
consumption. But maybe it should be done in mysqli and PDO extensions to ?
I'm not a "C developper", and the patch use the mysql internal struct, so
it's not really "clean". Maybe we can do it differently.
Thanks
Olivier
PS : sorry for my limited english.
diff -aur old/ext/mysql/php_mysql.c new/ext/mysql/php_mysql.c
--- old/ext/mysql/php_mysql.c 2006-08-02 12:04:11.000000000 +0200
+++ new/ext/mysql/php_mysql.c 2007-09-10 13:32:13.000000000 +0200
@@ -355,6 +355,7 @@
STD_PHP_INI_ENTRY("mysql.default_socket", NULL, PHP_INI_ALL, OnUpdateStringUnempty, default_socket, zend_mysql_globals, mysql_globals)
STD_PHP_INI_ENTRY("mysql.connect_timeout", "60", PHP_INI_ALL, OnUpdateLong, connect_timeout, zend_mysql_globals, mysql_globals)
STD_PHP_INI_BOOLEAN("mysql.trace_mode", "0", PHP_INI_ALL, OnUpdateLong, trace_mode, zend_mysql_globals, mysql_globals)
+ STD_PHP_INI_ENTRY("mysql.min_stored_data_before_warn", "0", PHP_INI_SYSTEM, OnUpdateLong, min_stored_data_before_warn, zend_mysql_globals, mysql_globals)
PHP_INI_END()
/* }}} */
@@ -1210,13 +1211,21 @@
#endif
#endif /* NETWARE */
+
/* {{{ php_mysql_do_query_general
*/
static void php_mysql_do_query_general(zval **query, zval **mysql_link, int link_id, zval **db, int use_store, zval *return_value TSRMLS_DC)
{
php_mysql_conn *mysql;
MYSQL_RES *mysql_result;
-
+
+ MYSQL_DATA *data;
+ MEM_ROOT alloc;
+ USED_MEM *next;
+
+ long result_size;
+
+
ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
if (db) {
@@ -1283,6 +1292,24 @@
mysql_result=mysql_use_result(&mysql->conn);
} else {
mysql_result=mysql_store_result(&mysql->conn);
+
+ if( mysql_result && ( MySG(min_stored_data_before_warn) > 0 ))
+ {
+ data = mysql_result->data ;
+ alloc = data->alloc ;
+
+ result_size = alloc.block_size ;
+ for (next = alloc.used; next; next= next->next )
+ {
+ result_size += ( next->size - next->left );
+ }
+
+ if( result_size >= MySG(min_stored_data_before_warn) )
+ {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Your query use too much memory (%ld o)", result_size );
+ }
+ }
}
if (!mysql_result) {
if (PHP_MYSQL_VALID_RESULT(&mysql->conn)) { /* query should have returned rows */
diff -aur old/ext/mysql/php_mysql.h new/ext/mysql/php_mysql.h
--- old/ext/mysql/php_mysql.h 2006-01-01 13:50:09.000000000 +0100
+++ new/ext/mysql/php_mysql.h 2007-09-10 13:32:13.000000000 +0200
@@ -105,6 +105,7 @@
long connect_timeout;
long result_allocated;
long trace_mode;
+ long min_stored_data_before_warn;
ZEND_END_MODULE_GLOBALS(mysql)
#ifdef ZTS
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php