MySQL 5.7新特性之在线收缩undo表空间
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表空间的更多相关文章
- ORACLE在线切换undo表空间
切换undo的一些步骤和基本原则 原文:http://www.xifenfei.com/3367.html 查看原undo相关参数 SHOW PARAMETER UNDO; 创建新undo空间 cre ...
- 初识 MySQL 5.6 新特性、功能
背景: 之前介绍过 MySQL 5.5 新功能.参数,现在要用MySQL5.6,所以就学习和了解下MySQL5.6新的特性和功能,尽量避免踩坑.在后续的学习过程中文章也会不定时更新. 一:参数默认值的 ...
- mysql 5.7 ~ 新特性
mysql 5.7特性 简介:mysql 5.7内存和线程性能方面的优化一 细节优化 参数: 1 innodb_buffer_pool 改进 innodb_buffer_pool可以动态扩大, ...
- MySQL 8.0 新特性梳理汇总
一 历史版本发布回顾 从上图可以看出,基本遵循 5+3+3 模式 5---GA发布后,5年 就停止通用常规的更新了(功能不再更新了): 3---企业版的,+3年功能不再更新了: 3 ---完全停止更新 ...
- MySql 5.7 新特性概览
安全的提升 1.1 在Mysql 8版本中,caching_sha2_password 是一个缺省的认证插见.5.7 版本的客户端支持 caching_sha2_password 的客户端认证. 1. ...
- MySQL 5.7新特性
新增特性 Security improvements. MySQL.user表新增plugin列,且若某账户该字段值为空则账户不能使用.从低版本MySQL升级至MySQL5.7时要注意该问题,且建议D ...
- [转帖 ]MySQL 5.7 新特性 JSON
MySQL 5.7 新特性 JSON 的创建,插入,查询,更新 作者: 我不是鱼 (2016-08-31 16:13)分类: MySQL 标签: MySQL JSON MySQL JSON 应用 ...
- Mysql 8.0 新特性测试
Mysql 8.0 新特性测试 Role MySQL8.0版本添加了role特性,role是一种逻辑概念是权限的集合,可以将一个或以上的权限赋予给role,再将role赋给user.Oracle,Po ...
- mysql-5.7 收缩系统表空间详解
innodb 系统表空间是一个逻辑上的概念,它的物理表现就是innodb系统表空间文件:在讲扩展系统表空间时我们说到 可以用增加文件,增加autoextend标记 这两种方式来解决:但是问题到了收缩表 ...
随机推荐
- sac cut
Put a perl script here in order to remind myself of its correct usage:
- 2019.3.22 Week 12 : ZigBee and T/H chamber test
Test purposes Remove backside center ventilation holes, pls help to conduct climatic chamber test of ...
- select标签的相关操作,选中,获取option的值,二级联动
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- 新建react项目
npm install -g create-react-app create-react-app my-app cd my-app npm start
- 校验总结:校验是否是中英文等等(1.正则校验 2.hibernate volidator)
1.正则校验 import java.util.regex.Matcher;import java.util.regex.Pattern; public class Validation { //-- ...
- 初识爬虫见到的两个类 BufferedWriter和 BufferedReader
BufferedWriter 和 BufferedReader 为带有默认缓冲的字符输出输入流,因为有缓冲区所以很效率比没有缓冲区的高. 使用BufferedWriter和BufferedReader ...
- paddle实践
Docker image阅读:https://github.com/PaddlePaddle/book/blob/develop/README.cn.md docker run -d -p 8888: ...
- 使用httputil中ReverseProxy反向代理遇到的坑
坑描述,当POST ContentType=="application/x-www-form-urlencoded"时,反向代理报错:http: proxy error: http ...
- python 变量名的规范
''' 1.变量命名规范: 规定python的变量必须是: 数字 字母 下划线 首字母不能用数字开头,也不能是纯数字 不能用关键字 要有相对应意义 不要使 ...
- apache用户认证、域名跳转、Apache访问日志(两种格式)
1.apache 设置,用户访问时 目录或文件的认证: 对目录的认证: <Directory /var/www/222> //指定认证的目录AllowOverride AuthConfig ...