簡介
MySQL 經過20來年發展現在已是世界上最流行的開源數據庫,8.0 版本作為5.7版本后的跨越大版本,除了大表秒級加列外還有其它什么特性了?能在生產上使用嗎?MySQL5.7 怎么才能無損升級到MySQL8.0?
MySQL發展歷程

起源於上個世紀末的MySQL每隔2~3年就會發布一次大版本,不斷持續的“升級”。2008年MySQL被Sun公司以10億美元收購,2009年甲骨文以74億美元收購Sun公司,這是很成功的一次收購與被收購!13年和16年的MySQL5.6、MySQL5.7都是里程碑式的版本,有了很多質的飛躍;18年發布了醞釀3年的MySQL8.0,又帶來了哪些新特性?
MySQL8.0新特性
秒級加列
- 只改數據字典表元數據信息
- 5.7和8.0 sbteset1表數據分別為3000w
# mysql8.0.18
mysql> alter table sbtest1 add str varchar(200) not null default 'mysql8.0 新加字段';
Query OK, 0 rows affected (0.13 sec)
Records: 0 Duplicates: 0 Warnings: 0
# mysql5.7.16
mysql> alter table sbtest1 add str varchar(200) not null default 'mysql5.7 新加字段';
Query OK, 0 rows affected (6 min 8.36 sec)
Records: 0 Duplicates: 0 Warnings: 0
以前表加列操作需要重建表(消耗大量的IO資源和時間),8.0加列沒有這個步驟。秒級加列(不要指定列位置,如after str1)讓開發人員再也不用等到大半夜列加完后再上線了,也讓我們dba不用老擔心加列失敗(生產環境出現加列報主鍵沖突錯誤)
性能提升

# mysql5.7.16
mysql> select count(*) from sbtest1;
+----------+
| count(*) |
+----------+
| 29991137 |
+----------+
1 row in set (3 min 12.24 sec)
# mysql8.0.18
mysql> select count(*) from sbtest1;
+----------+
| count(*) |
+----------+
| 30000000 |
+----------+
1 row in set (45.70 sec)
分別在只更新和只讀場景下,8.0相比5.7在高並發時性能提升近1倍;求表總數據量8.0響應時間也將近提升5倍
文檔數據庫
- MySQL Document Store,NoSQL + SQL = MySQL
- 多文檔事務,ACID特性
- 支持更新JSON中部分filed

文檔存儲無固定表結構動態schema是很受咱們開發人員喜愛的
SQL增強
共用表表達式(CTEs)
- 讓SQL語句更加簡單、直觀
支持CTE的DB有 Teradata, DB2, Firebird, Microsoft SQL Server, Oracle ,PostgreSQL (since 8.4), MariaDB (since 10.2), SQLite (since 3.8.3), HyperSQL and H2 (experimental), MySQL8.0
- 窗口函數
對每個門店銷售量最高的商品進行統計,每個部門按業績來排名
- 共用表表達式(CTEs)和窗口函數是報表、OLAP業務一大利器
不可見索引(Invisible Indexes)
SQL執行時內部優化器忽略指定索引;驗證刪除索引后對查詢性能影響
Alter table t1 alter index idx_str invisible;
Alter table t1 alter index idx_str visible;
降序索引(Descending Indexes)
索引按倒序存儲,之前方式都是按順序存儲;使用到具有倒序、升序列的復合索引
select * from tx where c1=10 order by c2 desc,c4 asc;
函數索引 (Functional Indexes)
Where條件中無法使用到索引成為傳說!
select * from tx where year(date_)=2020;
默認字符集為utf8mb4
- 更好的存儲補充字符,如emojis表情符號
- 可變長度編碼字符性能提升

一致性查詢改進(Better Handling of Hot Rows)
- SKIP LOCKED
需要加鎖的記錄若被其它線程占有鎖,則跳過,而不是等待
select * from tx where c1=12 for update skip locked;
Empty set (0.00 sec)
- NOWAIT
需要加鎖的記錄有鎖則報錯
select * from tx where c1=12 for update nowait;
ERROR 3572 (HY000): Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set.
SKIP LOCKED和NOWAIT對熱行(Hot Rows)場景如搶紅包、秒殺等有益
資源組(Resource Groups)
- 線程賦給不同的資源組
- 資源組和不同的內存、IO、CPU(現僅支持)進行關聯

