MySQL中的undo截断(r11笔记第89天)
MySQL中的undo截断还是一个很不错的特性。这让我想起了很久以前看到一个诺大的ibdata,但是却拿它无能为力,想把它收缩唯一的办法就是重建或者重构数据。
Oracle用得久了,总会有一些想法,看起来很平常的技术怎么在MySQL中却无能为力。当然这个念头也有些日子了。
MySQL 5.6中把undo做了剥离,可以指定单独的undo表空间,但是要收缩阶段还是无能为力,这个也算是一个过渡的特性吧,到了MySQL 5.7中,这个功能就可以说是上了正道了,我们可以截断,化被动为主动,这种方式就很好。
而如果要展望这个特性,我觉得还可以持续改进,就是可以在线修改,切换undo等。
要实现这个阶段功能,其实还需要花点功夫,那就是在初始化的时候就完成这些基础配置,否则会收到下面这样有些模糊的提示信息。
2017-02-28 22:39:48 7fedca8127e0 InnoDB: Expected to open 1 undo tablespaces but was able
2017-02-28 22:39:48 7fedca8127e0 InnoDB: to find only 0 undo tablespaces.
2017-02-28 22:39:48 7fedca8127e0 InnoDB: Set the innodb_undo_tablespaces parameter to the
2017-02-28 22:39:48 7fedca8127e0 InnoDB: correct value and retry. Suggested value is 0
所以我们打算初始化一个全新的库来做一个简单的测试。
my.cnf的内容如下,你可以自己根据需要指定也可以。
my.cnf
[client]
socket = /home/mysql/mysql.sock
[mysql]
socket = /home/mysql/mysql.sock
default-character-set = utf8
[mysqld]
user = mysql
basedir = /usr/local/mysql
datadir = /home/mysql
port = 3306
socket = /home/mysql/mysql.sock
pid-file = /home/mysql/mysql.pid
max_allowed_packet = 32M
ft_min_word_len = 4
event_scheduler = 1
explicit_defaults_for_timestamp=true
tmpdir = /dev/shm
character-set-server = utf8
#innodb_undo_directory=/data/undolog
innodb_undo_tablespaces=4
innodb_undo_logs=128
innodb_max_undo_log_size=200M
innodb_purge_rseg_truncate_frequency
innodb_undo_log_truncate=1
重点就是最后的几个参数了。
先初始化一下数据字典,
mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/home/mysql
然后配置使得MySQL服务启动
service mysql start
打开文件目录,就会赫然看到下面的几个undo文件,因为参数
innodb_undo_tablespaces为4,所以会有4个文件。innodb_undo_logs默认是128个,至少是35个,官网也有详细的解释。而innodb_undo_directory的目录则默认按照数据目录来取得,所以我索性去掉了。4个Undo文件都是10M,也就是初始大小。
drwxr-x--- 2 mysql mysql 8192 Feb 28 23:09 performance_schema
drwxr-x--- 2 mysql mysql 8192 Feb 28 23:09 sys
-rw-r----- 1 mysql mysql 10485760 Feb 28 23:09 undo001
-rw-r----- 1 mysql mysql 10485760 Feb 28 23:09 undo002
-rw-r----- 1 mysql mysql 10485760 Feb 28 23:09 undo003
-rw-r----- 1 mysql mysql 10485760 Feb 28 23:09 undo004
我们初始化数据,然后插入一些数据。
mysql> create table test_undo(id int,name varchar(30));
mysql> insert into test_undo values(1,'a');
mysql> insert into test_undo values(2,'b');
insert可以反复执行,数据就是指数级的增长,事务也会逐渐变大,大概在200万数据量的时候,undo的分布如下:
-rw-r----- 1 mysql mysql 13631488 Feb 28 23:16 undo001
-rw-r----- 1 mysql mysql 22020096 Feb 28 23:16 undo002
-rw-r----- 1 mysql mysql 10485760 Feb 28 23:16 undo003
-rw-r----- 1 mysql mysql 10485760 Feb 28 23:16 undo004
数据在1600万左右的时候,undo文件的大小如下:
-rw-r----- 1 mysql mysql 13631488 Feb 28 23:20 undo001
-rw-r----- 1 mysql mysql 22020096 Feb 28 23:20 undo002
-rw-r----- 1 mysql mysql 150994944 Feb 28 23:20 undo003
-rw-r----- 1 mysql mysql 75497472 Feb 28 23:20 undo004
这个时候我们开始测试一下截断的部分,和一个参数密切相关,那就是innodb_purge_rseg_truncate_frequency,我们可以为了测试,适当设置小一些,能够马上看到效果,比如我设置为20
mysql> set global innodb_purge_rseg_truncate_frequency=20;
然后我继续开启一个很大的事务,插入千万数据,undo的文件就会暴增,当然因为最大的事务占用了一个undo文件,那个文件还是会持续增大,尽管超过了设定的阈值。
-rw-r----- 1 mysql mysql 13631488 Feb 28 23:33 undo001
-rw-r----- 1 mysql mysql 22020096 Feb 28 23:33 undo002
-rw-r----- 1 mysql mysql 150994944 Feb 28 23:33 undo003
-rw-r----- 1 mysql mysql 293601280 Feb 28 23:33 undo004
然后我们使点小技巧,delete几条数据,触发截断的临界点。
mysql> delete from test_undo limit 10;
再次查看,undo的文件就会收缩,当然你可以清晰的看到,不是所有的,因为和事务大小也有关系。
-rw-r----- 1 mysql mysql 13631488 Feb 28 23:34 undo001
-rw-r----- 1 mysql mysql 22020096 Feb 28 23:34 undo002
-rw-r----- 1 mysql mysql 150994944 Feb 28 23:34 undo003
-rw-r----- 1 mysql mysql 10485760 Feb 28 23:34 undo004
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- 浙大版《C语言程序设计(第3版)》题目集 练习4-6 猜数字游戏
- 浙大版《C语言程序设计(第3版)》题目集 练习4-7 求e的近似值
- TypeScript高级类型备忘录(附示例)
- 浙大版《C语言程序设计(第3版)》题目集 练习4-10 找出最小值
- 牛逼!力挺一款实用的 Linux 资源监视工具
- 浙大版《C语言程序设计(第3版)》题目集 练习4-11 统计素数并求和
- 浙大版《C语言程序设计(第3版)》题目集 习题4-1 求奇数和
- Kotlin 使用DSL构建语法结构 看这一篇就够了~
- 浙大版《C语言程序设计(第3版)》题目集 习题4-2 求幂级数展开的部分和
- 2020 年 9 月编程语言排行榜
- 浙大版《C语言程序设计(第3版)》题目集 习题4-3 求分数序列前N项和
- 浙大版《C语言程序设计(第3版)》题目集 习题4-4 特殊a串数列求和
- 一个可能让你的页面渲染速度提升数倍的CSS属性
- 浙大版《C语言程序设计(第3版)》题目集 习题4-6 水仙花数
- 浙大版《C语言程序设计(第3版)》题目集 习题4-7 最大公约数和最小公倍数