1. 介紹
身處MySQL這個圈子,能夠切身地感受到大家對MySQL 5.7的期待和熱情,似乎每個人都迫不及待的想要瞭解、學習和使用MySQL 5.7。那麼,我們不禁要問,MySQL 5.7到底做了哪些改進,引入了哪些新功能,效能又提升了多少,能夠讓大家翹首以盼,甚至歡呼雀躍呢?
下面就跟隨我來一起瞭解一下MySQL 5.7的部分新功能。想要在一篇文章中介紹完MySQL 5.7的所有改進,幾乎是不可能的。所以,我會選擇一些有特別意思的、特別有用的功能進行介紹。希望通過這篇文章,能夠激發大家對MySQL 5.7的學習興趣,甚至能夠吸引大家將自己的業務遷移到MySQL 5.7上。
MySQL 5.7在諸多方面都進行了大幅的改進,本文將從安全性(見2.1節)、靈活性(見2.2節)、易用性(見2.3節)、可用性(見2.4節)和效能(見2.5節)等幾個方面進行介紹。最後,在第3節對本文進行了簡單的總結。
2. MySQL 5.7的新特性
這一節中,將依次介紹MySQL 5.7的各種新特性。由於MySQL 5.7改進較多,因此,本文將這些新特性進行了簡單的分類,分為安全性、靈活性、易用性、可用性和效能。接下來,將從各個分類依次進行介紹。
2.1 安全性
安全性是資料庫永恒的話題,在MySQL 5.7中,有不少安全性相關的改進。包括:
•MySQL資料庫初始化完成以後,會產生一個 root@localhost 使用者,從MySQL 5.7開始,root使用者的密碼不再是空,而是隨機產生一個密碼,這也導致了使用者安裝5.7時發現的與5.6版本比較大的一個不同點
•MySQL官方已經刪除了test資料庫,預設安裝完後是沒有test資料庫的,就算使用者建立了test庫,也可以對test庫進行許可權控制了
•MySQL 5.7版本提供了更為簡單SSL安全訪問配置,並且預設串連就採用SSL的加密方式
•可以為使用者佈建密碼到期策略,一定時間以後,強制使用者修改密碼
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
•可以”鎖”住使用者,用以暫時禁用某個使用者
ALTER USER 'jeffrey'@'localhost' ACCOUNT LOCK;
ALTER USER l 'jeffrey'@'localhost' ACCOUNT UNLOCK;
2.2 靈活性
在這一節,我將介紹MySQL 5.7的兩個全新的功能,即JSON和generate column。充分使用這兩個功能,能夠極大地提高資料存放區的靈活性。
2.2.1 JSON
隨著非結構化資料存放區需求的持續增長,各種非結構化資料存放區的資料庫應運而生(如MongoDB)。從最新的資料庫使用 熱門排行榜 來看,MongoDB已經超過了PostgreSQL,其火熱程度可見一斑。
各大關係型資料庫也不甘示弱,紛紛提供對JSON的支援,以應對非結構化資料庫的挑戰。MySQL資料庫從5.7.8版本開始,也提供了對JSON的支援。其使用方式如下:
CREATE TABLE t1 (jdoc JSON);INSERT INTO t1 VALUES('{"key1": "value1", "key2": "value2"}');
MySQL對支援JSON的做法是,在server層提供了一堆便於操作JSON的函數,至於儲存,就是簡單地將JSON編碼成BLOB,然後交由儲存引擎層進行處理,也就是說,MySQL 5.7的JSON支援與儲存引擎沒有關係,MyISAM 儲存引擎也支援JSON 格式。
MySQL支援JSON以後,總是避免不了拿來與MongoDB進行一些比較。但是,MySQL對JSON的支援,至少有兩點能夠完勝MongoDB:
1.可以混合儲存結構化資料和非結構化資料,同時擁有關係型資料庫和非關係型資料庫的優點
2.能夠提供完整的事務支援
2.2.2 generate column
generated column是MySQL 5.7引入的新特性,所謂generated column,就是資料庫中這一列由其他列計算而得。
例如,知道直角三角形的兩條直角邊,要求直角三角形的面積。很明顯,面積可以通過兩條直角邊計算而得,那麼,這時候就可以在資料庫中只存放直角邊,面積使用generated column,如下所示:
CREATE TABLE triangle (sidea DOUBLE, sideb DOUBLE, area DOUBLE AS (sidea * sideb / 2));insert into triangle(sidea, sideb) values(3, 4);select * from triangle;+-------+-------+------+| sidea | sideb | area |+-------+-------+------+| 3 | 4 | 6 |+-------+-------+------+
在MySQL 5.7中,支援兩種generated column,即virtual generated column和stored generated column,前者只將generated column儲存在資料字典中(表的中繼資料),並不會將這一列資料持久化到磁碟上;後者會將generated column持久化到磁碟上,而不是每次讀取的時候計算所得。很明顯,後者存放了可以通過已有資料計算而得的資料,需要更多的磁碟空間,與virtual column相比並沒有優勢。因此,在不指定generated column的類型時,預設是virtual column,如下所示:
show create table triangle\G*************************** 1. row *************************** Table: triangleCreate Table: CREATE TABLE `triangle` ( `sidea` double DEFAULT NULL, `sideb` double DEFAULT NULL, `area` double GENERATED ALWAYS AS (((`sidea` * `sideb`) / 2)) VIRTUAL) ENGINE=InnoDB DEFAULT CHARSET=latin1
如果讀者覺得generate column提供的功能,也可以在使用者代碼裡面實現,並沒有什麼了不起的地方,那麼,或許還有一個功能能夠吸引挑剔的你,那就是為generate column建立索引。在這個例子中,如果我們需要根據面積建立索引以加快查詢,就無法在使用者代碼裡面實現,使用generate column就變得非常簡單:
alter table triangle add index ix_area(area);
2.3 易用性
易用性是資料庫永恒的話題,MySQL也在持續不斷地提高資料庫的易用性。在MySQL 5.7中,有很多易用性方面的改進,小到一個用戶端快速鍵 ctrl+c 的使用,大到專門提供一個系統庫(sys)來協助DBA和開發人員使用資料庫。這一節將重點介紹MySQL 5.7引入的sys庫。
•在linux下,我們經常使用 ctrl+c 來終止一個命令的運行,在MySQL 5.7 之前,如果使用者輸入了錯誤的SQL語句,按下 ctrl+c ,雖然能夠”結束”SQL語句的運行,但是,也會退出當前會話,MySQL 5.7對這一違反直覺的地方進行了改進,不再退出會話。
•MySQL 5.7可以explain一個正在啟動並執行SQL,這對於DBA分析已耗用時間較長的語句將會非常有用
•在MySQL 5.7中,performance_schema提供了更多監控資訊,包括記憶體使用量,MDL鎖,預存程序等
2.3.1 sys schema
sys schema是MySQL 5.7.7中引入的一個系統庫,包含了一系列視圖、函數和預存程序, 該項目專註於MySQL的易用性。例如,我們可以通過sys schema快速的知道,哪些語句使用了暫存資料表,哪個使用者請求了最多的io,哪個線程佔用了最多的記憶體,哪些索引是無用索引等
sys schema中包含了大量的視圖,那麼,這些視圖的資訊來自哪裡呢?視圖中的資訊均來自performance schema統計資訊。 這裡 有一個很好的比喻:
For Linux users I like to compare performance_schema to /proc, and SYS to vmstat.
也就是說,performance schema提供了資訊源,但是,沒有很好的將這些資訊組織成有用的資訊,從而沒有很好的發揮它們的作用。而sys schema使用performance schema資訊,通過視圖的方式給出解決實際問題的答案。
例如,下面這些問題,在MySQL 5.7之前,需要藉助外部工具才能知道,在MySQL 5.7中,直接查詢sys庫下相應的表就能得到答案:
•如何查看資料庫中的冗餘索引select * from sys.schema_redundant_indexes;
•如何擷取未使用的索引select * from schema_unused_indexes;
•如何查看使用全表掃描的SQL語句select * from statements_with_full_table_scans
2.4 可用性
MySQL 5.7在可用性方面的改進也帶給人不少驚喜。這裡介紹特別有用的幾項改進,包括:
•線上設定 複製的過濾規則 不再需要重啟MySQL,只需要停止SQL thread,修改完成以後,啟動SQL thread
•線上修改buffer pool的大小
MySQL 5.7為了支援online buffer pool resize,引入chunk的概念,每個chunk預設是128M,當我們線上修改buffer pool的時候,以chunk為單位進行增長或收縮。這個參數的引入,對innodb_buffer_pool_size的配置有了一定的影響。innodb要求buffer pool size是innodb_buffer_pool_chunk_size* innodb_buffer_pool_instances的倍數,如果不是,將會適當調大innodb_buffer_pool_size,以滿足要求,因此,可能會出現buffer pool的實際分配比設定檔中指定的size要大的情況
•Online DDL MySQL 5.7支援重新命名索引和修改varchar的大小,這兩項操作在之前的版本中,都需要重建索引或表
ALTER TABLE t1 ALGORITHM=INPLACE, CHANGE COLUMN c1 c1 VARCHAR(255);
•線上開啟GTID ,在之前的版本中,由於不支援線上開啟GTID,使用者如果希望將低版本的資料庫升級到支援GTID的資料庫版本,需要先關閉資料庫,再以GTID模式啟動,所以導致升級起來特別麻煩。MySQL 5.7以後,這個問題不複存在
2.5 效能
效能一直都是使用者最關心的問題,在MySQL每次新版本中,都會有不少效能提升。在MySQL 5.7中,效能相關的改進非常多,這裡僅介紹部分改進,包括暫存資料表相關的效能改進、唯讀事務的效能最佳化、串連建立速度的最佳化和複製效能的改進。
2.5.1 暫存資料表的效能改進
MySQL 5.7 為了提高暫存資料表相關的效能,對暫存資料表相關的部分進行了大幅修改,包括引入新的暫存資料表空間;對於暫存資料表的DDL,不持久化相關表定義;對於暫存資料表的DML,不寫redo,關閉change buffer等。所有暫存資料表的改動,都基於以下兩個事實 :
1.暫存資料表只在當前會話中可見
2.暫存資料表的生命週期是當前串連(MySQL宕機或重啟,則當前串連結束)
也就是說,對於暫存資料表的操作,不需要其他資料一樣嚴格地進行一致性保證。通過不持久化元資訊,避免寫redo等方式,減少暫存資料表操作的IO,以提高暫存資料表操作的效能。
2.5.2 唯讀事務效能改進
眾所周知,在傳統的OLTP應用中,讀操作遠多於寫操作,並且,讀操作不會對資料庫進行修改,如果是非鎖定讀,讀操作也不需要進行加鎖。因此,對唯讀事務進行最佳化,是一個不錯的選擇。
在MySQL 5.6中,已經對唯讀事務進行了許多最佳化。例如,將MySQL內部實現中的事務鏈表分為唯讀事務鏈表和普通事務鏈表,這樣在建立ReadView的時候,需要遍曆事務鏈表長度就會小很多。
在MySQL 5.7中,首先假設一個事務是一個唯讀事務,只有在該事務發起了修改操作時,才會將其轉換為一個普通事務。MySQL 5.7通過 避免為唯讀事務分配事務ID ,不為唯讀事務分配復原段,減少鎖競爭等多種方式,最佳化了唯讀事務的開銷,提高了資料庫的整體效能。
2.5.3 加速串連處理
在MySQL 5.7之前,變數的初始化操作(THD、VIO)都是在串連接收線程裡面完成的,現在將這些工作下發給背景工作執行緒,以減少串連接收線程的工作量,提高串連的處理速度。這個最佳化對那些頻繁建立短連線應用程式,將會非常有用。
2.5.4 複製效能的改進
MySQL的複寫延遲是一直被詬病的問題之一,欣喜的是,MySQL 5.7版本已經支援”真正”的並行複製功能。MySQL 5.7並行複製的思想簡單易懂,簡而言之,就是”一個組提交的事務都是可以並行回放的”,因為這些事務都已進入到事務的prepare階段,則說明事務之間沒有任何衝突(否則就不可能提交)。MySQL 5.7以後,複寫延遲問題永不存在。
這裡需要注意的是,為了相容MySQL 5.6基於庫的並行複製,5.7引入了新的變數slave-parallel-type,該變數可以配置成DATABASE(預設)或LOGICAL_CLOCK。可以看到,MySQL的預設配置是庫層級的並行複製,為了充分發揮MySQL 5.7的並行複製的功能,我們需要將slave-parallel-type配置成LOGICAL_CLOCK。
3. 總結
1.從本文中可以看到,MySQL 5.7確實帶來了很多激動人心的功能,我們甚至不需要進行任何修改,只需要將業務遷移到MySQL 5.7上,就能帶來不少效能的提升。
2.從本文中還可以看到,雖然MySQL 5.7在易用性上有了很多的改進,但是,也有不少需要注意的地方, 例如:1)在設定innodb的buffer pool時,需要注意chunk的存在,合理設定buffer pool instance否則可能出現實際分配的buffer pool size比預想的大很多的情況;2)多線程複製需要注意將slave_parallel_type設定為LOGICAL_CLOCK,否則,MySQL使用的是庫層級的並行複製,對於大多數應用,並沒有什麼效果。那麼, 怎樣才是使用MySQL 5.7的正確姿勢呢?網易蜂巢是一個不錯的選擇 ,網易蜂巢的RDS(Relational Database Service,簡稱RDS)項目是一種即開即用、穩定可靠、可Auto Scaling的線上資料庫服務。使用RDS提供的服務,就是使用已經調優過的資料庫,使用者不需要對資料庫參數進行任何修改,就能夠獲得一個效能極好的資料庫服務。
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。