天天看點

《MySQL技術内幕:InnoDB存儲引擎》筆記

第一章 MySQL體系結構和存儲引擎

1.2 MySQL體系架構

存儲引擎是基于表的,而不是資料庫。

1.3MySQL存儲引擎

1.3.1InnoDB存儲引擎

   InnoDB存儲引擎支援事物,其特特是行鎖設計、支援外鍵。InnoDB存儲引擎通過使用多版本并發控制(MVCC)來獲得并發性。

同時,使用一種被稱為next-key locking 的政策來避免幻讀(phantom)現象的産生。

1.3.2MyISAM存儲引擎

   MyISAM存儲引擎不支援事物、表鎖設計、支援全文索引。

   MyISAM存儲引擎表由MYD和MYI組成,MYD用來存放資料檔案,MYI用來存放索引檔案。

1.3.3NDB存儲引擎

1.3.4 Memory存儲引擎

1.3.5 Archive存儲引擎

1.3.6 Federated存儲引擎

1.3.7 Maria存儲引擎

1.3.8 其他存儲引擎

第2章 InnoDB存儲

2.1 InnoDB存儲概述

該存儲引擎是第一個完整支援ACID事務的MySQL存儲引擎,其特點是行鎖設計、支援MVCC、支援外鍵、提供一緻性非鎖定讀,同時被設計用來最有效地利用以及使用記憶體和CPU。

2.3 InnoDB體系架構

2.3.2 記憶體

1 緩沖池

       具體來看,緩沖池中緩存的資料頁類型有:索引頁、資料頁、undo 頁、插入緩沖(insert buffer)、自适應哈希索引(adaptive hash index)、InnoDB 存儲的鎖資訊(lockinfo)、資料字典資訊(data dictionary)等。不能簡單地認為,緩沖池隻是緩存索引頁和資料頁,它們隻是占緩沖池很大的部分而已。 圖2-2 很好地顯示了InnoDB 存儲引擎中記憶體的結構情況。

《MySQL技術内幕:InnoDB存儲引擎》筆記

2 LRU算法

       帶有midpoint的LRU算法。和傳統的LRU算法做了一些優化。在InnoDB存儲引擎中,LRU算法清單中還加入了midpoint位置。新讀取到的頁,并不是直接放入到LRU清單的首部,而是放在midpoint位置。預設配置下載下傳LRU清單長度的5/8處。

      為什麼不用普通的LRU算法呢?因為某些SQL會全表掃描,把LRU清單中的熱點資料移除,而新放入的頁可能用一次就不用了,是以對LRU算法進行了優化。

LRU清單midpoint之前為new部分,之後為old部分,因為innodb_old_bolcks_time的設定而導緻old部分移動到new部分的操作成為page made young。

 夥伴算法了解一下。

3 重做日志緩沖

  通常情況下,8MB的重做日志緩沖池足以滿足絕大部分的應用,因為重做日志會在下列三種情況下回将重做日志緩沖中的内容重新整理到外部磁盤的重做日志檔案中。

  • MasterThread每-秒将重做日志緩沖重新整理到重做日志檔案;
  • 每個事務送出時會将重做日志緩沖重新整理到重做日志檔案;
  • 當重做日志緩沖池剩餘空間小于1/2 時,重做日志緩沖重新整理到重做日志檔案。

2.4 Checkpoint技術

Checkpoint技術的目的是解決一下幾個問題:

  • 縮短資料庫的恢複時間
  • 緩沖池不夠用時,将髒頁重新整理到磁盤
  • 重做日志不可用時,重新整理髒頁。

Checkponit所做的事情無外乎是将緩沖池中的髒頁刷回到磁盤。

2.6 InnoDB關鍵特性

插入緩沖(Insert Buffer)

兩次寫(Double Write)

自适應哈希索引(Adaptive Hash Index)

異步IO(Async IO)

重新整理鄰接表(Flush Neighbor Page)

2.6.1 插入緩沖

1 Insert Buffer

     InnoDB緩沖池中有Insert Buffer資訊固然不錯,但是Insert Buffer和資料頁一樣,也是實體頁的一個組成部分。

     插入緩沖是對輔助索引來說的,而不是對主鍵索引來的說的,即非唯一輔助索引的插入操作。

     比如此時有一張表student(id,name),id為主鍵索引, name為輔助索引。現在我插入一條記錄,插入記錄的同時伴随着主鍵索引和輔助索引的插入。主鍵索引其插入是有序的,是以速度比較快,但是輔助索引是離散型讀取和插入的,是以速度很慢,此時把插入輔助索引的操作放在插入緩沖中,等到合适的時候批量插入。

     Insert Buffer的使用需要同時滿足一下兩個條件:

  • 索引為輔助索引(secondary index)
  • 索引不是唯一(unique)的

