1. MySQL 5.5时代的undo log

在MySQL5.5以及之前,大家会发现随着数据库上线时间越来越长,ibdata1文件(即InnoDB的共享表空间,或者系统表空间)会越来越大,这会造成2个比较明显的问题:

(1)磁盘剩余空间越来越小,到后期往往要加磁盘;

(2)物理备份时间越来越长,备份文件也越来越大。

这是怎么回事呢?

原因除了数据量自然增长之外,在MySQL5.5以及之前,InnoDB的undo log也是存放在ibdata1里面的。一旦出现大事务,这个大事务所使用的undo log占用的空间就会一直在ibdata1里面存在,即使这个事务已经关闭。

那么问题来了,有办法把上面说的空闲的undo log占用的空间从ibdata1里面清理掉吗?答案是没有直接的办法,只能全库导出sql文件,然后重新初始化mysql实例,再全库导入。

2. MySQL 5.6时代的undo log

MySQL 5.6增加了参数innodb_undo_directory、innodb_undo_logs和innodb_undo_tablespaces这3个参数,可以把undo log从ibdata1移出来单独存放。

下面对这3个参数做一下解释:

(1)innodb_undo_directory,指定单独存放undo表空间的目录,默认为.(即datadir),可以设置相对路径或者绝对路径。该参数实例初始化之后虽然不可直接改动,但是可以通过先停库,修改配置文件,然后移动undo表空间文件的方式去修改该参数;

(2)innodb_undo_tablespaces,指定单独存放的undo表空间个数,例如如果设置为3,则undo表空间为undo001、undo002、undo003,每个文件初始大小默认为10M。该参数我们推荐设置为大于等于3,原因下文将解释。该参数实例初始化之后不可改动;

(3)innodb_undo_logs,指定回滚段的个数(早期版本该参数名字是innodb_rollback_segments),默认128个。每个回滚段可同时支持1024个在线事务。这些回滚段会平均分布到各个undo表空间中。该变量可以动态调整,但是物理上的回滚段不会减少,只是会控制用到的回滚段的个数。

实际使用方面,在初始化实例之前,我们只需要设置innodb_undo_tablespaces参数(建议大于等于3)即可将undo log设置到单独的undo表空间中。如果需要将undo log放到更快的设备上时,可以设置innodb_undo_directory参数,但是一般我们不这么做,因为现在SSD非常普及。innodb_undo_logs可以默认为128不变。

3. MySQL 5.7时代的undo log

那么问题又来了,undo log单独拆出来后就能缩小了吗?MySQL 5.7引入了新的参数,innodb_undo_log_truncate,开启后可在线收缩拆分出来的undo表空间。在满足以下2个条件下,undo表空间文件可在线收缩:

(1)innodb_undo_tablespaces>=2。因为truncate undo表空间时,该文件处于inactive状态,如果只有1个undo表空间,那么整个系统在此过程中将处于不可用状态。为了尽可能降低truncate对系统的影响,建议将该参数最少设置为3;

(2)innodb_undo_logs>=35(默认128)。因为在MySQL 5.7中,第一个undo log永远在系统表空间中,另外32个undo log分配给了临时表空间,即ibtmp1,至少还有2个undo log才能保证2个undo表空间中每个里面至少有1个undo log;

满足以上2个条件后,把innodb_undo_log_truncate设置为ON即可开启undo表空间的自动truncate,这还跟如下2个参数有关:

(1)innodb_max_undo_log_size,undo表空间文件超过此值即标记为可收缩,默认1G,可在线修改;

(2)innodb_purge_rseg_truncate_frequency,指定purge操作被唤起多少次之后才释放rollback segments。当undo表空间里面的rollback segments被释放时,undo表空间才会被truncate。由此可见,该参数越小,undo表空间被尝试truncate的频率越高。

4. MySQL 5.7的undo表空间的truncate示例

(1) 首先确保如下参数被正确设置:

# 为了实验方便,我们减小该值
innodb_max_undo_log_size =
100M
innodb_undo_log_truncate =
ON
innodb_undo_logs =
128
 
innodb_undo_tablespaces =
3
# 为了实验方便,我们减小该值
innodb_purge_rseg_truncate_frequency =
10

(2) 创建表:

mysql> create table t1(
   -> id int primary key auto_increment,
   -> name varchar(200));
Query OK, 0 rows affected (0.13 sec)

(3)插入测试数据

mysql> insert
into
t1(name) values(repeat('a',200));
Query OK,
1
row affected (0.01
sec)
mysql> insert
into
t1(name)
select
name from t1;
Query OK,
1
row affected (0.00
sec)
Records:
1
 Duplicates:  Warnings: mysql> insert
into
t1(name)
select
name from t1;
Query OK,
2
rows
affected (0.01
sec)
Records:
2
 Duplicates:  Warnings: mysql> insert
into
t1(name)
select
name from t1;
Query OK,
4
rows
affected (0.00
sec)
Records:
4
 Duplicates:  Warnings: ... mysql> insert
into
t1(name)
select
name from t1;
Query OK,
8388608
rows
affected (2
min
11.31
sec)
Records:
8388608
 Duplicates:  Warnings:

这时undo表空间文件大小如下,可以看到有一个undo文件已经超过了100M:

-rw-r----- 1 mysql mysql  13M Feb 17 17:59 undo001
-rw-r----- 1 mysql mysql 128M Feb 17 17:59 undo002
-rw-r----- 1 mysql mysql  64M Feb 17 17:59 undo003

此时,为了,让purge线程运行,可以运行几个delete语句:

mysql> delete from t1 limit 1;
Query OK, 1 row affected (0.00 sec)
mysql> delete from t1 limit 1;
Query OK, 1 row affected (0.00 sec)
mysql> delete from t1 limit 1;
Query OK, 1 row affected (0.00 sec)
mysql> delete from t1 limit 1;
Query OK, 1 row affected (0.00 sec)

再查看undo文件大小:

-rw-r----- 1 mysql mysql  13M Feb 17 18:05 undo001
-rw-r----- 1 mysql mysql  10M Feb 17 18:05 undo002
-rw-r----- 1 mysql mysql  64M Feb 17 18:05 undo003

可以看到,超过100M的undo文件已经收缩到10M了。

姜老师补充:周伯通同学介绍了MySQL 5.7中undo表空间的收缩问题,这个问题可谓历史久远,想当初MySQL 3.23.49版本不时的磁盘空间不足,undo也是罪魁祸首之一。感谢周伯通同学的分享,感恩MySQL 5.7对于此问题的修复。

MySQL 5.7新特性之在线收缩undo表空间的更多相关文章

  1. ORACLE在线切换undo表空间

    切换undo的一些步骤和基本原则 原文:http://www.xifenfei.com/3367.html 查看原undo相关参数 SHOW PARAMETER UNDO; 创建新undo空间 cre ...

  2. 初识 MySQL 5.6 新特性、功能

    背景: 之前介绍过 MySQL 5.5 新功能.参数,现在要用MySQL5.6,所以就学习和了解下MySQL5.6新的特性和功能,尽量避免踩坑.在后续的学习过程中文章也会不定时更新. 一:参数默认值的 ...

  3. mysql 5.7 ~ 新特性

    mysql 5.7特性 简介:mysql 5.7内存和线程性能方面的优化一 细节优化 参数:  1 innodb_buffer_pool    改进 innodb_buffer_pool可以动态扩大, ...

  4. MySQL 8.0 新特性梳理汇总

    一 历史版本发布回顾 从上图可以看出,基本遵循 5+3+3 模式 5---GA发布后,5年 就停止通用常规的更新了(功能不再更新了): 3---企业版的,+3年功能不再更新了: 3 ---完全停止更新 ...

  5. MySql 5.7 新特性概览

    安全的提升 1.1 在Mysql 8版本中,caching_sha2_password 是一个缺省的认证插见.5.7 版本的客户端支持 caching_sha2_password 的客户端认证. 1. ...

  6. MySQL 5.7新特性

    新增特性 Security improvements. MySQL.user表新增plugin列,且若某账户该字段值为空则账户不能使用.从低版本MySQL升级至MySQL5.7时要注意该问题,且建议D ...

  7. [转帖 ]MySQL 5.7 新特性 JSON

    MySQL 5.7 新特性 JSON 的创建,插入,查询,更新 作者: 我不是鱼 (2016-08-31 16:13)分类: MySQL   标签: MySQL JSON MySQL JSON 应用 ...

  8. Mysql 8.0 新特性测试

    Mysql 8.0 新特性测试 Role MySQL8.0版本添加了role特性,role是一种逻辑概念是权限的集合,可以将一个或以上的权限赋予给role,再将role赋给user.Oracle,Po ...

  9. mysql-5.7 收缩系统表空间详解

    innodb 系统表空间是一个逻辑上的概念,它的物理表现就是innodb系统表空间文件:在讲扩展系统表空间时我们说到 可以用增加文件,增加autoextend标记 这两种方式来解决:但是问题到了收缩表 ...

随机推荐

  1. 使用FileResult导出Excel数据文件

    用的是Html拼接成Table表格的方式,返回 FileResult 输出一个二进制的文件. 第一种:使用FileContentResult // 通过使用文件内容,内容类型,文件名称创建一个File ...

  2. 关于 global nonlocal 用法

    # 1 关于 globals() locals() nolocl 还有内置函数的引用## 概念的解释# 命名空间# 1 局部命名空间:每一个函数都有自己的命名空间# 2 全局命名空间:写在函数外的变量 ...

  3. localStorage的使用记录

    // 存数据 var str = JSON.stringify(back); localStorage.setItem("options", str); // 取数据 var op ...

  4. PHP中session_start 函数详解使用方法

    一.官方 session_status() 返回值为: PHP_SESSION_DISABLED 会话是被禁用的. PHP_SESSION_NONE 会话是启用的,但不存在当前会话. PHP_SESS ...

  5. python day02 作业答案

    1. (1).false   (2).false 2. (1).8  (2).4 3. (1).6  (2).3  (3).false (4).3   (5).true   (6).true  (7) ...

  6. 【Python】多进程-4

    #练习:用event事件控制进程执行顺序,下面例子中,主进程main函数在创建了子进程之后,依然会往下执行,所以会出现主进程先打印出来的情况 import multiprocessing import ...

  7. linux系统nginx的https的跳转

    环境:系统ubuntu16 申请证书是腾讯云免费证书 首先我在安装nginx SSL证书的时候犯了个错误,nginx是需要安装SSl的模块不然没法配置完成.需要安装一个 http_ssl_module ...

  8. shapefile 转 geojson 文件类型

    http://mapshaper.org/ 从natural earth下载后,扔进去2个文件,就可以了.

  9. 【转载】 Pytorch(0)降低学习率torch.optim.lr_scheduler.ReduceLROnPlateau类

    原文地址: https://blog.csdn.net/weixin_40100431/article/details/84311430 ------------------------------- ...

  10. 20165228 2017-2018-2 《Java程序设计》第8周学习总结

    20165228 2017-2018-2 <Java程序设计>第8周学习总结 教材学习内容总结 进程与线程的关系 多线程的运行机制 线程的四种状态:新建.运行.中断.死亡 使用Thread ...