Heim  >  Artikel  >  Datenbank  >  Was bedeutet MySQL-Sperre auf Zeilenebene?

Was bedeutet MySQL-Sperre auf Zeilenebene?

醉折花枝作酒筹
醉折花枝作酒筹nach vorne
2021-07-26 09:16:543582Durchsuche

Das erste, was wir wissen müssen, ist, dass MySQL-Sperren von einer bestimmten Speicher-Engine implementiert werden. Daher gibt es Unterschiede in den Sperrimplementierungsmechanismen der MySQL-Standard-Engine MyISAM und der Plug-in-Engine InnoDB eines Drittanbieters.

Was bedeutet MySQL-Sperre auf Zeilenebene?

Mysql verfügt über drei Sperrebenen: Sperren auf Tabellenebene, Sperren auf Seitenebene, Sperren auf Zeilenebene

1 Definition

Der Sperrmechanismus, der jedes Mal eine Datenzeile sperrt, ist die Sperre auf Zeilenebene ( Zeilenebene). Das Sperren auf Zeilenebene ist keine von MySQL selbst implementierte Sperrmethode, sondern eine von anderen Speicher-Engines implementierte Methode. 2. Vorteile und Nachteile

1. Aufgrund der geringen Sperrgranularität, der geringen Konfliktrate und der hohen Parallelität.

    2. Nachteile
  • Komplexe Implementierung und hoher Overhead.

    Das Sperren ist langsam und es kann zu Deadlocks kommen -Level-Sperrtyp
  • InnoDBs Sperren auf Zeilenebene sind ebenfalls in zwei Typen unterteilt: gemeinsame Sperren und exklusive Sperren. Bei der Implementierung des Sperrmechanismus ermöglicht InnoDB auch die Koexistenz von Sperren auf Zeilenebene und Sperren auf Tabellenebene Verwendet Absichtssperren (Tabellensperren). Es gibt zwei Arten von Absichts-Gemeinschaftssperren und Absichts-Exklusivsperren.

  • Die Funktion der Absichtssperre besteht darin, dass, wenn eine Transaktion eine Ressourcensperre erhalten muss und die benötigte Ressource bereits durch eine exklusive Sperre belegt ist, die Transaktion der Tabelle, die die Zeile sperren muss, eine entsprechende Absichtssperre hinzufügen kann. Wenn Sie eine gemeinsame Sperre benötigen, fügen Sie der Tabelle eine beabsichtigte gemeinsame Sperre hinzu. Wenn Sie eine exklusive Sperre für eine bestimmte Zeile (oder einige Zeilen) hinzufügen müssen, fügen Sie zunächst eine absichtliche exklusive Sperre für die Tabelle hinzu.
  • Mehrere gemeinsam genutzte Absichtssperren können gleichzeitig vorhanden sein, es kann jedoch nur eine exklusive Absichtssperre gleichzeitig vorhanden sein. Daher kann man sagen, dass die Sperrmodi von InnoDB tatsächlich in vier Typen unterteilt werden können: Shared Lock (S), Exclusive Lock (X), Intention Shared Lock (IS) und Intention Exclusive Lock (IX)

  • Kompatibilität der Sperrmodi:

  • 5. Implementierung der Sperrung auf Zeilenebene
InnoDB-Zeilensperre wird durch Sperren der Indexelemente im Index implementiert. Daher verwendet InnoDB Sperren auf Zeilenebene nur, wenn Daten über Indexbedingungen abgerufen werden. Andernfalls verwendet InnoDB Tabellensperren. Weitere Hinweise:

Bei Abfragen ohne Indexbedingungen verwendet InnoDB Tabellensperren anstelle von Zeilensperren.

Da die Zeilensperre von MySQL für den Index und nicht für den Datensatz gilt, kommt es bei Verwendung desselben Indexschlüssels zu einem Sperrkonflikt, selbst wenn Sie auf Datensätze in verschiedenen Zeilen zugreifen.

Was bedeutet MySQL-Sperre auf Zeilenebene?Wenn eine Tabelle über mehrere Indizes verfügt, können verschiedene Transaktionen unterschiedliche Indizes verwenden, um verschiedene Zeilen zu sperren. Unabhängig davon, ob ein Primärschlüsselindex, ein eindeutiger Index oder ein gewöhnlicher Index verwendet wird, verwendet InnoDB Zeilensperren, um Daten zu sperren.

