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: triangle Create 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)項目是一種即開即用、穩定可靠、可彈性伸縮的在線數據庫服務。使用RDS提供的服務,就是使用已經調優過的數據庫,用戶不需要對數據庫參數進行任何修改,就能夠獲得一個性能極好的數據庫服務。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持幫客之家。