データベースのトランザクション銀行間取引モデルシリーズ-MySQL

MySQLは言うことと、実際に宛てた、卒業生の最初の仕事は、クラウド上のMySQLデータベースサーバーの責任を作っ取得するには、RDSのチームに割り当てられました。一日とMySQLとの契約が、しかし、時間が非常にMySQLのカーネルの深い理解できなかった、基本的な管理および制御システムは、MySQLを中心にやっているんことを正直に言うと、トップを比較します。幸いなことに、神のMySQLのカーネル階級の人々に囲まれて、多かれ少なかれ、いくつかの断片的な記録とその影響下のMySQLのいくつかの基本的な知識の漠然とした理解があり、これらの基盤は、今日の銀行間取引モデルを仕上げのMySQLを理解するために非常に重要です。さらに重要なことは、多くの不可解な場所でも偉大な神に向けることができますがあります。

MySQLのトランザクション・モデルは、この記事を書く前に、私はまた、より詳細なと包括的に理解し、自分自身を作るために、参照として多くの情報を見て、多くのオンライン導入があります。記事を読むことの記事で見られるほとんどの部分が完了していない説明した後、例えば、いくつかは、いくつかのMySQLのパフォーマンスで分離レベルを説明し、技術的な観点から解釈しませんでした。いくつかの記事は本当に丸いだろうと言うが、少し混乱した読み取りを理解することは容易ではない欠けています。これは私が解釈の技術的な観点から、あなたに別の何かを持って来たいと思った時点で、理解することは有益。

MySQLのトランザクションの原子性を保証

アトミックトランザクションは、どちらかの完成されたトランザクションにおける一連の操作を必要とする、または半分しかない、何もしません。中国のHBaseの銀行業務原子レベルの実装は比較的単純であるようアトミックアトミック操作は、実装するのは非常に簡単です。しかし、例外がトランザクションの実行中に発生した場合、複数の文からなる取引のために、原子性を確保する必要が唯一、バックトランザクションの開始前の状態にロールバックをロールバックすることができ、トランザクションはこれが起こっていなかったように。どのようにそれを達成するには?

ロールバック操作は完全にものを言う、アンドゥログに依存して、アンドゥMySQLのアトミック性の保証に加えてログインするだけでなく、MVCCを実装するために、以下も関与達成MYSQL。最初のデータレコードの前に、任意のデータの前に元に戻す操作の原子は、次いで実際の変更、アンドゥログに変更されます。あなたが戻って異常なロールする必要がある場合は、トランザクションがバックアップ元に戻すを使用し始めた前に、システムはその状態にデータをリストアすることができます。フィールドがアンドゥinsert_undoとupdate_undo、この会社によって生成されるログ元に戻す点に関連している、請求のMySQLは、トランザクション図基本的なデータ構造で表現されます。

データベースのトランザクション銀行間取引モデルシリーズ-MySQL

ロールバックトランザクションupdate_undo(またはinsert_undo)、対応するアンドゥログを見つけるために、逆の操作を行うこと。削除データフラグを洗浄するために、削除のために直接ロールバック更新するための更新データをマークされている、データを削除するには、だけでなく、関連するレコードのクラスタ化インデックスとセカンダリインデックスを削除するだけではなく、少し複雑挿入します。

:アンドゥログは、次のような、より多くの知識と複合体を含む、コンテンツMySQLのカーネルの非常に重要な部分です

  • 1.アンドゥログには、レコードのREDO持続性やダウンタイムの異常を防止する必要がログUNDO、データ変更の前に存続しなければなりませんか?あなたがそれを必要とする場合も、ダウンタイムの回復を必要とします...

  • 2.どのようにアンドゥログでMVCCを実装するには?

  • 3.これらのアンドゥ・ログには、どのようなシナリオクリーン下にリサイクルすることができますか?どのようにきれいにするには?

一貫性の強い取引の保証:トランザクションの一貫性を確保するためのMySQL

MySQLのトランザクション分離レベル


READ UNCOMMITTED(RU解釈技術:同時実行のためのX-書き込みロック)

