MySQLの総務原則

MySQLの総務原則

トランザクションとは何ですか

トランザクションとは何ですか?トランザクションは、SQLの集合である行う作業の単一の論理ユニット、ユーザーフレンドリー、などの一連の動作は、原子を照会されます。デフォルトのMyISAMエンジンはInnoDBのを交換した後、MySQL用の最も基本的な理由でのInnoDBのサポートは、5.5.5ながら、ストレージエンジンでのMySQLのサポートトランザクション層は、MyISAMストレージエンジンは、トランザクションをサポートしていません。

トランザクションのACID特性

アトミック(原子性):作業の論理単位として、トランザクションはすべての操作で行われ、いずれかのすべてが成功するか、すべて失敗しています。

一貫性(一貫性):1つの一貫性のある状態から別の一貫性のあるデータベースの状態変更は、データベースの整合性が損なわれることはありません。

絶縁(アイソレーション):一般的に言えば、企業は最終提出前に変更を加え、他のトランザクションは表示されません。なぜ一般的な、次のセクションを特に参照すると、異なる同時トランザクション分離レベルの抽出を改善するためです。

(耐久性)永続:トランザクションがコミットされると変更し、それもシステム障害が発生した場合、変更されたデータが失われることはありません、永続的にデータベースに保存行われます。

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

高並行性を最大化するために、トランザクション分離は、4つのレベルに分かれていますコミットされていない、読んでコミットし、反復可能読み取りとシリアライズをお読みください。ユーザーは必要に応じて異なるレベルを選択することができます。

非コミット読み取り(UNCOMMITTEDをREAD):トランザクションが提出されていない、他の事項を変更することがわかります。

例:トランザクションは、Bが変更されたがコミットされていないデータのトランザクションを読み取ることができます(提出が失敗した後、データがトランザクション汚い読み込まれ、おそらくトランザクションB)ダーティリードにつながります。

(COMMITTED READ)コミット読む:トランザクションがコミットした後、その変更が他のトランザクションによって見ることができます。デフォルトレベルほとんどのデータベースシステムではなく、MySQLの。

例:トランザクションがデータだけを読み、修正Bを提出することができ、トランザクションは、非反復一回のトランザクションで、2回のクエリのトランザクション内の読み取り(コミットプロセスB、取引後に提出さBの原因となります、2が発生します)矛盾した結果を読み込みます。

反復可能読み取り(REPEATABLE READ):読み取り結果の間に1トランザクション数回は、同じレコードと一致している間、コミットされていないトランザクションを変更するには、他のトランザクションによって見ることができません。例:特定の範囲内の記録の実行中に複数回のトランザクションの取得は、挿入またはこの範囲内のトランザクションBのNレコードを削除の提出後に、中時間の範囲は、一貫性のないトランザクションの実行、すなわち、ファントム読み取り(MySQLを読み取りますMVVCによってデフォルトレベル、InnoDBはファントム読みの問題を解決します)。

シリアライゼーション(SERIALIZABLE)が2点のリードとの間に矛盾があり、シリアル実行を強制ロックすることにより、トランザクション、データベーストランザクションを記述する場合、(ダーティ・リード、非反復リード、ファントムリード)前述の全ての問題を解決します。分離は、分離の最高レベルです。

テーブルには、より明確に定義し、可能性のある問題の4つの分離レベルを記述することができます。

 

これらは、定義されており、4つの分離レベルの予備的な理解されている「 トランザクション分離レベルのMySQLの4種類を知るために10分  、」動的なグラフの記事は完全に分離レベルを理解することができます。

 

トランザクションでのMySQL

1、トランザクションが自動的に送信され

MySQLのデフォルトの自動提出(AUTOCOMMIT)モード、それはあなたが明示的にトランザクションを開始しない場合は、と言うことです、各クエリがトランザクションとして処理され、操作をコミットします。MySQLは自動的に開き、次のコマンドを送信する場合は、見ることができます

mysql> show variables like 'AUTOCOMMIT';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.01 sec)
--1 或者 ON 表示启用, 0 或者 OFF 表示禁用
mysql> SET AUTOCOMMIT = 0/1; 
--以上命令可以打开和关闭自动提交

図1に示すように、グローバルコンフィギュレーションファイルの発効のために必要であれば、自動コミット= 0は、現在のセッションの自動送信をオフセットは、その後、修正されなければなりません。

2は、それがトランザクションを終了するために、COMMITまたはROLLBACKコマンドに出会うまで、自動的に提出した後、すべてのユーザーが同じトランザクション内の文をDMLますシャットダウンします。

可動図2点上述します:

 

 

もちろん、ユーザーが表示またはトランザクション開始トランザクションを開き始めることができます。**オープン情勢は= 0自動的に設定オートコミットを実行され、トランザクションの終了は、自動コミット= 1をコミットまたはロールバックした後に設定し実行を示しています。次のように**より多くのトランザクション制御文は、次のとおりです。