3 Insert Buffer的内部實作

      Insert Buffer的資料結構是一顆B+樹。

      當一個輔助索引要插入到頁(space,offset)時,如果這個頁不在緩存池紅,那麼InnoDB存儲引擎首先根據上述規則構造一個search key,然後插入到Insert Buffer B+樹的葉子節點中。

4 Merger Insert Buffer

概括地說,Merge Insert Buffer的操作可能發生在以下幾種情況下:

  • 輔助索引頁被讀取到緩沖池時;
  • InsertBufferBitmap頁追蹤到該輔助索引頁已無可用空間時;
  • Master Thread。

2.6.2 兩次寫

貌似很厲害的樣子,看書吧。

第3章 檔案

3.1 參數檔案

mysql配置參數檔案

《MySQL技術内幕:InnoDB存儲引擎》筆記

3.1.1 什麼是參數

查詢所有的參數

SHOW VARIABLES;      

模糊查詢某個參數

SHOW VARIABLES LIKE "version%";      
《MySQL技術内幕:InnoDB存儲引擎》筆記

3.2 日志檔案

錯誤日志(error.log)

二進制日志(binlog)

慢查詢日志(slow query log)

查詢日志(log)

3.2.1 錯誤日志

  錯誤日志檔案對MySQL的啟動、運作、關閉過程進行了記錄。該檔案不僅記錄了所有的錯誤資訊,也記錄了一些警告資訊或者正确的資訊。

檔案的位置:

show variables like "log_error";      
《MySQL技術内幕:InnoDB存儲引擎》筆記

3.2.2 慢查詢日志

      可以在MySQL啟動時設一個門檻值,将運作時間超過該值的所有SQL語句都記錄到慢查詢日志檔案中。該門檻值可以通過參數long_query_time來設定,預設為10,代表10秒。

SHOW VARIABLES LIKE "long_query_time";      

       在預設情況下,MySQL資料庫并不啟動慢查詢日志,使用者需要手工将這個參數設為ON。

     查詢慢查詢日志開關狀态和日志位置

SHOW VARIABLES LIKE "slow_query_log%";      
《MySQL技術内幕:InnoDB存儲引擎》筆記

開啟慢查詢日志(修改/etc/my.cnf檔案)

# 開啟慢查詢日志
slow_query_log=on      

 重新啟動MySQL (重新開機、重新開機、重新開機)

測試慢查詢,如下圖所示,查詢時間為27秒

《MySQL技術内幕:InnoDB存儲引擎》筆記

則在慢查詢日志中記錄了目前SQL,如下圖所示 

《MySQL技術内幕:InnoDB存儲引擎》筆記

慢查詢日志資訊儲存的mysql.slow_log表裡

//查詢慢查詢儲存位置(檔案還是表)
show variables like "log_output";
//設定慢查詢儲存在表裡
SET GLOBAL log_output="table";
//執行SQL 。。。。。
//查詢慢SQL表
use mysql;
select * from slow_log;      
《MySQL技術内幕:InnoDB存儲引擎》筆記

3.2.3 查詢日志

  查詢日志記錄了所有對MySQL資料庫的請求資訊,無論這些請求是否得到了正确的執行。預設檔案名為:主機名.log

show variables like '%general_log%';      

此處和開始慢查詢日志類似,不在示範

3.2.4 二進制日志(很重要的問題)

   二進制日志(binary log)記錄了對MySQL資料庫執行更新的所有操作,但是不包括SELECT和SHOW這類操作,因為這類操作對資料本身沒有修改。然而,若操作本身并沒有導緻資料庫發生變化,那麼改操作可能也會寫入二進制日志。

開啟二進制日志

修改/etc/my.cnf檔案

#開啟二進制日志
log_bin=mysql-bin      

重新啟動MySQL (重新開機、重新開機、重新開機)

此時在/usr/local/mysql/data裡多了兩個檔案

《MySQL技術内幕:InnoDB存儲引擎》筆記

其中mysql-bin.00001即為二進制日志檔案,mysql-bin.index為二進制的索引檔案,不建議修改。

查詢mysql二進制檔案(不能用cat)

mysqlbinlog mysql-bin.000001      

二進制日志主要有以下幾種作用:恢複、複制、審計

其實很多MySQL用的主從複制就是基于bin.log日志檔案的。

3.3套接字檔案

3.4 pid檔案

3.5 表結構定義檔案

   我的mysql資料檔案的目錄為/usr/local/mysql/data

  當你建立了一個名稱為abc的資料庫時,在/usr/local/mysql/data下就會有一個abc的目錄,用來表示abc資料庫;

  當你在abc資料庫裡建了張bcd表,那麼在/usr/local/mysql/data/abc下就會有bcd.frm和bcd.ibd

 其中bcd.frm為表結構,bcd.ibd為表資料。

3.6 InnoDB存儲引擎檔案

很重要。看書吧

第4章 表

4.1 索引組織表

   在InnoDB存儲引擎表中,每張表都有主鍵(Primary Key),如果在建立表時沒有顯示地定義主鍵,則InnoDB存儲引擎會按照如下方式選擇或者建立主鍵:

  • 首先判斷表中是否有非空的唯一索引(Unique NOT NULL),如果有,則該列即為主鍵。
  • 如果不符合上述條件,InnoDB存儲引擎自動建立一個6位元組大小的指針。

當一個表中有多個非空唯一索引,InnoDB存儲引擎将選擇建表時的第一個定義的非空唯一索引為主鍵。主鍵的選擇根據的是定義索引的順序,而不是建表時列的順序。

4.2 InnoDB邏輯存儲結構

  從InnoDB存儲引擎的邏輯存儲結構看,所有的資料都被邏輯地存放在一個空間中,稱之為表空間(tablespace)。表空間又由段(segment)、區(extent)、頁(page)組成。頁在一些文檔中有時也被稱為快(block),InnoDB存儲引擎的邏輯存儲結構大緻如圖所示。

《MySQL技術内幕:InnoDB存儲引擎》筆記

4.2.1 表空間

    表空間可以看做是InnoDB存儲引擎邏輯結構的最高層,所有的資料都存放在表空間中。在預設的情況下InnoDB存儲引擎有一個共享表空間ibdata1,即所有的資料都存放在這個表空間内。如果使用者啟用了參數innodb_file_per_table,則每張表内的資料可以單獨放在一個表空間内。

   如果啟用了innodb_file_per_table的參數,需要注意的是每張表的表空間記憶體放的值是資料、索引和插入緩沖Bitmap頁,其它類型的資料,如復原(undo)資訊、插入緩沖索引頁、系統事物資訊、二次寫緩沖(Double write buffer)等還是存放在原來的共享表空間内。這同時也說明了一個問題:即使啟用了innodb_file_per_table ,共享表空間還是會不斷地增加其大小。

4.2.2 段

 表空間是由各個段組成,常見的段有資料端、索引段、復原段等。

 在InnoDB存儲引擎中,對段的管理都是由引擎自身完成,DBA不能也沒必要對其進行控制。

4.2.3 區

  區是由連續的頁組成的空間,在任何情況下每個區的大小都為1MB。為了保證區中頁的連續性,InnoDB存儲引擎一次從磁盤申請4~5個區。在預設情況下,InnoDB存儲引擎頁的大小為16KB,即一個區中一共有64個連續的頁。

4.2.4 頁

同大多數資料庫一樣,InnoDB 有頁(Page) 的概念(也可以稱為塊),頁是InnoDB磁盤管理的最小機關。在InnoDB存儲引擎中,預設每個頁的大小為16KB。而從InnoDB 1.2.x 版本開始,可以通過參數innodb_ page_ size 将頁的大小設定為4K、8K、16K。若設定完成,則所有表中頁的大小都為innodb_ page_ size, 不可以對其再次進行修改。除非通過mysqldump導人和導出操作來産生新的庫。

在InnoDB存儲引擎中,常見的頁類型有:

  • 資料頁(B-tree Node)
  • undo頁(undo Log Page)
  • 系統頁(System Page)
  • 事務資料頁(Transaction system Page)
  • 插人緩沖位圖頁(Insert Buffer Bitmap)
  • 插人緩沖空閑清單頁(Insert Buffer Free List)
  • 未壓縮的二進制大對象頁(Uncompressed BLOB Page)
  • 壓縮的二進制大對象頁(compressed BLOB Page)

4.2.5 行

      InnoDB存儲引擎是面向行的(row-oriented), 也就說資料是按行進行存放的。每個頁存放的行記錄也是有硬性定義的,最多允許存放16KB / 2 -200行的記錄,即7992行記錄。