READ UNCOMMITTEDにのみ書き込み同時実行制御を実現し、かつ効果的な読み取りと書き込みの同時実行制御はありません、現在のトランザクションにつながる他のトランザクションで変更データを読み取ることが提出されていない、これらのデータの精度が信頼できない(可能性の高いバックをロールさせます)、これに基づいて作られたので、すべての前提条件は飛ばないだろう。実際には分離レベルを選択するいくつかのビジネスシナリオがあります。

同時実装機構を書くのHBaseは、我々は、各記録プラス行ロックするための2つのフェーズロック・プロトコルを使用している、違いはありません。しかし、MySQLのBOCロック機構は、行の主キーインデックス、インデックスのみ非一意のインデックスまたは全くインデックスは、複数のロック状況に分けるかどうかに応じて、より複雑です。

  • 1. ID列が主キー索引の場合、MySQLはインデックスのみのレコードロックをクラスタ化します。

  • 2. idカラムがユニークセカンダリインデックスである場合、MySQLは二次インデックスのリーフノードとクラスタ化インデックスレコードロックを提供します。

  • 3.非一意のインデックスID列場合、MySQLは全ての条件(ID = 15)と二次索引クラスタ化インデックスレコードロックに対応するリーフノードを満足します。

  • 4.何のidカラムがインデックス化されていない場合、SQLクラスタ化インデックスは、全表スキャンがかかりますし、SQL Serverの層ならば、すべてのレコードがInnoDBは、一緒にロックするためにスキャンされますので、スキャン結果は、SQL Serverのフィルタ層にロードされますフィルタリング条件を満たしていない、InnoDBがロックを解除します。したがって、InnoDBは、怖い、すべてのレコードがロックされているスキャンするってことでしょう!

その後RC、RR、またはそれがシリアル化され、両方のは、書き込みの同時実行制御メカニズムは、上記を使用し、それはそれらを繰り返すことはしません。次の分析は、同時実行制御機構RCおよびRR分離レベルを読み書きに焦点を当てます。

RCとRRの詳細前に、RCとRRは、同時読み取りと書き込みトランザクション間MVCCメカニズムを使用しているので、MVCC機構では、この最初のMySQLを導入する必要があります。実装の詳細、あなたの話で唯一の2つの違いは、次の具体的な違いがあります。

MySQLでMVCC

MVCC機構においてMySQLは、データ構造がより複雑な関係、HBaseのに比べてはるかに複雑です。説明するためにテンプレートとして栗で、比較的明確に説明するために。下に示したように、現在のレコードのような行があります:

データベースのトランザクション銀行間取引モデルシリーズ-MySQL

フロント4行の実際の列の値である、に焦点を当てる必要がDB_TRX_IDとDB_ROLL_PTR 2つの隠された列(ユーザーには見えない)です。前記DB_TRX_IDライントランザクションを変更むしろDB_ROLL_PTR行ロールバックへのポインタを表し、トランザクションIDを表し、アンドゥリストの行上のデータのすべてのバージョンは、実際の点の列でアンドゥ履歴値によって編成されレコードのリスト。

今すぐ取引TRX2は、行データが変更されていると、銀行のレコードは、次のグラフィックに変更されます、DB_TRX_IDが最後に変更されたことアンドゥ履歴リストにライントランザクションのトランザクションID(TRX2)、DB_ROLL_PTRのポイント:

データベースのトランザクション銀行間取引モデルシリーズ-MySQL

MySQLの行の理解、取引の基本的な構造で見てみましょうには、次の図では、我々は上述したように、MySQLのトランザクションデータ構造です。トランザクションはオープン、ロック情報、アンドゥログと非常に重要なread_view情報の後にトランザクション関連情報を格納するためのデータ構造を作成します。

現在のトランザクションのオープンは、時間現在のトランザクションのオープンで、システムがアクティブなトランザクションTRX4、trx6、trx7とtrx10を持っていたときに示すようにread_view MySQLは、すべてのアクティブなトランザクションのリスト全体を保存します。さらに、up_trx_idは、現在のトランザクションの開始、トランザクションリスト最小の現在のトランザクションIDを表し、low_trx_idは、現在のトランザクションの開始、トランザクションリスト最大の現在のトランザクションIDを表します。

