mysql 雙寫 double write

os: centos 7.4
db: mysql 5.7.28

版本

# cat /etc/centos-release
CentOS Linux release 7.4.1708 (Core) 
# 
# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.7.28 MySQL Community Server (GPL)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.28    |
+-----------+
1 row in set (0.00 sec)

mysql> 

partial page write

innodb 的 page size 一般是16KB,其數據校驗也是針對這 16KB 來計算的,將數據寫入到磁盤是以Page爲單位進行操作的。
而計算機硬件和操作系統,在極端情況下(比如斷電)往往並不能保證這一操作的原子性,16K的數據,寫入4K 時,發生了系統斷電/os crash ,只有一部分寫是成功的,這種情況下就是 partial page write 問題。
如果使用 mysql redolog 進行恢復時,就會檢查 page 的 checksum(checksum 就是page的最後事務號),但是發生 partial page write 問題時,page已經損壞,找不到該page中的事務號,就無法恢復。

double write

這裏需要提一下共享表空間,是在 ibdbata 文件中劃出2M連續的空間,專門給 double write 刷髒頁用的,說白了就是磁盤上2MB(128個頁,2個區)連續空間。

mysql 爲什麼需要 double write,刷一次數據文件保存數據不就行了。

主要還是爲了解決極端情況下的 partial page write 問題 ,當 mysql 將髒數據 flush 到 data file 的時候, 先使用 memcopy 將髒數據複製到內存中的 double write buffer ,之後通過 double write buffer 再分2次,每次寫入1MB到共享表空間,然後馬上調用fsync函數,同步到磁盤上,避免緩衝帶來的問題,在這個過程中,doublewrite是順序寫,開銷並不大,在完成doublewrite寫入後,在將double write buffer寫入各表空間文件,這時是離散寫入。
如果發生了極端情況(斷電),InnoDB再次啓動後,發現了一個Page數據已經損壞,那麼此時就可以從 doublewrite buffer 中進行數據恢復了。

默認 double write 是開啓的,可以手動修改參數,禁止 double write

mysql> show global variables like '%double%';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| innodb_doublewrite | ON    |
+--------------------+-------+
1 row in set (0.01 sec)

查看 status double write

mysql> show status like  "%InnoDB_dblwr%";
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Innodb_dblwr_pages_written | 2     |
| Innodb_dblwr_writes        | 1     |
+----------------------------+-------+
2 rows in set (0.00 sec)

double write 的缺點
位於共享表空間上的double write buffer實際上也是一個文件,寫DWB會導致系統有更多的fsync操作, 而硬盤的fsync性能, 所以它會降低mysql的整體性能. 但影響並不是特別的大, 這主要是因爲:
1、double write 是一個連接的存儲空間, 所以硬盤在寫數據的時候是順序寫, 而不是隨機寫, 這樣性能更高.
2、將數據從double write buffer寫到真正的 segment 中的時候, 系統會自動合併連接空間刷新的方式, 每次可以刷新多個pages;

參考:

發佈了732 篇原創文章 · 獲贊 70 · 訪問量 51萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章