Minimize MySQL deadlock in 3 steps

background

MySQL具有锁定功能,例如表和行级别锁定,并且需要这种锁定来控制多用户并发中的数据完整性。死锁是一种不希望的情况,死锁是指两个或多个事务在等待事务成功进行之前互相放弃锁。这是所有数据库(包括MySQL / PostgreSQL / Oracle等)的经典问题。默认情况下,MySQL检测到死锁情况并打破死锁,它回滚事务之一。

Write in front
本文摘录自Percona官方社区博客https://www.percona.com/community-blog/2018/09/24/minimize-mysql-deadlocks-3-steps/
link

Some misunderstandings

关于死锁存在一些误解:

a)事务隔离级别负责死锁。死锁的可能性不受隔离级别的影响。隔离级别会更改读取操作的行为,但是由于写入操作会发生死锁。但是,隔离级别设置的锁较少,因此它可以帮助您避免某些锁类型(例如,间隙锁)。

b)小交易不受死锁的影响。小事务不太容易陷入僵局,但是如果事务不使用相同的操作顺序,它仍然会发生。

c)死锁是危险的。我仍然从使用MyISAM表的一些客户那里听到,他们不切换到InnoDB的原因是死锁问题。如果重试由于死锁而失败的事务并按照本文下面给出的步骤进行操作,则死锁并不危险。

我希望本文将有助于消除这种误解。

回到本文的主题。有很多可能导致死锁的可能性,为简单起见,我将建议分为3个步骤。

1. Use design strategies that avoid lock-in

Break large transactions into smaller transactions: shorten the transaction volume to make it less prone to conflicts.
If you use INSERT INTO...SELECT to copy some or all rows from one table to another, consider using a smaller lock transaction isolation level (for example, READ_COMMITTED), and set the binary log format of the transaction to row/mix. Or, design your application to put a single INSERT statement into a loop and then copy the rows into the table.
If your application performs locked reads, such as SELECT...FOR UPDATE or SELECT... FOR SHARE, please consider using the NOWAIT and SKIPPED LOCK options provided in MySQL 8.0. See Using NOWAIT and SKIP LOCKED to lock read concurrency. Or, you can consider using a smaller lock transaction isolation level (as described earlier)
. Multiple transactions in one or more tables update data sets and their transactions should use the same sequence of operations. Avoid locking tables A, B, C in one transaction and locking C, A, B in another transaction.
If the application is asked to retry when a transaction fails due to a deadlock, ideally, the application should be suspended for a while before resubmitting its query/transaction. This gives other transactions involved in the deadlock a chance to complete and release the lock that forms part of the deadlock cycle.

2. Optimize the query

Optimized query can check fewer rows, so locking can be reduced.

3. Disable deadlock detection (for systems running MySQL 8+)

If you are running a high concurrent system, it may be more effective to disable deadlock detection and rely on the innodb_lock_wait_timeout setting. However, keep the setting low. The default timeout is set to 50 seconds, which is too long if you are running without deadlock detection. Be careful when disabling deadlock detection because of it 弊大于利.

This article explains that the main technical content comes from the sharing of Internet technology giants, as well as some self-processing (only for the role of annotations). If related questions, please leave a message after the confirmation, the implementation of infringement will be deleted

Guess you like

Origin blog.csdn.net/baidu_34007305/article/details/111357409