MySQL

MySQL8.0的版本历史

  • 2016-09-12第一个DM(development milestone)版本8.0.0发布
  • 22018-04-19第一个GA(General Availability)版本开始,8.0.11发布
  • 22018-07-27 下一个GA版本,8.0.12发布
  • 22018-10-22 下一个GA版本,8.0.13发布
  • 22019-01-21 下一个GA版本,8.0.14发布
  • 最新的GA版本为8.0.15,于2019-02-01发布
  • 最近待GA的版本为8.0.16, 8.0.17,

从中可以看出,大概每1~3个月一个版本。

MySQL8.0中新增的特性

事务性数据字典

数据字典表以InnoDB表存储字典数据,位于mysql数据库下,对外不可见。有专门的表空间mysql.idb,位于数据目录下。但是可以通过informaction_schema下面的一些表来查询字典数据。在以前的版本中,字典数据以元数据文件、非事务表等来存储。现在这些元数据文件被删除了。比如:.frm, .par, .trn, .isl, .db.opt等都在 MySQL8.0中不存在了。

原子DDL

事务性数据字典的引入,使得原子DDL成为可能。作为事务要不提交,要不回滚。分为表级和非表级语句,表级支持InnoDB。非表级包括:create, drop等语句。

安全和账号管理

  • Mysql系统数据库下的权限表现在都是InnoDB的,以前是MyISAM的,对于多个用户进行操作时会出现部分成功,部分失败的情况。现在要不成功,要不rollback。
  • 新的caching_sha2_password认证插件作为默认的认证插件,比mysql_native_password更安全,性能更好。但可能在现网会出现一个连接相关的问题。

    支持角色(role)

  • 对于密码管理更加严格控制,可以维护密码历史信息。启用密码重用策略。

  • 资源管理,支持资源组的创建和管理,能将运行的线程分配给特定的资源组。

    InnoDB增强

  • 自增列方面。现在自增列计数器会在每次值修改时,将值写到REDO LOG中,并且在CHECKPOINT时写到存储引擎私有的系统表中。这就消除了以往重启实例自增列不连续的问题。

  • 当索引损坏时,会把损坏标识写到redo log。在checkpoint时会将内存的损坏标识数据写到存储引擎私有的系统表中。
  • InnoDB memcached插件支持多个get操作(在单个memcached查询中获取多个键值对)和范围查询。
  • 新的动态变量innodb_deadlock_detect,可以禁用死锁检查。在高并发的系统中,无数个线程等待同一个锁,死锁检查可能会引起系统宕机。有时,禁用死锁检查更有效。当死锁发生时,可以依赖innodb_lock_wait_timeout设置让事务回滚。
  • 新的information_schema.innodb_cached_indexes表可以报告每个索引在bufferpool中的索引页的数量。
  • InnoDB临时表现在创建在共享的临时表空间中。

image.png

