mysql用 fifo 记录日志_MySQL一丢丢知识点的了解
1. MySQL體系結構
從概念上講,數據庫是文件的集合,是依照某種數據模型組織起來并存放于二級存儲器中的數據集合;數據庫實例是程序,是位于用戶與操作系統之間的一層數據管理軟件,用戶對數據庫數據的任何操作,包括數據庫定義、查詢、維護、運行控制等都是在數據庫實例下進行的,應用程序只有通過數據庫實例才能和數據庫打交道。
MySQL的體系結構如上圖所示,主要由以下部分組成:
連接池組件
管理服務和工具組件
SQL接口組件
查詢分析器組件
優化器組件
緩沖組件
插件式存儲引擎
物理文件
InnoDB存儲引擎,設計目標是面向在線事務處理(Online Transaction Processing,OLTP),特點是支持事務、行鎖設計、支持外鍵,支持非鎖定讀,即默認讀取操作不會產生鎖,現在MySQL的默認引擎是InnoDB。
MyISAM存儲引擎,不支持事務、支持全文索引,主要面向一些OLAP數據庫應用。
2. InnoDB存儲引擎
關鍵特性:
插入緩沖(Insert Buffer),當索引是輔助索引(secondary index)和索引不是唯一索引的時候,就會使用插入緩沖。對于非聚集索引的插入或更新操作,不是每一次直接插入到索引頁中,而是先判斷插入的非聚集索引是否在緩沖池中,若在則直接插入;如偶在,則先放入到一個Insert Buffer中。數據結構是一棵B+樹。
兩次寫(Double Write),解決了部分寫失效(partial write)問題。由內存中的doublewrite buffer和磁盤上共享表空間中連續的128個頁(2個區(extent))組成,兩個部分的大小都是2M。
自適應哈希索引(Adaptive Hash Index),引擎會監控對表上個索引頁的查詢,如果觀察到建立哈希索引可以帶來查詢速度的提升,就會建立哈希索引,因此叫做自適應哈希索引(AHI)。
異步IO(Asynchronous IO,AIO),目的是為了提高磁盤操作性能。Sync IO和Async IO,前一個得等到一個IO操作完成才會進行下一個IO操作,而AIO則是發出一個IO請求后會繼續發出下一個IO請求,發送完所有請求后等所有IO操作的完成。
刷新鄰接頁(Flush Neighbor Page),當屬新一個臟頁時,引擎會檢測改業所在區的所有頁,如果是臟頁,則進行一起刷新,通過AIO將多個IO進行合并為一個IO,在機械硬盤中有優勢,在SSD中則me這個必要,可以通過設置參數innodb_flush_neighbors為0關閉該特性。
3. 文件
文件包括MySQL數據庫和InnoDB存儲引擎表的一部分文件。
參數文件:MySQL實例啟動時在哪里可以找到數據文件,并指定某些初始化參數,這些參數定義了某種內存結構的大小等設置;
日志文件:記錄MySQL實例對某種條件作出響應時寫入的文件,如錯誤日志文件、二進制日志文件、慢查詢日志文件、查詢日志文件等;
socket文件:當用UNIX域套接字方式進行連接時需要的文件;
pid文件:MySQL實例的進程ID文件;
MySQL表結構文件:用來存放MySQL表結構定義的文件;
存儲引擎文件:每個存儲引擎都會有自己的文件用來保存各種數據。這些存儲文件存儲了記錄和索引的數據。
日志文件
錯誤日志:MySQL的啟動、運行、關閉過程進行記錄。從中可以得到一些關于數據庫優化等等信息。
慢查詢日志:定位可能存在問題的SQL語句,從SQL語句層面進行優化。比如可以把運行時間超過某個閾值的SQL語句記錄到慢查詢日志文件中,然后每過一段時間對其檢查是否需要對語句進行優化。閾值可以通過參數long_query_time設置。
1. 當某條SQL語句的時間剛好為閾值的值的時候是不會被記錄的,只記錄大于long_query_time的語句。
2. 現在(版本5.1開始)long_query_time的值一般是一微秒為值。
查詢日志:記錄了所有對MySQL數據庫請求的信息,無論這些請求是否得到了正確的執行,默認文件名為:主機名.log。
二進制日志:記錄了所有對MySQL數據庫執行更改的操作,只有更改數據庫的操作才進行記錄,因此select、show等操作是沒有的。如果是update,盡管沒有更改也會記錄。主要作用有:恢復數據庫、復制數據庫、審計(對二進制日志中的信息進行審計,判斷是否有對輸入庫的注入攻擊)。
4. 表
主要是InnoDB存儲引擎表的邏輯存儲及實現。
4.1 索引組織表(Index Organized Table)
在InnoDB存儲引擎中,表都是根據主鍵順序組織存放的,這種存儲方式的表稱為索引組織表。在InnoDB存儲引擎表中,每張表都有個主鍵(primary key),如果在創建表時沒有顯示的定義主鍵,則InnoDB存儲引擎會根據如下方式選擇或創建主鍵:
首先判斷表中是否有非空唯一索引(Unique NOT NULL),如果有,則該列為主鍵;
如果沒有,InnoDB存儲引擎會自動創建一個6字節大小的指針作為主鍵。
當表中有多個非空唯一索引時,引擎會選擇建表時第一個定義的非空唯一索引為主鍵。注:主鍵的選擇根據的是定義索引的順序,而不是建表時列的順序。
4.2 InnoDB邏輯存儲結構
從InnoDB存儲引擎邏輯存儲結構看,所有數據都放在一個空間中,成為表空間(tablespace)。表空間由段(segment)、區(extent)、頁(page,有的也叫塊block)組成。
InnoDB存儲引擎邏輯結構如上圖。
表空間可以看做是InnoDB存儲引擎邏輯結構的最高層,所有的數據都存放在表空間中。表空間中的段由各個部分組成,常見的有數據段、索引段、回滾段等等,因為InnoDB存儲引擎表時索引組織,因此數據即索引,索引即數據,所以數據段為B+樹的葉子結點(圖中的Leaf node segment),索引為B+樹的非葉子結點(圖中的Non-leaf node segment)。段中的區是由連續的頁組成,在任何情況下每個區的大小都為1MB,默認的頁大小為16KB,因此一個區有64個連續的頁,因此為了保證區中頁的連續性,引擎一次會從磁盤申請4~5個區。
4.3 約束機制
數據完整性,關系型數據庫本身保證了存儲數據的完整性。通過Primary Key或Unique Key約束來保證完整性。還可以編寫觸發器保證數據的完整性。
約束的創建和查找,可以建表時就進行約束定義,或是利用Alter Table命令創建約束。
約束和索引的區別,創建了一個唯一索引就創建了一個唯一的約束。約束是一個邏輯概念,用來保證數據的完整性;而索引則是一個數據結構,既有邏輯上的概念,也代表了數據庫中的物理存儲方式。
對錯誤數據的約束,如向NOT NULL的字段插入一個NULL值,MySQL數據庫會將其更改為0在進行插入。
外鍵約束,用來保證參照完整性,關鍵字為foreign key。
4.4 視圖
MySQL數據庫中,視圖(View)是一個命名的虛表,由一個SQL查詢來定義,可以當做表使用。與持久表(permanent table)不同的是,視圖中的數據沒有實際的物理存儲。
作用:1)被用作一個抽象裝置,可以起到一個安全層的作用。某些應用程序本身不關心基表(base table)的結構,只是按照視圖定義來取數據或更新數據,即通過視圖來更新基本表。
5. 索引與算法
索引太多,影響性能;索引太少,也影響性能。
InnoDB存儲引擎支持的幾種常見索引:
B+樹索引
全文索引
哈希索引
注:B+樹中的B不是代表二叉(binary),而是代表平衡(balance),因為B+樹是從最早的平衡二叉樹演化而來,并且B+樹不是二叉樹。
B+樹索引并不能找到一個給定鍵值的具體行,智能查到數據行所在的頁,然后把頁讀入到內存,再從內存中進行查找,最后得到查找的數據。
5.1? 數據結構與算法
關于索引中的B+樹數據結構和相關算法,如下鏈接。
因為每頁的數據是按照主鍵的順序存放,因此在內存中的查詢就是通過對頁的二分查找而獲取。
5.2 B+樹索引
B+樹索引的本質就是B+樹在數據庫中的實現。在數據庫中B+樹的高度一般是在2~4層,即查找某一個鍵值的行記錄時最多只需要2~4次IO。
MySQL中的B+樹索引分為聚集索引(clustered index)和輔助索引(secondary index),兩個索引的內部實現都是B+樹?,葉子結點存放所有的數據。兩個索引的區別是:葉子結點存放的數據是否是一整行數據信息。
聚集索引:InnoDB存儲引擎表是索引組織表,即表中數據按照主鍵順序存放,聚集索引就是按照每張表的主鍵構造一棵B+樹,同時葉子節點中存放的為整張表的行記錄數據,另外也將聚集索引的葉子節點稱為數據頁。因此索引組織表中的數據也是索引的一部分,么個索引頁都通過一個雙向鏈表進行鏈接。每張表只有一個聚集索引。
輔助索引:輔助索引也稱非聚集索引,葉子結點并不包含行記錄的全部數據。葉子結點除了包含鍵值之外,每個葉子節點中的索引行還包含一個書簽(bookmark),概述前用來高數引擎那里可以找到與索引相對應的行數據,因此輔助索引的書簽就是相應行數據的聚集索引鍵。輔助索引不影響數據在聚集索引中的組織,每張表上可以有多個輔助索引。通過輔助索引來尋找數據時,InnoDB存儲引擎會遍歷輔助索引并通過葉子級別的指針來獲得指向主鍵索引的主鍵,然后通過主鍵索引來找到一個完整的行記錄。
B+樹索引的使用
聯合索引
指對表上的多個列進行索引。本質也是一棵B+樹,不同的地方在于鍵值數量大于等于2。
聯合索引(a, b)首先是根據a,b進行排過序的,并且查詢鍵值(a),(a, b)都可以使用聯合索引(a, b),但是(b)則不能使用聯合索引。
覆蓋索引
也稱索引覆蓋,即從輔助索引中可以查詢的記錄,就不需要查詢聚集索引中的記錄,輔助索引不包含整行的信息,大小會小于句句索引,可以減少IO操作。
6. 鎖
InnoDB存儲引擎不需要所升級,因為一個鎖和多個鎖的開銷是相同的。
InnoDB的3中行鎖算法:
Record Lock: 鎖定單個行記錄;
Gap Lock:?鎖定一個范圍,并且不鎖定記錄本身;
Next-Key Lock: Gap Lock + Record Lock,鎖定一個范圍,并且鎖定記錄本身。
lock與latch的區別
InnoDB實現的 兩種標準的行級鎖
共享鎖(S Lock),允許事務讀一行數據
排它鎖(X Lock),允許事務刪除或更新一行數據
InnoDB存儲引擎支持多粒度鎖定,這種鎖定允許事務在行級上的鎖和表級上的鎖同時存在。若要對最細粒度的對象進行上鎖,那么首先要對粗粒度的對象上鎖。如需要對也上的r行進行上X鎖,分別需要對數據庫、表、頁上鎖,最后對行r上X鎖。
一致性非鎖定讀(consistent nonlocking read),指InnoDB通過多版本并發控制(Multi Version Concurrency Control,MVCC)的方式讀取當前執行時間數據庫中的行數據,即如果讀取行正在執行DELETE或UPDATE操作,這時的讀操作不會去等待行鎖的釋放,而是去讀取行數據的一個快照數據。
快照數據:指該行之前版本的數據,實現通過undo段完成,undo用來在事務中進行回滾數據。
在InnoDB存儲引擎默認設置下,一致性非鎖定讀是默認的讀取方式。
在事務隔離級別中:
RREAD COMMITTED中,使用一致性非鎖定讀,讀取被鎖定行的最新一份快照數據。
REPEATABLE READ(InnoDB默認事務隔離級別),使用一致性非鎖定讀,讀取事務開始時的行數據。
一致性鎖定讀,對于語句加鎖,即使是SELECT的只讀操作。SELECT語句有兩種一致性鎖定讀(locking read)操作:
SELECT...FOR UPDATE,對讀取行加X鎖,后續事務不能對鎖定的行再加上任何所;
SELECT...LOCK IN SHARE MODE,對讀取行加S鎖,其他事物可以對該行繼續加S鎖,當不能加X鎖,不然會被阻塞。
鎖引發的幾個問題:
1. 臟讀
臟數據:指事務對緩沖池中行記錄的修改,并且修改后還沒有被提交。
臟頁:指在緩沖池已經被修改的頁,但還沒有刷新到磁盤中,即數據庫實例內存中的頁和磁盤中的頁的數據不一致,在刷新到磁盤之前,日志已經寫到重做日志文件中。主要因為數據庫實例內存和磁盤的異步造成的,不影響數據的一致性。
臟讀:在不同的事務下,當前事務讀取到另外事務未提交的數據。一般不發生,因為該種操作需要的事務隔離級別為READ UNCOMMITTED,但是一般情況下至少都是READ COMMITTED級別,而InnoDB的默認級別是READ REPEATABLE級別。違反了數據庫的隔離性。
2. 不可重復讀(幻讀)
指在一個事務內多次讀取同一數據集合的時候,在該事務還沒有結束前,另外一個事務也訪問了同一數據集合并作了DML操作,結果第一個事務的兩次讀取結果不同。違反了數據庫事務一致性的要求。InnoDB的READ REPEATABLE通過Next-Key Lock算法,避免了該情況。
與臟讀的區別是:臟讀讀取的是未提交的數據,不可重復讀讀取的是已經提交的數據。
3. 丟失更新
另一個鎖導致的問題,即一個事務的更新操作被另一個事務的更新操作所覆蓋,導致數據的不一致。
幾個事務隔離級別都不會導致丟失更新的問題。
但是有另一種邏輯意義上的丟失更新問題:
1)事務T1查詢一行記錄,顯示給USER1;
2)事務T2查詢同一行記錄,顯示給USER2;
3)USER1修改這行記錄,更新數據庫并提交;
4)USER2修改這行記錄,更新數據庫并提交。
如銀行賬戶有1000塊,T1轉了900,因為網路和數據關系,需要等待;此時T2操作該賬戶轉走1元,當量比操作都成功的時候,賬戶剩下的不是99元,而是999元,操作T2將T1覆蓋。
因此避免丟失更新發生,讓事務在該種情況下的操作變成串行化,而不是并行化。即在操作1)中加一個排它鎖X鎖,2)中也加一個排它鎖X鎖,那么2)會等1)提交后才會繼續讀取。
死鎖,指兩個或兩個以上的事務在執行過程中,因爭奪鎖資源而造成的一種互相等待的現象。
一種是通過超時機制解決,根據FIFO順序選擇回滾操作;更普遍的是采用等待圖(wait-for graph)的方式進行死鎖檢測,通過數據庫保存的鎖的信息鏈表和事務等待鏈表可以構造出一張圖,當圖中存在回路的時候,就代表存在死鎖,這時InnoDB選擇回滾undo量最小的事務。
所升級,指將當前鎖的粒度降低。比如將一個表的1000個行鎖升級為一個頁鎖,或將頁鎖升級為表鎖。
7. 事務
事務會把數據庫從一種一致狀態轉換為另一種一致狀態。
事務符合ACID特性:
原子性(Atomicity)——redo log
一致性(Consistency)——undo log
隔離性(Isolation)——鎖
持久性(Durability)——redo log
redo恢復提交事務修改的頁操作,undo回滾行記錄到某個特定版本。
redo一般是物理日志,記錄頁的物理修改操作;undo是邏輯日志,根據每行記錄進行行記錄。
參照《MySQL技術內幕——InnoDB存儲引擎》第2版所寫。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的mysql用 fifo 记录日志_MySQL一丢丢知识点的了解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果手机绕激活锁之亲身体验
- 下一篇: careercup-高等难度 18.6