1、mysql 8.0+ 新特性php
1. 默認字符集由latin1變爲utf8mb4html
在8.0版本以前,默認字符集爲latin1,utf8指向的是utf8mb3,8.0版本默認字符集爲utf8mb4,utf8默認指向的也是utf8mb4。mysql
2. MyISAM系統表所有換成InnoDB表sql
系統表所有換成事務型的innodb表,默認的MySQL實例將不包含任何MyISAM表,除非手動建立MyISAM表。數據庫
# MySQL 5.7 mysql> select distinct(ENGINE) from information_schema.tables; +--------------------+ | ENGINE | +--------------------+ | MEMORY | | InnoDB | | MyISAM | | CSV | | PERFORMANCE_SCHEMA | | NULL | +--------------------+ 6 rows in set (0.00 sec) # MySQL 8.0 mysql> select distinct(ENGINE) from information_schema.tables; +--------------------+ | ENGINE | +--------------------+ | NULL | | InnoDB | | CSV | | PERFORMANCE_SCHEMA | +--------------------+ 4 rows in set (0.00 sec)
3. 自增變量持久化json
在8.0以前的版本,自增主鍵AUTO_INCREMENT的值若是大於max(primary key)+1,在MySQL重啓後,會重置AUTO_INCREMENT=max(primary key)+1,這種現象在某些狀況下會致使業務主鍵衝突或者其餘難以發現的問題。自增主鍵重啓重置的問題很早就被發現(https://bugs.mysql.com/bug.php?id=199),一直到8.0才被解決,8.0版本將會對AUTO_INCREMENT值進行持久化,MySQL重啓後,該值將不會改變。windows
4. DDL原子化數組
InnoDB表的DDL支持事務完整性,要麼成功要麼回滾,將DDL操做回滾日誌寫入到data dictionary 數據字典表 mysql.innodb_ddl_log 中用於回滾操做,該表是隱藏的表,經過show tables沒法看到。經過設置參數,可將ddl操做日誌打印輸出到mysql錯誤日誌中。服務器
mysql> set global log_error_verbosity=3; mysql> set global innodb_print_ddl_logs=1; mysql> create table t1(c int) engine=innodb; # MySQL錯誤日誌: 2018-06-26T11:25:25.817245+08:00 44 [Note] [MY-012473] [InnoDB] InnoDB: DDL log insert : [DDL record: DELETE SPACE, id=41, thread_id=44, space_id=6, old_file_path=./db/t1.ibd] 2018-06-26T11:25:25.817369+08:00 44 [Note] [MY-012478] [InnoDB] InnoDB: DDL log delete : by id 41 2018-06-26T11:25:25.819753+08:00 44 [Note] [MY-012477] [InnoDB] InnoDB: DDL log insert : [DDL record: REMOVE CACHE, id=42, thread_id=44, table_id=1063, new_file_path=db/t1] 2018-06-26T11:25:25.819796+08:00 44 [Note] [MY-012478] [InnoDB] InnoDB: DDL log delete : by id 42 2018-06-26T11:25:25.820556+08:00 44 [Note] [MY-012472] [InnoDB] InnoDB: DDL log insert : [DDL record: FREE, id=43, thread_id=44, space_id=6, index_id=140, page_no=4] 2018-06-26T11:25:25.820594+08:00 44 [Note] [MY-012478] [InnoDB] InnoDB: DDL log delete : by id 43 2018-06-26T11:25:25.825743+08:00 44 [Note] [MY-012485] [InnoDB] InnoDB: DDL log post ddl : begin for thread id : 44 2018-06-26T11:25:25.825784+08:00 44 [Note] [MY-012486] [InnoDB] InnoDB: DDL log post ddl : end for thread id : 44
來看另一個例子,庫裏只有一個t1表,drop table t1,t2; 試圖刪除t1,t2兩張表,在5.7中,執行報錯,可是t1表被刪除,在8.0中執行報錯,可是t1表沒有被刪除,證實了8.0 DDL操做的原子性,要麼所有成功,要麼回滾。session
# MySQL 5.7 mysql> show tables; +---------------+ | Tables_in_db | +---------------+ | t1 | +---------------+ 1 row in set (0.00 sec) mysql> drop table t1, t2; ERROR 1051 (42S02): Unknown table 'db.t2' mysql> show tables; Empty set (0.00 sec) # MySQL 8.0 mysql> show tables; +---------------+ | Tables_in_db | +---------------+ | t1 | +---------------+ 1 row in set (0.00 sec) mysql> drop table t1, t2; ERROR 1051 (42S02): Unknown table 'db.t2' mysql> show tables; +---------------+ | Tables_in_db | +---------------+ | t1 | +---------------+ 1 row in set (0.00 sec)
5. 參數修改持久化
MySQL 8.0版本支持在線修改全局參數並持久化,經過加上PERSIST關鍵字,能夠將修改的參數持久化到新的配置文件(mysqld-auto.cnf)中,重啓MySQL時,能夠從該配置文件獲取到最新的配置參數。
例如執行:set PERSIST expire_logs_days=10 ;系統會在數據目錄下生成一個包含json格式的 mysqld-auto.cnf 的文件,格式化後以下所示,當 my.cnf 和 mysqld-auto.cnf 同時存在時,後者具備更高優先級。
{ "Version": 1, "mysql_server": { "expire_logs_days": { "Value": "10", "Metadata": { "Timestamp": 1529657078851627, "User": "root", "Host": "localhost" } } } }
6. 新增降序索引
MySQL在語法上很早就已經支持降序索引,但實際上建立的仍然是升序索引,以下MySQL 5.7 所示,c2字段降序,可是從show create table看c2仍然是升序。8.0能夠看到,c2字段降序。
# MySQL 5.7 mysql> create table t1(c1 int,c2 int,index idx_c1_c2(c1,c2 desc)); Query OK, 0 rows affected (0.03 sec) mysql> show create table t1\G *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t1` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL, KEY `idx_c1_c2` (`c1`,`c2`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 1 row in set (0.00 sec) # MySQL 8.0 mysql> create table t1(c1 int,c2 int,index idx_c1_c2(c1,c2 desc)); Query OK, 0 rows affected (0.06 sec) mysql> show create table t1\G *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t1` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL, KEY `idx_c1_c2` (`c1`,`c2` DESC) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC 1 row in set (0.00 sec)
再來看看降序索引在執行計劃中的表現,在t1表插入10萬條隨機數據,查看select * from t1 order by c1 , c2 desc;的執行計劃。從執行計劃上能夠看出,5.7的掃描數100113遠遠大於8.0的5行,而且使用了filesort。
DELIMITER ;; CREATE PROCEDURE test_insert () BEGIN DECLARE i INT DEFAULT 1; WHILE i<100000 DO insert into t1 select rand()*100000, rand()*100000; SET i=i+1; END WHILE ; commit; END;; DELIMITER ; CALL test_insert(); # MySQL 5.7 mysql> explain select * from t1 order by c1 , c2 desc limit 5; +----+-------------+-------+------------+-------+---------------+-----------+---------+------+--------+----------+-----------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+-----------+---------+------+--------+----------+-----------------------------+ | 1 | SIMPLE | t1 | NULL | index | NULL | idx_c1_c2 | 10 | NULL | 100113 | 100.00 | Using index; Using filesort | +----+-------------+-------+------------+-------+---------------+-----------+---------+------+--------+----------+-----------------------------+ 1 row in set, 1 warning (0.00 sec) # MySQL 8.0 mysql> explain select * from t1 order by c1 , c2 desc limit 5; +----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+ | 1 | SIMPLE | t1 | NULL | index | NULL | idx_c1_c2 | 10 | NULL | 5 | 100.00 | Using index | +----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec)
降序索引只是對查詢中特定的排序順序有效,若是使用不當,反而查詢效率更低,好比上述查詢排序條件改成 order by c1 desc, c2 desc,這種狀況下,5.7的執行計劃要明顯好於8.0的,以下:
# MySQL 5.7 mysql> explain select * from t1 order by c1 desc , c2 desc limit 5; +----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+ | 1 | SIMPLE | t1 | NULL | index | NULL | idx_c1_c2 | 10 | NULL | 5 | 100.00 | Using index | +----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.01 sec) # MySQL 8.0 mysql> explain select * from t1 order by c1 desc , c2 desc limit 5; +----+-------------+-------+------------+-------+---------------+-----------+---------+------+--------+----------+-----------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+-----------+---------+------+--------+----------+-----------------------------+ | 1 | SIMPLE | t1 | NULL | index | NULL | idx_c1_c2 | 10 | NULL | 100429 | 100.00 | Using index; Using filesort | +----+-------------+-------+------------+-------+---------------+-----------+---------+------+--------+----------+-----------------------------+ 1 row in set, 1 warning (0.01 sec)
7. group by 再也不隱式排序
mysql 8.0 對於group by 字段再也不隱式排序,如須要排序,必須顯式加上order by 子句。
# 表結構 mysql> show create table tb1\G *************************** 1. row *************************** Table: tb1 Create Table: CREATE TABLE `tb1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, `group_own` int(11) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC 1 row in set (0.00 sec) # 表數據 mysql> select * from tb1; +----+------+-----------+ | id | name | group_own | +----+------+-----------+ | 1 | 1 | 0 | | 2 | 2 | 0 | | 3 | 3 | 0 | | 4 | 4 | 0 | | 5 | 5 | 5 | | 8 | 8 | 1 | | 10 | 10 | 5 | +----+------+-----------+ 7 rows in set (0.00 sec) # MySQL 5.7 mysql> select count(id), group_own from tb1 group by group_own; +-----------+-----------+ | count(id) | group_own | +-----------+-----------+ | 4 | 0 | | 1 | 1 | | 2 | 5 | +-----------+-----------+ 3 rows in set (0.00 sec) # MySQL 8.0.11 mysql> select count(id), group_own from tb1 group by group_own; +-----------+-----------+ | count(id) | group_own | +-----------+-----------+ | 4 | 0 | | 2 | 5 | | 1 | 1 | +-----------+-----------+ 3 rows in set (0.00 sec) # MySQL 8.0.11顯式地加上order by進行排序 mysql> select count(id), group_own from tb1 group by group_own order by group_own; +-----------+-----------+ | count(id) | group_own | +-----------+-----------+ | 4 | 0 | | 1 | 1 | | 2 | 5 | +-----------+-----------+ 3 rows in set (0.00 sec)
8. JSON特性加強
MySQL 8 大幅改進了對 JSON 的支持,添加了基於路徑查詢參數從 JSON 字段中抽取數據的 JSON_EXTRACT() 函數,以及用於將數據分別組合到 JSON 數組和對象中的 JSON_ARRAYAGG() 和 JSON_OBJECTAGG() 聚合函數。
在主從複製中,新增參數 binlog_row_value_options,控制JSON數據的傳輸方式,容許對於Json類型部分修改,在binlog中只記錄修改的部分,減小json大數據在只有少許修改的狀況下,對資源的佔用。
9. redo & undo 日誌加密
增長如下兩個參數,用於控制redo、undo日誌的加密。
innodb_undo_log_encrypt
innodb_undo_log_encrypt
10. innodb select for update跳過鎖等待
select ... for update,select ... for share(8.0新增語法) 添加 NOWAIT、SKIP LOCKED語法,跳過鎖等待,或者跳過鎖定。
在5.7及以前的版本,select...for update,若是獲取不到鎖,會一直等待,直到innodb_lock_wait_timeout超時。
在8.0版本,經過添加nowait,skip locked語法,可以當即返回。若是查詢的行已經加鎖,那麼nowait會當即報錯返回,而skip locked也會當即返回,只是返回的結果中不包含被鎖定的行。
# session1: mysql> begin; mysql> select * from t1 where c1 = 2 for update; +------+-------+ | c1 | c2 | +------+-------+ | 2 | 60530 | | 2 | 24678 | +------+-------+ 2 rows in set (0.00 sec) # session2: mysql> select * from t1 where c1 = 2 for update nowait; ERROR 3572 (HY000): Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set. mysql> select * from t1 where c1 = 2 for update skip locked; Empty set (0.00 sec)
11. 增長SET_VAR語法
在sql語法中增長SET_VAR語法,動態調整部分參數,有利於提高語句性能。
select /*+ SET_VAR(sort_buffer_size = 16M) */ id from test order id ;
insert /*+ SET_VAR(foreign_key_checks=OFF) */ into test(name) values(1);
12. 支持不可見索引
使用INVISIBLE關鍵字在建立表或者進行表變動中設置索引是否可見。索引不可見只是在查詢時優化器不使用該索引,即便使用force index,優化器也不會使用該索引,同時優化器也不會報索引不存在的錯誤,由於索引仍然真實存在,在必要時,也能夠快速的恢復成可見。
# 建立不可見索引 create table t2(c1 int,c2 int,index idx_c1_c2(c1,c2 desc) invisible ); # 索引可見 alter table t2 alter index idx_c1_c2 visible; # 索引不可見 alter table t2 alter index idx_c1_c2 invisible;
13. 支持直方圖
優化器會利用column_statistics的數據,判斷字段的值的分佈,獲得更準確的執行計劃。
可使用 ANALYZE TABLE table_name [UPDATE HISTOGRAM on col_name with N BUCKETS |DROP HISTOGRAM ON clo_name] 來收集或者刪除直方圖信息。
直方圖統計了表中某些字段的數據分佈狀況,爲優化選擇高效的執行計劃提供參考,直方圖與索引有着本質的區別,維護一個索引有代價。每一次的insert、update、delete都會須要更新索引,會對性能有必定的影響。而直方圖一次建立永不更新,除非明確去更新它。因此不會影響insert、update、delete的性能。
# 添加/更新直方圖 mysql> analyze table t1 update histogram on c1, c2 with 32 buckets; +--------+-----------+----------+-----------------------------------------------+ | Table | Op | Msg_type | Msg_text | +--------+-----------+----------+-----------------------------------------------+ | db.t1 | histogram | status | Histogram statistics created for column 'c1'. | | db.t1 | histogram | status | Histogram statistics created for column 'c2'. | +--------+-----------+----------+-----------------------------------------------+ 2 rows in set (2.57 sec) # 刪除直方圖 mysql> analyze table t1 drop histogram on c1, c2; +--------+-----------+----------+-----------------------------------------------+ | Table | Op | Msg_type | Msg_text | +--------+-----------+----------+-----------------------------------------------+ | db.t1 | histogram | status | Histogram statistics removed for column 'c1'. | | db.t1 | histogram | status | Histogram statistics removed for column 'c2'. | +--------+-----------+----------+-----------------------------------------------+ 2 rows in set (0.13 sec)
14. 新增innodb_dedicated_server參數
可以讓InnoDB根據服務器上檢測到的內存大小自動配置innodb_buffer_pool_size,innodb_log_file_size,innodb_flush_method三個參數。
15. 日誌分類更詳細
在錯誤信息中添加了錯誤信息編號[MY-010311]和錯誤所屬子系統[Server]
# MySQL 5.7 2018-06-08T09:07:20.114585+08:00 0 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode. 2018-06-08T09:07:20.117848+08:00 0 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode. 2018-06-08T09:07:20.117868+08:00 0 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode. # MySQL 8.0 2018-06-21T17:53:13.040295+08:00 28 [Warning] [MY-010311] [Server] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode. 2018-06-21T17:53:13.040520+08:00 28 [Warning] [MY-010330] [Server] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode. 2018-06-21T17:53:13.040542+08:00 28 [Warning] [MY-010330] [Server] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
16. undo空間自動回收
17. 增長資源組
MySQL 8.0新增了一個資源組功能,用於調控線程優先級以及綁定CPU核。
MySQL用戶須要有 RESOURCE_GROUP_ADMIN權限才能建立、修改、刪除資源組。
在Linux環境下,MySQL進程須要有 CAP_SYS_NICE 權限才能使用資源組完整功能。
[root@localhost~]# sudo setcap cap_sys_nice+ep /usr/local/mysql8.0/bin/mysqld [root@localhost~]# getcap /usr/local/mysql8.0/bin/mysqld /usr/local/mysql8.0/bin/mysqld = cap_sys_nice+ep
默認提供兩個資源組,分別是USR_default,SYS_default
建立資源組:
create resource group test_resouce_group type=USER vcpu=0,1 thread_priority=5;
將當前線程加入資源組:
SET RESOURCE GROUP test_resouce_group;
將某個線程加入資源組:
SET RESOURCE GROUP test_resouce_group FOR thread_id;
查看資源組裏有哪些線程:
select * from Performance_Schema.threads where RESOURCE_GROUP='test_resouce_group';
修改資源組:
alter resource group test_resouce_group vcpu = 2,3 THREAD_PRIORITY = 8;
刪除資源組 :
drop resource group test_resouce_group;
# 建立資源組 mysql>create resource group test_resouce_group type=USER vcpu=0,1 thread_priority=5; Query OK, 0 rows affected (0.03 sec) mysql> select * from RESOURCE_GROUPS; +---------------------+---------------------+------------------------+----------+-----------------+ | RESOURCE_GROUP_NAME | RESOURCE_GROUP_TYPE | RESOURCE_GROUP_ENABLED | VCPU_IDS | THREAD_PRIORITY | +---------------------+---------------------+------------------------+----------+-----------------+ | USR_default | USER | 1 | 0-3 | 0 | | SYS_default | SYSTEM | 1 | 0-3 | 0 | | test_resouce_group | USER | 1 | 0-1 | 5 | +---------------------+---------------------+------------------------+----------+-----------------+ 3 rows in set (0.00 sec) # 把線程id爲60的線程加入到資源組test_resouce_group中,線程id可經過Performance_Schema.threads獲取 mysql> SET RESOURCE GROUP test_resouce_group FOR 60; Query OK, 0 rows affected (0.00 sec) # 資源組裏有線程時,刪除資源組報錯 mysql> drop resource group test_resouce_group; ERROR 3656 (HY000): Resource group test_resouce_group is busy. # 修改資源組 mysql> alter resource group test_resouce_group vcpu = 2,3 THREAD_PRIORITY = 8; Query OK, 0 rows affected (0.10 sec) mysql> select * from RESOURCE_GROUPS; +---------------------+---------------------+------------------------+----------+-----------------+ | RESOURCE_GROUP_NAME | RESOURCE_GROUP_TYPE | RESOURCE_GROUP_ENABLED | VCPU_IDS | THREAD_PRIORITY | +---------------------+---------------------+------------------------+----------+-----------------+ | USR_default | USER | 1 | 0-3 | 0 | | SYS_default | SYSTEM | 1 | 0-3 | 0 | | test_resouce_group | USER | 1 | 2-3 | 8 | +---------------------+---------------------+------------------------+----------+-----------------+ 3 rows in set (0.00 sec) # 把資源組裏的線程移出到默認資源組USR_default mysql> SET RESOURCE GROUP USR_default FOR 60; Query OK, 0 rows affected (0.00 sec) # 刪除資源組 mysql> drop resource group test_resouce_group; Query OK, 0 rows affected (0.04 sec)
18. 增長角色管理
角色能夠認爲是一些權限的集合,爲用戶賦予統一的角色,權限的修改直接經過角色來進行,無需爲每一個用戶單獨受權。
# 建立角色 mysql> create role role_test; Query OK, 0 rows affected (0.03 sec) # 給角色授予權限 mysql> grant select on db.* to 'role_test'; Query OK, 0 rows affected (0.10 sec) # 建立用戶 mysql> create user 'read_user'@'%' identified by '123456'; Query OK, 0 rows affected (0.09 sec) # 給用戶賦予角色 mysql> grant 'role_test' to 'read_user'@'%'; Query OK, 0 rows affected (0.02 sec) # 給角色role_test增長insert權限 mysql> grant insert on db.* to 'role_test'; Query OK, 0 rows affected (0.08 sec) # 給角色role_test刪除insert權限 mysql> revoke insert on db.* from 'role_test'; Query OK, 0 rows affected (0.10 sec) # 查看默認角色信息 mysql> select * from mysql.default_roles; +------+-----------+-------------------+-------------------+ | HOST | USER | DEFAULT_ROLE_HOST | DEFAULT_ROLE_USER | +------+-----------+-------------------+-------------------+ | % | read_user | % | role_test | +------+-----------+-------------------+-------------------+ 1 row in set (0.00 sec) # 查看角色與用戶關係 mysql> select * from mysql.role_edges; +-----------+-----------+---------+-----------+-------------------+ | FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION | +-----------+-----------+---------+-----------+-------------------+ | % | role_test | % | read_user | N | +-----------+-----------+---------+-----------+-------------------+ 1 row in set (0.00 sec) # 刪除角色 mysql> drop role role_test; Query OK, 0 rows affected (0.06 sec)
2、mysql 8.0+安裝(以mysql8.0.15版本爲例)
1.下載地址https://www.mysql.com/downloads/
2. 選擇版本以下(以windows 64位平臺安裝爲例)
3.下載後解壓zip文件
4.進入解壓後的目錄,配置初始化的my.ini文件
ps:解壓後的目錄並無的my.ini文件,不要緊能夠自行建立在安裝根目錄下添加的my.ini(新建文本文件,將文件類型改成的.ini),寫入基本配置:
5. cmd直接進入的mysql的目錄,進行數據庫初始化
在MySQL的安裝目錄的倉目錄下執行命令:mysqld --initialize --console
ps: [服務器]爲root @ localhost生成臨時密碼:9P0gYk-?0,kT其中root @ localhost:後面的************就是初始密碼(不含首位空格)。在沒有更改密碼前,須要記住這個密碼,後續登陸須要用到。
6. 執行安裝
在MySQL的安裝目錄的倉目錄下執行命令下執行命令:mysqld --install [服務名](服務名能夠不加默認爲mysql)
7. 啓動服務
服務安裝成功以後經過命令net start mysql啓動MySQL的服務
8.使用navicat鏈接數據庫
1)新建的MySQL的鏈接
2)還記得剛剛讓你複製的root @ localhost:後面的初始密碼了嗎?如今要用到它了複製粘貼上去!點擊【鏈接測試】進行測試!
3) 查看會話
本次就寫到這裏,有不足之處,請你們諒解並進行指正!