支持redo log和undo log的加密

  • 对于select…for share和select…for update 锁读语句,支持nowait和skip locked选项。Nowait表示如果请求的行被去其他事务锁住了立即返回。SKIP LOCKED则会从结果集中移除上锁的行。
  • InnoDB存储引擎使用MySQL的数据字典,而不是用自己的和引擎相关的数据字典。
  • mysql库的系统表和数据字典表创建在单独的InnoDB表空间中,文件名为mysql.ibd. 以前这些表都是创建在各自的InnoDB表空间中。

    字符集支持

    默认字符集从latin1变成了utf8mb4. 对于utf8mb4字符集增加了新的比较规则,比如utf8mb4_ja_0900_as_cs。
    image.png

    JSON增强

    数据类型支持

    MySQL支持将字符常量或者表达式作为数据类型的默认值。包括能将表达式作为BLOB, TEXT, GEOMETRY, JSON等数据类型的默认值,这在以前是不可以的。

    1. CREATE TABLE t1(
    2. -- literal defaults
    3. i INT DEFAULT 0,
    4. c VARCHAR(10) DEFAULT '',
    5. -- expression defaults
    6. f float DEFAULT (RAND() * RAND()),
    7. b BINARY(16) DEFAULT (UUID_TO_BIN(UUID())),
    8. d DATE DEFAULT (CURRENT_DATE + INTERVAL 1 YEAR),
    9. p POINT DEFAULT (Point(0, 0)),
    10. j JSON DEFAULT (JSON_ARRAY())
    11. );

    image.png

    优化器

    通用表表达式

    在SELECT等语句前,使用WITH字句来对临时结果集进行命名。

    窗口函数

    MySQL现在支持窗口函数,在一个查询中对每行进行计算。这些函数包括RANK(), LAG(), NTILE()。另外,有几个聚合函数也能用作窗口函数。比如SUM(),AVG()。

    横向派生表(Lateral derived tables)

    支持正则表达式

    内部临时表

    内存内部临时表,默认的存储引擎从MEMORY变成了TempTable。TempTable对于VARCHAR和VARBINARY字段存储更高效。
    Internal_tmp_mem_storage_engine:该变量用来定义内存内部临时表使用哪个引擎。允许取值有TempTable(默认)和MEMORY。
    Temtable_max_ram: 内存内部临时表超过这个值就会将数据存储到磁盘上。

    日志记录

    错误日志模块使用MySQL组件架构重写了,使用内置的组件来实现错误日志。另外,还有一个可加载的JSON日志记录器。要控制启用哪些日志组件,使用 log_error_services 系统变量。

    备份锁

    引入了一种新的备份锁(backup lock),它允许在online备份的时候进行DML操作,同时可防止快照不一致。备份锁由lock instance for backup和unlock instance语法支持。使用这些语句需要BACKUP_ADMIN权限。
    原来的extrabackup等备份软件是不是应该改写,不要使用flush table with read lock这样的语句来上锁。
    当有大事务时,会hung住,无法备份。
    image.png
    如果采用lock instance for backup则没有问题。
    image.png

    复制增强

    支持使用压缩格式,对JSON文档的部分更新记录binlog,能节省空间。如果使用的STATEMENT格式的binlog,该功能自动开启,或者通过binlog_row_value_options系统变量设为PARTIAL_JASON来开启。

    连接管理

    允许配置一个专门端口用于管理连接,当连接数打满时可以用于连接数据库进行管理。

  • 需要设置admin_address,默认该值为空。

  • 使用的端口默认为33062, 由admin_port来设置。
  • 该端口的没有连接数的限制。
  • 需要有SERVICE_CONNECTION_ADMIN的权限
  • Create_admin_listener_thread系统变量用来决定是用普通连接的监听线程还是采用自己专用的线程。默认值为普通监听线程。

操作如下:

  1. mysql> show variables like 'admin_%';
  2. +---------------+---------------+
  3. | Variable_name | Value |
  4. +---------------+---------------+
  5. | admin_address | 192.168.1.187 | //这个IP地址是服务器的地址,不是客户端的。一定要设置这个变量
  6. | admin_port | 33062 |
  7. +---------------+---------------+
  8. 2 rows in set (0.00 sec)

然后将max_connections调小,制造连接数打满的场景。

  1. mysql> set global max_connections=30;
  2. Query OK, 0 rows affected (0.00 sec)
  3. mysql> show variables like 'max_connections';
  4. +-----------------+-------+
  5. | Variable_name | Value |
  6. +-----------------+-------+
  7. | max_connections | 30 |
  8. +-----------------+-------+
  9. 1 row in set (0.00 sec)
  10. nohup mysql -h192.168.1.187 -P3306 -uroot -p****** -NBe 'select sleep(2000)' &
  11. mysql: [Warning] Using a password on the command line interface can be insecure.
  12. ERROR 1040 (HY000): Too many connections

此时,发现还可以用管理端口进行连接,并且没有数量限制。