Php Catch Mysql Deadlock and Try Again

MySQL deadlocksA deadlock in MySQL happens when two or more transactions mutually hold and request for locks, creating a cycle of dependencies. In a transaction system, deadlocks are a fact of life and non completely avoidable. InnoDB automatically detects transaction deadlocks, rollbacks a transaction immediately and returns an error. It uses a metric to pick the easiest transaction to rollback. Though an occasional deadlock is non something to worry near, frequent occurrences call for attention.

Earlier MySQL 5.6, only the latest deadlock can be reviewed using SHOW ENGINE INNODB STATUS command. Simply with Percona Toolkit'southward pt-deadlock-logger y'all can have deadlock data retrieved from SHOW ENGINE INNODB STATUS at a given interval and saved to a file or table for late diagnosis. For more information on using pt-deadlock-logger, run into this post. With MySQL v.6, you lot tin can enable a new variable innodb_print_all_deadlocks to take all deadlocks in InnoDB recorded in mysqld error log.

Before and above all diagnosis, information technology is ever an important exercise to have the applications catch deadlock error (MySQL error no. 1213) and handles it by retrying the transaction.

How to diagnose a MySQL deadlock

A MySQL deadlock could involve more than two transactions, but the LATEST DETECTED DEADLOCK section only shows the last two transactions. As well, it only shows the last statement executed in the ii transactions and locks from the two transactions that created the bicycle. What is missed are the earlier statements that might have really acquired the locks. I volition show some tips on how to collect the missed statements.

Let's look at two examples to see what information is given. Instance 1:

Line one gives the time when the deadlock happened. If your application code catches and logs deadlock errors, which it should, then you can match this timestamp with the timestamps of deadlock errors in the application log. Yous would have the transaction that got rolled back. From in that location, think all statements from that transaction.

Line 3 & xi, take note of Transaction number and Agile fourth dimension. If yous log SHOW ENGINE INNODB STATUS output periodically(which is a good practice), then you tin can search previous outputs with a transaction number to hopefully come across more than statements from the aforementioned transaction. The Agile sec gives a hint on whether the transaction is a single statement or multi-statement i.

Line 4 & 12, the tables in use and locked are simply with respect to the current statement. So having i tabular array in utilise does non necessarily hateful that the transaction involves 1 tabular array only.

Line 5 & xiii, this is worthy of attention as it tells how many changes the transaction had fabricated, which is the "undo log entries" and how many row locks it held which is "row lock(s)". This info hints the complexity of the transaction.

Line 6 & fourteen, take note of thread id, connecting host and connecting user. If you utilize different MySQL users for unlike application functions which is some other good do, and then you tin can tell which application expanse the transaction comes from based on the connecting host and user.

Line 9, for the first transaction, information technology only shows the lock it was waiting for, in this case, the Car-INC lock on table t1. Other possible values are S for shared lock and X for exclusive with or without gap locks.

Line 16 & 17, for the second transaction, information technology shows the lock(south) it held, in this example, the AUTO-INC lock which was what TRANSACTION (i) was waiting for.

Line 18 & nineteen shows which lock TRANSACTION (ii) was waiting for. In this case, it was a shared not gap record lock on some other tabular array's primary key. There are only a few sources for a shared record lock in InnoDB:
1) use of SELECT … LOCK IN SHARE MODE
2) on strange central referenced record(s)
3) with INSERT INTO… SELECT, shared locks on the source table
The current statement of trx(two) is a simple insert to tabular array t1, so i and 3 are eliminated. By checking Prove CREATE Table t1, you could ostend that the S lock was due to a foreign primal constraint to the parent table t2.

Example 2: With MySQL customs version, each tape lock has the tape content printed:

Line 9 & x: The 'space id' is tablespace id, 'page no' gives which page the record lock is on inside the tablespace. The 'n bits' is not the page offset, instead, the number of bits in the lock bitmap. The page beginning is the 'heap no' on line 10,

Line 11~xv: Information technology shows the record data in hex numbers. Field 0 is the cluster alphabetize(primary key). Ignore the highest bit, the value is 3. Field ane is the transaction id of the transaction which last modified this record, decimal value is 2164001 which is TRANSACTION (2). Field two is the rollback pointer. Starting from field iii is the remainder of the row data. Field 3 is integer column, value 8. Field four is a cord column with grapheme 'c'. Past reading the data, we know exactly which row is locked and what is the electric current value.

What else can we learn from the analysis?

Since most MySQL deadlocks happen between 2 transactions, we could starting time the analysis based on that assumption. In Instance 1, trx (2) was waiting on a shared lock, then trx (ane) either held a shared or exclusive lock on that primary key record of table t2. Permit's say col2 is the foreign key column, by checking the current statement of trx(1), we know it did not require the same record lock, so information technology must be some previous statement in trx(1) that required S or X lock(south) on t2'due south PK record(s). Trx (1) only made 4 row changes in 7 seconds. So you learned a few characteristics of trx(1): it does a lot of processing just a few changes; changes involve table t1 and t2, a single tape insertion to t2. This data combined with other data could help developers to locate the transaction.

Where else can we find previous statements of the transactions?

A helper query to excerpt the history of a transaction is the following where <PROCESSID> is the ID of the offending connectedness.

More details for the events_statements_history table can exist found hither.

Likewise application log and previous Evidence ENGINE INNODB STATUS output, you may also leverage binlog, slow log and/or general query log. With binlog, if binlog_format=argument, each binlog consequence would accept the thread_id. Only committed transactions are logged into binlog, so nosotros could only wait for Trx(2) in binlog. In the case of Example i, nosotros know when the deadlock happened, and nosotros know Trx(2) started 9 seconds ago. We tin can run mysqlbinlog on the right binlog file and expect for statements with thread_id = 155097580. It is e'er practiced to then cross reference the statements with the application code to confirm.

With Percona Server 5.5 and in a higher place, y'all can set up log_slow_verbosity to include InnoDB transaction id in the slow log. Then if yous accept long_query_time = 0, yous would be able to catch all statements including those rolled dorsum into the ho-hum log file. With general query log, the thread id is included and could be used to await for related statements.

How to avoid a MySQL deadlock

There are things nosotros could do to eliminate a deadlock later we understand it.

– Make changes to the application. In some cases, y'all could greatly reduce the frequency of deadlocks by splitting a long transaction into smaller ones, and then locks are released sooner. In other cases, the deadlock rises because two transactions touch on the aforementioned sets of data, either in one or more tables, with different orders. And so alter them to access information in the same society, in some other give-and-take, serialize the access. That way you would have lock wait instead of deadlock when the transactions happen concurrently.

– Make changes to the tabular array schema, such every bit removing strange key constraint to detach two tables, or adding indexes to minimize the rows scanned and locked.

– In example of gap locking, you may change the transaction isolation level to read committed for the session or transaction to avoid information technology. But and then the binlog format for the session or transaction would accept to be ROW or MIXED.

longtwold1986.blogspot.com

Source: https://www.percona.com/blog/2014/10/28/how-to-deal-with-mysql-deadlocks/

0 Response to "Php Catch Mysql Deadlock and Try Again"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel