天天看點

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

作者介紹  楊奇龍

前阿裡資料庫團隊資深dba,主要負責淘寶業務線,經曆多次雙十一,有海量業務通路db架構設計經驗。

目前就職于有贊科技,負責資料庫運維工作,熟悉mysql性能優化,故障診斷,性能壓測。

一、innodb新特性 

1、 innodb buffer dump 功能增強      

mysql 5.7.5 版本新增innodb_buffer_pool_dump_pct參數,用于控制轉儲每個innodb buffer pool instance中innodb buffer pages的比例。之前的版本中該參數的預設值是100%。當觸發轉儲的時候 會全量dump innodb buffer pool中的pages。如果啟用新的參數比如40 ,每個innodb buffer pool instance中有100個 ,每次轉儲每個innodb buffer 執行個體中的40個pages。

注意:當innodb發現系統背景io資源緊張時,會主動降低該參數設定的比例。

2、支援多線程刷髒頁   

mysql 5.6.2版本中,mysql将刷髒頁的線程從master線程獨立出來,5.7.4版本之後,mysql系統支援多線程刷髒頁,線程的數量由innodb_page_cleaners參數控制,該參數不能動态修改,最小值為1 ,最大值支援64,5.7.7以及之前預設值是1 ,5.7.8版本之後修改預設參數為4。

當啟用多線程刷髒時,系統将重新整理innodb buffer instance髒頁的任務配置設定給各個空閑的刷髒頁的線程,如果設定的innodb_page_cleaners>innodb_buffer_pool_instances,系統會自動重置為innodb_buffer_pool_instances大小。

3、動态調整innodb buffer size

從5.7.5版本,mysql支援在不重新開機系統的情況下動态調整innodb_buffer_pool_size。resize的過程是以chunk(每個chunk的大小預設為128m)的為機關遷移pages到新的記憶體空間,遷移進度可以通過innodb_buffer_pool_resize_status 檢視。記住整個resize的大小是以chunk為機關的。

innodb_buffer_pool_chunk_size的大小,計算公式是innodb_buffer_pool_size / innodb_buffer_pool_instances,新調整的值必須是 innodb_buffer_pool_chunk_size*innodb_buffer_pool_instances的整數倍。如果不是整數倍,則系統則會調整值為大于兩者乘積的最大值。 

例子

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

online調整bp size的log記錄大緻過程:

計算要調整的bpsize

禁止ahi,清理所有的索引緩存

withdrawing block是周遊freelist 确定可以使用的空閑block

鎖住整個buffer pool 

遷移重新配置設定chunk/删除可以釋放的chunk 

設定innodb_buffer_pool_size為新的值

重新開啟ahi 

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

這個特性是最令衆多mysql dba期待的特性之一。以後線上動态擴容,縮容就無需做資料庫切換了,間接增強了系統的穩定性和dba的生活幸福感。

4、支援全局表空間

全局表空間可以被所有的資料庫的表共享,而且相比于file-per-table tablespaces. 使用共享表空間可以節約中繼資料方面的記憶體。(需要更深入的了解共享表空間,主要是大小收縮問題) 

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

5、行格式預設為dynamic

從mysql 5.7.9開始,行格式dynamic取代compact 成為innodb存儲引擎預設的行格式,mysql提供了新的參數innodb_default_row_format來控制innodb 行格式,詳細的資訊請參考《specifying the row format for a table》。

6、支援原生的分區表

在mysql 5.7.6之前的版本中,建立分區表時mysql為每個分區建立一個ha_partition handler,自mysql 5.7.6之後,mysql支援原生的分區表并且隻會為分區表建立一個partition-aware handler,這樣的分區表功能增強節約分區表使用的記憶體。對于老版本建立的分區表在更新到新的版本之後怎麼處理呢?莫慌,5.7.9之後,mysql提供了如下更新方式解決這個問題:

alter table ... upgrade partitioning.

當然友情提示:從我個人的了解來看,在沒有合适的自動化維護分區表系統的基礎上,不推薦使用分區表。四年的工作經曆已經數次在分區表上掉坑裡了。

7、支援truncate undo logs 

mysql 5.7.5版本開始支援truncate undo 表空間中的undo log。啟用該特性必須設定innodb_undo_log_truncate=[on|1]。大緻原理是系統必須設定至少兩個undo 表空間(初始化的時候設定 innodb_undo_tablespaces=2 ) 用于清理undo logs的切換。該特性的好處是解決了 ibdata 檔案一直增大的問題,減輕系統的空間使用。

二、對json格式的支援 

1、支援json

從mysql 5.7.8開始,mysql支援原生的json格式,即有獨立的json類型,用于存放json格式的資料。json格式的資料并不是以string格式存儲于資料庫而是以内部的binary格式,以便于快速的定位到json格式中值。

