《MySQL技術內幕:InnoDB存儲引擎》讀書筆記.

1、MySQL 體系架構和存儲引擎

一、MySQL 被設計成一個單進程多線程架構的數據庫,MySQL 數據庫實例在系統上的表現就是一個進程。html

二、MySQL 的體系架構,須要特別注意的是,存儲引擎是基於表的,而不是數據庫。
mysql

三、InnoDB 存儲引擎是面向在線事務處理(OLTP)應用的首選,其特色是:支持事務、支持外鍵、聚簇索引、行鎖設計、基於 MVCC 來得到高併發性,使用一種被稱爲 next-keylocking 的策略來避免幻讀,還提供了插入緩衝(insert buffer)、二次寫(double write)、自適應哈希索引(adaptive hash index)、預讀(read ahead)等高性能和高可用的功能。InnoDB 存儲引擎在 1.2 版本中新增了全文索引等內容。git

MyISAM 存儲引擎不支持事務、表鎖設計、支持全文索引,主要是面向一些在線分析處理(OLAP)數據庫應用。MyISAM 存儲引擎表由 MYD 和 MYI 組成,MYD 用來存放數據文件,MYI 用來存放索引文件。MyISAM 存儲引擎的另外一個不同凡響的地方是它的緩衝池只緩存索引文件,而不緩存數據文件,這點和大多數的數據庫都很是不一樣。github

Memory 存儲引擎不支持事務、表鎖設計、支持哈希索引、併發性能較差,而且不支持 TEXT 和 BLOB 列類型。Memory 存儲引擎將表中的數據存放在內存中,若是數據庫重啓或者崩潰,表中的數據都將消失,它很是適合用於存儲臨時數據的臨時表,以及數據倉庫中的緯度表。Memory 存儲引擎默認使用哈希索引,而不是咱們熟悉的 B+ 樹索引。算法

2、文件

一、查看 MySQL 的參數配置sql

SHOW VARIABLES

二、錯誤日誌(error log)文件對 MySQL 的啓動、運行、關閉過程當中進行了記錄。數據庫

SHOW VARIABLES LIKE 'log_error'

慢查詢日誌(slow log)文件記錄了可能存在問題的 SQL 語句,可根據慢查詢日誌進行 SQL 語句層面的優化。數組

# 記錄沒有使用索引的 SQL 語句
SHOW VARIABLES LIKE 'log_queries_not_using_indexes';
# 容許記錄到 slow log 且未使用索引的 SQL 語句次數
SHOW VARIABLES LIKE 'log_throttle_queries_not_using_indexes'
# 大於該時間的 SQL 語句都會被記錄下來
SHOW VARIABLES LIKE 'long_query_time';
# 指定慢查詢輸出的格式(FILE/TABLE)
SHOW VARIABLES LIKE 'log_output';

二進制日誌(binary log)記錄了對 MySQL 數據庫執行更改的全部操做,可是不包括 SELECT 和 SHOW 這類操做,由於這類操做對數據自己並無修改。二進制日誌在數據庫恢復、主從複製、審計等場景中獲得了普遍的應用。緩存

要查看二進制日誌文件的內容,必須經過 MySQL 提供的工具 mysqlbinlog。安全

# 單個二進制文件的最大值
SHOW VARIABLES LIKE 'max_binlog_size';
# 二進制日誌緩衝,基於會話,全部未提交的二進制日誌都會被緩衝
SHOW VARIABLES LIKE 'binlog_cache_size';
# 二進制日誌文件記錄緩衝與記錄臨時文件的次數
SHOW GLOBAL STATUS LIKE 'binlog_cache%';
# 表示每寫緩衝多少次就同步到磁盤,該參數的有效值爲0 、一、N;
# 0:默認值,事務提交後,將 binlog 日誌寫入操做系統緩存,不當即刷新到磁盤;
# 1:事務提交後,將 binlog 日誌寫入操做系統緩存並當即刷新到磁盤,即同步寫磁盤;
# N:每寫 N 次操做系統緩存就執行一次刷新操做;
SHOW VARIABLES LIKE 'sync_binlog'
# slave 角色配置,從 master 取得 bin_log 日誌寫入到本身的二進制日誌文件中
SHOW VARIABLES LIKE 'log_slave_updates%'
# 動態參數,記錄二進制日誌文件的格式,STATEMENT/ROW/MIXED,一般設置爲 ROW
SHOW VARIABLES LIKE 'binlog_format'

3、由於 MySQL 插件式存儲引擎體系結構的關係,MySQL 數據的存儲是根據表進行的,每一個表都會有與之對應的文件,但不論表採用何種存儲引擎,MySQL 都有一個以 frm 爲後綴名的文件,這個文件記錄了該表的表結構定義。