第5章 索引與算法

    索引是應用程式設計和開發的一個重要方面。若索引太多,應用程式的性能可能會受到影響。而索引太少,對查詢性能又會産生影響。要找到-個合适的平衡點,這對應用程式的性能至關重要。

5.1 InnoDB存儲引擎索引概述

 InnoDB存儲引擎支援以下幾種常見的索引:

  • B+樹索引
  • 全文索引
  • 哈希索引

5.2 資料結構與算法

略。。。

5.3 B+樹

特别重要,看書吧

5.4 B+樹索引

  B+樹索引的本質就是B+樹在資料庫中的實作。但是B+樹在資料庫中有一個特點是高扇出性,是以在資料庫中,B+樹的高度一般都在2~4層,這也就是說查詢某一鍵值的行記錄時最多隻需要2到4次IO。

    資料庫中的B+樹索引可以分為聚集索引(clustered index)和輔助索引(secondary index) ,但是不管是聚集還是輔助的索引,其内部都是B+樹的,即高度平衡的,葉子節點存放着所有的資料。聚集索引與輔助索引不同的是,葉子節點存放的是否是一 整行的資訊。

5.4.1 聚集索引

   聚集索引(clustered index)就是按照每張表的主鍵構造一棵B+樹,同時葉子節點中存放的即為整張表的行記錄資料,也将聚集索引的葉子節點稱為資料頁。聚集索引的這個特性決定了索引組織表中的資料也是索引的一部分。

  換句話說:聚集索引的葉子節點存放了整行的資料。非葉子節點存放的是鍵值以及指向資料頁的偏移量。

每張表隻能擁有一個聚集索引。即主鍵索引。

5.4.2 輔助索引

  輔助索引(secondary index)又稱非聚集索引。葉子節點中除了包含鍵值以為,還有聚集索引鍵。

5.4.3 B+樹索引的分裂

沒看懂,太菜。。。

5.5 Cardinality值

5.5.1 什麼事Carinality值

 并不是所有的查詢條件中出現的列都需要添加索引。

 如果某個字段的取值範圍很廣,幾乎沒有重複,即屬于高選擇性,适合建立索引。反例,性别列加索引,不是很可取

Carinality值擷取如下圖所示:

《MySQL技術内幕:InnoDB存儲引擎》筆記

Carinality/n_rows_in_table應盡可能地接近1.如果非常小,那麼使用者需要考慮是否還有必要建立這個索引。

即通過Carinality值可以看某個索引是否有必要存在。

5.5.2 InnoDB存儲引擎的Cardinality統計

       在InnoDB存儲引擎中,Cardinality 值是通過對8個葉子節點預估而得的,不是一個實際精确的值。再者,每次對Cardinality值的統計,都是通過随機取8個葉子節點得到的,這同時又暗示了另一個Cardinality現象,即每次得到的Cardinality值可能是不同的。 

5.6 B+樹索引的實用

5.6.1  不同應用中B+樹索引的實用

 無論是在OLAP還是OLTP應用中,添加索引都是有意義的,隻是添加索引的列不一樣,關注點不一樣。

5.6.2 聯合索引

 即複合索引。

比如我建立了一個表student(id,name,age)

我建立了一個索引index_name_age(name,age),查詢name的時候可以實用到複合索引index_name_age,查詢age的時候不能用到index_name_age索引。

5.6.3 覆寫索引

  覆寫索引又稱索引覆寫。覆寫索引不是一種新的索引。(其實我感覺叫索引覆寫其實更形象)

比如我建立了一個表student(id,name,age),建立了index_name(name),我查詢select name from student where name="zhangsan"; 該處就實用了覆寫索引,即我查詢的資料在索引中就可以拿到。

如果select age,name from student where name="zhangsan"這麼查詢,那麼請問index_name中會存age的值嗎,不會的,那就不叫覆寫索引(索引覆寫)了。

5.6.6 Multi-Range Read優化

MRR優化有以下幾個好處:

  • 0 MRR使資料通路變得較為順序。在查詢輔助索引時,首先根據得到的查詢結果,按照主鍵進行排序,并按照主鍵排序的順序進行書簽查找。
  • 口減少緩沖池中頁被替換的次數。
  • 0批量處理對鍵值的查詢操作。

舉例:

select * from student where name like "關系戶" or score >90

此時可能查到的ID為9,19,1,2,8

因為記錄是在頁中,假設9和8的記錄在一個頁中,那麼會有一種情況為9記錄所在的頁進入緩沖區又被移除,後來8記錄所在的頁又被加入緩沖區,這樣相當于8和9所在頁進了2次。

