1. 程式人生 > >MySQL 物理文件體系結構的簡單整理說明

MySQL 物理文件體系結構的簡單整理說明

清理 定時執行 再次 bte 物理文件 重要 定時 等待 etc

原文:MySQL 物理文件體系結構的簡單整理說明

本文出處:http://www.cnblogs.com/wy123/p/7102128.html
(保留出處並非什麽原創作品權利,本人拙作還遠遠達不到,僅僅是為了鏈接到原文,因為後續對可能存在的一些錯誤進行修正或補充,無他)

本文的數據庫版本是MySQL5.7.18,簡單介紹一下MySQL數據文件目錄的物理結構和作用,從中可以窺見MySQL的整體上的物理文件結構以及邏輯功能。
可以從整體結構上了解到MySQL的物理體系架構(本人學習的思路往往是被與已了解的事物對照學習,或者快速了解其輪廓,再逐步細化整個知識體系)
鑒於MySQL中任何一項邏輯性或者物理性文件都具有可配置性,另外就是由於開源,MySQL在每個大版本中都有一些改進的東西,不能根據某一項或者默認配置生搬硬套。

如下圖是MySQL(5.7.18)在Linux系統yum默認安裝的數據文件目錄,可以看到有如下幾類文件。

技術分享

1,數據庫路徑:可以看到,系統數據庫和用戶自定義的數據庫都是一個路徑,展開具體的路徑之後是具體的每個數據庫自己的對象)
2,logbin二進制日誌文件:如果開啟了二進制日誌,會有若幹個二進制日誌文件(如圖的mysql-bin.000042,mysql-bin.000043)與其對應的描述文件(mysql-bin.index)
3,redo重做日誌文件:ib_logfile0,ib_logfile1,是支持事務性引擎的redo日誌文件
4,共享表空間:ibdata1,如果指定innodb表為非獨立文件的,用戶自定義庫中的表的數據就存儲在共享表空間中。
  即便是innnodb表指定為獨立表空間,用戶自定義庫中的某些元數據信息(比如存儲過程等信息都存儲在共享表空間中)。
  同時,共享表空間還負責存儲undo數據的存儲的作用(undo數據也即事物性操作的數據的修改之前的值)。
  不過,而從5.6開始,用戶可以把undo log存儲到獨立的tablespace中,並拆分成多個Undo log文件。
5,臨時表空間:ibtemp1,存儲臨時對象的空間,比如臨時表對象等。
6,errorlog:error_log.log,記錄啟動、運行或停止MySQL服務器過程,以及MySQL運行過程中一些較為嚴重的錯誤信息
7,mysql.sock:作用是MySQL服務器本身的客戶端連接的時候,發起本地連接時可用
8,slow_log:截圖的MySQL服務中尚未配置慢查詢日誌,如果配置了MySQL的慢查詢日誌,MySQL會將運行過程中的慢查詢日誌記錄到slow_log文件中
9,general_log:同上面的8,截圖的服務器尚未配置MySQL的通用查詢日誌,如果配置了通用查詢日誌,MySQL將運行過程中的所有sql都記錄在此文件中。
10,另外一個是最終的MySQL的配置文件,my.cnf,YUM安裝的MySQL的配置文件my.cnf默認在etc目錄下

  技術分享

  上述文件可以分類之後用結構化的方式展現出來,如下,也即上述描述的一系列文件結構的歸類展現
  需要說明的是,上述列舉的一系列文件中尚未包括一些文件,比如啟用復制的時候的中繼日誌文件等等(粗淺拙圖,大神輕噴)

技術分享

 

下面對從類別上對各個文件進行一個簡單的說明:

  系統數據庫

  在MySQL5.7.18中,系統數據庫包括information_schema,mysql,sys,performance_schema
  1,information_schema庫,提供了數據庫的元數據信息,是數據庫的數據,比如數據庫的名字,數據庫中的表名,字段名,字段類型等,可以說是數據庫的數據字典信息。
    這個庫中的信息並非物理地保存在表中,而是動態地去讀取其他文件得到的,比如上面一開始提到的共享表空間,對於用戶數據中的對象,比如表結構等,都保存在共享表空間中,
    information_schema庫中的一些信息可以認為是直接映射到共享表空間中的信息的。因此第一個截圖中,並沒有information_schema的路徑(文件夾)
  2,performance_schema庫,是數據庫性能相關的信息的數據,記錄的是數據庫服務器的性能參數。
    1)保留進程等待信息,包括鎖,互斥變量,文件信息等。
    2)保存歷史事件匯總信息,為MySQL服務器性能評估提供參考信息
    3)配置型選項,來決定是否記錄一些與性能相關的信息,比如profile信息等,參考http://www.cnblogs.com/wy123/p/6979499.html
  3,sys庫,可以根據sys庫中的數據快速了解系統的運行信息,方便地查詢出來數據庫的信息,在性能瓶頸,自動化吧運維等方面都有很大的幫助
    sys庫中的信息是通過視圖的方式,將information_schema和performance_schema庫中的數據結合起來,可以得到更加直觀和容易理解的信息
  4,mysql庫,存儲了系統的用戶權限信息及幫助信息,新建的用戶,用戶的權限信息的都存儲在MySQL庫。
    比如在修改MySQL的root密碼的時候,都要先use mysql這個系統庫,然後再執行用戶,授權等操作。

  用戶數據庫

  用戶數據庫實際上是一個目錄,目錄中保存了數據庫中的表以及數據信息,如下截圖是一個典型的數據庫目錄下的文件信息。
  對於innodb引擎的表,一個表分別對應兩個文件,一個是*.frm,存儲的是表結構信息,一個是*.ibd,存儲的是表中的數據,從大小也可以看出來*.ibd較大而*.frm較小。
  另外一個文件是db.opt,保存的是數據庫的配置信息,比如編碼信息等。
  對於innodb表,如果是獨立的表空間的話,數據庫中的表結構以及數據都存儲在數據庫的路徑下(而不是在共享表空間中ibdata1文件中)
  但是數據中的其他對象,包括undo信息,也即數據被修改之後,事務提交之間的版本信息,仍然存儲在共享表空間的ibdata1文件中

  test_database1對應的數據庫物理文件

  技術分享

  test_database1對應的邏輯數據庫如下

技術分享

基於ibdata1文件的共享表空間

對於innodb,innodb_file_per_table選項決定了是否啟動獨立表空間,MySQL5.7中是默認啟動的,也就是說MySQL的用戶數據庫將使用獨立表空間來存儲數據,

技術分享

正如截圖看到的,本測試服務器的共享表空間中只有一個文件,如下通過show variables like ‘innodb_data%‘;命令可以查詢共享表空間的文件信息,實際上共享表空間可以配置成多個物理文件。

  技術分享

  關於共享表空間和獨立表空間都有各自的優缺點,本文不在抄了,也可以將數據文件從共享表空間轉移到獨立表空間。
  不過從當前(MySQL5.7.18)來看,MySQL默認innodb引擎默認是獨立的表空間,讓MySQL數據文件住上“單間”而不是集體宿舍,可見獨立的表空間還是有一定優勢的。

  基於ibtmp1文件的臨時表空間

   臨時表空間是存儲全局級,回話級,事物級,檢索級臨時表對象的地方,有參數innodb_temp_data_file_path可以看到臨時表空間的信息。

  技術分享

  有關臨時表空間更多的信息,請參考:https://yq.aliyun.com/ziliao/89528

  

  基於ib_logfileN的重做日誌

  redo日誌默認情況下有兩個文件,也即:ib_logfile0和ib_logfile1,如果在數據庫啟動的過程中沒有這兩個文件,系統會默認自動生成這兩個文件。
  默認情況下,ib_logfile0和ib_logfile1是兩個獨立的日誌文件(可以配置的更多個ib_logfile文件),但是redo日誌的寫入在邏輯上對於ib_logfile0和ib_logfile1是連續的。
  重做日誌是MySQL事物處理的核心文件,事務處理的核心之一是一致性,也就是說要麽全做,要麽全不做。
  事物性操作都是基於一個或者多個表中部分數據的操作,為了保證一致性,在確保事物的一致性的時候,需要事物提交的時候直接或者間接寫盤操作。
  MySQL事物操作是logwrite-ahead操作,也即先寫日誌(具體怎麽寫日誌取決於innodb_flush_log_at_trx_commit的配置),相當於間接寫盤操作。
  目的是將對數據庫具體的數據文件的分散隨機寫入(多個表的數據寫入數據文件)轉換成基於日誌的順序寫入操作,而數據文件是異步寫盤,
  如果數據文件寫盤異常,可以通過redo日誌來“重做”,據此來提高事物性操作的效率。
  redo日誌空間的使用,在邏輯上相當於一個環形空間,redo日誌不斷向前推進寫入記錄,後臺的定時執行的checkpoint將事務修改過尚未寫盤的記錄異步寫入數據文件之後,日誌空間可重用。

  技術分享

  基於mysql-bin.n的二進制日誌

  bin-log日誌記錄數據中發生的寫入性操作(增刪改),但不記錄查詢操作,語句以事件的方式保存,描述了數據的更改過程,此日誌對發生災難時數據恢復起到了極為重要的作用。
  對應的物理文件如截圖

  技術分享

  MySQL默認情況下並沒有開啟二進制日誌,需要在my.cnf中配置log_bin的路徑,重啟MySQL之後會自動開啟log_bin二進制日誌記錄功能。
  這其中包括了一系列關於log_bin的配置。