四、InnoDB 採用了將存儲的數據按表空間(tablespace)進行存放的設計,innodb_data_file_path 參數用來設置默認的表空間,全部基於 InnoDB 存儲引擎的表數據都會記錄到默認的表空間中,若設置了參數 innoDB_file_per_table,每一個基於 InnoDB 存儲的表都將產生一個獨立的表空間,命名規則爲:表名.ibd,獨立的表空間僅存儲該表的數據、索引和插入緩衝 BITMAP 等信息,其他信息(如回滾(undo)信息、插入緩衝索引頁、系統事務信息、二次寫緩衝(doublewrite buffer)等)仍是存放在默認的表空間中。

SHOW VARIABLES LIKE 'innodb_data_file_path';
SHOW VARIABLES LIKE 'innodb_file_per_table';

五、InnoDB 重作(REDO)日誌文件對於 InnoDB 存儲引擎相當重要,它們記錄了 InnoDB 存儲引擎的事務日誌,記錄了關於每一個頁(Page)的更改的物理狀況。重作日誌文件跟 binlog 日誌文件不一樣,binlog 日誌記錄了全部與 MySQL 數據庫有關的日誌記錄,包括 InnoDB、MyISAM、Heap 等其餘存儲引擎的日誌。

六、redo log 稱爲重作日誌,恢復提交事務修改的頁操做,用來保證事務的原子性和持久性;undo log 稱爲回滾日誌,幫助回滾行記錄到某個特定版本及 MVCC 的功能,用來保證事務的一致性。

3、表

一、表是關於特定實體得數據集合,這也是關係型數據庫模型的核心。

二、在 InnoDB 存儲引擎中,表都是根據主鍵順序組織存放的,這種存儲方式的表稱爲索引組織表(index organized table),能夠參考 聚簇索引。所以,InnoDB 存儲引擎表老是 B+ 樹索引組織的。

三、從 InnoDB 存儲引擎的邏輯存儲結構看,全部數據都被邏輯地存放在一個空間中,稱之爲表空間(tablespace)。表空間又由段(segment)、區(extent)、頁(page)組成。

常見的段有數據段、索引段、回滾段等。數據段即爲 B+ 樹的葉子節點,索引段即爲 B+ 樹的非索引節點;

區是由連續頁組成的空間,在任何狀況下每一個區的大小都爲 1MB。

頁是 InnoDB 磁盤管理的最小單位,默認每一個頁的大小是 16K,能夠經過參數 innodb_page_size 設置。而後每一個頁兩行數據,因此每行最大 8K 數據。

四、InnoDB 存儲引擎和大多數數據庫同樣,記錄是以行的形式存儲的,InnoDB 存儲引擎提供了 Antelope(Compact、Redundant)、Barracuda(Dynamic、Compressed、FIXED)等格式 來存放行記錄數據,能夠經過命令 SHOW TABLE STATUS LIKE 'table_name' 來查看當前表使用的行格式。

SHOW GLOBAL VARIABLES LIKE '%FILE_FORMAT%';
SHOW TABLE STATUS LIKE 'table_name';
ALTER TABLE `table_name` ROW_FORMAT = FIXED;

Antelope 存儲格式會把每一個字段的前 864 個字節存儲在 PAGE 裏,因此你的字段超過必定數量的話,單行大小就會超過 8K。

Barracuda 存儲格式對字段的處理方式是在 PAGE 裏頭存儲一個 20byte 大小的指針,其它全存在溢出區,因此輕易超不了 8K。

Compressed 行記錄格式的另外一個功能就是,存儲在其中的行數據會以 zlib 的算法進行壓縮,所以對於 BLOB、TEXT、VARCHAR 這類大長度類型的數據能進行很是有效的存儲。

若一張表裏面不存在varchar、text以及其變形、blob以及其變形的字段的話,那麼張這個表其實也叫靜態表,即該表的 row_format 是 fixed,就是說每條記錄所佔用的字節同樣。其優勢讀取快,缺點浪費額外一部分空間。

若一張表裏面存在varchar、text以及其變形、blob以及其變形的字段的話,那麼張這個表其實也叫動態表,即該表的 row_format 是 dynamic,就是說每條記錄所佔用的字節是動態的。其優勢節省空間,缺點增長讀取的時間開銷。

五、關係型數據庫系統和文件系統的一個不一樣點是,文件系統通常須要在程序端進行控制以保證存儲數據的完整性,而關係數據庫自己能保證存儲數據的完整性,不須要應用程序的控制,好比主鍵約束、惟一鍵約束、外鍵約束等等(惟一索引是能夠容許有 NULL 值的)。