Selbst wenn in der Bedingung ein Indexfeld verwendet wird, bestimmt MySQL anhand der Kosten verschiedener Ausführungspläne, ob ein vollständiger Tabellenscan effizienter ist, z. B Für einige kleine Tabellen werden keine Indizes verwendet. In diesem Fall verwendet InnoDB Tabellensperren anstelle von Zeilensperren. Vergessen Sie daher bei der Analyse von Sperrkonflikten nicht, den SQL-Ausführungsplan zu überprüfen, um sicherzustellen, dass der Index tatsächlich verwendet wird.

  • Implizite Sperre:

  • InnoDB fügt automatisch Absichtssperren hinzu.

  • Für UPDATE-, DELETE- und INSERT-Anweisungen fügt InnoDB automatisch exklusive Sperren (X) zu den beteiligten Datensätzen hinzu.

  • Für gewöhnliche SELECT-Anweisungen fügt InnoDB keine Sperren hinzu :

Gemeinsame Sperre (S): SELECT * FROM table_name WHERE ... SPERRE IM SHARE-MODUS

  • Exklusive Sperre (X): SELECT * FROM table_name WHERE ... FOR UPDATE

  • Verwenden Sie SELECT . .. IM SHARE-MODUS erhält eine gemeinsame Sperre, die hauptsächlich verwendet wird, um zu bestätigen, ob eine bestimmte Zeile von Datensätzen vorhanden ist, wenn Datenabhängigkeiten erforderlich sind, und um sicherzustellen, dass niemand UPDATE- oder DELETE-Vorgänge für diesen Datensatz ausführt.

  • Wenn die aktuelle Transaktion jedoch auch den Datensatz aktualisieren muss, führt dies wahrscheinlich zu einem Deadlock. Bei Anwendungen, die den Zeilendatensatz nach dem Sperren aktualisieren müssen, sollte die Methode SELECT... FOR UPDATE verwendet werden, um einen zu erhalten Exklusives Schloss.
  • So sperren Sie die Tabelle in InnoDB:

  • Wenn Sie LOCK TABLES zum Sperren der InnoDB-Tabelle verwenden, achten Sie darauf, AUTOCOMMIT auf 0 zu setzen, da MySQL die Tabelle sonst nicht sperren wird Die Transaktion endet, da UNLOCK TABLES die Transaktion implizit festschreibt. COMMIT oder ROLLBACK können die mit LOCK TABLES hinzugefügte Sperre auf Tabellenebene nicht aufheben, und die Tabellensperre muss mit UNLOCK TABLES aufgehoben werden.
SET AUTOCOMMIT=0;
LOCK TABLES t1 WRITE, t2 READ, ...;
[do something with tables t1 and t2 here];
COMMIT;
UNLOCK TABLES;

Da wir alle Tabellensperren verwendet haben, warum nicht die MyISAM-Engine wählen?

六、间隙锁(Next-Key锁)

1. 间隙锁定义:

Innodb的锁定规则是通过在指向数据记录的第一个索引键之前和最后一个索引键之后的空域空间上标记锁定信息而实现的。 Innodb的这种锁定实现方式被称为“ NEXT-KEY locking” (间隙锁),因为Query执行过程中通过范围查找的话,它会锁定整个范围内所有的索引键值,即使这个键值并不存在。

例:假如emp表中只有101条记录,其empid的值分别是 1,2,…,100,101,下面的SQL:

mysql> select * from emp where empid > 100 for update;

是一个范围条件的检索,InnoDB不仅会对符合条件的empid值为101的记录加锁,也会对empid大于101(这些记录并不存在)的“间隙”加锁。

2. 间隙锁的缺点:

  • 间隙锁有一个比较致命的弱点,就是当锁定一个范围键值之后,即使某些不存在的键值也会被无辜的锁定,而造成在锁定的时候无法插入锁定键值范围内的任何数据。在某些场景下这可能会对性能造成很大的危害

  • 当Query无法利用索引的时候, Innodb会放弃使用行级别锁定而改用表级别的锁定,造成并发性能的降低;

  • 当Quuery使用的索引并不包含所有过滤条件的时候,数据检索使用到的索引键所指向的数据可能有部分并不属于该Query的结果集的行列,但是也会被锁定,因为间隙锁锁定的是一个范围,而不是具体的索引键;

  • 当Query在使用索引定位数据的时候,如果使用的索引键一样但访问的数据行不同的时候(索引只是过滤条件的一部分),一样会被锁定

3 . 间隙锁的作用:

  • 防止幻读,以满足相关隔离级别的要求。

  • 为了数据恢复和复制的需要。

4. 注意

  • 在实际应用开发中,尤其是并发插入比较多的应用,我们要尽量优化业务逻辑,尽量使用相等条件来访问更新数据,避免使用范围条件。

  • InnoDB除了通过范围条件加锁时使用间隙锁外,如果使用相等条件请求给一个不存在的记录加锁,InnoDB也会使用间隙锁。

七、查看行级锁争用情况

执行SQL:mysql> show status like 'InnoDB_row_lock%';

mysql> show status like 'InnoDB_row_lock%';
+-------------------------------+-------+| Variable_name                 | Value |
+-------------------------------+-------+| InnoDB_row_lock_current_waits | 0     |
| InnoDB_row_lock_time          | 0     |
| InnoDB_row_lock_time_avg      | 0     |
| InnoDB_row_lock_time_max      | 0     |
| InnoDB_row_lock_waits         | 0     |+-------------------------------+-------+

如果发现锁争用比较严重,还可以通过设置InnoDB Monitors 来进一步观察发生锁冲突的表、数据行等,并分析锁争用的原因。如:

设置监视器:mysql> create table InnoDB_monitor(a INT) engine=InnoDB;

查看:mysql> show engine InnoDB status;

停止查看:mysql> drop table InnoDB_monitor;

具体参考:InnoDB Monitor

八、死锁

什么是死锁:你等我释放锁,我等你释放锁就会形成死锁。

如何发现死锁: 在InnoDB的事务管理和锁定机制中,有专门检测死锁的机制,会在系统中产生死锁之后的很短时间内就检测到该死锁的存在

解决办法:

  • 回滚较小的那个事务

  • 在REPEATABLE-READ隔离级别下,如果两个线程同时对相同条件记录用SELECT…FOR UPDATE加排他锁,在没有符合该条件记录情况下,两个线程都会加锁成功。程序发现记录尚不存在,就试图插入一条新记录,如果两个线程都这么做,就会出现死锁。这种情况下,将隔离级别改成READ COMMITTED,就可避免问题。

判断事务大小:事务各自插入、更新或者删除的数据量

注意:

  • 当产生死锁的场景中涉及到不止InnoDB存储引擎的时候,InnoDB是没办法检测到该死锁的,这时候就只能通过锁定超时限制参数InnoDB_lock_wait_timeout来解决。

九、优化行级锁定

InnoDB存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面所带来的性能损耗可能比表级锁定会要更高一些,但是在整体并发处理能力方面要远远优于MyISAM的表级锁定的。当系统并发量较高的时候,InnoDB的整体性能和MyISAM相比就会有比较明显的优势了。但是,InnoDB的行级锁定同样也有其脆弱的一面,当我们使用不当的时候,可能会让InnoDB的整体性能表现不仅不能比MyISAM高,甚至可能会更差。

(1)要想合理利用InnoDB的行级锁定,做到扬长避短,我们必须做好以下工作:

  • Lassen Sie den gesamten Datenabruf so weit wie möglich über den Index abschließen, um zu vermeiden, dass InnoDB auf Sperren auf Tabellenebene aktualisiert wird, da es nicht über den Indexschlüssel gesperrt werden kann.

  • Entwerfen Sie den Index angemessen und lassen Sie InnoDB sperren Seien Sie so genau wie möglich und schränken Sie den Sperrbereich so weit wie möglich ein, um unnötige Sperren zu vermeiden, die die Ausführung anderer Abfragen beeinträchtigen.

  • Reduzieren Sie die Filterbedingungen für den bereichsbasierten Datenabruf so weit wie möglich Negative Auswirkungen von Lückensperren.

  • Versuchen Sie, die Größe der Transaktionen zu kontrollieren, die Menge der gesperrten Ressourcen und die Dauer der Sperrung zu reduzieren.

  • Versuchen Sie es Verwendung einer niedrigeren Transaktionsisolation, um die zusätzlichen Kosten für MySQL zu reduzieren, die durch die Implementierung von Transaktionsisolationsstufen entstehen.

(2) Aufgrund der Sperrung auf Zeilenebene und der Transaktionsnatur von InnoDB kommt es definitiv zu Deadlocks. Hier sind einige häufig verwendete Tipps, um die Wahrscheinlichkeit von Deadlocks zu verringern:

  • Versuchen Sie in ähnlichen Geschäftsmodulen Ihr Bestes Um einen Deadlock zu verhindern, versuchen Sie in derselben Transaktion, alle erforderlichen Ressourcen gleichzeitig zu sperren, um die Wahrscheinlichkeit eines Deadlocks zu verringern Für den geschäftlichen Teil der Sperre können Sie versuchen, die Sperrgranularität zu verbessern und die Wahrscheinlichkeit eines Deadlocks durch Sperren auf Tabellenebene zu verringern.

  • Verwandte Empfehlungen: „

    MySQL-Tutorial

Das obige ist der detaillierte Inhalt vonWas bedeutet MySQL-Sperre auf Zeilenebene?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen