本文出處:http://www.cnblogs.com/wy123/p/7102128.html (保留出處並非什麼原創作品權利,本人拙作還遠遠達不到,僅僅是為了鏈接到原文,因為後續對可能存在的一些錯誤進行修正或補充,無他) 本文的資料庫版本是MySQL5.7.18,簡單介紹一下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文件中)
但是數據中的其他對象,比如存儲過程,觸發器等信息仍然存儲在共用表空間的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操作,事物提交之後可以直接清理回滾日誌記錄。
總結:
本位粗淺地分析了MySQL物理文件的結構以及對應的邏輯功能,多數配置是按照預設情況下來進行展現的,從中可以對MySQL的物理結構以及邏輯功能進行一個簡單又粗淺的說明(很粗很淺,歡迎指正)。
但終究是窺探管中窺豹僅見一斑而已,路曼曼其修遠。中間經歷了各種翻書,各種查資料,各種抄(學習不就是一個模仿和創造的過程,自我安慰一下)。
再次說明,MySQL每一步都是可配置化的,配置不同,甚至每個MySQL的髮型版本,某些地方都不盡一致,切勿照搬。