START TRANSACTION | BEGIN: 显式地开启一个事务;
COMMIT:也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改成为永久性的;
ROLLBACK:也可以使用 ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;
SAVEPOINT identifier:SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT;
RELEASE SAVEPOINT identifier:删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;
ROLLBACK TO identifier:把事务回滚到标记点;
SET TRANSACTION:用来设置事务的隔离级别。

2、トランザクション分離レベル

最も人気のある非InnoDBストレージエンジンのMySQLのサポートサービスは、InnoDBのの、以下基づいているMySQLの分離レベルに他なりません。

1、查看InnoDB存储引擎系统级的隔离级别和会话级的隔离级别,命令和结果如下:

mysql> select @@global.tx_isolation,@@tx_isolation;
+-----------------------+-----------------+
| @@global.tx_isolation | @@tx_isolation  |
+-----------------------+-----------------+
| REPEATABLE-READ       | REPEATABLE-READ |
+-----------------------+-----------------+

2、设置InnoDB存储引擎隔离级别:

语句:

set [ global | session ] transaction isolation level Read uncommitted | Read committed | Repeatable | Serializable; 

示例:

mysql> set session  transaction isolation level Serializable;
Query OK, 0 rows affected (0.01 sec)

mysql> select @@global.tx_isolation,@@tx_isolation;
+-----------------------+----------------+
| @@global.tx_isolation | @@tx_isolation |
+-----------------------+----------------+
| REPEATABLE-READ       | SERIALIZABLE   |
+-----------------------+----------------+
1 row in set (0.00 sec)

3、事务的 MVCC 机制

Mysql 的事务型存储引擎(InnoDB)使用 MVCC(Multi-Version Concurrency Control,多版本并发控制)代替行级锁来提高并发读写的性能。InnoDB 的 MVCC 原理比较简单,它通过在在每行记录后面保存三个隐藏列(事务 id,行的创建的版本号、行的过期版本号)来实现的,下面是 InnoDB 在 REPEATABLE READ 隔离级别下 MVCC 的简化工作原理:

INSERT: InnoDB 为新插入的每一行保存当前系统版本号作为行版本号。

UPDATE: InnoDB为插入一行新记录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识。

DELETE: InnoDB为删除的每一行保存当前系统版本号作为行删除标识。