優化後,把ID排序,然後按照順序查,就能保證8和9記錄所在的頁隻需要進入一次緩沖區。

5.6.7 Index Condition Pushdown(ICP)優化

看書吧

5.8 全文檢索

略。。。用ES

6 鎖

6.1 什麼是鎖

 鎖是資料庫系統差別于檔案系統的一個關鍵特性。

InnoDB存儲引擎是行級鎖。MyISAM是表級鎖。

6.2 lock與latch

lock的對象為事務,latch的對象為線程

《MySQL技術内幕:InnoDB存儲引擎》筆記

6.3 InnoDB存儲引擎中的鎖

6.3.1 鎖的類型

  • 共享鎖(S Lock):允許事務讀一行資料。
  • 排他鎖(X Lock):允許事務删除或者更新一行資料。
  • 意向共享鎖(IS Lock):事務想要獲得一張表中某幾行的共享鎖。
  • 意向排他鎖(IX Lock):事務想要獲得一張表中某幾行的排他鎖。

由于InnoDB存儲引擎支援的是行級别的鎖,是以意向鎖其實不會阻塞除全表掃以外的任何請求。故表級意向鎖與行級鎖的相容性如表6-4所示。

《MySQL技術内幕:InnoDB存儲引擎》筆記

6.3.2 一緻性非鎖定讀

  很重要,建議看書

  一緻性非鎖定讀(consistent nonlocking read)是指InnoDB存儲引擎通過行多版本控制( multi versioning)的方式來讀取目前執行時間資料庫中行的資料。如果讀取的行正在執行DELETE或UPDATE操作,這時讀取操作不會是以去等待行上鎖的釋放。相反地,InnoDB 存儲引擎會去讀取行的一個快照資料。如圖6-4所示。

《MySQL技術内幕:InnoDB存儲引擎》筆記

  之是以稱其為鎖定讀,因為不需要等待通路行上X鎖的釋放,快照資料是指該行的之前版本的資料,該實作是通過undo段來完成。

        在事務隔離級别READ COMMITTED和REPEATABLE READ (InnoDB存儲引擎的預設事務隔離級别)下,InnoDB 存儲引擎使用非鎖定的一緻性讀。然而,對于快照資料的定義卻不相同。在READ COMMITTED事務隔離級别下,對于快照資料,非一緻性讀總是讀取被鎖定行的最新一份快照資料。而在REPEATABLE READ事務隔離級别下,對于快照資料,非一緻性讀總是讀取事務開始時的行資料版本。 這就是為什麼READ COMMITTED時候能讀到修改後的資料,而REPEATABLE READ不能讀到修改後的資料,以為你他們讀的版本不一樣。

6.3.3 一緻性鎖定讀

 在預設配置下,即事務的隔離級别為REPEATABLE READ模式下,innoDB存儲引擎的SELECT操作使用的是一緻性非鎖定讀。

但在某些情況下,使用者需要顯式地對資料庫讀取操作進行加鎖以保障資料邏輯的一緻性。而這要求資料庫支援加鎖語句。

SELECT 。。。FOR UPDATE:對讀取的行加了一個X鎖,其他事務不能對已鎖定的行加任何鎖。

SELECT。。。LOCK IN SHARE MODE:對讀取的行加了一個S鎖。

6.3.4 自增長與鎖

     在Innodb存儲引擎中,自增長值的列必須是索引,同時必須是索引的第一個列。如果不是第一個列,則MySQL資料庫會抛出異常。

6.4 鎖的算法(賊重要)

6.4.1 行鎖的3種算法

  • Record Lock:單個行記錄上的鎖
  • Gap Lock:間隙鎖,鎖定一個範圍,但不包含記錄本身。
  • Next-key Lock:Gap Lock+Gap Lock ,鎖定一個範圍,并且鎖定記錄本身。

對于唯一鍵值的鎖定,Next-Key Lock降級為Record Lock僅存在于查詢所有的唯一索引列。若唯一索引由多個列組成,而查詢僅是查找多個唯一索引列中的其中一個,那麼查詢其實是range類型查詢,而不是point類型查詢,故InnoDB存儲引擎依然使用Next-Key Lock進行鎖定。

案例:

表如下

