文章目錄
MySql的物理結構
- MySQL是通過文件系統對數據和索引進行存儲的。
- MySQL從物理結構上可以分爲日誌文件和數據索引文件。
- MySQL在Linux中的數據索引文件和日誌文件都在/var/lib/mysql目錄下。
- 日誌文件採用順序IO方式存儲、數據文件採用隨機IO方式存儲。
日誌文件
日誌文件分爲
- 錯誤日誌(errorlog)
- 二進制日誌(bin log)
- 通用查詢日誌(general query log)
- 慢查詢日誌(slow query log)
- 重做日誌(redo log)
- 回滾日誌(undo log)
- 中繼日誌(replay log)
錯誤日誌(errorlog)
默認是開啓的,而且從5.5.7以後無法關閉錯誤日誌,錯誤日誌記錄了運行過程中遇到的所有嚴重的錯誤
信息,以及 MySQL每次啓動和關閉的詳細信息。
二進制日誌(bin log)
MySQL的二進制日誌(binary log)是一個二進制文件,主要用於記錄修改數據或有可能引起數據變更的MySQL語句。二進制日誌(binary log)中記錄了對MySQL數據庫執行更改的所有操作,並且記錄了語句發生時間、執行時長、操作數據等其它額外信息,但是它不記錄SELECT、SHOW等那些不修改數據的SQL語句。二進制日誌(binary log)主要用於數據庫恢復和主從複製,以及審計(audit)操作。
二進制日誌開啓方法
查看系統變量log_bin,如果其值爲OFF,表示沒有開啓二進制日誌(binary log)
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | OFF |
+---------------+-------+
1 row in set (0.00 sec)
開啓需要修改mysql.cnf,在[mysqld]下面增加log_bin=mysql_bin_log
,不添加路徑只有文件名默認在datadir中。
通用查詢日誌(general query log)
記錄建立的客戶端連接和執行的所有語句。這種比較消耗資源,且沒有什麼價值,不建議開啓。
通用查詢日誌開啓方法
log_output=[none|file|table|file,table] #通用查詢日誌輸出格式
general_log=[on|off] #是否啓用通用查詢日誌
general_log_file[=filename] #通用查詢日誌位置及名字
慢查詢日誌(slow query log)
MySQL 慢查詢日誌是排查問題 SQL 語句,以及檢查當前 MySQL 性能的一個重要功能。記錄的是超過預設置秒數的查詢日誌信息。
查看是否開啓慢查詢功能
mysql> show variables like 'slow_query%';
+---------------------+------------------------------------+
| Variable_name | Value |
+---------------------+------------------------------------+
| slow_query_log | OFF |
| slow_query_log_file | /var/lib/mysql/instance-1-slow.log |
+---------------------+------------------------------------+
2 rows in set (0.01 sec)
mysql> show variables like 'long_query_time';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.00 sec)
slow_query_log 慢查詢開啓狀態
slow_query_log_file 慢查詢日誌存放的位置(這個目錄需要MySQL的運行帳號的可寫權限,一般設置爲MySQL的數據存放目錄)
long_query_time 查詢超過多少秒才記錄
開啓慢查詢功能
修改mysql.cnf
[mysqld]
slow_query_log = ON #代表是否開啓
slow_query_log_file = /var/lib/mysql/instance-1-slow.log #日誌文件存放位置
long_query_time = 2 #超過多少秒才進行記錄
重做日誌(redo log)
作用:
確保事務的持久性。防止在發生故障的時間點,尚有髒頁未寫入磁盤,在重啓mysql服務的時候,根據redo log進行重做,從而達到事務的持久性這一特性。
內容:
物理格式的日誌,記錄的是物理數據頁面的修改的信息,其redo log是順序寫入redo log file的物理文件中去的。
什麼時候產生:
事務開始之後就產生redo log,redo log的落盤並不是隨着事務的提交才寫入的,而是在事務的執行過程中,便開始寫入redo log文件中。
什麼時候釋放:
當對應事務的髒頁寫入到磁盤之後,redo log的使命也就完成了,重做日誌佔用的空間就可以重用(被覆蓋)。
對應的物理文件:
默認情況下,對應的物理文件位於數據庫的data目錄下的ib_logfile1&ib_logfile2
innodb_log_group_home_dir 指定日誌文件組所在的路徑,默認./ ,表示在數據庫的數據目錄下。
innodb_log_files_in_group 指定重做日誌文件組中文件的數量,默認2
關於文件的大小和數量,由以下兩個參數配置:
innodb_log_file_size 重做日誌文件的大小。
innodb_mirrored_log_groups 指定了日誌鏡像文件組的數量,默認1
其他:
很重要一點,redo log是什麼時候寫盤的?前面說了是在事物開始之後逐步寫盤的。
之所以說重做日誌是在事務開始之後逐步寫入重做日誌文件,而不一定是事務提交才寫入重做日誌緩存,原因就是,重做日誌有一個緩存區Innodb_log_buffer,Innodb_log_buffer的默認大小爲8M(這裏設置的16M),Innodb存儲引擎先將重做日誌寫入innodb_log_buffer中。
然後會通過以下三種方式將innodb日誌緩衝區的日誌刷新到磁盤
Master Thread 每秒一次執行刷新Innodb_log_buffer到重做日誌文件。
每個事務提交時會將重做日誌刷新到重做日誌文件。
當重做日誌緩存可用空間 少於一半時,重做日誌緩存被刷新到重做日誌文件
由此可以看出,重做日誌通過不止一種方式寫入到磁盤,尤其是對於第一種方式,Innodb_log_buffer到重做日誌文件是Master Thread線程的定時任務。
因此重做日誌的寫盤,並不一定是隨着事務的提交才寫入重做日誌文件的,而是隨着事務的開始,逐步開始的。
另外引用《MySQL技術內幕 Innodb 存儲引擎》(page37)上的原話:
即使某個事務還沒有提交,Innodb存儲引擎仍然每秒會將重做日誌緩存刷新到重做日誌文件。
這一點是必須要知道的,因爲這可以很好地解釋再大的事務的提交(commit)的時間也是很短暫的。
回滾日誌(undo log)
作用:
保存了事務發生之前的數據的一個版本,可以用於回滾,同時可以提供多版本併發控制下的讀(MVCC),也即非鎖定讀
內容:
邏輯格式的日誌,在執行undo的時候,僅僅是將數據從邏輯上恢復至事務之前的狀態,而不是從物理頁面上操作實現的,這一點是不同於redo log的。
什麼時候產生:
事務開始之前,將當前是的版本生成undo log,undo 也會產生 redo 來保證undo log的可靠性
什麼時候釋放:
當事務提交之後,undo log並不能立馬被刪除,而是放入待清理的鏈表,由purge線程判斷是否由其他事務在使用undo段中表的上一個事務之前的版本信息,決定是否可以清理undo log的日誌空間。
對應的物理文件:
MySQL5.6之前,undo表空間位於共享表空間的回滾段中,共享表空間的默認的名稱是ibdata,位於數據文件目錄中。
MySQL5.6之後,undo表空間可以配置成獨立的文件,但是提前需要在配置文件中配置,完成數據庫初始化後生效且不可改變undo log文件的個數
如果初始化數據庫之前沒有進行相關配置,那麼就無法配置成獨立的表空間了。
關於MySQL5.7之後的獨立undo 表空間配置參數如下:
innodb_undo_directory = /data/undospace/ –undo獨立表空間的存放目錄
innodb_undo_logs = 128 –回滾段爲128KB
innodb_undo_tablespaces = 4 –指定有4個undo log文件
如果undo使用的共享表空間,這個共享表空間中又不僅僅是存儲了undo的信息,共享表空間的默認爲與MySQL的數據目錄下面,其屬性由參數innodb_data_file_path配置。
其他:
undo是在事務開始之前保存的被修改數據的一個版本,產生undo日誌的時候,同樣會伴隨類似於保護事務持久化機制的redolog的產生。
默認情況下undo文件是保持在共享表空間的,也即ibdatafile文件中,當數據庫中發生一些大的事務性操作的時候,要生成大量的undo信息,全部保存在共享表空間中的。
因此共享表空間可能會變的很大,默認情況下,也就是undo 日誌使用共享表空間的時候,被“撐大”的共享表空間是不會也不能自動收縮的。
因此,mysql5.7之後的“獨立undo 表空間”的配置就顯得很有必要了。
數據文件
SHOW VARIABLES LIKE '%datadir%';
每種存儲引擎的數據結構是不一樣的
InnoDB數據文件
- .frm文件:主要存放與表相關的數據信息,主要包括表結構的定義信息.
- .ibd:使用獨享表空間存儲表數據和索引信息,一張表對應一個ibd文件。
- ibdata文件:使用共享表空間存儲表數據和索引信息,所有表共同使用一個或者多個ibdata文件。
MyIsam數據文件
- .frm文件:主要存放與表相關的數據信息,主要包括表結構的定義信息
- .myd文件:主要用來存儲表數據信息。
- .myi文件:主要用來存儲表數據文件中任何索引的數據樹。
注意
- 日誌文件在磁盤中是順序寫入的。速度快,耗費時間短
- 數據文件在磁盤中是隨機寫入的。速度慢,耗費時間長
那爲什麼數據文件不採用順序寫入的方式呢,因爲數據文件有大量的插入刪除操作,順序寫入會產生大量的磁盤碎片。(這和磁盤的硬件結構有關,順序寫入只進行一次尋道,隨機寫入會經常尋道)