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

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

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

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

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

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

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

二、文件

1、查看 MySQL 的參數配置

SHOW VARIABLES

2、錯誤日誌(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 、1、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 爲後綴名的文件,這個文件記錄了該表的表結構定義。

4、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';

5、InnoDB 重做(REDO)日誌文件對於 InnoDB 存儲引擎至關重要,它們記錄了 InnoDB 存儲引擎的事務日誌,記錄了關於每個頁(Page)的更改的物理情況。重做日誌文件跟 binlog 日誌文件不同,binlog 日誌記錄了所有與 MySQL 數據庫有關的日誌記錄,包括 InnoDB、MyISAM、Heap 等其他存儲引擎的日誌。

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

三、表

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

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

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

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

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

頁是 InnoDB 磁盤管理的最小單位,默認每個頁的大小是 16K,可以通過參數 innodb_page_size 設置。然後每個頁兩行數據,所以每行最大 8K 數據。

4、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,就是說每條記錄所佔用的字節是動態的。其優點節省空間,缺點增加讀取的時間開銷。

5、關係型數據庫系統和文件系統的一個不同點是,文件系統一般需要在程序端進行控制以保證存儲數據的完整性,而關係數據庫本身能保證存儲數據的完整性,不需要應用程序的控制,比如主鍵約束、唯一鍵約束、外鍵約束等等(唯一索引是可以允許有 NULL 值的)。

6、在某些設置下,MySQL 數據庫允許非法的或不正確的數據插入或更新,如向 EUNM 約束中插入一個非法值,又或者可以在數據庫內部將其轉化爲一個合法的值,如向 NOT NULL 的字段插入一個 NULL 值,MYSQL 數據庫會將其更改爲 0 再進行插入,因此數據庫本身沒有對數據的正確性進行約束,只會得到一個 WARNINGS 提示,通過設置參數 sql_mode 的值爲 STRICT_TRANS_TABLES 對於輸入值的合法性進行約束。

SHOW GLOBAL VARIABLES LIKE 'sql_mode'

7、視圖的主要用途之一是被用作一個抽象裝置。特別是對於一些應用程序,程序本身不需要關心基表的結構,只需要按照視圖定義來取數據或更新數據,因此,視圖同時在一定程度上起到一個安全層的作用。

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

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

四、備份和恢復

1、可以根據備份的方法不同將備份分爲:

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

2、可以根據備份後文件的內容不同將備份分爲:

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

3、MySQL 數據庫本身提供的工具並不支持真正的增量備份,藉助 xtrabackup 工具可以完成 InnoDB 存儲引擎的增量備份;

4、複製(replication)是 MySQL 數據庫提供的一種高可用性能的解決方案,一般用來建立大型的應用。總體來說,replication 的工作原理分爲以下三個步驟:

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

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

五、其它

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

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

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

SHOW GLOBAL STATUS LIKE 'innodb%read%';

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

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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章