背景:html
繼上次介紹 初識 MySQL 5.6 新功能、參數完以後,恰好MySQL 5.7又GA了,在官方測試裏看到,MySQL5.7在功能、性能、可用性、安全和監控上又提高了很高。如今看看和MySQL5.6對比,以前介紹了新增配置參數和安全相關特性。本文來講明MySQL5.7關於功能和性能提高的方面(持續更新)。node
1,功能性能上的提高
mysql
1.1:複製功能的提高。linux
①支持並行複製。slave-parallel-type算法
5.6開始支持基於庫(database)的並行複製,對於只有一個庫的,效果很差。5.7開始支持基於組提交(LOGICAL_CLOCK)的並行複製,提升複製的可用性。sql
②支持多源複製,經過channel支持一個從庫複製多個主庫。shell
③支持在線修改REPLICATION FILTER:REPLICATE_DO_DB、REPLICATE_IGNORE_DB。經過change replicate filter,須要中止SQL thread,修改完成之後,啓動SQL thread。能夠參考這篇文章。數據庫
因爲篇幅的緣由,後面會另起一篇文章介紹上面功能的細節。json
1.2:mysqlpump,並行版 mysqldump,也是替換原生 mysqldump 和 mydumper 的。--watch-progress 查看dump進度,--compress-ouptut 壓縮,也支持 SSL。 大體的優點以下:(後面會起一篇文章來講明mysqlpump的使用)緩存
1.3:online alter table。在初識 MySQL 5.6 新功能、參數裏介紹的online ddl的基礎上又增長了:
①:在線加主鍵:當主鍵列爲null字段的時候,5.6建主鍵須要複製表,5.7能夠inplace:
5.6: >create table test(id int); Query OK, 0 rows affected (0.00 sec) >insert into test values(1),(2),(3); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 >alter table test add primary key(id); Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 ###copy 5.7: >create table test(id int); Query OK, 0 rows affected (0.01 sec) >insert into test values(1),(2),(3); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 >alter table test add primary key(id); Query OK, 0 rows affected (0.03 sec) ###inplace Records: 0 Duplicates: 0 Warnings: 0
②:varchar長度變動(加大)支持inplace,須要注意的是有一個限制,即用於表示varchar字段長度的字節數不能發生變化,也就是支持好比varchar的字節長度在255(Latin1)如下變動或者255以上的範圍進行變動,由於從小於255變動到大於255,其size的字節須要從1個增長到2個,另外一個注意的是不容許inplace字段長度變小:
>show create table test\G *************************** 1. row *************************** Table: test Create Table: CREATE TABLE `test` ( `id` int(11) NOT NULL, `name` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.00 sec) >alter table test modify name varchar(64); ##inplace modify Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 >alter table test modify name varchar(128); ##inplace modify Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 >alter table test modify name varchar(255); ##inplace modify Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 >alter table test modify name varchar(256); ##copy modify,超過了255 Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 >alter table test modify name varchar(64); ##copy modify,長度變小 Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0
③:支持online rename index操做:
>show create table test\G *************************** 1. row *************************** Table: test Create Table: CREATE TABLE `test` ( `id` int(11) NOT NULL, `name` varchar(64) DEFAULT NULL, PRIMARY KEY (`id`), KEY `name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.00 sec) >alter table test rename index name to idx_name;
...
1.4:Undo Log日誌的在線回收。innodb undo log佔用共享表空間而且沒法回收,在5.6的時候能夠把undo log分離到獨立的表空間,並放到單獨的文件目錄下,可是其文件大小也不會回收。5.7以後能夠在線收縮undo log:須要開啓innodb_undo_log_truncate、innodb_undo_tablespaces和innodb_undo_directory參數,當大小超過innodb_max_undo_log_size的大小則會被undo會被標記爲可truncate。具體的原理能夠看這篇文章。undo log 在整個事務未提交前,undo page是必須強佔內存,這會讓buffer pool size 收到污染,能夠看這個例子說明。
1.5:新增json類型。關於json類型操做的函數參考官方文檔和MySQL5.7 JSON類型使用介紹,原理介紹見MySQL5.7的JSON 實現。
MySQL對支持JSON的作法是在server層提供了一堆便於操做JSON的函數,簡單地將JSON編碼成BLOB,而後交由存儲引擎層進行處理。MySQL 5.7的JSON支持與存儲引擎沒有關係,MyISAM 存儲引擎也支持JSON 格式。MySQL對JSON的支持,至少有兩點可以完勝MongoDB:能夠混合存儲結構化數據和非結構化數據,同時擁有關係型數據庫和非關係型數據庫的優勢;可以提供完整的事務支持。
1.6:generate column。一列由其餘列計算而得,可生成索引的虛擬化列。
mysql> create table t(id int,score int,score_ss int as (score*33)); Query OK, 0 rows affected (0.25 sec) mysql> select * from t; Empty set (0.00 sec) mysql> select * from t; Empty set (0.00 sec) mysql> insert into t(id,score) values(1,10); Query OK, 1 row affected (0.03 sec) mysql> select * from t; +------+-------+----------+ | id | score | score_ss | +------+-------+----------+ | 1 | 10 | 330 | +------+-------+----------+ 建表標準的語法: CREATE TABLE `t` ( `id` int(11) DEFAULT NULL, `score` int(11) DEFAULT NULL, `score_ss` int(11) GENERATED ALWAYS AS ((`score` * 33)) VIRTUAL/STORED, KEY `idx_score_ss` (`score_ss`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
MySQL5.7支持兩種generated column,即virtual generated column和stored generated column,前者只將generated column保存在數據字典中(表的元數據),並不會將這一列數據持久化到磁盤上;後者會將generated column持久化到磁盤上,而不是每次讀取的時候計算所得。很明顯,後者存放了能夠經過已有數據計算而得的數據,須要更多的磁盤空間,與virtual column相比並無優點。所以,在不指定generated column的類型時,默認是virtual column,而且爲generate column建立索引能夠提升性能。
1.7:InnoDB 全文索引的增強:支持中文分詞。InnoDB默認的全文索引parser很是合適於Latin,由於Latin是經過空格來分詞的。能夠看這篇文章的介紹,但對於像中文,日文和韓文來講,沒有這樣的分隔符。一個詞能夠由多個字來組成,因此咱們須要用不一樣的方式來處理。在MySQL 5.7.6中咱們能使用一個新的全文索引插件來處理它們:n-gram parser。關於n-gram的介紹和使用能夠看這篇文章。
在全文索引中,n-gram就是一段文字裏面連續的n個字的序列。例如,用n-gram來對」信息系統」來進行分詞,獲得的結果以下:
1
2
3
4
|
N=1 : '信', '息', '系', '統'
N=2 : '信息', '息系', '系統';
N=3 : '信息系', '息系統';
N=4 : '信息系統';
|
其中N是有參數ngram_token_size控制,即分詞的大小,默認是2。這裏簡單說明一下:
mysql> CREATE TABLE t_fulltext( -> `id` int(11) DEFAULT NULL, -> `name` varchar(512) DEFAULT NULL, -> `content` text, -> FULLTEXT KEY idx_name(name), -> FULLTEXT KEY idx_content(content) WITH PARSER ngram -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8; Query OK, 0 rows affected (0.07 sec) 或則建好表後添加: alter table t_fulltext add fulltext idx_content(content) WITH PARSER ngram; mysql> INSERT INTO t_fulltext (id,name,content) VALUES (1,'信息系統','天然科學'); Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM t_fulltext WHERE MATCH (name) AGAINST ('信息系統'); ###普通的全文檢索必需要整個詞才能檢索到。 +------+--------------+--------------+ | id | name | content | +------+--------------+--------------+ | 1 | 信息系統 | 天然科學 | +------+--------------+--------------+ 1 row in set (0.01 sec) mysql> SELECT * FROM t_fulltext WHERE MATCH (name) AGAINST ('信息'); ###拿裏面的出來檢索不出來 Empty set (0.01 sec) mysql> SELECT * FROM t_fulltext WHERE MATCH (content) AGAINST ('天然'); ###新的全文檢索功能能夠檢索到任意2個組合 +------+--------------+--------------+ | id | name | content | +------+--------------+--------------+ | 1 | 信息系統 | 天然科學 | +------+--------------+--------------+ 1 row in set (0.00 sec) mysql> SELECT * FROM t_fulltext WHERE MATCH (content) AGAINST ('然科'); ###新的全文檢索功能能夠檢索到任意2個組合 +------+--------------+--------------+ | id | name | content | +------+--------------+--------------+ | 1 | 信息系統 | 天然科學 | +------+--------------+--------------+ 1 row in set (0.01 sec)
這裏能夠查看分詞的信息:
mysql> INSERT INTO articles (title) VALUES ('信息系統'); Query OK, 1 row affected (0.01 sec) mysql> SET GLOBAL innodb_ft_aux_table="test/articles"; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +--------+--------------+-------------+-----------+--------+----------+ | WORD | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION | +--------+--------------+-------------+-----------+--------+----------+ | 信息 | 1 | 1 | 1 | 1 | 0 | | 息系 | 1 | 1 | 1 | 1 | 3 | | 系統 | 1 | 1 | 1 | 1 | 6 | +--------+--------------+-------------+-----------+--------+----------+ 3 rows in set (0.00 sec)
關於全文檢索的進一步測試,包括中止詞語會另起一篇文章說明。
1.8:動態修改InnoDB Buffer Pool Size。mysql> show variables like '%innodb_buffer_pool_size%'; #當前BP的大小512M +-------------------------+-----------+ | Variable_name | Value | +-------------------------+-----------+ | innodb_buffer_pool_size | 536870912 | +-------------------------+-----------+ 1 row in set (0.00 sec) mysql> show variables like 'innodb_buffer_pool_instances'; #BP實例1個,由於BP小於1G +------------------------------+-------+ | Variable_name | Value | +------------------------------+-------+ | innodb_buffer_pool_instances | 1 | +------------------------------+-------+ 1 row in set (0.00 sec) mysql> set global innodb_buffer_pool_size=1048576000; #設置BP的大小爲1000M Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> show warnings;#設置1000M報warnings,緣由是它不是innodb_buffer_pool_chunk_size* innodb_buffer_pool_instances的倍數,即128M的倍數。 +---------+------+-----------------------------------------------------------------+ | Level | Code | Message | +---------+------+-----------------------------------------------------------------+ | Warning | 1292 | Truncated incorrect innodb_buffer_pool_size value: '1048576000' | +---------+------+-----------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> show global status like 'Innodb_buffer_pool_resize_status'; #查看進度 +----------------------------------+----------------------------------------------------+ | Variable_name | Value | +----------------------------------+----------------------------------------------------+ | Innodb_buffer_pool_resize_status | Completed resizing buffer pool at 160708 18:20:15. | +----------------------------------+----------------------------------------------------+ 1 row in set (0.00 sec) mysql> show variables like '%innodb_buffer_pool_size%'; #被設置成了1024M,由於1024是128的整數倍,出現了BP比配置文件裏指定的size還大。 +-------------------------+------------+ | Variable_name | Value | +-------------------------+------------+ | innodb_buffer_pool_size | 1073741824 | +-------------------------+------------+ 1 row in set (0.00 sec)
在線調整BP的日誌:
2016-07-08T18:20:15.278753+08:00 3 [Note] InnoDB: Requested to resize buffer pool. (new size: 1073741824 bytes) #調整的BP大小。 2016-07-08T18:20:15.278786+08:00 0 [Note] InnoDB: Resizing buffer pool from 536870912 to 1073741824 (unit=134217728).#從多大到多大,單位多少 2016-07-08T18:20:15.278845+08:00 0 [Note] InnoDB: Disabling adaptive hash index. #禁用AHI,清理全部的索引緩存 2016-07-08T18:20:15.280839+08:00 0 [Note] InnoDB: disabled adaptive hash index. 2016-07-08T18:20:15.280864+08:00 0 [Note] InnoDB: Withdrawing blocks to be shrunken.#回收空閒的block 2016-07-08T18:20:15.280876+08:00 0 [Note] InnoDB: Latching whole of buffer pool. #鎖住整個BP 2016-07-08T18:20:15.280896+08:00 0 [Note] InnoDB: buffer pool 0 : resizing with chunks 4 to 8. #大小從4個chunks變成8個chunks 2016-07-08T18:20:15.295961+08:00 0 [Note] InnoDB: buffer pool 0 : 4 chunks (32764 blocks) were added. 2016-07-08T18:20:15.296015+08:00 0 [Note] InnoDB: Completed to resize buffer pool from 536870912 to 1073741824. #設置新值完成 2016-07-08T18:20:15.296031+08:00 0 [Note] InnoDB: Re-enabled adaptive hash index. #開啓AHI 2016-07-08T18:20:15.296048+08:00 0 [Note] InnoDB: Completed resizing buffer pool at 160708 18:20:15. #調整完成
1.9:多線程髒頁刷寫
innodb_page_cleaners,表示刷寫BP髒頁的線程數,5.6.2開始從master線程中獨立出來,5.7.4以後開始支持多線程flush,默認是4。這個值必須小於等於innodb_buffer_pool_instances,提升CPU的利用率。
1.10:終止會話ctrl+c
在linux下,咱們常用ctrl+c
來終止一個命令的運行,在MySQL 5.7 以前,若是用戶輸入了錯誤的SQL語句,按下ctrl+c
,雖然可以"結束"SQL語句的運行,可是,也會退出當前會話,MySQL 5.7對這一違反直覺的地方進行了改進,再也不退出會話。
1.11:臨時表性能的優化
MYSQL5.7爲了提升臨時表相關的性能,對臨時表相關的部分進行了大幅修改,包括引入新的臨時表空間(ibtmp1);對於臨時表的DDL,不持久化相關表定義;對於臨時表的DML,不寫redo,關閉change buffer等。
InnoDB臨時表元數據再也不存儲於InnoDB系統表而是存儲在INNODB_TEMP_TABLE_INFO,包含全部用戶和系統建立的臨時表信息。該表在第一次在其上運行select時被建立:
mysql> select * from information_schema.innodb_temp_table_info; Empty set (0.00 sec) mysql> use dba_test mysql> create temporary table temp_1(id int,name varchar(100))default charset utf8; Query OK, 0 rows affected (0.00 sec) mysql> select * from information_schema.innodb_temp_table_info; +----------+--------------+--------+-------+----------------------+---------------+ | TABLE_ID | NAME | N_COLS | SPACE | PER_TABLE_TABLESPACE | IS_COMPRESSED | +----------+--------------+--------+-------+----------------------+---------------+ | 42 | #sql1883_8_0 | 5 | 27 | FALSE | FALSE | +----------+--------------+--------+-------+----------------------+---------------+ 1 row in set (0.00 sec)
而且MySQL5.7使用了獨立的臨時表空間來存儲臨時表數據,但不能是壓縮表。臨時表空間在實例啓動的時候進行建立,shutdown的時候進行刪除。即爲全部非壓縮的innodb臨時表提供一個獨立的表空間,默認的臨時表空間文件爲ibtmp1,位於數據目錄。咱們可經過innodb_temp_data_file_path參數指定臨時表空間的路徑和大小,默認12M。只有重啓實例才能回收臨時表空間文件ibtmp1的大小。create temporary table和using temporary table將共用這個臨時表空間。
mysql >show variables like 'innodb_temp_data_file_path'; +----------------------------+-----------------------+ | Variable_name | Value | +----------------------------+-----------------------+ | innodb_temp_data_file_path | ibtmp1:12M:autoextend | +----------------------------+-----------------------+
物理文件:
# ls -lh ibtmp1 -rw-r----- 1 mysql mysql 12M 7月 12 15:13 ibtmp1 mysql> create temporary table temp_1(id int,name varchar(100))default character set utf8; Query OK, 0 rows affected (0.01 sec) mysql> insert into temp_1 select * from ttt; Query OK, 2752512 rows affected (7.10 sec) Records: 2752512 Duplicates: 0 Warnings: 0 # ls -lh ibtmp1 -rw-r----- 1 mysql mysql 204M 7月 12 15:16 ibtmp1 #重啓才能回收
在MySQL5.7中,臨時表在鏈接斷開或者數據庫實例關閉的時候,會進行刪除,也就無需redo logs,避免了寫relog相關的io,從而提升了性能。只有臨時表的metadata使用了redo保護,保護元數據的完整性,以便異常啓動後進行清理工做。臨時表的元數據5.7以後使用了一個獨立的表(innodb_temp_table_info)進行保存,這樣就不要使用redo保護,元數據也只保存在內存中。但這有一個前提,必須使用共享的臨時表空間,若是使用file-per-table,仍然須要持久化元數據,以便異常恢復清理。臨時表須要undo log,用於MySQL運行時的回滾、MVCC等。具體的能夠看官方文檔和臨時表優化說明。
注意:從5.7.5開始,新增一個系統選項internal_tmp_disk_storage_engine可定義磁盤臨時表的引擎類型,默認爲InnoDB,可選MyISAM。而在這之前,只能使用MyISAM。而在5.6.3之後新增的參數default_tmp_storage_engine是控制create temporary table建立的臨時表的存儲引擎,在之前默認是MEMORY。
mysql> show variables like '%engine%'; +----------------------------------+--------+ | Variable_name | Value | +----------------------------------+--------+ | default_storage_engine | InnoDB | | default_tmp_storage_engine | InnoDB | | disabled_storage_engines | | | enforce_storage_engine | | | internal_tmp_disk_storage_engine | InnoDB | +----------------------------------+--------+
1.12:innochecksum離線的InnoDB文件校驗工具功能加強,能夠查看ibd文件。新增選擇項或擴展的功能:
1.支持使用指定校驗算法; 2.支持只重寫校驗值而不進行驗證; 3.可指定容許的校驗和不匹配量; 4.顯示各種頁的個數、導出頁類型信息、輸出至日誌、從標準輸入讀取數據等; 5.從5.7.2起可支持校驗超過2G的文件;
如何使用innochecksum能夠看官網和執行innochecksum --help。使用時須要中止mysql服務,或則把ibd文件複製出來,不然會報錯:
# innochecksum --page-type-summary ibdata1 Error: Unable to lock file:: ibdata1 fcntl: Resource temporarily unavailable
關閉數據庫或則複製出ibd文件執行:
# innochecksum --page-type-summary /tmp/ibdata1 File::/tmp/ibdata1 ================PAGE TYPE SUMMARY============== #PAGE_COUNT PAGE_TYPE =============================================== 13 Index page #索引頁 2820 Undo log page #undo頁 2 Inode page 0 Insert buffer free list page #插入緩存空閒頁 1928 Freshly allocated page #可用頁 1 Insert buffer bitmap #插入緩存位圖頁 98 System page #系統頁 1 Transaction system page 1 File Space Header 0 Extent descriptor page 0 BLOB page 0 Compressed BLOB page 0 Other type of page =============================================== Additional information: Undo page type: 2806 insert, 14 update, 0 other Undo page state: 0 active, 36 cached, 0 to_free, 0 to_purge, 0 prepared, 2784 other
經過 --page-type-summary 參數能夠看到表空間裏面各個頁的狀況,關於頁的一些細節信息能夠參考看MySQL Innodb 存儲結構 。
經過 --count 參數能夠查看錶空間的總頁數:
# innochecksum --count /tmp/ibdata1 Number of pages:4864
1.13:默認行格式改變,由innodb_default_row_format控制,5.7.9以後默認DYNAMIC,以前默認COMPACT。更多信息見官方文檔。
1.14:支持建立全局通用表空間,全局表空間能夠被全部的數據庫的表共享,並且相比於獨享表空間使用手動建立共享表空間能夠節約元數據方面的內存。能夠在建立表的時候,指定屬於哪一個表空間,也能夠對已有表進行表空間修改,具體的信息能夠查看官方文檔。
mysql> create tablespace dxy add datafile 'dxy.ibd' file_block_size=16k; #建立名爲dxy的共享表空間 Query OK, 0 rows affected (0.10 sec) mysql> create table t1(id int,name varchar(10))engine = innodb default charset utf8mb4 tablespace dxy; #指定表空間 Query OK, 0 rows affected (0.09 sec) # ls -lh -rw-r----- 1 mysql mysql 96K 7月 14 12:11 dxy.ibd #查看錶空間文件 mysql> alter table ttt tablespace dxy; #指定表空間
# ls -lh dxy.ibd -rw-r----- 1 mysql mysql 244M 7月 14 12:18 dxy.ibd #表空間文件變大
如何刪除建立的共享表空間?由於是共享表空間不能直接經過drop table tbname來刪除,也不能回收空間。當肯定共享表空間的數據都沒用,而且依賴該表空間的表均已經刪除,則能夠經過drop tablespace來刪除共享表空間來釋放空間,若是依賴該共享表空間的表存在則會刪除失敗。
# ls -lh dxy.ibd -rw-r----- 1 mysql mysql 452M 7月 14 12:27 dxy.ibd mysql> drop table t1; #刪除依賴該表空間的表 Query OK, 0 rows affected (0.16 sec) mysql> drop tablespace dxy; #刪除表空間 ERROR 1529 (HY000): Failed to drop TABLESPACE dxy #刪除失敗,由於還有表依賴這個表空間。 mysql> drop table ttt; Query OK, 0 rows affected (0.04 sec) mysql> drop tablespace dxy; #成功刪除自建的共享表空間 Query OK, 0 rows affected (0.03 sec) # ls -lh dxy.ibd ls: cannot access dxy.ibd: No such file or directory #ibd文件被刪除,空間回收。
1.15:InnoDB Tablespace Encryption,支持對獨享表空間的InnoDB數據文件加密,其依賴keyring plugin來進行祕鑰的管理,開啓加密功能須要啓動參數--early-plugin-load。
[mysqld] early-plugin-load=keyring_file.so
開始參數後,查看是否支持:
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS where PLUGIN_NAME LIKE 'keyring%'; +--------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +--------------+---------------+ | keyring_file | ACTIVE | +--------------+---------------+ 1 row in set (0.00 sec)
建立加密表空間:
mysql> create table t(id int,name varchar(10))engine = innodb default charset utf8mb4 encryption='y'; Query OK, 0 rows affected (0.17 sec) mysql> show create table t\G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` int(11) DEFAULT NULL, `name` varchar(10) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ENCRYPTION='y' 1 row in set (0.00 sec)
1.16:NVM file system。MySQL一直使用double write buffer來解決一個page寫入的partial write問題,但在linux系統上的Fusion-io Non-Volatile Memory (NVM) file system支持原子的寫入。這樣就能夠省略掉double write buffer的使用, 5.7.4之後,若是Fusion-io devices支持atomic write,那麼MySQL自動把dirty block直接寫入到數據文件了。這樣減小了一次內存copy和IO操做。
1.17:InnoDB分區表。MySQL 5.7以前的版本,InnoDB並不支持分區表,分區表的支持是在ha_partition引擎上支持的,從5.7開始,InnoDB支持原生的分區表,而且可使用傳輸表空間。
1.18:支持在一個table對象上建多個trigger。
持續更新...
...
MySQL 5.7.7版本以後新增了sys 數據庫,該庫經過視圖的形式把information_schema和performance_schema結合起來,查詢出更加使人容易理解的數據,幫助dba和開發人員收集的數據庫性能信息,快速定位性能瓶頸。sys下的一共包括三種對象:1. view,2. procedure 3 function
這些對象都是基於performance_schema下的表,進行了可讀性的聚合,沒有真正存儲數據,只存儲了定義。默認經過帳號'mysql.sys'@'localhost'收集信息,以前是root@localhost進行收集操做。安裝時能夠經過--skip-sys-schema跳過安裝。後面會另起一篇文章對sys schema進行說明,也能夠先看DBA的好幫手——sys schema和MySQL 5.7系列之sys schema(2) by吳炳錫。
3,被刪除和被修改默認值的參數和特性
參數移除:
3.1:MySQL 5.7.4以後innodb_additional_mem_pool_size參數被移除。原來是存放數據字典和內部數據結構,要是表不少,須要分配更多的內存。若緩衝池的內存溢出則須要從系統分配內存,但會寫一個warning到錯誤日誌。
3.2:MySQL5.7.4以後innodb_use_sys_malloc參數被移除。原來表示InnoDB使用操做系統內存分配器仍是本身的內存分配器,默認是使用操做系統內存分配器。3.1和3.2被移除的緣由,是由於內部實現不如外部的實現,能夠見http://www.kancloud.cn/taobaomysql/monthly/143931。
3.3:innodb 存儲引擎不能被禁用,系統表有innodb表。 --innodb=OFF
and --skip-innodb沒有做用,將來會移除該參數。
3.4:innodb_file_format、innodb_file_format_check、innodb_file_format_max在MySQL5.7.7被棄用,將來會被移除。
3.5:innodb_large_prefix在MySQL5.7.7中被棄用,未來會移除。該參數表示當innodb爲字段建立索引時,限制的字節長度。關閉時,字節長度大於767則會報warnings。開啓時,則會報錯,建立不成功。
3.6:innodb_locks_unsafe_for_binlog在MySQL5.6.3被棄用,未來會移除。該參數表示innodb鎖和二進制的安全問題,當ON的時候能夠避免gap lock的問題,可是會引發binlog寫入順序出問題,致使主從數據不一致。建議關閉。
3.7:innodb_support_xa在MySQL5.7.1中被棄用,未來會移除。MySQL5.7.1以後不能禁用innodb_support_xa。雖然它會致使一次額外的磁盤flush(prepare階段flush redo log). 可是咱們必須啓用,而不能關閉它。由於關閉會致使binlog寫入的順序和實際的事務提交順序不一致,會致使崩潰恢復和slave複製時發生數據錯誤。若是啓用了log-bin參數,而且不止一個線程對數據庫進行修改,那麼就必須啓用innodb_support_xa參數。
3.8:@@session.gtid_executed 不建議使用,未來會移除。
3.9:binlog_format在MySQL5.7.7以後,默認值變成ROW。
3.10:slave_net_timeout在MySQL5.7.7以後,默認改爲60秒。該參數定義了從庫從主庫獲取數據等待的秒數,超過這個時間從庫會主動退出讀取,中斷鏈接,並嘗試重連。即:設置在多久沒收到數據後認爲網絡超時,以後 Slave 的 IO 線程會從新鏈接 Master。此前的默認值是3600秒,長時間的複製延遲極可能是網絡瞬斷形成的。能夠用一個心跳時間master_heartbeat_period來避免,具體能夠看MySQL複製心跳的詳細說明。大體的流程以下:
說明: 在MySQL的複製協議裏,由 Slave 發送一個 COM_BINLOG_DUMP 命令後,就徹底由 Master 來推送數據,Master、Slave 之間再也不須要交互。若是 Master 沒有更新,也就不會有數據流,Slave 就不會收到任何數據包。可是若是因爲某種緣由形成 Master 沒法把數據發送到 Slave ,好比發生過網絡故障或其餘緣由致使 Master 上的 TCP 鏈接丟失,Slave 沒有機會獲得通知,因此也無法知道收不到數據是由於 Master 原本就沒有更新呢仍是因爲出了故障。 stop slave; change master to master_heartbeat_period = 10; set global slave_net_timeout = 25; start slave; 心跳會讓Master 在沒有數據的時候,每10秒發送一個心跳包。這樣 Slave 就能知道 Master 是否是還正常。slave_net_timeout是設置在多久沒收到數據後認爲網絡超時,以後 Slave 的 IO 線程會從新鏈接 Master 。 結合這兩個設置就能夠避免因爲網絡問題致使的複製延誤。master_heartbeat_period 單位是秒,能夠是個帶上小數,如 10.5。最高精度爲 1 毫秒。 須要注意的是:默認狀況heartbeat_period的值是slave_net_timeout的通常。在從上經過show global status like 'slave%'來查看心跳信息。 要是heartbeat_period設置大於slave_net_timeout會報warnings: The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout.
關於從庫重連主庫的相關信息:
MySQL 能夠指定三個參數,用於複製線程重連主庫: --master-retry-count , --master-connect-retry , --slave-net-timeout 。 其中 master-connect-retry 和 master-retry-count 須要在 Change Master 搭建主備複製時指定,而 slave-net-timeout 是一個全局變量,能夠在 MySQL 運行時在線設置。 具體的重試策略爲:備庫過了slave-net-timeout秒尚未收到主庫來的數據,它就會開始第一次重試。而後每過 master-connect-retry 秒,備庫會再次嘗試重連主庫。直到重試了 master-retry-count 次,它纔會放棄重試。若是重試的過程當中,連上了主庫,那麼它認爲當前主庫是好的,又會開始 slave-net-timeout 秒的等待。 slave-net-timeout 的默認值是 60 秒, master-connect-retry 默認爲 60 秒, master-retry-count 默認爲 86400 次。也就是說,若是主庫一分鐘都沒有任何數據變動發送過來,備庫纔會嘗試重連主庫。 若是主庫上變動比較頻繁,能夠考慮將 slave-net-timeout 設置的小一點,避免主庫Binlog dump(IO)線程終止,沒法將最新的更新推送過來,及時發現問題而不是等到超時以後才收到報錯去處理。 固然 slave-net-timeout 設置的太小也有問題,這樣會致使若是主庫的變動確實比較少的時候,備庫頻繁的從新鏈接主庫,形成資源浪費。
3.11:sync_binlog在MySQL5.7.7以後,默認值改爲了1,更安全。由於MySQL5.6支持了組提交的功能,因此值1不像5.6以前的說的binlog提交一次就寫一次磁盤,而是表了在把binlog刷新到磁盤前,提交的組的數量。
...
特性移除:
3.1:innodb_table_monitor特性在MySQL 5.7.4中被移除。經過參數innodb_status_output、innodb_status_output_locks動態修改爲on,把show engine innodb status打印到error log中;經過information_schema中INNODB_SYS%開頭的表能夠把innodb_table_monitor的信息顯示出來,對比說明下他們的差別,方便本身查閱。
####經過innodb_table_monitor打印到error log 中的信息,關於說明請見innodb_table_monitor的介紹 TABLE: name jute/jute_vote, id 149, flags 1, columns 8, indexes 1, appr.rows 182198 COLUMNS: surveyId: DATA_INT DATA_BINARY_TYPE DATA_NOT_NULL len 4; userId: DATA_INT DATA_BINARY_TYPE DATA_NOT_NULL len 4; choiceId: DATA_INT DATA_BINARY_TYPE DATA_NOT_NULL len 4; voteTime: DATA_FIXBINARY DATA_BINARY_TYPE DATA_NOT_NULL len 5; comment: DATA_BLOB len 11; DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; DB_ROLL_PTR: DATA_SYS prtype 258 len 7; INDEX: name PRIMARY, id 324, fields 2/7, uniq 2, type 3 root page 3, appr.key vals 182198, leaf pages 472, size pages 545 FIELDS: surveyId userId DB_TRX_ID DB_ROLL_PTR choiceId voteTime comment #####經過information_schema中各相關表(7張表)的說明,和上面對比 information_schema 12:31:21>select * from INNODB_SYS_TABLES where NAME='jute/jute_vote'; +----------+----------------+------+--------+-------+-------------+------------+---------------+ | TABLE_ID | NAME | FLAG | N_COLS | SPACE | FILE_FORMAT | ROW_FORMAT | ZIP_PAGE_SIZE | +----------+----------------+------+--------+-------+-------------+------------+---------------+ | 149 | jute/jute_vote | 1 | 8 | 143 | Antelope | Compact | 0 | +----------+----------------+------+--------+-------+-------------+------------+---------------+ 1 row in set (0.00 sec) information_schema 12:32:30>select * from INNODB_SYS_DATAFILES where SPACE=143; +-------+----------------------+ | SPACE | PATH | +-------+----------------------+ | 143 | ./jute/jute_vote.ibd | +-------+----------------------+ 1 row in set (0.00 sec) information_schema 12:32:44>select * from INNODB_SYS_TABLESPACES where SPACE=143; +-------+----------------+------+-------------+----------------------+-----------+---------------+ | SPACE | NAME | FLAG | FILE_FORMAT | ROW_FORMAT | PAGE_SIZE | ZIP_PAGE_SIZE | +-------+----------------+------+-------------+----------------------+-----------+---------------+ | 143 | jute/jute_vote | 0 | Antelope | Compact or Redundant | 16384 | 0 | +-------+----------------+------+-------------+----------------------+-----------+---------------+ 1 row in set (0.01 sec) information_schema 12:32:55>select * from INNODB_SYS_TABLESTATS where table_id=149; +----------+----------------+-------------------+----------+------------------+------------------+------------------+---------+-----------+ | TABLE_ID | NAME | STATS_INITIALIZED | NUM_ROWS | CLUST_INDEX_SIZE | OTHER_INDEX_SIZE | MODIFIED_COUNTER | AUTOINC | REF_COUNT | +----------+----------------+-------------------+----------+------------------+------------------+------------------+---------+-----------+ | 149 | jute/jute_vote | Initialized | 182198 | 545 | 0 | 0 | 0 | 1 | +----------+----------------+-------------------+----------+------------------+------------------+------------------+---------+-----------+ 1 row in set (0.01 sec) information_schema 12:38:33>select * from INNODB_SYS_INDEXES where TABLE_ID=149; +----------+---------+----------+------+----------+---------+-------+ | INDEX_ID | NAME | TABLE_ID | TYPE | N_FIELDS | PAGE_NO | SPACE | +----------+---------+----------+------+----------+---------+-------+ | 324 | PRIMARY | 149 | 3 | 2 | 3 | 143 | +----------+---------+----------+------+----------+---------+-------+ 1 row in set (0.01 sec) information_schema 12:33:25>select * from INNODB_SYS_COLUMNS where TABLE_ID=149; +----------+----------+-----+-------+---------+-----+ | TABLE_ID | NAME | POS | MTYPE | PRTYPE | LEN | +----------+----------+-----+-------+---------+-----+ | 149 | surveyId | 0 | 6 | 1283 | 4 | | 149 | userId | 1 | 6 | 1283 | 4 | | 149 | choiceId | 2 | 6 | 1283 | 4 | | 149 | voteTime | 3 | 3 | 525580 | 5 | | 149 | comment | 4 | 5 | 2949372 | 11 | +----------+----------+-----+-------+---------+-----+ 5 rows in set (0.01 sec) information_schema 12:33:37>select * from INNODB_SYS_FIELDS where INDEX_ID in (324); +----------+----------+-----+ | INDEX_ID | NAME | POS | +----------+----------+-----+ | 324 | surveyId | 0 | | 324 | userId | 1 | +----------+----------+-----+ 2 rows in set (0.00 sec)
也能夠經過一條sql進行對innodb_table_monitor的展現,裏面各參數的意義看官方文檔:
SELECT a.PATH datafile,b.NAME name,b.TABLE_ID table_id,b.FLAG flags,b.N_COLS columns,count(distinct c.INDEX_ID) indexes,d.NUM_ROWS `appr.rows`,group_concat(distinct e.NAME) column_name,substring_index(group_concat(e.LEN),',',b.N_COLS-3) column_len,c.NAME index_name,c.INDEX_ID index_id,group_concat(distinct g.NAME) index_fields,d.CLUST_INDEX_SIZE,d.OTHER_INDEX_SIZE,f.PAGE_SIZE,b.FILE_FORMAT,b.ROW_FORMAT FROM INNODB_SYS_TABLES b,INNODB_SYS_DATAFILES a,INNODB_SYS_INDEXES c,INNODB_SYS_TABLESTATS d,INNODB_SYS_COLUMNS e,INNODB_SYS_TABLESPACES f,INNODB_SYS_FIELDS g WHERE a.SPACE=b.SPACE and b.TABLE_ID=c.TABLE_ID and b.TABLE_ID=d.TABLE_ID and b.TABLE_ID=e.TABLE_ID and b.SPACE=f.SPACE and c.INDEX_ID=g.INDEX_ID and b. NAME='jute/jute_vote' GROUP BY c.TABLE_ID,c.INDEX_ID;
效果以下:
*************************** 1. row *************************** datafile: ./jute/jute_vote.ibd name: jute/jute_vote table_id: 149 ###表id flags: 1 columns: 8 ###表只有5列,爲何顯示8列?由於包含了隱藏列:DB_ROW_ID(6)、DB_TRX_ID(6)、DB_ROLL_PTR(7) indexes: 1 appr.rows: 182198 ###錶行的估算值 column_name: surveyId,choiceId,voteTime,userId,comment ###表列 column_len: 4,4,5,4,4 ###對應表列的長度 index_name: PRIMARY ###索引名 index_id: 324 ###索引id index_fields: surveyId,userId ###索引列 CLUST_INDEX_SIZE: 545 ###彙集索引的頁數 OTHER_INDEX_SIZE: 0 ###二級索引的頁數,表中沒有二級索引 PAGE_SIZE: 16384 ###頁的單位,16K FILE_FORMAT: Antelope ###文件格式 ROW_FORMAT: Compact ####行格式
從上面看出雖然能用information_schema中的各表展現,但仍是少了一些信息,好比隱藏字段和索引包括主鍵的完整字段。
3.2:alter ignore table 語法被移除。
3.3:SHOW PROFILE 語法將被移除。經過information_schema.profiling或則performance_schema相關表來代替,如:
##老 show profile cpu,block io for query 2; ##information_schema SELECT query_id,state,DURATION,CPU_USER,CPU_SYSTEM,BLOCK_OPS_IN,BLOCK_OPS_OUT FROM INFORMATION_SCHEMA.PROFILING WHERE QUERY_ID = 36;
官方文檔已經出了說明,這裏大體講下如何經過performance_schema查看,關於performance_schema的說明能夠看這裏 1)setup_actors:配置用戶緯度的監控,默認監控全部用戶 performance_schema 01:40:04>SELECT * FROM setup_actors; +------+------+------+---------+---------+ | HOST | USER | ROLE | ENABLED | HISTORY | +------+------+------+---------+---------+ | % | % | % | YES | YES | +------+------+------+---------+---------+ 默認是監控全部用戶的操做,會有必定性能的損耗,因此只須要開啓指定用戶的便可: performance_schema 01:40:23>UPDATE performance_schema.setup_actors SET ENABLED = 'NO', HISTORY = 'NO' WHERE HOST = '%' AND USER = '%'; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 performance_schema 01:40:40>SELECT * FROM setup_actors; +------+------+------+---------+---------+ | HOST | USER | ROLE | ENABLED | HISTORY | +------+------+------+---------+---------+ | % | % | % | NO | NO | +------+------+------+---------+---------+ 1 row in set (0.17 sec) ##開啓對dba用戶的監控: performance_schema 01:40:42>INSERT INTO performance_schema.setup_actors (HOST,USER,ROLE,ENABLED,HISTORY) VALUES('192.168.100.%','dba','%','YES','YES'); performance_schema 01:43:08>SELECT * FROM setup_actors; +---------------+------+------+---------+---------+ | HOST | USER | ROLE | ENABLED | HISTORY | +---------------+------+------+---------+---------+ | % | % | % | NO | NO | | 192.168.100.% | dba | % | YES | YES | +---------------+------+------+---------+---------+ 2)打開全部須要監控的選項: performance_schema 01:51:35>UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE '%statement/%'; performance_schema 01:57:01>UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE '%stage/%'; performance_schema 01:57:09>UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%events_statements_%'; performance_schema 01:57:27>UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%events_stages_%'; 3)執行須要監控的語句 select ..... 4)查看: ①老的: performance_schema 01:42:06>show profile cpu,block io for query 6; +----------------------+----------+----------+------------+--------------+---------------+ | Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out | +----------------------+----------+----------+------------+--------------+---------------+ | starting | 0.000178 | NULL | NULL | NULL | NULL | | checking permissions | 0.000012 | NULL | NULL | NULL | NULL | | Opening tables | 0.000050 | NULL | NULL | NULL | NULL | | init | 0.000065 | NULL | NULL | NULL | NULL | | System lock | 0.000017 | NULL | NULL | NULL | NULL | | optimizing | 0.000022 | NULL | NULL | NULL | NULL | | statistics | 0.001057 | NULL | NULL | NULL | NULL | | preparing | 0.000135 | NULL | NULL | NULL | NULL | | executing | 0.000009 | NULL | NULL | NULL | NULL | | Sending data | 1.265446 | NULL | NULL | NULL | NULL | | end | 0.000013 | NULL | NULL | NULL | NULL | | query end | 0.000393 | NULL | NULL | NULL | NULL | | removing tmp table | 0.000033 | NULL | NULL | NULL | NULL | | query end | 0.000004 | NULL | NULL | NULL | NULL | | closing tables | 0.000013 | NULL | NULL | NULL | NULL | | freeing items | 0.000056 | NULL | NULL | NULL | NULL | | logging slow query | 0.000006 | NULL | NULL | NULL | NULL | | logging slow query | 0.000202 | NULL | NULL | NULL | NULL | | cleaning up | 0.000042 | NULL | NULL | NULL | NULL | +----------------------+----------+----------+------------+--------------+---------------+ ②新的: 先找出EVENT_ID: SELECT EVENT_ID, TRUNCATE(TIMER_WAIT/1000000000000,6) as Duration, SQL_TEXT FROM performance_schema.events_statements_history_long WHERE SQL_TEXT like '%18,19,20,21%'; ... ... 經過上面找到的EVENT_ID再執行: SELECT event_name AS Stage, TRUNCATE(TIMER_WAIT/1000000000000,6) AS Duration FROM performance_schema.events_stages_history_long WHERE NESTING_EVENT_ID=231; +--------------------------------+----------+ | Stage | Duration | +--------------------------------+----------+ | stage/sql/starting | 0.000213 | | stage/sql/checking permissions | 0.000009 | | stage/sql/Opening tables | 0.000049 | | stage/sql/init | 0.000065 | | stage/sql/System lock | 0.000016 | | stage/sql/optimizing | 0.000022 | | stage/sql/statistics | 0.001060 | | stage/sql/preparing | 0.000136 | | stage/sql/executing | 0.000003 | | stage/sql/Sending data | 1.265452 | | stage/sql/end | 0.000006 | | stage/sql/query end | 0.000412 | | stage/sql/removing tmp table | 0.000011 | | stage/sql/closing tables | 0.000012 | | stage/sql/freeing items | 0.000058 | | stage/sql/logging slow query | 0.000203 | | stage/sql/cleaning up | 0.000002 | +--------------------------------+----------+
3.4:採用ALTER USER來爲用戶修改密碼,不建議再使用SET PASSWORD修改密碼。
...
4,總結
在官方測試裏看到,MySQL5.7在功能、性能、可用性、安全和監控上又提高了很高。如上面介紹的這些,特別是複製方面的改進:多線程、多源、GTID,半同步等都作了很大改進,以及中文分詞的支持還有sys schema上面的數據庫性能信息狀態收集等。後續會詳細介紹這幾方面的知識,增強對MySQL5.7的認識,本文只是說了一些本身比較關注的,比較詳細的請見 What’s New in MySQL 5.7,後續會持續更新說明。
5,參考文檔:
MySQL5.7中InnoDB不可不知的新特性(9月5號更新)