MySQL 5.7 新特性詳解

oschina發表於2016-01-19

我們自豪的宣佈 MySQL 5.7 穩定版開放下載了。 MySQL 5.7.9 是目前世界上最流行開源資料庫的一令人興奮的新版本, 比 MySQL 5.6 快 3 倍,同時還提高了可用性,可管理性和安全性。一些重要的增強功能如下:

  1. 效能和可擴充套件性:改進 InnoDB 的可擴充套件性和臨時表的效能,從而實現更快的網路和大資料載入等操作。
  2. JSON支援:使用 MySQL 的 JSON 功能,你可以結合 NoSQL 的靈活和關聯式資料庫的強大。
  3. 改進複製 以提高可用性的效能。包括多源複製,多從執行緒增強,線上 GTIDs,和增強的半同步複製。
  4. 效能模式 提供更好的視角。我們增加了許多新的監控功能,以減少空間和過載,使用新的 SYS 模式顯著提高易用性。
  5. 安全: 我們貫徹“安全第一”的要求,許多 MySQL 5.7 新功能幫助使用者保證他們資料庫的安全。
  6. 優化: 我們重寫了大部分解析器,優化器和成本模型。這提高了可維護性,可擴充套件性和效能。
  7. GIS: MySQL 5.7 全新的功能,包括 InnoDB 空間索引,使用 Boost.Geometry,同時提高完整性和標準符合性。

上述只是一些亮點,我鼓勵你們深入瞭解。可以通過一系列的里程碑部落格5.7.15.7.25.7.35.7.45.7.55.7.65.7.75.7.8 —甚至通過記錄他們的技術規範和實施細則的個人 worklogs ,或許你只是想在 github.com/mysql 上看一下程式碼。我們已經實施了 365  個worklogs,新增了 1007 個 MTR 測試,並且修復了 28125.7 個具體的 bug。勢不可擋的感覺,所以這個“小的”指導可能是有用的。

非常感謝開發團隊的每一個成員,是你們成就了這些!我說開發是指所有人,包括:需求,設計,編碼,稽核,測試,bug 修復,文件,釋出和實驗支援,真的是一個團隊的努力。非常感謝開源社群的每一個人,感謝你們反饋 bug,建議和貢獻!一個世界的努力。

為 MySQL 新增 JSON 支援

使用 MySQL 的最新的 JSON 功能,你可以結合 NoSQL 的靈活和關聯式資料庫的力量。

