歡迎光臨
每天分享高質量文章

連跳7個版本之後,MySQL 8.0.12有什麼新特性?

關註“高可用架構”獲得更多內容


引言


時隔三個月,MySQL 8.0.12 有什麼新內容?


今年4月份,MySQL突然直接從8.0.5跳過多個版本號到8.0.11,直接宣佈8.0.11 GA,告訴大家說,這個版本已經可以到線上用了。


到今年7月底,MySQL 8.0.12版本釋出,我從官方的release note裡面,選取出來我認為的重點內容,在這裡展開聊一下。



如果有想要看全文的人,可以直接去看官方的釋出內容:

https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-12.html


filesort 演演算法的快取設定最佳化


眾所周知,MySQL 在處理 Order by 的時候,如果沒有索引可以用,會採用一個名為 file sort 的演演算法排序,但和這個演演算法有一個關聯的引數, sort_buffer_size,估計很多人都知道這個引數,這個引數在之前有個算是比較蛋疼的問題:如果 sql 會話中,執行 sql 需要進行file sort,那麼 mysql 就會給當前回話直接分配 sort_buffer_size大小的記憶體出來。


這個乍一看沒啥問題,但需要註意的是,在 MySQL 中,沒辦法像 Oracle 那樣統一管理 PGA(使用者執行緒/行程消耗的總記憶體大小),遇到那種恰好會話數量比較多,filesort 比較多(哪怕SQL陳述句單拎出來效能沒啥問題),sql 查詢量比較大的情況,就非常容易讓 MySQL 的記憶體使用量超標被作業系統 OOM 了。


或者如果你有習慣設定 swap 空間,那麼巨慢的 swap 會拖死整個機器,只能揮淚重啟,類似這種事故,在網際網路業務中,並不鮮見,也間接導致了很多人非常厭惡 file sort,哪怕多加幾條索引,也要全改寫式地處理掉所有 file sort。


但現在,這個記憶體分配機制總算改變了,從 8.0.12 開始,這個記憶體分配變成了按需分配。也就是說,對於排序量非常小的 sql(比如某個人的微博串列)這種,觸發了file sort,就再也不會直接分配 sort_buffer_size(預設256KB)的大小了,而是分配很小的記憶體出來用,某種程度上可以避免了很多突發性流量導致的事故。


rewrite外掛支援DML陳述句


MySQL 從 5.7 開始,新增了一個 plugin 的介面,rewrite,用於在伺服器接受 SQL 陳述句後,執行前修改 SQL 陳述句,最初只是支援 select,從 8.0.12 開始,支援了 insert,update,replace 這些 DML 陳述句。


SELECT ORDER BYGROUP BY語法變更


8.0.12,8.0.13(未釋出版本,但檔案中已經更新內容)開始,MySQL 的 Order by 支援 GROUPING函式 以及 WITH ROLLUP語法,然後,在8.0.13開始,廢棄掉group gy 中的desc,asc關鍵字,對於 WITH ROLLUP 得到的結果集合的排序,需要使用order by 語法。


對於搞資料聚合比較多的人來說,WITH ROLLUP 與 GROUPING 應該不算陌生,這個語法變更,相當於是把 order by 的語法補全完整,更相容 SQL 標準語法了,如果遷移程式到 8.0,需要註意這種不相容的變更。


順帶一提,官方檔案此處寫的是小寫的 grouping,但實際上指的是 GROUPING函式 而非普通聚合函式(普通聚合函式一直是支援的)。參考程式碼:


https://github.com/mysql/mysql-server/commit/d401baf535a69d6f2a945229acecbfd5863c0a48


測試表資料

With rollup語法:



8.0.12 之前(測試版本為 5.7.22),如果想要排序,會出現語法錯誤:



需要寫為(排序關鍵字寫到 group by  裡面):


8.0.12 開始可以執行併排序(為了顯著效果增加了desc 關鍵字):


Group Replication繼續最佳化


新增了引數 group_replication_exit_state_action 來控制,如果一個實體發現自己屬於被拋棄(網路分割槽發生後的少數派)的實體的情況下,這個值預設為ABORT_SERVER,也就是說,少數派會自己關閉,這個值也可以設定為 READ_ONLY,這個設定下,會以只讀(設定super read only)的形式加入叢集,並設定狀態為 ERROR。


InnoDB Alter Table最佳化


這個可以說是一個源遠流長的故事,簡單來說,就是騰訊遊戲部門的 DBA 們,為了資料庫快速加列(遊戲運營先天的快速變更問題),寫了補丁出來用(非常早年的時候),後來這個補丁逐漸被各個第三方發行版接受,現在終於進入官方釋出版,讓更多的人受益。


MySQL 的 DDL一直是非常出名的問題,社群與官方都在這個問題上投入了很大的精力,從最早 percona 的 toolkit 裡面帶的 pt-osc(這個基於觸發器實現的線上改表,由於 MySQL 早年單表只支援一個觸發器,為了避免無法使用 pt-osc,有了早年一直流傳到現在的 MySQL重大守則之一:不許使用觸發器),到 github 釋出的 gh-ost(基於 row 格式 binlog),官方也一直在搞 alter 相關的線上修改最佳化(比如加索引等操作,參考連結 https://dev.mysql.com/doc/refman/8.0/en/innodb-create-index-overview.html)。


alter table 的 inplace 演演算法,實質上解決的,是主庫 DDL 不會導致讀寫鎖表,但對於主從結構,當 SQL 傳輸到從庫執行的時候,從庫依然會有相當大的延遲出現。因此實際上,對於延遲敏感性業務,依然是前面提到那倆工具的天下。


8.0.12的最佳化是,新增了一個演演算法 ALGORITHM=INSTANT,專門處理只需要修改元資料就可以完成的變更,這個就可以相對比較方便地直接使用了,不需要擔心從庫延遲。


目前支援的操作是:


  1. 新增新列。已知限制條件如下:

  • 不能與其他不支援INSTANT演演算法的alter子陳述句合併在一起。

  • 只能新增在表列的末尾。

  • 不能用於innodb的壓縮表(ROW_FORMAT=COMPRESSED)。

  • 標的表不能包含全文索引。

  • 標的表不能是臨時表。

  • 標的表不能是資料字典表。

  • 這種新增方式下,不會計算行長度是否合適,這個計算會在發生insert或者update的時候處理。

   2. 新增或者刪除虛擬列。

   3. 新增或者去掉列的預設值。

   4. 修改 enum,set 列型別的定義(題外話,有多少人知道併在用這個?)

   5. 修改索引型別。

   6. 重新命名錶名稱。


binlog支援管道輸入


對於大個頭 binlog 的處理,由於 MySQL mysqlbinlog 程式之前是不支援管道的,只能先解壓,之後再處理。從 8.0.12 開始,mysqlbinlog支援管道輸入了,簡單來說,就是下麵這麼一回事:

gzip -cd binlog-files_1.gz | ./mysqlbinlog – | ./mysql -uroot -p


當一條drop 陳述句裡麵包含了關聯的父子表,則會直接刪除,不在額外要求父子表順序正確


如題,對於每次刪表都需要關閉外來鍵檢查的人來說,無疑是個好訊息。


MySQL 外來鍵關聯刪表:

 

8.0,版本中,普通情況下,刪除父表:


報錯 3730

 

在更早的版本(5.7)中:


可以看出錯誤資訊,在 8.0 開始更加詳細了。


如果執行 drop table father,child:

必須寫成:

但是,在 8.0.12 開始:



ADMIN成為關鍵字


以後 SQL 欄位又少了一個常用的詞哎=_=。


是誰關閉了資料庫?


MySQL 終於會在日誌裡面記錄,是誰發的 shutdown 命令了。


MySQL 關閉資料庫:


 

那些或許很好玩的bug


下麵是從 bugfix 記錄中,找的一些好玩被修複的內容,註意——由於每個人笑點不同,如果只關註新特性修改的話,下麵的內容不看就不看了。


  1. 早前宣佈的新事務模型 VATS,由於其需要追蹤所有等待其他事務的事務數量,為了避免死鎖,目前被修改為生成出來的近似值。

  2. gtid_purge(記錄那些gtid事務已經被purge掉)的值,在Group Replication 執行期間,應該是不能被修改的,然而現在發現它是可以修改的,因此改為在 group replication 執行時候不能修改。

  3. 當 expire_logs_days 與 binlog_expire_logs_seconds 引數都設定的情況下,如果設定了 skip-log-bin ,現在開始這個資訊會被寫入錯誤日誌。

  4. 當有超大事務執行(binlog 量超過 binlog_cache_size)的時候,在刷出到臨時檔案期間,如果遇到磁碟滿導致的刷出失敗,事務回滾,這個資訊沒有被記錄在錯誤日誌裡面,並且,事務回滾後,快取也不會被清空。

  5. SUPER 許可權的使用者,沒辦法修改 keyring_operations 引數。

  6. It was possible to drop the Performance Schema. 哈哈哈哈哈。

  7. slave_rows_search_algorithms 指定了 row 格式複製時候,行匹配的的方式,指定為 INDEX_SCAN 的話,如果表上有索引,則會使用索引操作。但如果主從庫的同一張表,使用了不同的列作為主鍵,並且從庫表上還有唯一索引的情況下,bug 會導致使用 table scan(全表掃描)而非索引。

  8. 對於 MyISAM 來說,特定的 insert 與 delete 陳述句順序,會導致表資料損壞。

相關閱讀:


本文轉載自『資料和雲』公眾號,作者劉偉。轉載本文請聯絡原公眾號,歡迎更多小夥伴加入投稿文章的行列,詳情請戳公眾號選單「聯絡我們」。


高可用架構

改變網際網路的構建方式

長按二維碼 關註「高可用架構」公眾號

贊(0)

分享創造快樂