Current Location: Home> Latest Articles> Why Is mysql_info Sometimes Inaccurate? Causes and Solutions

Why Is mysql_info Sometimes Inaccurate? Causes and Solutions

M66 2025-06-27

When developing MySQL-based applications with PHP, some developers use mysql_info() or mysqli_info() to retrieve supplementary details after executing certain SQL operations, such as the number of affected rows in bulk inserts, updates, or deletes. However, you may occasionally find that the returned data is inaccurate—or even false or an empty string after some operations. What causes this unreliable behavior? This article explores the underlying mechanisms, analyzes the reasons, and offers practical solutions.

1. What Does mysql_info() Do?

mysql_info() is primarily used to get a brief status message after executing non-SELECT statements, such as:

$link = mysqli_connect("localhost", "user", "pass", "testdb");
mysqli_query($link, "UPDATE users SET status = 1 WHERE id < 100");
echo mysqli_info($link);

The output might be:

Rows matched: 100 Changed: 100 Warnings: 0

This is especially useful during batch operations to determine how many rows were matched or changed. However, it depends on the status information returned by MySQL itself.

2. Why Is It Sometimes Inaccurate?

1. Not All Statements Return Info

Not all non-SELECT SQL statements generate info messages. According to MySQL’s official documentation, only certain statement types may return this information:

  • INSERT INTO ... SELECT ...

  • UPDATE

  • DELETE

  • LOAD DATA

Statements like plain INSERT or REPLACE, especially those that don't use subqueries to insert data, often won’t populate the info buffer.

2. Impact of Client Driver Behavior

The MySQL client library used by PHP (libmysql or mysqlnd) also affects info retrieval. When using mysqlnd (MySQL Native Driver), mysqli_info() tends to return more accurate results. In contrast, libmysql may not log or may delay info details.

3. Multi-Statement Execution Overwrites Info

If multiple SQL statements are executed in a single connection (e.g., in batch mode), mysqli_info() only reflects the info of the last executed statement. For example:

mysqli_query($link, "UPDATE table1 SET name = 'A'; UPDATE table2 SET name = 'B';");
echo mysqli_info($link); // Returns info only for table2

This may mislead developers into thinking that earlier operations didn't execute or had no effect.

4. MySQL Version and Configuration Limits

Different MySQL versions return different levels of info. For instance, older versions might omit Rows matched or Warnings, or contain bugs that report incorrect row counts. Additionally, certain performance-optimizing configurations might bypass some internal statistics gathering.

3. How to Use It Properly and Avoid Misinterpretation

1. Use mysqli with mysqlnd Driver

Ensure your PHP environment is running mysqlnd, which can be checked like this:

if (function_exists('mysqli_get_client_stats')) {
    echo "mysqlnd enabled";
}

mysqlnd offers more standardized and comprehensive support for info reporting and is preferred over libmysql in production environments.

2. Avoid Relying on Info in Multi-Statements

Don’t depend on info in multi-statement queries. Instead, execute each SQL statement individually and read its corresponding info result right after:

mysqli_query($link, "DELETE FROM logs WHERE created_at < NOW() - INTERVAL 30 DAY");
$logInfo = mysqli_info($link);
echo "Log cleanup result: " . $logInfo;

3. Manually Track Key Data Based on Logic

For critical SQL operations, don’t fully rely on the textual output of mysql_info(). Validate results through additional queries or logging mechanisms. For instance, compare row counts before and after cleanup, or use transactions for precise control.

4. Beware of Misleading Row Counts

Note that Changed: 0 does not imply that the SQL statement failed—it may simply indicate no actual data change occurred (e.g., updating to the same value). This is common in UPDATE operations and explains why you might see Rows matched alongside Changed: 0.

4. Debugging Tips

To enhance debugging and monitoring, consider logging the info output like this:

$sql = "UPDATE users SET status = 0 WHERE active = 0";
mysqli_query($link, $sql);
file_put_contents("/var/log/mysql_ops.log", date('Y-m-d H:i:s') . " " . $sql . " => " . mysqli_info($link) . "\n", FILE_APPEND);

You can also send these logs to a remote monitoring system via API: