由于8.0内有很多C++11特性。需要gcc4.8版本以上。Rhel6系列默认gcc是4.7。在安装gcc6.1之后仍然检查不过。
原因可能是6.1版本不一定高于4.7,暂不讨论。鉴于升级gcc耗时较长,与测试目的不符。暂用官方rpm包安装。以便达到快速测试目的。
以下新功能介绍中,跟日常工作强相关大都经过测试。时间有限,未能面面俱到,有兴趣自行测试。
以下大部分来源自 https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html。其中部分以此引申出来。测试版本为MySQL8.0.11 GA版。
水平有限,有问题多多指教。qq 475982055
一 MySQL 8.0发行说明及特性
Ⅰ 安全以及账户管理方面
认证加密插件变更
除了sha256_password认证插件。可用一种新的caching_sha2_password认证插件。后者可以使用缓存解决连接时的延时问题。
它还支持更多的连接协议,并且不需要与基于RSA密钥对的密码交换功能的OpenSSL进行链接。
对比可以看出。MySQL8.0中默认新建用户使用caching_sha2_password,而不是原生的加密策略。这样客户端使用原有方式连接就会出现问题。
Windows nivicat客户端连接问题
Linux 客户端下连接
这是由于两边默认密码插件不匹配导致无法加解密的原因。有两种方法解决。一种是服务端降级加密方式,一种是客户端升级加密方式。
第一种方式以安全代价换便捷。第二种相反。我想服务端应该是有全局参数控制新建用户使用什么插件进行加密的。如下:
这样一来客户端就能常规方式连接。但是之前创建的用户依然会报那样的错。解决方法是alter 语句修改。
注意的一点5.6的set password 的方式已经彻底被淘汰。且password函数已经被删除。
默认配置启动。初始化启动后,使用生成的密码登录不能做任何事,但是可以set命令。
由于密码强度之强,使得多数情况下的修改validate_password.policy
参数。(这点伤透了我的心,以前是下划线“_”。有点面向对象的味道)
总结:也就是说加密方式改变导致帐号连接改变。亦可以通过默认恢复到先前方式。
新增角色特性
同Oracle一样,用来将权限打包。再赋给拥有用户。
详见:http://dev.mysql.com/doc/refman/8.0/en/create-role.html
用户密码方面
MySQL以前有密码强度策略,过期时间。现在还维护有关密码历史记录的信息,从而限制重复使用以前的密码(社会工程学)。
存在mysql.password_history表中。也就是说如果是从老版本升级到8.0.3版本之上。需要同时升级这些系统表(废话)。
mysql.user 表中多出了几个关于密码重用的列。(相关表已确认,未测试功能。)
用户权限方面
新增多个管理权限。
Ⅱ InnoDB增强
自增列方面
自增列方面。现在自增列计数器会在每次值修改时,将值写到REDO LOG中,并且在CHECKPOINT时写到存储引擎私有的系统表中。
这就消除了以往重启实例自增列不连续的问题(这也可能形成了一个新的竞争点(盖国强会上提问InnoDB开发者))。
Btree索引方面
Btree索引被损坏。InnoDB会向REDO LOG中写入一个损坏标志。同时也会CHECKPOINT时将内存中损坏页的数据记录到存储引擎私有的系统表中。
这也就促成了恢复时。两边一致的情形。索引不可用,并不会造成实例起不来。这很大程度上降低了之前使用innodb_force_recovery和innodb_fast_shutdown的必要。
提升了一致性。(对于一般DBA来说透明,知道有这么回事就好)
NoSQl操作
InnoDB memcached插件支持多个get操作(在单个memcached查询中获取多个键/值对)
和范围查询。(个人认为这个挺牛逼,有点像NoSQL,不仅仅是NoSQL)。
需要安装daemon_memcached插件,其中多了一个innodb_memcache schema,这个schema中有几张表,其中一张containers用来与InnoDB表之间做映射,,
然后通过接口访问Innodb表。然后会有一个11211的端口打开,用于建立连接。
好处是通过减少客户端和服务器之间的通信流量,在单个memcached查询中获取多个键/值对的功能可以提高读取性能。
对于InnoDB来说,也意味着更少的事务和开放式表操作。
死锁检测
新的动态配置选项innodb_deadlock_detect可用于禁用死锁检测,默认打开。 在高并发系统上,当大量线程等待相同的锁时,死锁检测会导致速度下降。 有时,在死锁发生时,
禁用死锁检测并依赖innodb_lock_wait_timeout设置进行事务回滚可能更有效。记得之前版本遇到死锁会自动回滚。以下截图来自MySQL5.7,与8.0默认相同。
(也就是说即便MySQL5.7也是有死锁检测的,并且自动回滚权重较小的事务(套死除外))。
尝试更改innodb_deadlock_detect参数为OFF。则遇到死锁时两个工作线程都会被堵塞。直到innodb_lock_wait_timeout设定的锁超时。
新的INFORMATION_SCHEMA.INNODB_CACHED_INDEXES
表保存了Innodb索引缓存在Innodb buffer pool中的页数。
现在,所有InnoDB临时表都将在共享临时表空间ibtmp1中创建。
加密特性
支持REDO和UNDO表空间加密。
共享锁方面
InnoDB在 SELECT ... FOR SHARE
和 SELECT ... FOR UPDATE
锁定读语句上
支持不等待( NOWAIT
)和跳过锁(SKIP LOCKED)的选项。也就是说以往加了共享锁之后必须手动释放。
这里如果没有锁就返回结果,如果有就报下面错误。
如果是用有锁就跳过,则无数据。
根据场景使用。反正都是秒回。降低了排查数据库超时的可能。
与MySQL 5.7使用上的不同。首先初始化的日志言简意赅(前三条)
重启日志如下:
InnoDB使用自己的MySQL服务层的数据字典,不再保留自己的数据字典。有利于事务的原子性。
MySQL系统表和数据字典表现在创建在MySQL数据目录中名为mysql.ibd的单个InnoDB表空间文件中。
以前,这些表是在mysql数据库目录中的各个InnoDB表空间文件中创建的。
数据字典
现在将表对象信息等数据字典存在内部事务表中。而不是之前的.frm 文件。
mysql schema多出的表:(相比MySQL5.7)
component
default_roles
global_grants
password_history
role_edges
移除的表
Proc
ndb_binlog_index
event
由于存储引擎层不再保留自己的数据字典。所以表的.frm文件也不存在了。
原子性DDL
联合上述改变的数据字典更新。实现了DDL的原子性。以前版本中,不具备。
Ⅲ UNDO表空间的改变
(基本上不需要DBA配置关于UNDO表空间的参数了)
在线修改UNDO表空间数量
UNDO表空间数量可以在线修改。或者在实例重启时使用原本只能初始化之前设定的innodb_undo_tablespaces
参数。
默认值更改
innodb_undo_log_truncate
默认被打开。
innodb_undo_tablespaces
表空间数量默认由0变为2.并且被设置为0已经不被允许。
UNDO默认名有UNDONNN变成UNDO_NNN。
参数改变
innodb_rollback_segments
配置选项定义每个UNDO表空间的回滚段数量。以前,这是一个针对MySQL实例的一个全局设定,单个写。
这次的改变是,事务写撤销日志时可以并发写入。innodb_undo_logs
被移除了。该参数代替。
Innodb_available_undo_logs状态变量被移除。要查看可用回滚段可用SHOW VARIABLES LIKE 'innodb_rollback_segments';
Ⅳ BUFFER POOL的改变
参数默认值改变
innodb_max_dirty_pages_pct_lwm
从0变为10
innodb_max_dirty_pages_pct
从75到90.
控制INNODB BUFFER POOL预写,刷盘动作参数改变。我想应该是这些年来硬件的提升。
INNODB自增长锁模式变成2。基于语句对此很敏感,很显然这是全面基于行的象征。
支持使用 ALTER TABLESPACE ... RENAME TO
语句为通用表空间改名。
自动内存管理
新配置选项innodb_dedicated_server能通过服务器内存总量控制innodb_buffer_pool_size
,
大小和方式。详见
默认。
打开该参数过后
INFORMATION_SCHEMA.INNODB_TABLESPACES_BRIEF
记录表空间信息。
当系统不在线时,可以移除或者转存系统表空间到其他机器上。这对备份恢复又开辟一条路。必须是停机状态有点差强人意。
提取表空间
SDI(序列化字典信息)存在于除临时表空间和撤消表空间文件之外的所有InnoDB表空间文件中。 SDI数据的存在提供元数据冗余。
如果数据字典变得不可用,字典对象元数据可能从表空间文件中提取。 使用ibd2sdi工具执行SDI提取。
如下:其中SDI数据以JSON格式存储。这个工具,在线或者离线都可以使用。回头看看如何将这个json数据导入(MySQL高版本已经支持JSON)。
Ⅴ REDO方面优化
并行写入
1、 用户线程现在可以并发写入日志缓冲区,以前是串行写入。
特性添加
1、 用户线程现在可以按照relaxed的顺序将脏页添加到flush列表中。
2、 现在专用的日志线程负责将日志缓冲区写入系统缓冲区,将系统缓冲区刷新到磁盘,将写入和刷新的重做通知用户线程,维持放宽的清空列表顺序所需的延迟,
并写检查点。以前就是read,write进程负责后台读写。现在有点想Oracle的DBWR进程。
一些系统变量增加了。控制刷新REDO的CPU等待方式。
innodb_log_wait_for_flush_spin_hwm
innodb_log_spin_cpu_abs_lwm
innodb_log_spin_cpu_pct_hwm
动态修改log buffer
3、 innodb_log_buffer_size配置选项现在是动态的。
Ⅵ 其他关键特性
资源管理
MySQL8.0有了资源组(详情点击链接)的概念。也就是说可以创建并管理一个资源组。
将工作线程分配给特定的组。以便DBA限制,调配资源。目前只针对CPU。
INFORMATION_SCHEMA.RESOURCE_GROUPS
表显示有关资源定义。Performance
Schema
threads
表显示了每个线程的资源组分配。
有SQL接口支持资源组管理。这些操作不会被记录到binlog中,也就是说不会被复制。
字符集
官方建议用utf8mb4代替utf8(utf8现在是utf8mb3的别名)。默认也是utf8mb4
JSON 增强
鉴于没见到有用,不提及了。
优化器增强
1、 支持不可见索引。优化器不会使用不可用索引。索引默认是可见的。这个在索引优化的时候非常有用。不需要删除一个索引来增加系统负担。
2、 MySQL现在支持降序索引:索引定义中的DESC不再被忽略,会导致键值以降序存储。 以前,索引可能会以相反顺序扫描,但性能会受到影响。
可以按照顺序扫描降序索引,这是更高效的。 降序索引还使得优化器可以在最有效的扫描顺序混合某些列的升序和其他列的降序时使用多列索引。
通用表表达式
也就是说可以将很多表的不同列取出来作为新表,然后在做关联联合等等操作。个人认为这个对编写含有大量子查询的SQL有很大帮助,以及行转列。
窗口函数
支持大量窗口函数。
类似以下数据。尝试窗口函数的特性。Oracle有这些特性叫做分析函数等。
聚合函数的窗口函数
AVG()
BIT_AND()
BIT_OR()
BIT_XOR()
COUNT()
MAX()
MIN()
STDDEV_POP(), STDDEV(), STD()
STDDEV_SAMP()
SUM()
VAR_POP(), VARIANCE()
VAR_SAMP()
示例:如果每列包含总利润,且包含当前行所在国家利润和。如下结果
如果利用传统SQL实现.如下,得写一堆表关联、聚合。
SELECT t1. YEAR,t1.country,t1.product,t1.profit,t2.total_profit,t3.country_profit FROM ( SELECT YEAR,country,product,profit FROM sales ) t1 LEFT JOIN ( SELECT sum(profit) AS total_profit FROM sales ) t2 ON 1 = 1 LEFT JOIN ( SELECT country,sum(profit) AS country_profit FROM sales GROUP BY country ) t3 ON t1.country = t3.country ORDER BY country,YEAR,product,profit; |
窗口函数实现:
SELECT year, country, product, profit, SUM(profit) OVER() AS total_profit, SUM(profit) OVER(PARTITION BY country) AS country_profit FROM sales ORDER BY country, year, product, profit; |
非聚合函数的窗口函数
CUME_DIST()
DENSE_RANK()
FIRST_VALUE()
LAG()
LAST_VALUE()
LEAD()
NTH_VALUE()
NTILE()
PERCENT_RANK()
RANK()
ROW_NUMBER()
示例:
还有一种比较常见的操作。上述表中,同一个国家的利润排行。
如下所示:
常规实现需要将每个城市的利润排序,在union 到一起。过于繁琐。
窗口函数实现
SELECT YEAR,country,product,profit, ROW_NUMBER () OVER ( PARTITION BY country ORDER BY profit DESC ) AS row_num2 FROM sales; |
正则表达式支持
之前MySQL使用Henry Spencer正则表达式库来支持正则表达式运算符(REGEXP,RLIKE) ,现在支持强大的正则表达式.
如:函数REGEXP_INSTR,REGEXP_REPLACE和REGEXP_SUBSTR函数可用于查找匹配位置并分别执行子字符串替换和提取。
日志记录
除了传统错误日志外。另外,还有一个可加载的JSON日志记录器。
要控制启用哪些日志组件,使用 log_error_services
系统变量。更多信息参见错误日志。
备份锁
一种新的备份锁允许在线备份期间的DML,同时防止可能导致快照不一致的操作。 新备份锁由LOCK INSTANCE FOR BACKUP和UNLOCK INSTANCE语法支持。
SET命令增强
类似Oracle,可用改变当前且用于下次重启生效的SET PERSIST,以及PERSIST_ONLY(更改仅仅应用下次重启。)不同的是,不像Oracle 记录到spfile参数文件中。(此特性已经测试)
命令行部分补全功能
比较爽的是,命令支持表补全功能。待补的对象不是所在Schema下的表。而是Schema所对应的
二 MySQL 8.0中弃用的
1、validate_password插件已被重新实现以使用服务器组件基础结构。
2、 ALTER
TABLESPACE
和 DROP
TABLESPACE
ENGINE
子句被弃用。
3、JSON_MERGE
函数在8.0.3中被弃用,使用 JSON_MERGE_PRESERVE()
代替.
三 MySQL 8.0中移除的
1、以下information Schema中的视图被改名
Old Name |
New Name |
INNODB_SYS_COLUMNS |
INNODB_COLUMNS |
INNODB_SYS_DATAFILES |
INNODB_DATAFILES |
INNODB_SYS_FIELDS |
INNODB_FIELDS |
INNODB_SYS_FOREIGN |
INNODB_FOREIGN |
INNODB_SYS_FOREIGN_COLS |
INNODB_FOREIGN_COLS |
INNODB_SYS_INDEXES |
INNODB_INDEXES |
INNODB_SYS_TABLES |
INNODB_TABLES |
INNODB_SYS_TABLESPACES |
INNODB_TABLESPACES |
INNODB_SYS_TABLESTATS |
INNODB_TABLESTATS |
INNODB_SYS_VIRTUAL |
INNODB_VIRTUAL |
2
、不能使用grant 语句创建用户了。只能赋权。Identified
子句移除。
3
、transaction_isolation 和
transaction_read_only
用来替代
tx_isolation
和tx_read_only
4、因为没有.frm文件了,sync_frm系统变量移除了。 ignore_db_dirs也被移除。
5、have_query_cache
仍然保持弃用状态, SQL_CACHE和SQL_NO_CACHE子句被弃用,且不起作用。这些在将来版本会被删除。
6
、log_warnings被移除了,log_error_verbosity代替
7
、加密相关的函数
ENCODE()
和
DECODE()
以及
ENCRYPT()
等都被移除了。
8
、存储过程的ANALYSE() 语法被移除。
9
、INFORMATION_SCHEMA.
INNODB_LOCKS
和INNODB_LOCK_WAITS表被移除。使用 Performance Schema.
data_locks
和data_lock_waits 的表代替。
10
、InnoDB文件格式相关配置选项已经不存在了。它们是MySQL5.1的产物,现在5.1的产品时代已经终结。
11
、innodb_support_xa系统变量被移除,MySQL总是支持分布式事务。