Mysql Affairs and principle

Mysql Affairs and principle

What is a transaction

What is a transaction? A transaction is a series of operations as a single logical unit of work performed, user-friendly, that is to a set of SQL queries atoms. Mysql support transaction layer in the storage engine, MyISAM storage engine does not support transactions, while InnoDB support, which is the most fundamental reason for Mysql 5.5.5 after the default MyISAM engine replaced the InnoDB.

ACID properties of transactions

Atomicity (Atomicity): as a logical unit of work, a transaction is performed in all the operations, either all succeed or all fail.

Consistency (Consistency): consistent database state change from one consistent state to another, the integrity of the database will not be damaged.

Isolation (Isolation): Generally speaking, a firm make changes before final submission, other transactions are not visible. Why general, in order to improve the extraction of different concurrent transaction isolation levels, with particular reference to the next section.

Persistent (Durability): Modify Once the transaction is committed, it will be done permanently saved to the database, even if a system failure, the modified data will not be lost.

Transaction isolation level

In order to maximize the high concurrency, transaction isolation is divided into four levels: read uncommitted, read committed, repeatable read and serialization. Users can choose different levels according to need.

Uncommitted read (READ UNCOMMITTED): a transaction has not been submitted, it can be seen to change other matters.

Example: A transaction can read data transaction B modified but not committed, will lead to dirty read (probably Transaction B after submission fails, data is read Transaction A dirty).

Read Committed (READ COMMITTED): After a transaction commits, its changes can be seen by other transactions. The default level most database systems, but not the Mysql.

Example: Transaction A transaction can only read data and submit the modified B, will cause non-repeatable read (in A query transactions performed twice, once in the transaction commit process B, a B submitted after the transaction, will cause the two reading the results inconsistent).

Repeatable read (REPEATABLE READ): Change uncommitted transactions can not be seen by other transactions, while one transaction several times during the reading results are consistent with the same record. Example: A transaction acquisition a plurality of times during execution of recording within a certain range, after submission of inserting or deleting transaction B N records within this range, the range of times during read inconsistently A transaction execution, i.e. phantom read (Mysql the default level, InnoDB by MVVC solve the problem of phantom read).

Serialization (SERIALIZABLE): When there is a conflict between two read and write transactions, database transactions by locking enforce serial execution, solves all the problems mentioned earlier (dirty reads, non-repeatable read, phantom read). Isolation is the highest level of isolation.

A table can more clearly describe the four isolation levels of definition and possible problems:

 

These are defined and a preliminary understanding of the four isolation levels, " ten minutes to get to know MySQL four kinds of transaction isolation level  ," the article in the dynamic graph can completely understand isolation levels.

 

Mysql in the transaction

1, the transaction is automatically submitted

Mysql default automatic submission (AUTOCOMMIT) mode, that is to say, if you do not explicitly begin a transaction, each query is treated as a transaction commit operation. You can see if mysql open automatically submit the following command,

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, the set autocommit = 0 turn off automatic submission of the current session, if needed for entry into force of the global configuration file must then be modified.

2, shut down automatically after submission, all users will DML statements in the same transaction until it encounters COMMIT or ROLLBACK command to end the transaction.

A movable FIG described above two points:

 

 

Of course, users can begin to open display or a transaction start transaction. ** open affairs show will be performed automatically set autocommit = 0, and perform set after the end of a transaction commit or rollback autocommit = 1. ** more transaction control statements are as follows:

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

2, the transaction isolation level

Mysql support services of the most popular non-InnoDB storage engine is none other than, the following are based Mysql isolation level of InnoDB.

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. 提交事务

Guess you like

Origin www.cnblogs.com/weilingfeng/p/11531528.html