官方版多租戶資源隔離成為了可能,更好提升在不同讀寫業務場景下的性能
新的數據字典
- 基於innodb的庫表元數據信息
- 增強了MySQL crash-safe能力
- 原子DDL( Atomic DDLs )

以前版本MySQL數據字典存放在多個地方,一機器多實例時存在大量文件描述符性能消耗,8.0版本都存放在事務性InnoDB表,MySQL異常掛掉后也不會再出現表損壞情況;DDL操作失敗也不會再留下占空間的“臨時文件”
MGR增強
- 金融級別99.999%官方高可用方案
- MGR是業務多活(應用多活+數據庫多活)的終極方案
- 多個MySQL組成一個group,數據寫group
- 線上10套多主8.0 MGR集群
節點自動加入group次數 https://dev.mysql.com/doc/refman/8.0/en/group-replication-options.html#sysvar_group_replication_autorejoin_tries
group剔除異常節點等待時間
https://dev.mysql.com/doc/refman/8.0/en/group-replication-options.html#sysvar_group_replication_member_expel_timeout
節點自行脫離group等待時間
https://dev.mysql.com/doc/refman/8.0/en/group-replication-options.html#sysvar_group_replication_unreachable_majority_timeout

線上8.0.18 MGR已穩定運行大半年,MGR的增強大大提升了在網絡異常(機房級故障)下的健壯、穩定性;之前多次的機房故障演練8.0 MGR也都符合預期,網絡恢復后MGR節點自動加入group 恢復讀寫
安全增強
SQL Roles SQL角色
Atomic ACL Statements 原子ACL語句
Dynamic Privileges 動態特權
Protection Against Brute Force Attacks 防止暴力攻擊
REDO & UNDO Logs Encryption REDO & UNDO Logs加密
Caching sha2 authentication plugin 緩存Sa2認證插件
Password Rotation Policy 密碼輪詢策略
復制增強
Additional Metadata in the binary log binlog中額外的Metadata
Efficient JSON Replication 高效的json復制
Monitor Replication Lag with Microsecond Precision 監控復制延遲細到毫秒
More P_S Instrumentation for Group Replication 組復制更多的P_S
Enable binary log by default 默認啟動了binlog
Improving the Parallel Applier with Writeset-based Dependency Tracking
基於Writeset-based Dependency Tracking的並行應用
Hostname support in Group Replication Whitelist 組復制白名單中支持主機名
實例克隆
- 傳統方式,備份恢復再加入主從復制
- 源目標實例上安裝克隆插件、授權、進行克隆
- 極大提高了MySQL的擴展性

全局變量持久化
- SYSTEM_VARIABLES_ADMIN (SET PERSIST)
- PERSIST_RO_VARIABLES_ADMIN (SET PERSIST_ONLY)
mysql> set persist_only innodb_buffer_pool_size=268435456*2;
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> set persist innodb_buffer_pool_size=268435456*2;
Query OK, 0 rows affected (0.00 sec)
其它特性
- 優化器直方圖
- 自增主鍵持久化
- 移除Query Cache
- GIS增強
- 備份鎖
- group by 不再隱式排序
- redo_log優化、多線程並發寫log buffer
MySQL5.7升級8.0

線上8.0.18 MGR大多是從5.7.22 MySQL原地升級;依次升級從庫,online switch老主庫至新從庫(30s內完成),再升級老主庫
展望未來

每個產品、版本都有一定生命周期,數據庫也不列外,MySQL5.6 甲骨文官方支持到明年;也不是為了用新版本而“新版本”,主要是為了提升性能,享受開源帶來的紅利,更好地支持業務
MySQL 8.0 Release Notes
https://dev.mysql.com/doc/relnotes/mysql/8.0/en/preface.html
Oracle Lifetime Support for MySQL
https://www.oracle.com/us/assets/lifetime-support-technology-069183.pdf
MySQL8.0 Benchmarks https://www.mysql.com/why-mysql/benchmarks/
