MySQL8.0新特性集錦
1. 默認字符集由latin1變為utf8mb4
在8.0版本之前,默認字符集為latin1,utf8指向的是utf8mb3,8.0版本默認字符集為utf8mb4,utf8默認指向的也是utf8mb4。
注:在Percona Server 8.0.15版本上測試,utf8仍然指向的是utf8mb3,與官方文檔有出入。
2. MyISAM系統表全部換成InnoDB表
系統表全部換成事務型的innodb表,默認的MySQL實例將不包含任何MyISAM表,除非手動創建MyISAM表。
3. 自增變量持久化
在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重啟后,該值將不會改變。
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;
來看另外一個例子,庫里只有一個t1表,drop table t1,t2;
試圖刪除t1,t2兩張表,在5.7中,執行報錯,但是t1表被刪除,在8.0中執行報錯,但是t1表沒有被刪除,證明了8.0 DDL操作的原子性,要么全部成功,要么回滾。
5. 參數修改持久化
MySQL 8.0版本支持在線修改全局參數並持久化,通過加上PERSIST關鍵字,可以將修改的參數持久化到新的配置文件(mysqld-auto.cnf)中,重啟MySQL時,可以從該配置文件獲取到最新的配置參數。
例如執行:
set PERSIST expire_logs_days=10 ;
系統會在數據目錄下生成一個包含json格式的 mysqld-auto.cnf 的文件,格式化后如下所示,當 my.cnf 和 mysqld-auto.cnf 同時存在時,后者具有更高優先級。
6. 新增降序索引
MySQL在語法上很早就已經支持降序索引,但實際上創建的仍然是升序索引,
如下MySQL 5.7 所示,c2字段降序,但是從show create table看c2仍然是升序。
8.0可以看到,c2字段降序。
再來看降序索引在執行計划中的表現,在t1表插入10萬條隨機數據,
查看select * from t1 order by c1 , c2 desc;的執行計划。從執行計划上可以看出,
5.7的掃描數100113遠遠大於8.0的5行,並且使用了filesort。
7. group by 不再隱式排序
mysql 8.0 對於group by 字段不再隱式排序,如需要排序,必須顯式加上order by 子句。
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_truncate
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也會立即返回,只是返回的結果中不包含被鎖定的行。
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. 新增innodb_dedicated_server參數
能夠讓InnoDB根據服務器上檢測到的內存大小自動配置innodb_buffer_pool_size,innodb_log_file_size,innodb_flush_method三個參數。
14. 日志分類更詳細
在錯誤信息中添加了錯誤信息編號[MY-010311]和錯誤所屬子系統[Server]
15. undo空間自動回收
innodb_undo_log_truncate參數在8.0.2版本默認值由OFF變為ON,默認開啟undo日志表空間自動回收。
innodb_undo_tablespaces參數在8.0.2版本默認為2,當一個undo表空間被回收時,還有另外一個提供正常服務。
innodb_max_undo_log_size參數定義了undo表空間回收的最大值,當undo表空間超過這個值,該表空間被標記為可回收。
15. 增加資源組
MySQL 8.0新增了一個資源組功能,用於調控線程優先級以及綁定CPU核。
MySQL用戶需要有 RESOURCE_GROUP_ADMIN權限才能創建、修改、刪除資源組。
在Linux環境下,MySQL進程需要有CAP_SYS_NICE 權限才能使用資源組完整功能。
默認提供兩個資源組,分別是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;
16. 增加角色管理
角色可以認為是一些權限的集合,為用戶賦予統一的角色,權限的修改直接通過角色來進行,無需為每個用戶單獨授權。
17、MySQL8.0現在支持窗口函數(over)和公用表表達式(with)。毫無疑問,這是兩個最重要的Post-SQL-92功能。
18、8.0.12的優化是,新增了一個算法 ALGORITHM=INSTANT,專門處理只需要修改元數據就可以完成的變更,這個就可以相對比較方便地直接使用了,不需要擔心從庫延遲。
目前支持的操作是:
1.添加新列。已知限制條件如下:
不能與其他不支持INSTANT算法的alter子語句合並在一起。
只能添加在表列的末尾。
不能用於innodb的壓縮表(ROW_FORMAT=COMPRESSED)。
目標表不能包含全文索引。
目標表不能是臨時表。
目標表不能是數據字典表。
這種添加方式下,不會計算行長度是否合適,這個計算會在發生insert或者update的時候處理。
2. 添加或者刪除虛擬列。
3. 添加或者去掉列的默認值。
4. 修改 enum,set 列類型的定義(題外話,有多少人知道並在用這個?)
5. 修改索引類型。
6. 重命名表名稱。
Mysql8.0初始化
出現的問題:
- 在安裝MySQL8.0時,修改臨時密碼,因密碼過於簡單(如:123456),不符合MySQL密碼規范,會觸發一個報錯信息:
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements。
免密登陸后無法修改密碼:
[(none)] >alter user 'root'@'%' identified with mysql_native_password by 'MyNewPass4!';
ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement
