MySQL--一貫した非ロックリード(スナップショットを読み取ります)

MySQL--一貫した非ロックリード(スナップショットを読み取ります)

MySQLデータベースが非ロックの読み取り一貫性に読み込まれ、一貫性が読み取りロック

  • マルチバージョン同時実行制御(MVCC)を介して達成一貫した非ロックリード(スナップショットを読み取る)、通常のSELECT、。
  • 一貫性のロックは、ロックによって達成(現在読ん)、SELECT ... FOR UPDATE / SELECTを... LOCKを共有MODE、読書します。

本論文では、非ロック読み取りの一貫性について説明し、単純に2つのシナリオを見て:

-- 创建表tx
create table t (id int auto_increment,name varchar(10),primary key(id)) engine=innodb;
-- 写入数据
insert into t(name) values ('a');

シーンワン

セッション1 セッション2
ビュートランザクション分離レベル @@ session.tx_isolationを選択します。
@@ session.tx_isolationを選択します。
ビューデータ ID = 1トンSELECT * FROM。
ID = 1トンSELECT * FROM。
オープン情勢 ベギン; ベギン;
セッション1の更新データ ID = 1更新Tセット名= 'B';
ビューデータ ID = 1トンSELECT * FROM。
ID = 1トンSELECT * FROM。
セッション1つのトランザクションのコミット コミット;
第2セッションビューのデータ ID = 1トンSELECT * FROM。
セッション2つのトランザクションのコミット コミット;

シーンII

セッション1 セッション2
ビュートランザクション分離レベル @@ session.tx_isolationを選択します。
@@ session.tx_isolationを選択します。
ビューデータ ID = 1トンSELECT * FROM。
ID = 1トンSELECT * FROM。
オープン情勢 ベギン; ベギン;
セッション1の更新データ 更新Tセット名= ID = 1 'C'。
ビューデータ ID = 1トンSELECT * FROM。
セッション1つのトランザクションのコミット コミット;
第2セッションビューのデータ ID = 1トンSELECT * FROM。
セッション2つのトランザクションのコミット コミット;

シーンの一つ、二つセッション1のそれぞれのデータを変更することができ、トランザクション分離レベルが反復可能読み取り(反復可能読み取り)であるセッション2リード、シーンへの2つのセッション1変更されたデータを読み取り、
それはビットが混乱しないのですか?これは上にある、これはシーン1であるMVCC実装により、異なるシーン1、2を見て、MySQLの一貫非ロック読み取りと呼ばれ、トランザクションの後にセッション1シーン二セッション2のトランザクションを送信する前にデータを読み取ることはありません発見された、2つの結果がありません理由は同じ(つまり、データのバージョンを選択)。

一貫性は、非ロックマルチバージョン管理の方法により、データベース内のデータ行の現在の実行時間を読み取るためにInnoDBストレージエンジンを読み取ることをいいます。行がDELETEまたはUPDATE操作を読んで実行している場合は、この時点では読み出し動作が行のロックを待機するためにリリースされることはありません。逆に、データInnoDBストレージエンジンのスナップショットは、行を読み取ります。

一致性非锁定读之所以成为非锁定读,因为不需要等待访问数据行的X锁的释放。快照数据是指该行数据的之前版本,改实现通过undo log完成。而undo是用来事务回滚的数据,因此快照数据本身没有额外的开销;此外快照数据不需要上锁,因为没有事务需要对历史数据进行修改操作。

一致性非锁定读机制极大的提高了数据库的并发性。在InnoDB存储引擎的默认设置下,这个默认的读取方式,即读取不会占用和等待表上的锁(SELECT ... FOR UPDATE/SELECT ... LOCK IN SHARE MODE除外);一致性行非锁定读,用到到数据的之前的历史版本,可能会有多个历史版本,由此带来的并发控制,就是大名鼎鼎的多版本并发控制(MVCC)

因为MYSQL数据库InnoDB存储引擎支持4中事务隔离级别,并不是每个事务隔离级别都采用一致性非锁定读。
在事务隔离级别已提交读(Read committed)、可重复读(Repeatable read InnoDB存储引擎默认的事务隔离级别)下,InnoDB存储引擎采用一致性非锁定读。

  • 已提交读(Read committed):每次普通的SELECT(非SELECT ... FOR UPDATE/SELECT ... LOCK IN SHARE MODE)都会读取数据的最新行版本(每次创建最新快照read view)。
  • 可重复读(Repeatable read):事务开启后第一次普通的SELECT(非SELECT ... FOR UPDATE/SELECT ... LOCK IN SHARE MODE)读取最新行版本(第一次创建快照,以后沿用read view)。

对于Innodb存储引擎的聚集索引即数据行存在2个隐藏的列tx_id事务id、roll_pointer回滚指针,tx_id用来一致性非锁定读判断数据是否可见,roll_pointer用于事务回滚(指向数据的上一个版本);undo log中存在数据的版本链

tx_id事务id全局自增

对于ReadView的实现:ReadView创建是根据当前活跃事务的列表,生成一个ReadView数据结构,包含当前所有活跃的事务id的ids集合、maxId最大事务id、minId最小事务id;

当读取数据时,数据行的事务id为tx_id

  • tx_id大于ReadView的maxId,则表示此tx_id的事务在生成ReadView之后开启的,数据的当前版本不可见
  • tx_id<ReadView的minId,则表示此tx_id的事务在生成ReadView之前开启并提交的,数据的当前版本可见
  • tx_id处于minId与maxId之间的,需判断tx_id是否在ids里,在则数据的当前版本不可见,不在则数据的当前版本可见

上面简述了ReadView的原理和在事务隔离级别已提交读(Read committed)、可重复读(Repeatable read)的生成策略;接下来回顾一下本文开始的场景;

  • 场景一,session2的事务隔离级别为可重复读,ReadView在第一次SELECT时创建,此时session1的事务已开启且尚未提交处于活跃状态;ReadView中ids含session1的tx_id,在之后读取的时复用ReadView(ids含session1的tx_id),即使session1的事务提交后,session1修改的数据仍不可见。
  • 场景一,session2的事务隔离级别为可重复读,ReadView在第一次SELECT时创建,此时session1的事务已提交;ReadView中ids不含session1的tx_id,session1修改的数据可见。

本文简单简单描述了一下MySQ InnoDB存储引擎的一致性非锁定读以及实现原理,因本人能力有限,如有不妥之处请多多指教。

おすすめ

転載: www.cnblogs.com/sunjingwu/p/12386660.html