跨时代的MySQL8.0新特性解读

704 阅读6分钟

前言

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

可以看到8.0版本只需要0.13秒,而5.7版本需要6分8.36秒

以前表加列操作需要重建表(消耗大量的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版本只需要45.70秒,而5.7版本需要3分12.24秒

分别在只更新和只读场景下,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集群

线上8.0.18 MGR已稳定运行大半年,MGR的增强大大提升了在网络异常(机房级故障)下的健壮、稳定性;

之前多次的机房故障演练8.0 MGR也都符合预期,网络恢复后MGR节点自动加入group 恢复读写

安全增强

# SQL角色
SQL Roles      
# 原子ACL语句
Atomic ACL Statements       
# 动态特权
Dynamic Privileges          
# 防止暴力攻击
Protection Against Brute Force Attacks     
# REDO & UNDO Logs加密
REDO & UNDO Logs Encryption        
# 缓存Sa2认证插件
Caching sha2 authentication plugin     
# 密码轮询策略
Password Rotation Policy        

复制增强

# binlog中额外的Metadata
Additional Metadata in the binary log      

# 高效的json复制 
Efficient JSON Replication 

# 监控复制延迟细到毫秒
Monitor Replication Lag with Microsecond Precision 

# 组复制更多的P_S
More P_S Instrumentation for Group Replication 

#默认启动了binlog
Enable binary log by default   

# 基于Writeset-based Dependency Tracking的并行应用
Improving the Parallel Applier with Writeset-based Dependency Tracking 

# 组复制白名单中支持主机名
Hostname support in Group Replication Whitelist    

实例克隆

  • 传统方式,备份恢复再加入主从复制

  • 源目标实例上安装克隆插件、授权、进行克隆

  • 极大提高了MySQL的扩展性

全局变量持久化

以前我们在客户端执行MySQL配置,都是暂时性的,MySQL重启后就会失效。想永久设置只能修改配置文件。

8.0版本直接通过SQL命令,就可以直接永久配置。

  • set persist命令

    会在设置当前全局变量的前提下,将其保存到 mysqld-auto.cnf 文件中,这个命令需要有这个权限:system_variables_admin,才能执行

  • set persist_only命令

    只会将其保存到 mysqld-auto.cnf 文件中,而不会设置当前全局变量,这对只读全局变量有用,这个命令需要有这个权限:persist_ro_variables_admin,才能执行

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内完成),再升级老主库