データベースのトランザクション銀行間取引モデルシリーズ-MySQL

MVCCは、可視現在のトランザクションのレコードのバージョンを決定するために使用されるキーポイント、ある実施read_view。現在のトランザクションがその行のレコード、trxidの行のバージョン番号(トランザクションID)を読み取る場合:

  • 1. 如果trxid < up_trx_id,说明该行记录所在的事务已经在当前事务创建之前就提交了,所以该行记录对当前事务可见。

  • 2. 如果trxid > low_trx_id,说明该行事务所在的事务是在当前事务创建之后才开启,所以该行记录对当前事务不可见。

  • 3. 如果up_trx_id < trxid < low_trx_id, 那么表明该行记录所在事务在本次新事务创建的时候处于活动状态。从up_trx_id到low_trx_id进行遍历,如果trxid等于他们之中的某个事务id的话,那么不可见,否则可见。

以下面行记录为例,该行记录存在多个版本(trx2、trx5、trx7以及trx12),其中trx12是最新版本。看看该行记录中哪个版本对当前事务可见。

  • 1. 该行记录的最新版本为trx12,与当前事务read_view进行对比发现,trx12大于当前活跃事务列表中的最大事务trx10,表示trx12是在当前事务创建之后才开启的,因此不可见。

  • 2. 再查看该行记录的第二个最新版本为trx7,与当前事务read_view对比发现,trx7介于当前活跃事务列表最小事务ID和最大事务ID之间,表明该行记录所在事务在当前事务创建的时候处于活动状态,在活跃列表中遍历发现trx7确实存在,说明该事务还没有提交,所以对当前事务不可见。

  • 3. 继续查看该记录的第三个最新版本trx5,也介于当前活跃事务列表最小事务ID和最大事务ID之间,表明该行记录所在事务在当前事务创建的时候处于活动状态,但遍历发现该版本并不在活跃事务列表中,说明trx5对应事务已经提交(注:事务提交时间与事务编号没有任何关联,有可能事务编号大的事务先提交,事务编号小的事务后提交),因此trx5版本行记录对当前事务可见,直接返回。

データベースのトランザクション銀行間取引モデルシリーズ-MySQL


Read Committed(技术解读:写写并发使用X锁,读写并发使用MVCC避免脏读)

上文介绍了MySQL中MVCC技术实现机制,但要明白RC隔离级别下事务可见性,还需要get一个核心点:RC隔离级别下的事务在每次执行select时都会生成一个最新的read_view代替原有的read_view。

データベースのトランザクション銀行間取引モデルシリーズ-MySQL

如上图所示,左侧为1号事务,在不同时间点对id=1的记录分别查询了三次。右侧为2号事务,对id=1的记录进行了更新。更新前该记录只有一个版本,更新好变成了两个版本。

1号事务在RC隔离级别下每次执行select请求都会生成一个最新的read_view,前两次查询生成的全局事务活跃列表中包含trx2,因此根据MVCC规定查到的记录为老版本;最后一次查询的时间点位于2号事务提交之后,因此生成的全局活跃事务列表中不包含trx2,此时在根据MVCC规定查到的记录就是最新版本记录。

Repeatable Read(技术解读:写写并发使用X锁,读写并发使用MVCC避免不可重复读;当前读使用Gap锁避免幻读)

和RC模式不同,RR模式下事务不会再每次执行select的时候生成最新的read_view,而是在事务第一次select时就生成read_view,后续不会再变更,直至当前事务结束。这样可以有效避免不可重复读,使得当前事务在整个事务过程中读到的数据都保持一致。示意图如下所示:

データベースのトランザクション銀行間取引モデルシリーズ-MySQL

这个就很容易理解,三次查询所使用的全局活跃事务列表都一样,且都是第一次生成的read_view,那之后查到的记录必然和第一次查到的记录一致。

RR隔离级别能够避免幻读吗?

如果对幻读还不了解的话,可以参考该系列的第一篇文章。如下图所示,1号事务对针对id>1的过滤条件执行了三次查询,2号事务执行了一次插入,插入的记录刚好符合id>1这个条件。可以看出来,三次查询得到的数据是一致的,这个是由RR隔离级别的MVCC机制保证的。这么看来,是避免了幻读,但是在最后1号事务在id=2处插入一条记录,MySQL会返回Duplicate entry的错误,可见避免了幻读是一种假象。