我們開發了一個 JSON 資料型別和一個二進位制儲存格式 ,使用伺服器可以高效儲存,檢索和查詢 JSON 資料(WL#8132) 。

這項工作改進了 CREATE TABLEALTER TABLE ,所以你可以建立 JSON 型別的資料列,並且它擴充套件了 Field 類,允許對 JSON 型別資料進行 INSERT和SELECT 操作。

我們已經引入了一系列服務端功能,內建的 JSON 函式(WL#7909),這項工作可以讓使用者,從其他關係資料構建 JSON 資料,從 JSON 資料中抽取關係資料, 感知 JSON 資料值和文字(效度,長度,深度,鍵)的結構,對JSON 資料進行檢索和操作。

我們已經介紹了 JSON 比較器 ,類似於 DATE/TIME/DATETIME(日期/時間/日期時間)比較器,它允許 JSON 常量和 SQL 常量比較、JSON 變數和 SQL 變數比較(WL#8249)。比較器依賴在 WL#7909 新增的 DOM 元素的支援。比較器將 SQL 常量轉換為為 JSON 變數然後比較他們的值。

我們已經實現了 JSON 變數值排序(WL#8539),即一個函式產生內部方法 filesort 所需的用老排序 JSON 值的排序鍵。當排序 JSON 變數時用 ORDER BY,它將會返回 JSON 比較器 WL#8249 定義的排序規則所排序的結果。

我們已經為生成的列(WL#8170)實現了一個表示式分析器。這樣做可以讓我們的排序和參考優化器有機會使用已經為生成的列定義的索引。關於這個功能的一個案例是在 JSON 文件上產生和自動使用索引。

我們已經在 SQL 查詢(WL#8607)中加上了內聯 JSON 路徑表示式。MySQL 現在這樣執行查詢:SELECT … FROM t1 WHERE t1.json_field->”$.path.to[0].key”= 123;

生成的列&可生成索引的虛擬化列

我們第一次實現生成的列(WL#411, WL#8114)。每列的值,不像一個有規律的欄位的值,沒有通過使用者設定而是當行建立或者更新時通過伺服器使用使用者定義表時定義的特殊的表示式計算。生成的列也可以被物化(被儲存)或者非物化(虛擬)。關於這方面的內容可以看看 Evgeny Potemkin 的文章“在MySQL 5.7.5中的生成列“。

然後我們在非物化虛擬列上為二級索引的建立提供了支援,以及這些索引在快速檢索計算值和搜尋方面的使用((
WL#8149, 
WL#8227
,
WL#8481) 。

非物化虛擬列是用來處理在真正的 InnoDB 索引記錄中不存在時,但是他們的後設資料在 InnoDB 系統表和後設資料快取中註冊了的情況,虛擬列為表提供了靈活性和儲存空間,還有較重要的一點,新增/刪除這樣的列而不用重新構建表。這樣做是儲存和處理非關係型資料如 JSON 最好的選擇。然而,由於這些列不是物化的,因此掃描和檢索比一般的列(物化的列)要慢一些,但是,虛擬列的值在二級索引裡物化了,因此這些列的資料還是比較容易進行檢索和處理的。因此這也極大的提高了虛擬列的實際值。通過這樣的方式,在一個虛擬生成的列上建立索引也變成了線上操作.

效能&可伸縮性

從社群反饋,賬戶追蹤和在計算機硬體開發及本身架構方面瞭解到,  對 MySql 來說效能和可伸縮性是最重要的部分。迄今為止,在 MySql5.7 中, 我們已經在 InnoDB 實現了對只讀(RO)結果的可伸縮性處理和在服務層明顯的提高了連線速度的處理。我們也在 InnoDB 上的可伸縮性讀寫,提高內部操作(快速穩定的重新整理/清除),和快速批量資料載入方面有了很好的進展。

InnoDB 的可伸縮性只讀。我們已經提高了只讀和多數讀取工作負載的效能。我們也已經極大的提高InnoDB 處理只讀事務(WL#6047, WL#6899, WL#6906, WL#6578)。我們也去掉了服務層連線與後設資料鎖定(MDL) 有關的部分和 InnoDB 中 THR_LOCK 鎖的使用(WL#7304, WL#7305, WL#7306, WL#6671)。在 WL#6671 之後的一些工作負載中,LOCK_grant 鎖就在未來可伸縮性的瓶頸方面清晰了很多; 例如,單張表 InnoDB POINT_SELECT Sysbench 的測試(見 Bug#72829)。目前這個問題已經通過分割 LOCK_grant 鎖解決了(見WL#8355)。最終,我們也在涉及到基於記憶體的臨時表建立的工作負載方面突破了 LOCK_plugin 和 THR_LOCK_lock 鎖的瓶頸;例如,InnoDB 中像 Sysbench 的 SELECT_DISTINCT 的測試。但是,我們不應該為內部臨時表獲得這些鎖,因此,我們清除了這些不必要的開銷(見WL#8356)。也可以看一下 Dimitri Kravtchuk 的文章“MySQL 效能:  MySQL 5.7 達到 500K QPS ““MySQL 5.7 : 使用 InnoDB 快取外掛超過 1M QPS“,Sunny Bains 的文章“MySQL5.7.3對事務生命週期的改進“,和 Jimmy Yang 的文章”MySQL 5.7.3: 深入瞭解使用 InnoDB快取達到 1百萬QPS “

InnoDB 讀寫擴充套件。改善了資料庫的讀寫負載效能。移除了 InnoDB 的索引死鎖(WL#6363, WL#6326)。現在的索引鎖被替換成更加精細的樹的“塊鎖”,然而以前常常用它來保護整個的索引樹結構。可以參考 Yasufumi Kinoshita 的文章“MySQL-5.7 improves DML oriented workloads(MySQL-5.7 改善了面向資料操作語言的工作負載)”。

InnoDB 更快的並行資料重新整理。掃描重新整理一批佇列資料的時候,減少了需要檢索的頁面數目,從而提高了頁面更新的速度(WL#7047)。檢索的時間複雜度已經從 O(n*n) 降低到了 O(n)。與此同時,利用多執行緒的多頁清除技術實現了並行的資料重新整理(WL#6642)。這使得資料庫在多核系統上的擴充套件性和吞吐量均大大得到增強的同時,避免了資料重新整理成為瓶頸。最後,改善了自適應的重新整理演算法以及其他相關機制,來達到更加一致和平滑的吞吐量。

加速連線處理。在某些應用場景下(例如:PHP 應用程式)客戶的連線常常只有很短的生命週期,有時只用執行單次的查詢。這意味著,用在處理連線和斷開連線的時間的長短嚴重關係到整體的應用程式的執行效能。在 5.7 下,壓縮了執行緒初始化和網路初始化的負載成為一個普通的執行緒(WL#6606)。取而代之的是 MySQL 雙倍的處理高頻的連線與斷開連線的能力,從每秒鐘 26K 次的處理能力提升至每秒鐘 56K 次。也可以參考 Jon Olav Hauglid 的一篇文章“Improving connect/disconnect performance“

載入塊資料的效能的提升。為了建立索引所進行的塊資料的載入,(WL#7277)。通過實現塊資料的索引排序,從而加速了 CREATE INDEX 運算操作符的實現。在此之前,InnoDB 迴圈遍歷基表,為每訪問一次基表裡的每條記錄建立一個索引。在此次更新之後,InnoDB 可以一次從基表讀取多條記錄,並且通過索引的鍵值排序這些記錄,從而由單次的塊操作下建立出一整塊記錄的索引集。

線上操作

“時刻線上”的特性對於所有完美的 web 解決方案而言都是必需的。對於資料庫管理員或者網站的開發運維人員來說,在不影響前臺服務的條件下除錯和擴充其後臺資料庫系統是極其重要的。因此,我們要確保 MySQL 在這一領域處於領先地位。在 5.7 下,我們提供如下這些:

提供了確保全域性事務始終線上是方式(WL#7083)。因此,讀寫的操作在此過程中是可行的,並且伺服器不需要同步或者重啟。在此次更新之前,使用者不得不停止所有的更新操作,同步所有的伺服器,並且同時重啟伺服器。這意味著,為了確保全域性事務,必須提前規劃好伺服器的當機時間。可以參考 Sven Sandberg 的文章”Enabling Global Transaction Identifiers Without Downtime in MySQL 5.7.6“(利用 MySQL 5.7.6 在不當機的情況下確保全域性事務)

相關文章