包括:
  1)log-bin的路徑配置:log-bin=/var/lib/mysql/mysql-bin
  2)二進制日誌的格式:binlog_format = MIXED
  3)設置日誌文件的失效期:expire_logs_days = n,參數為expire_logs_days,set global expire_log_days=n,N天前的日誌自動刪除;
  4)二進制日誌緩存大小,binlog_cache_size = ***:二進制日誌緩存大小,是每一個連接進來的線程分配的大小,不是整個服務器的大小;
  5)最大緩存大小:max_binlog_cache_size=***
  6)單個文件最大大小,:max_binlog_size = 100m,單個文件最大大小,超過此大小則再分配一個文件,但是一個事務必須在一個文件中,所以可能會稍大點;
具體配置的詳細信息如下截圖所示。

  技術分享

  開啟log_bin之後,可以在系統變量中查詢到相關的配置。

  技術分享

  在數據庫發生災難的時候,可以借助完整備份和差異備份進行大部分數據的恢復,但是log_bin記錄了數據庫中所有發生的事件,
  因此在完整備份和差異備份還原的基礎上,借助l最後一次差異備份(前提是有完整備份)的log_bin,可以將數據庫恢復至具體的某一個時間點。
  關於數據中的操作(增刪改)記錄到log_bin的時機,有sync_binlog參數進行控制。
  sync_binlog=0,當事務提交之後,MySQL不做fsync之類的磁盤同步指令刷新binlog_cache中的信息到磁盤,而讓Filesystem自行決定什麽時候來做同步,
  此時(sync_binlog=0)就增加了不可控性(事物提交後還有多少日誌尚未寫入log_bin文件)。
  sync_binlog=n,當每進行n次事務提交之後,MySQL將進行一次fsync之類的磁盤同步指令來將binlog_cache中的數據強制寫入磁盤。
  在MySQL中系統默認的設置是sync_binlog=0,也就是不做任何強制性的磁盤刷新指令,這時候的性能是最好的,但是風險也是最大的。
  因為一旦系統Crash,在binlog_cache中的所有binlog信息都會被丟失。而當設置為“1”的時候,是最安全但是性能損耗最大的設置。
  因為當設置為1的時候,即使系統Crash,也最多丟失binlog_cache中未完成的一個事務,對實際數據沒有任何實質性影響(如果此時宕機,可以借助重做日誌進行重做)。

  sync_binlog也是一個系統變量,可以通過如下命令查看配置信息。

  技術分享

  詳情參考這裏:http://www.cnblogs.com/ggjucheng/archive/2012/11/15/2771535.html

  undo表空間

  redo重做日誌在提高事物性操作的效率的同時,也通過redo重做機制保證了事物的可靠性。
  如果事物回滾,則需要依賴undo日誌進行回滾操作,MySQL在進行事物操作的同時,會記錄事務性操作修改數據之前的信息,就是undo日誌,確保可以回滾到事物發生之前的狀態
  默認情況下,MySQL將undo日誌記錄在共享表空間中(上文提到的bdata1共享文件),如果事物成功提交,記錄在共享表空間的undo日誌會被後臺進程做puege清理
  當然這個undo日誌也有差別,如果是update操作之後提交事務,undo日誌還需要為MVCC提供服務器,如果是insert操作,事物提交之後可以直接清理回滾日誌記錄。

  不過,而從5.6開始,用戶可以把undo log存儲到獨立的tablespace中,並拆分成多個Undo log文件。   詳情參考:http://mysqllover.com/?p=873

  

總結:

  本位粗淺地分析了MySQL物理文件的結構以及對應的邏輯功能,多數配置是按照默認情況下來進行展現的,從中可以對MySQL的物理結構以及邏輯功能進行一個簡單又粗淺的說明(很粗很淺,歡迎指正)。
  但終究是窺探管中窺豹僅見一斑而已,路曼曼其修遠。中間經歷了各種翻書,各種查資料,各種抄(學習不就是一個模仿和創造的過程,自我安慰一下)。
  再次說明,MySQL每一步都是可配置化的,配置不同,甚至每個MySQL的發型版本,某些地方都不盡一致,切勿照搬。

MySQL 物理文件體系結構的簡單整理說明