データベースのトランザクション銀行間取引モデルシリーズ-MySQL

严格意义避免幻读(技术解读:当前读使用Gap锁避免幻读)

之前提到的所有RR级别的select语句我们称为快照读,快照读能够保证不可重复读,但并不能避免幻读。于是MySQL又提出”当前读”的概念,常见的当前读语句有:

1.  select for update

2.  select lock in share mode

3.  update / delete

并且规定,RR级别下当前读语句会给记录加上一种特殊的锁-Gap锁,Gap锁并不锁定某个具体的记录,而是锁定记录与记录之间的间隔,保证这个间隔中不会插入新的其他记录。下图是一个示意图:

データベースのトランザクション銀行間取引モデルシリーズ-MySQL

上图中1号事务首先执行了一个当前读的select语句,这个语句会在 id > 0的所有间隔加上Gap锁,接下来2号事务在id = 3处执行插入时系统就会返回Lock wait timeout execcded的异常。当然,其他事务可以在id <= 0的条件下插入成功,这没问题。

Serializable (技术解读:S锁(读)+X锁(写))

Serialization隔离级别是最严格的隔离级别,所有读请求都会加上读锁,不分快照读和当前读,所有写会加上写锁。当然,这种隔离级别的性能因为锁开销而相对最差。

MySQL事务持久性保证

MySQL事务持久化策略和HBase基本相同,但是涉及的组件相对比较多,主要有doublewrite、redo log以及binlog:

1. MySQL数据持久化(DoubleWrite)

实际上MySQL的真实数据写入分为两次写入,一次写入到一个称为DoubleWrite的地方,写成功之后再真实写入数据所在磁盘。为什么要写两次?这是因为MySQL数据页大小与磁盘一次原子操作大小不一致,有可能会出现部分写入的情况,比如默认InnoDB数据页大小为16K,而磁盘一次原子写入大小为512字节(扇区大小),这样一个数据页写入需要多次IO,这样一旦中间发生异常就会出现数据丢失。另外需要注意的是DoubleWrite性能并不会影响太大,因为写入DoubleWrite是顺序写入,对性能影响来说不是很大。

2. redolog持久化策略(innodb_flush_log_at_trx_commit)

redolog是InnoDB的WAL,数据先写入redolog并落盘,再写入更新到bufferpool。redolog的持久化策略和HBase中hlog的持久化策略一致,默认为1,表示每次事务提交之后log就会持久化到磁盘;该值为0表示每隔1秒钟左右由异步线程持久化到磁盘,这种情况下MySQL发生宕机有可能会丢失部分数据。该值为2表示每次事务提交之后log会flush到操作系统缓冲区,再由操作系统异步flush到磁盘,这种情况下MySQL发生宕机不会丢失数据,但机器宕机有可能会丢失部分数据。

3. binlog持久化策略(sync_binlog)

binlog作为Server层的日志系统,主要以events的形式顺序纪录了数据库的各种操作,同时可以纪录每次操作所花费的时间。在MySQL官方文档上,主要介绍了Binlog的两个最基本核心作用:备份和复制,因此binlog的持久化会一定程度影响数据备份和复制的完整性。和redo持久化策略相同,可取值有0,1,N。默认为0,表示写入操作系统缓冲区,异步flush到磁盘。该值为1表示同步写入磁盘。为N则表示每写N次操作系统缓冲就执行一次刷新操作。

要約すると、これは、より詳細な説明については、ロック分離技術が関与する単一コアのMySQL銀行間取引モデル、MVCCメカニズムを導入データベーストランザクションの第三のシリーズは、です。アトミック性、耐久性、また、簡単な分析と説明の関連する特性。そして、それは、分散トランザクションモデルについて話を一緒に皆を取り、最終的には、スタンドアローンのトランザクション・モデル間のどのような違いが表示されます。

おすすめ

転載: blog.51cto.com/14230003/2448194
おすすめ