START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */

   在使用mysqldump 进行数据库备份的时候,如果我们指定了--single-transaction参数。我们在generallog中会有如下输出:

160203  9:51:59    63 Connect   root@localhost on
                   63 Connect   Access denied for user 'root'@'localhost' (using password: YES)
160203  9:52:02    64 Connect   root@localhost on
                   64 Query     /*!40100 SET @@SQL_MODE='' */
                   64 Query     /*!40103 SET TIME_ZONE='+00:00' */
                   64 Query     FLUSH /*!40101 LOCAL */ TABLES  
                   64 Query     <span style="color:#ff0000;">FLUSH TABLES WITH READ LOCK <span style="font-family: Arial, Helvetica, sans-serif;">##这里是因为我们使用了--master-data,所以需要提交一个全局read lock,然后取binlog位置(但该锁会很快释放)</span></span>
                   64 Query     SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ
                   64 Query     <span style="color:#ff0000;">START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */ ##这个是因为我们指定了--single-transaction参数</span>
                   64 Query     SHOW VARIABLES LIKE 'gtid\_mode'
                   64 Query     SHOW MASTER STATUS
                   64 Query     UNLOCK TABLES

  那么START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */ 到底表示什么意思呢?,我们先来看一下官方文档中有关介绍:

在mysql 5.1.13中看到如下信息(从5.1.13开始mysqldump指定--single-transaction备份时使用START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */ 来代替begin 开启一个事物,这样就能在备份的时候产生一个一致的快照)

mysqldump --single-transaction now uses START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */ rather than BEGIN to start a transaction, so that a consistent snapshot will be used on those servers that support it. (Bug #19660)

##这里说使用START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */ 来代替 begin,那么两者的区别是什么呢。请继续往下看

在5.6官方文档中,我们看到如下描述;

With START TRANSACTION, autocommit remains disabled until you end the transaction with COMMIT or ROLLBACK. The autocommit mode then reverts to its previous state.

START TRANSACTION permits several modifiers that control transaction characteristics. To specify multiple modifiers, separate them by commas.

The WITH CONSISTENT SNAPSHOT modifier starts a consistent read for storage engines that are capable of it. This applies only to InnoDB. The effect is the same as issuing a START TRANSACTION followed by a SELECT from any InnoDB table. See Section 14.2.2.2, “Consistent Nonlocking Reads”. The WITH CONSISTENT SNAPSHOT modifier does not change the current transaction isolation level, so it provides a consistent snapshot only if the current isolation level is one that permits a consistent read. The only isolation level that permits a consistent read is REPEATABLE READ. For all other isolation levels, the WITH CONSISTENT SNAPSHOT clause is ignored.
##使用WITH CONSISTENT SNAPSHOT对于支持一致性读的存储引擎表开启一致性读。(目前只有innodb存储引擎支持一致性读)。 START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */  和 START TRANSACTION followed by a SELECT from any InnoDB table的效果是一样的。

##注意with consistent snapshot不会修改当前transaction的 隔离级别,所以只有当当前transaction隔离级别是支持一致性读的时候,with consistent snapshot才能起作用。仅有REPEATABLE READ支持一致性读,对于其他隔离级别的 with consistent snapshot语句会被忽略。(注意oracle rc隔离级别也是支持一致性读的)

  

  下面我们通过两个例子来看一下 start transaction(begin)和start transaction followed by select from any innodb table的区别,看懂他们的区别 你也就知道了START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */ 作用了

1)begin的例子(按时间顺序执行)

1. session1
mysql> select id from test1;
+----+
| id |
+----+
|  1 |
|  4 |
|  7 |
+----+
3 rows in set (0.00 sec)
##表test1中有三条记录

2. session2
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

##使用begin开启一个事物

3. session3
mysql> delete from test1 where id=1;
Query OK, 1 row affected (0.05 sec)

mysql> select id from test1;
+----+
| id |
+----+
|  4 |
|  7 |
+----+
2 rows in set (0.01 sec)
##删除test1表中的一条记录

4. session2
mysql> select id from test1;
+----+
| id |
+----+
|  4 |
|  7 |
+----+
2 rows in set (0.00 sec)
##在session中访问 test1只有两条条记录
##因为session开启一个事物后,并没有访问任何一张innodb表,所以并没有避免幻读


2) start transaction followed by select from any innodb table

1. session1
mysql> select id from test1;
+----+
| id |
+----+
|  1 |
|  4 |
|  7 |
+----+
3 rows in set (0.00 sec)
##表test1中有三条记录

2. session2
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select count(1) from test3;
+----------+
| count(1) |
+----------+
|        2 |
+----------+
1 row in set (0.00 sec)
##开启一个事物,并查询任意一个innodb表

3. session3
mysql> delete from test1 where id=1;
Query OK, 1 row affected (0.05 sec)

mysql> select id from test1;
+----+
| id |
+----+
|  4 |
|  7 |
+----+
2 rows in set (0.01 sec)
##删除test1表中的一条记录

4. session1
mysql> select id from test1;
+----+
| id |
+----+
|  1 |
|  4 |
|  7 |
+----+
3 rows in set (0.00 sec)
##在session中访问 test1依然是三条记录





你可能感兴趣的:(with,consistent,Snap)