1. 程式人生 > >MySQL 5.7基礎之innodb儲存引擎總結

MySQL 5.7基礎之innodb儲存引擎總結

一、innodb初探:

1、MySQL日誌檔案:

①:slow.log 檔案會記錄慢查詢日誌,當一條語句執行時間超過在配置引數long_query_time中指定的值時,這條語句就會被記錄在這個檔案中;

②:error.log 檔案會記錄一些系統啟動或執行時的錯誤或警告資訊,通過配置引數log_error來設定;

③:general.log 檔案會記錄所有在資料庫上執行的語句,經常用來追蹤問題,但會影響一點效能,所以一般不會開啟,只有在除錯的時候會偶爾開啟。(如果在QPS很高的情況下,這個檔案可能會非常大不太好處理一般不建議開啟)

2、MySQL系統的datadir目錄下,有一個目錄叫MySQL:

 這個目錄實際上是MySQL資料庫的一些系統表,比如許可權、使用者等,但這些表都是MyISAM儲存引擎的表;

3、預設的3個數據庫例項:information_schema  performance_schema  sys

①:information_schema :

  information_schema資料庫是MySQL自帶的,它是一個資訊資料庫,其中儲存著關於MySQL伺服器維護的所有其他資料庫的資訊,如資料庫名、資料庫表、表列的資料型別及訪問許可權等;在該資料庫中有數個只讀表,它們實際上是檢視,而不是基本表;

②:performance_schema:

  performance_schema資料庫是在MySQL5.5新增的,命名為performance_schema,該資料庫它是針對性能的,主要用於收集資料庫伺服器效能引數。該資料庫有如下功能:

  提供程序等待的詳細資訊,包括鎖、互斥變數、檔案資訊;

  儲存歷史事件彙總資訊,為判斷MySQL伺服器效能做出詳細的依據

  新增或刪除監控事件點都非常不容易,並可以隨意改變MySQL伺服器的監控週期;

③:sys:

注意:這個庫是通過檢視的形式把information_schema和performance_schema結合起來的,查詢出讓人更加容易理解的結果;但是前提是,sys庫本身的資訊來源要依賴information_schema;

4、innoDB儲存引擎包括兩個預設的日誌檔案,

  日誌檔案大小通過引數innodb_log_file_size來設定,個數通過引數innodb_log_files_in_group來設定。這幾個日誌檔案的大小被設定後在執行過程中是不能被改變的,如果要修改需要關閉資料庫然後修改;

--注意:innodb儲存引擎還有一個小檔案,db.opt 這個檔案儲存的是MySQL資料庫的一些配置資訊,例如編碼,排序的資訊,如果在建立資料庫時指定一些非預設的引數的話就會在這個檔案中儲存這些資訊;

二、innodb資料字典:

1、在MySQL中是看不到資料字典的,原因就是MySQL是一個外掛式的資料庫管理系統,它的結構分兩層,分別是server層和儲存引擎層,這兩層需要相互配合才能一起友好的工作,但是作為一個外掛式的資料庫管理系統,儲存引擎層可以有多個儲存引擎的外掛,但server層只有一個;最早的預設儲存引擎為MyISAM,它是沒有資料字典的,關於表結構,它所擁有的只有.frm檔案,所以這導致了innodb也必須要有這個檔案才能使得server層識別並管理它;

2、innodb有4個最基本的系統表,

 用來儲存使用者定義的表、列、索引及索引列等資訊,這些表分別為:sys_tables  sys_columns  sys_indexes  sys_fields

①:sys_tables表:用來儲存所有以innodb為儲存引擎的表,每條記錄對應已經定義的一個表;

  name:表示一個表名

  ID:表的ID號

  N_COLSL :表示這個表的列的個數,建表指定的列數(4個位元組)

  type:表示這個表的儲存型別,包括記錄的格式、壓縮等資訊(4個位元組)

  space:表示這個表所在的表空間ID號;

  (其中,mix_id  mix_len  cluster_name這三個位置暫時使用不到)

②:sys_columns:用來儲存innodb中定義的所有表中所有列的資訊,每一列對應這個表中的一條記錄;

  table_id :表示這個列所屬的表的ID號;

  pos :表示這個列在表中是第幾列;

  name :表示這個列的列名

  mtype :表示這個列的主資料型別;

  prtype :表示這個列的一些精確資料型別,它是一個組合值,包括null標誌,是否有符號數的標誌,是否是二進位制字串的標誌及表示這個列是真的varchar;

  len :表示這個列的資料長度,但不包括varchar型別,因為這個型別在記錄裡面儲存了資料長度

  prec :表示這個列資料的精度,但目前好像沒有使用;

③:sys_indexes:用來儲存innodb中所有表的索引資訊,每條記錄對應一個索引;

  table_id :表示這個索引所屬的表的ID號

  ID :表示這個索引的索引ID號

  name :表示這個索引的索引名;

  n_fields :表示這個索引包含的列個數;

  type :表示這個索引的型別,包括聚簇索引、唯一索引、等

  space :表示這個索引資料所在表空間ID號;

  page_no :表示這個索引對應的B+樹的根頁面;

④:sys_fields :用來儲存所有索引中定義的索引列,每一條記錄對應一個索引列

  index_id :這個列所在的索引

  pos :這個列在某個索引中是第幾個索引列;

  col_name :這個索引列的列名;

3、字典表載入:

  在innodb啟動的時候,如果是新建資料庫,則需要初始化庫,所以首先需要做的就是建立字典管理的B+樹等資訊,在這些初始化操作之後,就通過函式dict_boot載入常駐記憶體的四個系統表並讀取一些其他資訊;

4、rowid管理:

  在innodb中,使用者表中的記錄不一定都會有一個rowid列,rowid只有在一個表沒有定義主鍵時,也就是需要rowid作為聚簇索引列的時候才會被分配給這個表。而rowid的管理分配,並不是一個表獨享一個ID空間,而是全域性的,所有表都共享這個ID號;

三、innodb資料儲存結構 

1、表空間檔案組成結構

  innodb儲存引擎在儲存設計上模仿了Oracle的儲存結構,其資料是按照表空間進行管理的。新建一個數據庫時,innodb儲存引擎會初始化一個名為ibdata1 的表空間檔案,預設情況下,這個檔案會儲存所有表的資料,以及我們所熟知但看不到的系統表sys_tables、sys_columns、sys_indexes 、sys_fields等。此外,還會儲存用來保證資料完整性的回滾段資料,當然這部分資料在新版本的MySQL中,已經可以通過引數來設定回滾段的儲存位置了;

  innodb儲存引擎的設計很靈活,可以通過引數innodb_file_per_table來設定,使得每一個表都對應一個自己的獨立表空間檔案,而不是儲存到公共的ibdata1檔案中。獨立的表空間檔案之儲存對應表的B+樹資料、索引和插入緩衝等資訊,其餘資訊還是儲存在預設表空間中。

  這個檔案所儲存的內容主要就是B+樹(索引),一個表可以有多個索引,也就是在一個檔案中,可以儲存多個索引,而如果一個表沒有索引的話,用來儲存資料的被稱為聚簇索引,也就是說這也是一個索引。最終的結論是,ibd檔案儲存的就是一個表的所有索引資料;

2、段:

  段是表空間檔案中的主要組織結構,它是一個邏輯概念,用來管理物理檔案,是構成索引、表、回滾段的基本元素。建立一個索引(B+樹)時會同時建立兩個段,分別是內節點段和葉子段,內節點段用來管理(儲存)B+樹非葉子(頁面)的資料,葉子段用來管理(儲存)B+樹葉子節點的資料;也就是說,在索引資料量一直增長的過程中,所有新的儲存空間的申請,都是從“段”這個概念中申請的。一個索引,包括兩個段,那麼一個表的段的數目就是索引的個數乘以2了。(更形象的解釋:ibd檔案,就是由多個段組成的,沒有任何其他空間是脫離了段的管理。)

3、簇:

  innodb引入了簇的概念,在程式碼中被稱為extent;

  簇是構成段的基本元素,一個段由若干個簇構成。一個簇是物理上連續分配的一個段空間,每一個段至少會有一個簇,在建立一個段時會建立一個預設的簇。如果儲存資料時,一個簇已經不足以放下更多的資料,此時需要從這個段中分配一個新的簇來存放新的資料。一個段所管理的空間大小是無限的,可以一直擴充套件下去,但是擴充套件的最小單位就是簇。簇的空間大小是固定的,一般是64個頁面;(簇是實際的物理儲存空間)

4、頁面:

  “頁面”是簇細分之後的產物,它是簇的組成單位,也是段所管理的最小單位、資料檔案管理的最小單位,當然也是檔案中空間分配的最小單位。

  一個簇中可以包括多個頁面(預設為64個頁面,每個頁面是16KB),這個頁面數通常被叫做“簇的大小”。這些頁面都歸這個簇管理,在邏輯上(頁面號都是從小到大連續的)及物理上都是連續的。在向表中插入資料時,如果一個頁面已經被寫完,系統會從當前簇中分配一個新的空閒頁面處理使用,如果當前簇中的64個頁面都被分配完,系統會從當前頁面所在段中分配一個新的簇,然後再從這個簇中分配一個新的頁面來使用;(更簡單的說:表空間檔案就是被劃分成相等長度的塊,每一個塊就是一個頁面,一個頁面預設為16KB,一個檔案中沒有任何空間是脫離了段的管理而存在的)

---注意:沒有任何空間不是一頁面的形式而存在的。

5、段、簇、頁面組織結構:

  一個表空間可以有多個檔案,每個檔案都有各自的編號,建立一個表空間時,至少有一個檔案,這個檔案被稱為“0號檔案”。一個檔案是被切割為等長“預設16KB”的塊,這個塊通常被稱為頁面,那麼在“0號檔案”的第一個頁面(page_no為0)中,儲存了這個表空間中所有段簇也管理的入口,那麼在這個頁面儲存的資料就是16KB,但通常會有頁面頭資訊會佔用一些空間,真正的管理資訊資料是從頁面偏移為fil_page_data(38)的位置開始的,這個位置儲存了表空間的描述資訊;

---注意:

①:表空間控制資訊有:滿簇連結串列、半滿簇連結串列、空閒簇連結串列,而段的inode資訊中也有這些資訊;表空間中的連結串列管理的是整個表空間中所有的簇,包括滿    簇、半滿簇及空閒簇,而段的iNode資訊中管理的是屬於自己段中的滿簇、半滿簇及空閒簇。

②:在innodb中,一個簇描述頁面要管理16384個頁面,簇大小預設為(fsp_extent_size)64個,而簇描述符的大小為40B,所以一個簇描述頁面中可以描述的簇的個數為(univ_page_size-頁面頭長度)/40,其中univ_page_size=16384B表示頁面大小;在一個表空間中,簇描述頁面的儲存是每隔16384個頁面就有一個簇描述頁面,所以簇描述頁面中只需要描述16384個頁面即可;

③:所謂的btr,在innodb中,表示的就是B+樹的處理,不管以它為開頭的是函式,還是檔案,都是相關的處理,是Btree的簡稱;