六、在某些設置下,MySQL 數據庫容許非法的或不正確的數據插入或更新,如向 EUNM 約束中插入一個非法值,又或者能夠在數據庫內部將其轉化爲一個合法的值,如向 NOT NULL 的字段插入一個 NULL 值,MYSQL 數據庫會將其更改成 0 再進行插入,所以數據庫自己沒有對數據的正確性進行約束,只會獲得一個 WARNINGS 提示,經過設置參數 sql_mode 的值爲 STRICT_TRANS_TABLES 對於輸入值的合法性進行約束。

SHOW GLOBAL VARIABLES LIKE 'sql_mode'

七、視圖的主要用途之一是被用做一個抽象裝置。特別是對於一些應用程序,程序自己不須要關心基表的結構,只須要按照視圖定義來取數據或更新數據,所以,視圖同時在必定程度上起到一個安全層的做用。

# 查看基表
SELECT * FROM information_schema.TABLES WHERE table_type ='BASE TABLE' AND table_schema = database();
# 查看視圖
SELECT * FROM information_schema.VIEWS WHERE table_schema = database();

八、視圖是基於基表的一個虛擬表,基於視圖的更新操做,其本質都是經過視圖的定義來更新基本表。

4、備份和恢復

一、能夠根據備份的方法不一樣將備份分爲:

  • Hot Backup(熱備):數據庫運行中直接備份,對正在運行的數據庫操做沒有任何的影響;
  • Cold Backup(冷備):數據庫中止的狀況下複製,通常只須要複製相關的數據庫物理文件(.frm、.ibd 等)便可;
  • Warm Backup(溫備):數據庫運行中進行,會對當前數據庫的操做有所影響,如加一個全局讀鎖以保證備份數據的一致性;

二、能夠根據備份後文件的內容不一樣將備份分爲:

  • 邏輯備份:通常是文本文件,內容可讀,內容通常由一條條 SQL 語句構成,可使用 mysqldump 工具完成;
  • 裸文件備份:複製數據庫的物理文件,既能夠是在數據庫運行中的複製(如 ibbackup、xtrabackup 這類工具),也能夠是在數據庫中止運行時直接的數據文件複製;

三、MySQL 數據庫自己提供的工具並不支持真正的增量備份,藉助 xtrabackup 工具能夠完成 InnoDB 存儲引擎的增量備份;

四、複製(replication)是 MySQL 數據庫提供的一種高可用性能的解決方案,通常用來創建大型的應用。整體來講,replication 的工做原理分爲如下三個步驟:

1)主服務器(master)把數據更改記錄到二進制日誌(binlog)中;
2)從服務器(slave)把主服務器的二進制日誌複製到本身的中繼日誌(relay log)中;
3)從服務器重作中繼日誌中的日誌,把更改應用到本身的數據庫上,以達到數據的最終一致性;(從服務器有 2 個線程,一個是 I/O 線程,負責讀取主服務器的二進制日誌,並將其保存爲中繼日誌;另外一個是 SQL 線程,負責執行中繼日誌)

# 查看主服務器中二進制日誌的狀態
SHOW MASTER STATUS;
# 查看從服務器中二進制日誌的狀態(主從服務器上 binlog 日誌的偏移量,就能夠得知 I/O 線程的延遲)
SHOW SLAVE STATUS;

5、其它

一、OLAP 的應用適用 CPU 密集型的數據庫;OLTP 的應用適用於 IO 密集型的數據庫;

# 檢查當前數據庫的運行狀態,顯示有哪些線程在運行
SHOW FULL PROCESSLIST;

二、內存的大小是最能直接反映數據庫的性能,所以,應該在開發應用前預估「活躍」數據庫的大小是多少,並以此肯定數據庫服務器內存的大小。能夠經過查看當前服務器的狀態,比較物理磁盤的讀取和內存讀取的比例來判斷緩存池的命中率,一般 InnoDB 存儲引擎的緩存池的命中率不該該小於 99%;

SHOW GLOBAL STATUS LIKE 'innodb%read%';

三、RAID(Redundant Array of Independent Disks,獨立磁盤冗餘數組)的基本思想就是把多個相對便宜的硬盤組合起來,成爲一個磁盤數組,使性能達到甚至超過一個價格昂貴、容量巨大的硬盤;

四、sysbench 是一個模塊化的、跨平臺的多線程基準測試工具,主要用於測試各類不一樣系統參數下的數據庫負載狀況;

五、TPC(Transaction Processing Performance Conuncil,事務處理性能協會)是一個用來評價大型數據庫系統軟硬件性能的非盈利組織。TPC-C 是 TPC 協會制定的,用來測試典型的複雜 OLTP(在線事務處理)系統的性能。tpcc-mysql 是開源的 TPC-C 測試工具,徹底遵照 TPC-C 的標準,專用於 MySQL 基準測試;

相關文章
相關標籤/搜索