mysql> show variables like '%general_log%'; +------------------+--------------------------------------------+ | Variable_name | Value | +------------------+--------------------------------------------+ | general_log | OFF | | general_log_file | /data/mysqldata/3306/general_statement.log | +------------------+--------------------------------------------+ 2 rows in set (0.00 sec)
mysql> set global general_log=on;
[mysql@racnode1 ~]$ /usr/local/mysql/bin/mysqldump -uroot -p'zsd@7101' -S /data/mysqldata/3306/mysql.sock --single-transaction --default-character-set=utf8 zdemo student > /tmp/studentbackup.sql
其中使用了两个参数node
--single-transaction
此选项会将隔离级别设置为:REPEATABLE READ。而且随后再执行一条START TRANSACTION语句,让整个数据在dump过程当中保证数据的一致性,这个选项对InnoDB的数据表颇有用,且不会锁表。可是这个不能保证MyISAM表和MEMORY表的数据一致性。
为了确保使用--single-transaction
命令时,保证dump文件的有效性。需没有下列语句ALTER TABLE, CREATE TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE
,由于一致性读不能隔离上述语句。因此若是在dump过程当中,使用上述语句,可能会致使dump出来的文件数据不一致或者不可用。
如何验证上述的过程呢,能够开启general log看看过程是否如上述所说。mysql
--default-character-set=utf8
导出的dump文件字符集为uft8,检验文件字符集的命令可使用file -i
sql
通用查询日志文件以下:bash
2018-06-18T11:42:31.035205Z 9163 Query /*!40100 SET @@SQL_MODE='' */ 2018-06-18T11:42:31.036090Z 9163 Query /*!40103 SET TIME_ZONE='+00:00' */ 2018-06-18T11:42:31.036905Z 9163 Query /*!80000 SET SESSION information_schema_stats_expiry=0 */ 2018-06-18T11:42:31.037521Z 9163 Query SET SESSION NET_READ_TIMEOUT= 700, SESSION NET_WRITE_TIMEOUT= 700 2018-06-18T11:42:31.038398Z 9163 Query SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ 2018-06-18T11:42:31.038977Z 9163 Query START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */ 2018-06-18T11:42:31.039859Z 9163 Query SHOW VARIABLES LIKE 'gtid\_mode' 2018-06-18T11:42:31.058093Z 9163 Query UNLOCK TABLES 中间日志省略 ...... 2018-06-18T11:42:31.084432Z 9163 Query SAVEPOINT sp 2018-06-18T11:42:31.087632Z 9163 Query show create table `student` 2018-06-18T11:42:31.088094Z 9163 Query SET SESSION character_set_results = 'utf8' 2018-06-18T11:42:31.088407Z 9163 Query show fields from `student` 2018-06-18T11:42:31.092360Z 9163 Query show fields from `student` 2018-06-18T11:42:31.094718Z 9163 Query SELECT /*!40001 SQL_NO_CACHE */ * FROM `student` 2018-06-18T11:42:32.815435Z 9163 Query ROLLBACK TO SAVEPOINT sp 2018-06-18T11:42:32.815546Z 9163 Query RELEASE SAVEPOINT sp
从上述日志分析:
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ 设置隔离级别为REPEATABLE READ
START TRANSACTION 开启了事务
事务的实现是经过InnoDB存储引擎的MVCC机制事项,细节以下:InnoDB是一个多版本控制的存储引擎。它能够对已修改的行保留一个旧版本的数据信息。用于支持事务特性。例如:并发和数据回滚。这个信息保留在数据结构中的表空间中,这个表空间称之为rollback segment回滚段。(在Oracle中也有一种相似的数据结构)。
当事务须要回滚的时候,InnoDB会使用回滚段的信息,用于执行undo操做。对于某一行,InnoDB会用早先版本的信息来保障读一致性(consistent read)。
Undo日志在回滚段(rollback segment)中被分为两部分,一部分叫作插入undo日志(insert undo logs),另一部分叫作更新undo日志(update undo logs)。插入undo日志只用于事务回滚,如事务一旦提交,那么日志就能够被丢弃。更新undo日志用在读一致性,InnoDB会指定一个数据快照,这个快照的构建来自于更新undo日志中数据行的早期版本。经过数据行早期版本的快照来保证读一致性,若是不须要这种事务数据保护的时候,这个日志能够被丢弃。数据结构
SAVEPOINT SP ......中间日志省略... SELECT /*!40001 SQL_NO_CACHE */ * FROM `student` ......中间日志省略... ROLLBACK TO SAVEPOINT sp RELEASE SAVEPOINT sp
能够看到经过REPEATABLE READ事务,保证数据一致性数据,而后
设置保存点sp,当读取了全部数据的快照,就回退这个保存点sp。能够比喻为游戏中存档以后,而后取档备份成一个游戏外的文件,删除这个档。能够看成这个档在这个游戏内不存在。并发
## 会话级当前事务级别 mysql> show variables like '%isolation%'; +-----------------------+-----------------+ | Variable_name | Value | +-----------------------+-----------------+ | transaction_isolation | REPEATABLE-READ | +-----------------------+-----------------+ 1 row in set (0.03 sec) ## 系统全局级当前事务级别 mysql> show global variables like '%isolation%'; +-----------------------+-----------------+ | Variable_name | Value | +-----------------------+-----------------+ | transaction_isolation | REPEATABLE-READ +-----------------------+-----------------+ 1 row in set (0.11 sec) ## 修改全局级事务级别 mysql>set global transaction_isolation='read-committed'
就算修改了全局事务级别,Mysqldump导出时也会设定隔离事务级别为:REPEATABLE READ。用于保证数据的读一致性。版本控制
[mysql@racnode1 tmp]$ file -i studentbackup.sql studentbackup.sql: text/plain; charset=utf-8