在插入和更新操作時mysql會對json類型做校驗,已檢查資料是否符合json格式,如果不符合則報錯。同時5.7.8版本提供了四種json相關的函數,進而不用周遊全部資料。

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

我們通過簡單的例子來對json有一定的認識。

建立

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

初始化 

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)
迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

修改

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

删除 

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

檢視json的key

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

其他函數的用法請感興趣的讀者朋友自行參考《官方文檔》。

mysql 5.7版本提供的json格式以及對應的操作函數極豐富了mysql的存儲格式,可以在一定程度上和mongodb和pg競争,對于經常使用mysql varchar 存儲json的業務是一個福音。同時再強調一下對于oltp業務的表結構設計 盡可能的避免大字段存儲。一來是減少不必要的查詢帶來的io,帶寬,記憶體方面的影響 二來是 避免因為表大小太大導緻的ddl時間成本增加系統風險。

2、sys schema

mysql 5.7版本新增了sys資料庫,該庫通過視圖的形式把information_schema 和performance_schema結合起來,查詢出更加令人容易了解的資料,幫助dba快速擷取資料庫系統的各種緯度的中繼資料資訊,幫助dba和開發快速定位性能瓶頸。詳細的資訊請參考《官方文檔》,這裡給兩個例子能直覺的了解sys 功能的強大。

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

三、功能類新特性 

1、優化(工具方面)增強

5.7版本中如果一個會話正在執行sql,且該sql是支援explain的,那麼我們可以通過指定會話id,檢視該sql的執行計劃。

explain [options] for connection connection_id

該功能可以在一個會話裡面檢視另外一個會話中正在執行的長查詢。

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

2、hint功能增強

相比于mysql5.6版本的hint主要是index 級别的hint和控制表join順序的hint,5.7.7之後,mysql增加了優化器hint,來控制sql執行的方式,因為目前mysql支援nest loop join,故暫時無hint來修改sql的join方式。熟悉oracle的朋友是否會發現mysql和oracle在功能上越來越近了。話說回來5.7的hint (先别和 index hint 比較)的用法,和oracle的類似:

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

優化器級别的hint分四種類型 

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

其他更加詳細的資訊請參考《官方文檔》。

3、觸發器功能增強

5.7版本之前一個表對于每種action(insert,update, delete)和時機(before or after) 隻能支援一種類型的觸發器。新版本可以針對同一個action支援多個觸發器。

4、syslog功能

之前的版本,*nix系統上的mysql支援将錯誤日志發送到syslog是通過mysqld_safe捕獲錯誤輸出然後傳遞到syslog來實作的。新的版本原生支援将錯誤日志輸出到syslog,且适用于windows系統,隻需要通過簡單的參數(log_syslog等)配置即可。

mysql支援–syslog選項,可将在互動式模式下執行過的指令輸出到syslog中(*nix系統下一般是.mysql_history)。對于比對“ignore”過濾規則(可通過 –histignore選項或者 mysql_histignore環境變量進行設定)的語句不會被記入。

5、虛拟列

在mysql 5.7中,支援兩種generated column:

1)virtual generated column :隻将generated column儲存在資料字典中表的中繼資料,每次讀取該列時進行計算,并不會将這一列資料持久化到磁盤上;

注意:mysql 5.7.8以前 虛拟列字段不支援建立索引。5.7.8之後innodb支援在虛拟列建立輔助索引。

2)stored generated column : 将column持久化到存儲,會占用一定的存儲空間。與virtual column相比并沒有明顯的優勢,是以,mysql 5.7中,不指定generated column的類型,預設是virtual column。

建立虛拟列文法:

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

具體的例子

迄今最安全的MySQL?細數5.7那些驚豔與雞肋的新特性(中)

看到這個例子,熟悉oracle的朋友可能會和函數索引作比較,兩者比較類似.使用虛拟列達到函數索引或者解決業務上的設計缺陷,但是個人不建議使用類似的功能,因為虛拟列在一定程度上也會給後期運維帶來潛在的風險和複雜度。網絡上的例子基本都是使用虛拟列解決業務邏輯上的問題,違背了資料庫隻存儲資料的初衷,思考一下mvc架構的基本邏輯,業務邏輯要放到c層或者v層,m層隻存放資料即可。

6、小結

本文算是對5.7版本innodb、對json格式的支援和功能類新特性做收尾,後面會介紹主從複制、gtid、innodb性能優化方面以及資料庫更新相關的知識,這些特性更具有操作性,相對前面幾篇文章會更難寫。

<b></b>

<b>本文來自雲栖社群合作夥伴"dbaplus",原文釋出時間:2016-09-13</b>