当前位置: 首页 > 科技观察

连跳7个版本后,MySQL8.0.12有哪些新特性?

时间:2023-03-22 12:02:53 科技观察

简介三个月后,MySQL8.0.12有什么新变化?今年4月,MySQL突然跳过了8.0.5到8.0.11的多个版本号,直接宣布8.0.11GA,告诉大家这个版本已经上线了。今年7月底,MySQL8.0.12发布。从官方的releasenote中,我挑选了一些我认为比较关键的地方,在这里说一下。如果有人想阅读全文,可以直接进入官方发布内容:https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-12.htmlfilesortalgorithmcache设置优化众所周知,MySQL在处理Orderby时,如果没有可用的索引,就会使用一种叫做filesort的算法进行排序,但是这个算法有一个相关的参数,sort_buffer_size,估计大家都知道很多人。之前有一个比较痛苦的参数问题:如果在一个sql会话中,执行sql需要文件排序,那么mysql会直接为当前会话分配sort_buffer_size内存。这乍一看不是问题,但需要注意的是,在MySQL中,没有办法像Oracle那样管理PGA(用户线程/进程消耗的总内存大小)。如果SQL语句过多(即使把SQL语句挑出来性能也不是问题),如果SQL的查询量比较大,MySQL的内存占用很容易超标,被操作系统OOM。或者你有设置swap空间的习惯,那么极慢的swap会把整台机器拖死,只能含泪重启。类似的事故在互联网业务中屡见不鲜,也间接导致了很多人对文件排序的厌恶,即使多加几个索引,所有的文件排序也得全覆盖。但是现在,这种内存分配机制终于发生了变化。从8.0.12开始,这种内存分配变成了按需分配。也就是说,对于排序量非常小的SQL(比如一个人的微博列表),触发文件排序将不再直接分配sort_buffer_size的大小(默认256KB),而是分配一个小内存的使用,可以避免很多交通事故在一定程度上是突发性交通造成的。重写插件支持DML语句。从MySQL5.7开始,新增了一个插件接口rewrite,用于在服务器接受SQL语句后,执行前修改SQL语句。最初,它只支持选择。从8.0.12开始支持insert。更新、替换这些DML语句。SELECTORDERBY和GROUPBY语法从8.0.12和8.0.13开始变化(未发布版本,但文档中更新了内容),MySQL的Orderby支持GROUPING函数和WITHROLLUP语法,然后,从8.0开始.13、discarded去掉gy组中的desc和asc关键字。对于WITHROLLUP得到的结果集的排序,需要使用orderby语法。对于做大量数据聚合的人来说,WITHROLLUP和GROUPING应该不会陌生。这种语法上的改变相当于完成了orderby的语法,更加兼容SQL标准语法。如果将程序移植到8.0,需要注意这个不兼容的变化。对了,官方文档这里写的grouping是小写的,其实指的是GROUPING函数,而不是普通的聚合函数(普通的聚合函数一直都支持)。参考代码:https://github.com/mysql/mysql-server/commit/d401baf535a69d6f2a945229acecbfd5863c0a48测试表数据Withrollup语法:8.0.12之前(测试版本为5.7.22),如果要排序,语法错误会出现:需要写成(排序关键字写在groupby中):8.0.12可以执行排序(加desc关键字效果显着):GroupReplication继续优化,新增参数group_replication_exit_state_action来控制,如果一个实例发现自己被遗弃的实例(发生网络分区后的少数),这个值默认为ABORT_SERVER,即少数会自行关闭,这个值也可以设置为只读。在此设置下,会以只读(设置superreadonly)加入集群,并设置状态为ERROR。InnoDBAlterTable优化可以说是源远流长。简单的说,腾讯游戏部的DBA为了给数据库快速加列(游戏运营固有的快速变化问题)(很早的几年),写了一个patch来使用,后来这个patch逐渐被各种接受第三方发布,现在终于进入正式发布,造福更多人。MySQL的DDL一直是一个非常有名的问题。社区和官方都在这个问题上投入了大量的精力。来自最早的perconatoolkit中的pt-osc(这个基于触发器的在线表修改,由于MySQL早年单表只支持一个触发器。为了避免不能使用pt-osc,有一个重要的早年流传至今的MySQL规则:不允许触发器),以及github发布的gh-ost(基于行格式的binlog),官方也一直在进行alter相关的在线修改和优化(比如添加索引等操作,参考链接https://dev.mysql.com/doc/refman/8.0/en/innodb-create-index-overview.html)。altertable的inplace算法本质上解决了主库DDL不会造成表读写锁的问题,但是对于主从结构来说,SQL传输到从库执行时,还是会有相当大的延迟在从属数据库中。所以,其实对于延迟敏感的业务来说,上面说的这两个工具还是天下的。8.0.12的优化是增加了一个新的算法ALGORITHM=INSTANT来处理只能通过修改元数据才能完成的变化。这个可以直接拿来用,不用担心出库耽误时间。目前支持的操作有:1.添加新列。已知的限制如下:不能与其他不支持INSTANT算法的alter子句结合使用。只能添加在表格列的末尾。不能用于innodb压缩表(ROW_FORMAT=COMPRESSED)。目标表不能包含全文索引。目标表不能是临时表。目标表不能是数据字典表。这种添加方式不会计算行长是否合适,这个计算会在insert或者update发生的时候处理。2.添加或删除虚拟列。3.添加或删除列的默认值。4.修改enum的定义,设置列类型(题外话,有多少人知道并用过这个?)5.修改索引类型。6.重命名表名。Binlog支持管道输入来处理大的binlog。由于之前MySQL的mysqlbinlog程序不支持管道,只能先解压,再处理。从8.0.12开始,mysqlbinlog支持管道输入。简单的说就是如下:gzip-cdbinlog-files_1.gz|./mysqlbinlog-|./mysql-uroot-p当drop语句包含关联的父子表时,会直接删除,父子表的顺序-子表不再要求正确,这对于每次删除表都需要关闭外键检查的人来说无疑是个好消息。删除MySQL外键关联的表:8.0版本,正常情况下,删除父表:错误3730早期版本(5.7):可以看到错误信息,8.0版本更详细。如果执行droptablefather,child:必须写成:但是自8.0.12:ADMIN成为关键字后,SQL字段少了一个常用词=_=。谁关闭了数据库?MySQL最终会在日志中记录,是谁发出了关闭命令。MySQL关闭数据库:那些可能有趣的错误。以下是从错误修复记录中找到的一些有趣且已修复的内容。注意——因为每个人的笑点不一样,如果你只关注新功能和修改,请不要阅读以下内容。匆读。早些时候宣布的新交易模型VATS,由于它需要跟踪等待所有其他交易的交易数量,目前修改为生成近似值以避免死锁。gtid_purge的值(记录那些被purge的gtid事务)在GroupReplication运行的时候应该是不能修改的,但是现在发现可以修改,所以在GroupReplication运行的时候不能修改。当同时设置了expire_logs_days和binlog_expire_logs_seconds参数时,如果设置了skip-log-bin,则此信息将从现在开始写入错误日志。当执行一个非常大的事务时(binlog量超过binlog_cache_size),在刷写到临时文件的过程中,如果因为磁盘已满导致刷写失败,则回滚事务。错误日志中不会记录此信息,事务回滚后也不会清空缓存。具有SUPER权限的用户不能修改keyring_operations参数。可以删除性能模式。哈哈哈哈哈。slave_rows_search_algorithms指定复制行格式时的行匹配方式,如果指定为INDEX_SCAN,如果表上有索引,则使用索引操作。但是,如果主从数据库中的同一张表使用不同的列作为主键,并且从数据库表上存在唯一索引,该bug会导致使用表扫描(全表扫描)而不是索引.对于MyISAM,插入和删除语句的特定顺序会导致表数据损坏。