SELECT: InnoDB会根据以下两个条件检查每行记录:

  • InnoDB只查找版本早于当前事务版本的数据行(也就是,行的系统版本号小于或等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的。
  • 行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。

只有符合上述两个条件的记录,才能返回作为查询结果。

下面用更浅显易懂的例子说明 MVCC 下的 INSERT/DELETE/UPDATE/SELECT 操作: 假如 test 表有两个字段 name 和 age;MVCC 的三个隐藏列字段名为 transaction_id、 create_version 和 delete_version。

insert

 
update 
 
delete
 
select 满足以下两个条件的记录才能被 select 读取出来:
  • delete_version 未定义或者大于 select 所在事务的 delete_version 的行。
  • create_version 小于或等于 select 所在事务的的 create_version。

通过这个例来看下为什么 MVCC 在 REPEATABLE READ 隔离级别下能解决幻读。假如有个事务开始于 update 之后 delete 之前,且结束于 delete 之后,如下:

start transaction;  //假如事务 id = 2.5
select * from test; //执行时间在 update 之后 delete 之前
select * from test; //执行时间在 delete 之后
commit;

如果不使用 MVCC 第一条 select * from test 能读到 1 条记录,而 第二条将读取到 0 条记录,同一事务中多次 select 范围查询读取到的记录不一致即幻读。而使用 MVVC 之后,两条 select 语句读取到的记录相同。

MVCC 只在 REPEATABLE READ 和 READ COMMITTED 两个隔离级别下工作。其他两个隔离级别都和MVCC不兼容,因为 READ UNCOMMITTED 总是读取最新的数据行,而不是符合当前事务版本的数据行。而 SERIALIZABLE 则会对所有读取的行都加锁。

4、事务的实现(redo/undo log)

事务的隔离性通过锁或 MVCC 机制来实现,而原子性、持久性和一致性通过 redo/undo log 来完成。redo log 称为重做日志,用来保证事务的原子性和持久性。undo log 称为撤销日志,用来保证事务的一致性。

1、redo log

基本概念

重做日志用来实现事务的持久性,由以下两部分组成:

  • 重做日志缓冲区(redo log buffer),内存中,易丢失。
  • 重做日志文件(redo log file),磁盘中,持久的。

redo log file 是顺序写入的,在数据库运行时不需要进行读取,只会在数据库启动的时候读取来进行数据的恢复工作。 redo log file 是物理日志,所谓的物理日志是指日志中的内容都是直接操作物理页的命令。重做时是对某个物理页进行相应的操作。

整体流程

更新事务操作一次数据的流程图如下所示:

 

 

  • 第一步:先将原始数据从磁盘中读入内存中来,修改数据的内存拷贝。

  • 第二步:生成一条重做日志并写入redo log buffer,记录的是数据被修改后的值。

  • 第三步:在必要的时候,采用追加写的方式将 redo log buffer 中的内容刷新到 redo log file。

  • 第四步:定期将内存中修改的数据刷新到磁盘中。

以上比较重要的是第三步,其中必要的时候有以下几种情况:

  • 事务提交时(最常见的情景,在 commit 之前)
  • 当 log buffer 中有一半的内存空间被使用时
  • log checkpoint 时
  • 实例 shutdown 时
  • binlog切换时
  • 后台线程

写入策略

学过 linux 操作系统的都知道内存中数据写入到磁盘文件中时如果不打开 O_DIRECT 选项。数据是要先写入文件操作系统缓存区中的,然后再某个时刻 flush 到磁盘。流程如下:

 

 

事务提交时将 redo log buffer 写入 redo log file,为了保证数据一定能正确同步到磁盘(不仅仅只写到文件缓冲区中)文件中,InndoDB 默认情况下调用了 fsync 进行写操作。而 fsync 的性能比较低。当然这只是默认情况,InnoDB 也提供了参数 innodb_flush_log_at_trx_commit 来配置 redo log 刷新到磁盘的策略,有以下三个值:

  • 当设置该值为 1 时,每次事务提交都要做一次 fsync,这是最安全的配置,即使宕机也不会丢失事务;
  • 当设置为 2 时,则在事务提交时只做 write 操作,只保证写到系统的缓冲区,因此实例crash不会丢失事务,但宕机则可能丢失事务;
  • 当设置为 0 时,事务提交不会触发 redo 写操作,而是留给后台线程每秒一次的刷盘操作,因此实例 crash 将最多丢失一秒钟内的事务。

用下图可以更直观的说明 innodb_flush_log_at_trx_commit 不同值下的不同策略。操作越接近磁盘性能越低,当然可靠性越来越高。故性能:1 < 2 < 0,可靠性:0 < 2 < 1。

当 innodb_flush_log_at_trx_commit 设置为 0 或者 2 时丧失了事务的 ACID 特性,通常在日常环境时将其设置为 1,而在系统高峰时将其设置为 2 以应对大负载。

 

恢复

InnoDB 引擎启动时不管上次数据库运行时是否正常关闭,都会尝试进行恢复操作。整个恢复操作有如下特点:

  • 从 checkpoint 开始的日志部分进行恢复。
  • 顺序读取及并行应用重做日志。
  • 重做日志的应用具有幂等性。
  • 重做日志是物理日志,恢复的速度相对较快。
2、undo log

基本概念

  • undo log 用来实现事务的一致性,InndoDB 可以通过 redo log 对页进行重做操作。但是有时候事务需要进行回滚,这时就需要 undo log。
  • undo log 还可可以用来协助 InnoDB 引擎实现 MVCC 机制。
  • undo log 是逻辑日志,恢复时并不是对物理页直接进行恢复,而是逻辑地将数据库恢复到原来的样子。
  • undo log 的产生也会伴随着 redo log 的产生。

写入时机

事务开始之前,流程如图:

 

日志格式

 

在 InnoDB 中 undo log 分为 insert undo log 和 update undo log

insert undo log

insert 操作产生的日志。根据隔离性,insert 插入的记录只对本事务可见,所以事务提交后可以删除因 insert 产生的日志。

update undo log

delete 和 update 操作产生的日志。根据前面的 MVCC 机制可以知道此部分记录还有可能要被其他事务所使用,所以即使事务提交也不能删除相应的日志。在事务提交时会被保存到 undo log 链表,在 purge 线程中做最后的删除。

3、redo 与 undo log 记录过程

undo 记录更新之前的日志,为了回滚。 redo 记录更新之后的日志,为了重做。 redo log 与 undo log 产生过程的简化版本如下,可以更方便的理解 redo 与 undo 的区别。

假设有A,B两个数据,原值分别为 1, 2;现将A更新为10,B 更新为 20;undo log记录信息过程如下:
1. 事务开始 2. 记录 A = 1 到 undo log 3. 更新 A = 10 4. 记录 A = 10 到 redo log 5. 记录 B = 2 到 undo log 6. 更新 B = 20 7. 记录 B = 20 到 redo log 8. redo log 信息写入磁盘 9. 提交事务

おすすめ

転載: www.cnblogs.com/weilingfeng/p/11531528.html