MySQL Native Driver contains support for gathering statistics on the communication between the client and the server. The statistics gathered are of two main types:
When using the mysqli extension, these statistics can be obtained through two API calls:
Note: Statistics are aggregated among all extensions that use the MySQL Native Driver. For example, if the mysqli extension and the PDO MySQL driver are both set-up to use MySQLnd, then function calls from mysqli and method calls from PDO will affect the statistics. There is no way to find out how much a certain API call of any extension that has been compiled against MySQL Native Driver has impacted a certain statistic.
Client statistics can be retrieved by calling the mysqli_get_client_stats() function.
Connection statistics can be retrieved by calling the mysqli_get_connection_stats() function.
Both functions return an associative array, where the name of a statistic is the key for the corresponding statistical data.
Most statistics are associated to a connection, but some are associated to the process in which case this will be mentioned.
The following statistics are produced by the MySQL Native Driver:
bytes_sentbytes_receivedpackets_sentpackets_receivedprotocol_overhead_inprotocol_overhead_in = packets_received * 4protocol_overhead_outprotocol_overhead_out = packets_received * 4bytes_received_ok_packetNote: The total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_okbytes_received_eof_packetNote: The total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_eofbytes_received_rset_header_packetLOAD LOCAL INFILE, INSERT, UPDATE, SELECT, error message).Note: The total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_rset_headerbytes_received_rset_field_meta_packetNote: The total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_rset_field_metabytes_received_rset_row_packetrows_fetched_from_server_normal and rows_fetched_from_server_ps from bytes_received_rset_row_packet.Note: The total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_rset_rowbytes_received_prepare_response_packetNote: The total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_prepare_responsebytes_received_change_user_packetNote: The total size in bytes includes the size of the header packet (4 bytes, see protocol overhead).
packets_received_change_userpackets_sent_commandbytes_received_real_data_normalmysqlnd using the text protocol. This is the size of the actual data contained in result sets that do not originate from prepared statements and which have been fetched by the PHP client. Note that although a full result set may have been pulled from MySQL by mysqlnd, this statistic only counts actual data pulled from mysqlnd by the PHP client.An example of a code sequence that will increase the value is as follows:
$mysqli = new mysqli();
$res = $mysqli->query("SELECT 'abc'");
$res->fetch_assoc();
$res->close();
However, the statistic will not be increased if the result set is only buffered on the client, but not fetched, such as in the following example:
$mysqli = new mysqli();
$res = $mysqli->query("SELECT 'abc'");
$res->close();
bytes_received_real_data_psmysqlnd using the prepared statement protocol. This is the size of the actual data contained in result sets that originate from prepared statements and which have been fetched by the PHP client. The value will not be increased if the result set is not subsequently read by the PHP client. Note that although a full result set may have been pulled from MySQL by mysqlnd, this statistic only counts actual data pulled from mysqlnd by the PHP client. See also bytes_received_real_data_normal.result_set_queriesSELECT, SHOW. The statistic will not be incremented if there is an error reading the result set header packet from the line.Note: This statistic can be used as an indirect measure for the number of queries PHP has sent to MySQL. This could help identifying a client that causes a high database load.
non_result_set_queriesINSERT, UPDATE, LOAD DATA. The statistic will not be incremented if there is an error reading the result set header packet from the line.Note: This statistic can be used as an indirect measure for the number of queries PHP has sent to MySQL. This could help identifying a client that causes a high database load.
no_index_used--log-queries-not-using-indexes).Note: Those queries can be reported via an exception by calling
mysqli_report(MYSQLI_REPORT_INDEX);. It is possible to have them be reported via a warning instead by callingmysqli_report(MYSQLI_REPORT_INDEX ^ MYSQLI_REPORT_STRICT);.
bad_index_used--log-slow-queries).Note: Those queries can be reported via an exception by calling
mysqli_report(MYSQLI_REPORT_INDEX);. It is possible to have them be reported via a warning instead by callingmysqli_report(MYSQLI_REPORT_INDEX ^ MYSQLI_REPORT_STRICT);.
slow_querieslong_query_time seconds to execute and required at least min_examined_row_limit rows to be examined.Not reported through mysqli_report().
buffered_setsExamples of API calls that will buffer result sets on the client: mysqli_query(), mysqli_store_result(), mysqli_stmt_get_result()
unbuffered_setsExamples of API calls that will not buffer result sets on the client: mysqli_use_result()
ps_buffered_setsExamples of API calls that will buffer result sets on the client: mysqli_stmt_store_result()
ps_unbuffered_setsflushed_normal_setsNote: Flushing happens only with unbuffered result sets. Unbuffered result sets must be fetched completely before a new query can be run on the connection otherwise MySQL will throw an error. If the application does not fetch all rows from an unbuffered result set, mysqlnd does implicitly fetch the result set to clear the line. See also
rows_skipped_normal,rows_skipped_ps.Some possible causes for an implicit flush:
- Faulty client application
- Client stopped reading after it found what it was looking for but has made MySQL calculate more records than needed
- Client application has stopped unexpectedly
flushed_ps_setsNote: Flushing happens only with unbuffered result sets. Unbuffered result sets must be fetched completely before a new query can be run on the connection otherwise MySQL will throw an error. If the application does not fetch all rows from an unbuffered result set, mysqlnd does implicitly fetch the result set to clear the line. See also
rows_skipped_normal,rows_skipped_ps.Some possible causes for an implicit flush:
- Faulty client application
- Client stopped reading after it found what it was looking for but has made MySQL calculate more records than needed
- Client application has stopped unexpectedly
ps_prepared_never_executedps_prepared_once_executedrows_fetched_from_server_normalrows_fetched_from_server_pspackets_received_rset_row.rows_buffered_from_client_normalExamples of queries that will buffer results:
rows_buffered_from_client_psrows_buffered_from_client_normal but for prepared statements.rows_fetched_from_client_normal_bufferedrows_fetched_from_client_ps_bufferedrows_fetched_from_client_normal_unbufferedrows_fetched_from_client_ps_unbufferedrows_fetched_from_client_ps_cursorrows_skipped_normalrows_skipped_pscopy_on_write_savedcopy_on_write_performedexplicit_free_resultimplicit_free_resultproto_text_fetched_nullMYSQL_TYPE_NULL fetched from a normal query (MySQL text protocol).proto_binary_fetched_nullMYSQL_TYPE_NULL fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_bitMYSQL_TYPE_BIT fetched from a normal query (MySQL text protocol).proto_binary_fetched_bitMYSQL_TYPE_BIT fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_tinyintMYSQL_TYPE_TINY fetched from a normal query (MySQL text protocol).proto_binary_fetched_tinyintMYSQL_TYPE_TINY fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_shortMYSQL_TYPE_SHORT fetched from a normal query (MySQL text protocol).proto_binary_fetched_shortMYSQL_TYPE_SHORT fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_int24MYSQL_TYPE_INT24 fetched from a normal query (MySQL text protocol).proto_binary_fetched_int24MYSQL_TYPE_INT24 fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_intMYSQL_TYPE_LONG fetched from a normal query (MySQL text protocol).proto_binary_fetched_intMYSQL_TYPE_LONG fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_bigintMYSQL_TYPE_LONGLONG fetched from a normal query (MySQL text protocol).proto_binary_fetched_bigintMYSQL_TYPE_LONGLONG fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_decimalMYSQL_TYPE_DECIMAL, or MYSQL_TYPE_NEWDECIMAL fetched from a normal query (MySQL text protocol).proto_binary_fetched_decimalMYSQL_TYPE_DECIMAL, or MYSQL_TYPE_NEWDECIMAL fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_floatMYSQL_TYPE_FLOAT fetched from a normal query (MySQL text protocol).proto_binary_fetched_floatMYSQL_TYPE_FLOAT fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_doubleMYSQL_TYPE_DOUBLE fetched from a normal query (MySQL text protocol).proto_binary_fetched_doubleMYSQL_TYPE_DOUBLE fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_dateMYSQL_TYPE_DATE, or MYSQL_TYPE_NEWDATE fetched from a normal query (MySQL text protocol).proto_binary_fetched_dateMYSQL_TYPE_DATE, or MYSQL_TYPE_NEWDATE fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_yearMYSQL_TYPE_YEAR fetched from a normal query (MySQL text protocol).proto_binary_fetched_yearMYSQL_TYPE_YEAR fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_timeMYSQL_TYPE_TIME fetched from a normal query (MySQL text protocol).proto_binary_fetched_timeMYSQL_TYPE_TIME fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_datetimeMYSQL_TYPE_DATETIME fetched from a normal query (MySQL text protocol).proto_binary_fetched_datetimeMYSQL_TYPE_DATETIME fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_timestampMYSQL_TYPE_TIMESTAMP fetched from a normal query (MySQL text protocol).proto_binary_fetched_timestampMYSQL_TYPE_TIMESTAMP fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_stringMYSQL_TYPE_STRING, MYSQL_TYPE_VARSTRING, or MYSQL_TYPE_VARCHAR fetched from a normal query (MySQL text protocol).proto_binary_fetched_stringMYSQL_TYPE_STRING, MYSQL_TYPE_VARSTRING, or MYSQL_TYPE_VARCHAR fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_blobMYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, or MYSQL_TYPE_BLOB fetched from a normal query (MySQL text protocol).proto_binary_fetched_blobMYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, or MYSQL_TYPE_BLOB fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_enumMYSQL_TYPE_ENUM fetched from a normal query (MySQL text protocol).proto_binary_fetched_enumMYSQL_TYPE_ENUM fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_setMYSQL_TYPE_SET fetched from a normal query (MySQL text protocol).proto_binary_fetched_setMYSQL_TYPE_SET fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_geometryMYSQL_TYPE_GEOMETRY fetched from a normal query (MySQL text protocol).proto_binary_fetched_geometryMYSQL_TYPE_GEOMETRY fetched from a prepared statement (MySQL binary protocol).proto_text_fetched_otherMYSQL_TYPE_* not listed previously fetched from a normal query (MySQL text protocol).Note: In theory, this should always be
0.
proto_binary_fetched_otherMYSQL_TYPE_* not listed previously fetched from a prepared statement (MySQL binary protocol).Note: In theory, this should always be
0.
connect_successNote:
connect_successholds the sum of successful persistent and non-persistent connection attempts. Therefore, the number of successful non-persistent connection attempts isconnect_success - pconnect_success.
pconnect_successconnect_failurereconnectactive_connectionsNote: The total number of active non-persistent connections is
active_connections - active_persistent_connections.
active_persistent_connectionsexplicit_closeExample #1 Examples of code snippets that cause an explicit close
$link = new mysqli(/* ... */); $link->close(/* ... */);
$link = new mysqli(/* ... */); $link->connect(/* ... */);
implicit_closeExample #2 Examples of code snippets that cause an implicit close
$link = new mysqli(/* ... */); $link->real_connect(/* ... */);
unset($link)disconnect_closemysql_real_connect during an attempt to establish a connection.in_middle_of_command_closeUnless asynchronous queries are used, this should only happen if the PHP application terminated unexpectedly, and PHP shuts down the connection automatically.
init_command_executed_countmysqli_options(MYSQLI_INIT_COMMAND , $value). The number of successful executions is init_command_executed_count - init_command_failed_count.init_command_failed_countCOM_* Command Related Statisticscom_quitcom_init_dbcom_querycom_field_listcom_create_dbcom_drop_dbcom_refreshcom_shutdowncom_statisticscom_process_infocom_connectcom_process_killcom_debugcom_pingcom_timecom_delayed_insertcom_change_usercom_binlog_dumpcom_table_dumpcom_connect_outcom_register_slavecom_stmt_preparecom_stmt_executecom_stmt_send_long_datacom_stmt_closecom_stmt_resetcom_stmt_set_optioncom_stmt_fetchcom_daemonCOM_* command from PHP to MySQL. The statistics are incremented after checking the line and immediately before sending the corresponding MySQL client server protocol packet.If MySQLnd fails to send the packet over the wire the statistics will not be decremented. In case of a failure MySQLnd emits a PHP warning Error while sending %s packet. PID=%d.
Example #3 Usage examples
COM_PROCESS_KILLCOM_EXECUTE with COM_PREPARECOM_QUERY is zeroCOM_QUERY and COM_EXECUTEexplicit_stmt_closeimplicit_stmt_closeNote: A prepared statement is always explicitly closed. The only time it's closed implicitly is when preparing it fails.
mem_emalloc_countmem_emalloc_ammountmem_ecalloc_countmem_ecalloc_ammountmem_realloc_countmem_realloc_ammountmem_efree_countmem_malloc_countmem_malloc_ammountmem_calloc_countmem_calloc_ammountmem_ealloc_countmem_ealloc_ammountmem_free_countcommand_buffer_too_smallCOM_QUERY (normal query), does not fit into the buffer, MySQLnd will grow the buffer to what is needed for sending the command. Whenever the buffer gets extended for one connection command_buffer_too_small will be incremented by one. If MySQLnd has to grow the buffer beyond its initial size of mysqlnd.net_cmd_buffer_size bytes for almost every connection, considerations to increase the default size should be made to avoid re-allocations.connection_reused