Bug #76525 [Asn->Csd]: mysqli::commit does not throw if MYSQLI_REPORT_ERROR enabled and mysqlnd used
| From: | nikic@php.net | Date: | Wed, 28 Oct 2020 10:39:24 +0000 |
| Subject: | Bug #76525 [Asn->Csd]: mysqli::commit does not throw if MYSQLI_REPORT_ERROR enabled and mysqlnd used | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-229967@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=76525&edit=1
ID: 76525
Updated by: nikic@php.net
Reported by: willem at mollie dot nl
Summary: mysqli::commit does not throw if MYSQLI_REPORT_ERROR
enabled and mysqlnd used
-Status: Assigned
+Status: Closed
Type: Bug
Package: MySQLi related
Operating System: Debian
PHP Version: 7.1.19
Assigned To: nikic
Block user comment: N
Private report: N
New Comment:
This should be fixed by https://github.com/php/php-src/commit/990bb34891c83d12c5129fd781893704f948f2f4.
Previous Comments:
------------------------------------------------------------------------
[2018-12-13 16:22:17] willem at mollie dot nl
Dominik, we fixed it by switching to using a COMMIT query instead of the method.
------------------------------------------------------------------------
[2018-12-13 16:01:23] dominik dot fiser at w3w dot cz
We have similar and probably related problem with Galera and mysql PDO.
Galera Cluster instead of standard MySQL/MariaDD could fail on commit query due to its replication
mechanism (described e.g. at https://www.percona.com/blog/2012/11/20/understanding-multi-node-writing-conflict-metrics-in-percona-xtradb-cluster-and-galera/).
We are using PPH 7.2.11 and mysql PDO with error mode PDO::ATTR_ERRMODE = PDO::ERRMODE_EXCEPTION.
That's really pain and very hard to find, if you are catching exceptions and there is no
exception, no error and transaction is not commited in database. This should be fixed ASAP.
------------------------------------------------------------------------
[2018-06-25 08:35:40] willem at mollie dot nl
Description:
------------
We experienced lost data because the mysqli::commit() function does not throw under some conditions
if mysqlnd is used. We configured mysqli to use report_mode = MYSQLI_REPORT_ERROR |
MYSQLI_REPORT_STRICT.
We use a MySQL Galera cluster setup and during reboots of nodes deadlocks in the commit query can
occur.
However, these deadlocks do not cause an exception to be thrown if the ::commit() method is used.
Instead, false is returned. In practice, the call fails silently.
Sending COMMIT queries manually works as expected (an exception is thrown on a dead lock).
You can see in https://github.com/php/php-src/blob/5f54f48024783df739dd5bbec64cb74063fefa06/ext/mysqli/mysqli_api.c#L741
that the error handling is missing for mysqlnd if you compare to https://github.com/php/php-src/blob/5f54f48024783df739dd5bbec64cb74063fefa06/ext/mysqli/mysqli_api.c#L1579.
I'd guess that the MYSQLI_REPORT_MYSQL_ERROR macro is missing.
Expected result:
----------------
If the commit() method encounters a "Deadlock found when trying to get lock; try restarting
transaction" error (1213 code), with report_mode = MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT
we expect it to throw mysqli_sql_exception.
Actual result:
--------------
False is returned, e.g. the report_mode is ignored.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=76525&edit=1