MySql學習(二)MySql物理結構

MySql的物理結構

  1. MySQL是通過文件系統對數據和索引進行存儲的。
  2. MySQL從物理結構上可以分爲日誌文件和數據索引文件。
  3. MySQL在Linux中的數據索引文件和日誌文件都在/var/lib/mysql目錄下。
  4. 日誌文件採用順序IO方式存儲、數據文件採用隨機IO方式存儲。

日誌文件

日誌文件分爲

  1. 錯誤日誌(errorlog)
  2. 二進制日誌(bin log)
  3. 通用查詢日誌(general query log)
  4. 慢查詢日誌(slow query log)
  5. 重做日誌(redo log)
  6. 回滾日誌(undo log)
  7. 中繼日誌(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數據文件

  1. .frm文件:主要存放與表相關的數據信息,主要包括表結構的定義信息.
  2. .ibd:使用獨享表空間存儲表數據和索引信息,一張表對應一個ibd文件。
  3. ibdata文件:使用共享表空間存儲表數據和索引信息,所有表共同使用一個或者多個ibdata文件。

MyIsam數據文件

  1. .frm文件:主要存放與表相關的數據信息,主要包括表結構的定義信息
  2. .myd文件:主要用來存儲表數據信息。
  3. .myi文件:主要用來存儲表數據文件中任何索引的數據樹。

注意

  1. 日誌文件在磁盤中是順序寫入的。速度快,耗費時間短
  2. 數據文件在磁盤中是隨機寫入的。速度慢,耗費時間長

那爲什麼數據文件不採用順序寫入的方式呢,因爲數據文件有大量的插入刪除操作,順序寫入會產生大量的磁盤碎片。(這和磁盤的硬件結構有關,順序寫入只進行一次尋道,隨機寫入會經常尋道)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章