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