CREATE TABLE `z` (
  `a` int(11) NOT NULL DEFAULT '0',
  `b` int(11) DEFAULT NULL,
  PRIMARY KEY (`a`),
  KEY `b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;      
《MySQL技術内幕:InnoDB存儲引擎》筆記
步驟 事務1 事務2
1 begin;
2 begin;
3 SELECT * FROM z WHERE b = 3 for update;
INSERT INTO z SELECT 2,2;(阻塞、阻塞、阻塞)
5

步驟3的時候,此時給主鍵索引5加了X鎖,給輔助索引(1,3)(3,6)加了X鎖;是以步驟4的時候是阻塞的。

步驟3加了兩個鎖:在主鍵索引a上加了Record Lock,在輔助索引b上加了Gap Lock

6.4.2 解決Phantom Problem(幻讀問題)

   Phantom Problem是指在同一事務下,連續執行兩次同樣的SQL語句可能導緻不同的結果,第二次的SQL語句可能會傳回之前不存在的行。

  在預設的隔離級别下,即可重複讀,InnoDB存儲引擎采用Next-Key Locking機制避免幻讀問題。

6.5 鎖問題

很重要。。。看書吧

6.6 阻塞

 在預設的情況下InnoDB存儲引擎不會復原逾時引發的錯誤異常。

6.8 鎖更新

   鎖更新是指将目前鎖的粒度降低。

        假設一張表有3 000 000個資料頁,每個頁大約有100條記錄,那麼總共有300 000 000條記錄。若有一個事務執行全表更新的SQL語句,則需要對所有記錄加X鎖。若根據每行記錄産生鎖對象進行加鎖,并且每個鎖占用10位元組,則僅對鎖管理就需要差不多需要3GB的記憶體。而InnoDB存儲引擎根據頁進行加鎖,并采用位圖方式,假設每個頁存儲的鎖資訊占用30個位元組,則鎖對象僅需90MB的記憶體。由此可見兩者對于鎖資源開銷的差距之大。

第7章 事務

7.1 認識事務

7.1.1 概述

原子性(automicity)

一緻性(consistency)

隔離性(isolation)

持久性(durability)

7.1.2 分類

  • 扁平事務(Flat Transactions)

我們平時最常用的事務,就是扁平事務。

  • 帶有儲存點的扁平事務(Flat Transactions with Savepoints)
BEGIN;//開啟事務
INSERT INTO student VALUES(5,"5",5);
SAVEPOINT x;//設定儲存點為X
INSERT INTO student VALUES(6,"6",6);
INSERT INTO student VALUES(7,"7",7);
ROLLBACK TO x;//復原到儲存點X
INSERT INTO student VALUES(8,"8",8);
COMMIT;//隻插入5和8      
  • 鍊事務(Chained Transactions)
  • 嵌套事務(Nested Transactions)
  • 分布式事務(Distributed Transactions)

7.2 事務的實作(很重要,建議看書)

redo log稱為重做日志,用來保證事務的原子性和持久性。undo log用來保證事務的一緻性。

redo恢複送出事務修改的頁操作,而undo復原行記錄到某個特定的版本。是以兩者記錄的内容不同。

redo通常是實體日志,記錄的是頁的實體修改操作。undo是邏輯日志,根據每行記錄進行記錄。

7.2.1 redo

 重做日志用來實作事務的持久性,其又兩部分組成:一是記憶體中的重做日志緩沖(redo log buffer),其是易失的;二是重做日志檔案(redo log file),其實持久的。

bin log和redo log的不同:

《MySQL技術内幕:InnoDB存儲引擎》筆記

7.2.2 undo

   undo是邏輯日志。

當事務送出時,InnoDB存儲引擎會做一下兩件事情:

  1. 将nudo log 放入清單中,以供之後的purge操作
  2. 判斷undo log所在的頁是否可以重用,弱可以配置設定給下個事務使用。

7.2.3 purge

很重要,略。。。

用來清理undo log的。

總結

1)版本不同,可能參數名稱不同

2)動手做一做,比一直看要好

3)了解了一下 explan的實用,本文沒講,但是用到了

4)搭建資料庫的時候開啟二進制日志,有利無害

SQL測試資料

CREATE TABLE `bigdata` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=48344397 DEFAULT CHARSET=utf8;      
CREATE DEFINER=`root`@`%` PROCEDURE `createDataInBigdata`()
BEGIN
  #Routine body goes here...
  declare i int;
  set i = 0;
  while i<5000000000 do
   INSERT into bigdata (username,password,age,create_time) VALUES(
substring(md5(rand()),1,10),
substring(md5(rand()),1,10),
FLOOR((RAND() * 100)),now());
   set i=i+1;
  end while;
END      

參考