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

时间: 2024-09-20 15:42:34

MySQL中的undo截断(r11笔记第89天)的相关文章

MySQL中Procedure事务编写基础笔记

原文:MySQL中Procedure事务编写基础笔记 目录: 一.PROCEDURE: 二.CREATE PROCEDURE基本语法: 三.PROCEDURE小进阶   3.1.基本的DECLARE语句;   3.2.声明HANDLER句柄;   3.3.声明CURSOR游标;   3.4.循环语句; 四.顺带提一下触发器TRIGGER 一.PROCEDURE: PROCEDURE,事务,一个存储过程,实际上就是在服务器端直接在数据库中编写一段代码作运算,在服务器端进行高效的运算,运算结果直接返

MySQL中的derived table(r12笔记第47天)

初始MySQL中的derived table还是在一个偶然的问题场景中. 下面的语句在执行的时候抛出了错误. UPDATE payment_data rr    SET rr.penalty_date = '2017-4-12'  where rr.id =        (SELECT min(r.id)           FROM payment_data r          where data_no =                (SELECT data_no          

MySQL中的反连接(r12笔记第45天)

  关于Oracle的半连接,反连接,我一直认为这是一个能讲很长时间的话题,所以在我的新书<Oracle DBA工作笔记>中讲性能优化的时候,我花了不少的笔墨做了阐述,结果在做MySQL性能优化的时候,优化思路切换到MySQL层面,我发现要说的东西要更多.总体来看,这部分的优化细节MySQL还在路上,不同的版本中都能够一窥其中的变化,可以看到在不断改进.    在表的连接上,半连接,反连接本身很平常,但是统计信息的不够丰富导致执行计划的评估中可能会出现较大差别,会很可能把半连接,反连接的实现方

分分钟搭建MySQL Group Replication测试环境(r11笔记第83天)

   最近看了下MySQL 5.7中的闪亮特性Group Replication,也花了不少做了些测试,发现有些方面的表现确实不赖.当然要模拟这么一套环境还是需要花不少的功夫的,一般来说都是3个节点的环境,实际中要找这样的环境也不是很容易.我们怎么快速模拟呢.一种方式就是在一台服务器上搭建多实例.    这样一来,服务器的问题就解决了,下面要解决的问题就要艰巨的多了,那就是部署环境.    可以看到各路博客中都有了详细的解释,而官方文档中对于搭建过程也花了不少的额篇幅来解释,每一个步骤,每个操作

动态创建MySQL Group Replication的节点(r11笔记第84天)

前几天分享了下搭建MySQL Group Replication的脚本,其实感觉还是不太踏实,虽然我成功搭建了3个节点的环境,但是有不少问题还没有解决,甚至是特意避开了.     1.节点数都是在脚本里固定的,想搭建4个,6个节点的,完全适应不了    2.模板臃肿,每个节点一个参数模板,其实就几个参数不一样    3.单主模式下的节点,其实就一个写节点的配置略有不同,其它节点配置都是一样的,但是脚本里也是写固定了.    4.端口也是写固定了,没法再改了. ....   我能够一口气列出很多很

MySQL中的online DDL(第一篇)(r11笔记第3天)

记得有一天快下班的时候,一位开发同事找到我说,需要对一个表做变更,数据量据说有上千万,而当时是使用的MySQL版本是5.5,这可如何是好,对于在线业务要求高的情况下,这种需求真是让人头疼. 而在早期的版本中,这种问题就更让人无语了.在Oracle中这个问题解决的较早,当然在很多技术实现细节上,Oracle和MySQL还是蛮大的差距.Oracle中有在线重定义的方案物化视图prebuilt和在线重定义 (r10笔记第25天),而且本身对于一些DDL的操作代价要比MySQL低.不过在碰到添加字段且加

浅谈MySQL中的事务隔离级别(r11笔记第86天)

   之前写了一篇浅谈事务(一),算是对事务的一个基本认识,今天来简单总结一下事务的隔离级别,虽然是老掉牙的知识点,重温一下还是值得的.    在MySQL中基本有这两种事务隔离级别的设置,默认的RR(Repeatable-Read)和实际中常见的RC(Read-Committed).两者区别是什么,怎么正确理解,用几个SQL语句就能说明白,就用简单的实验来说明白.    我们开始吧.        首先创建一个测试表test,插入一些数据. create table test( id int

MySQL Online DDL(二)(r11笔记第88天)

对于Online DDL,之前简单分析了一些场景MySQL中的Online DDL(第一篇)(r11笔记第3天),其实有一个很关键的点没提到,那就是online DDL的算法,目前有三个操作选项,default,inplace,copy可选 具体可以参考  https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl.html > select count(*) from newtest; +----------+ | count(*) |

用Oracle的眼光来学习MySQL 5.7的sys(下)(r11笔记第25天)

昨天写了篇分析sys的文章,用Oracle的眼光来学习MySQL 5.7的sys(上)(r11笔记第24天)收到了一些朋友的反馈,还不错,今天继续努力,再整理一篇. sys还是很有借鉴意义     今天还和同事偶然聊起sys schema的事情,我觉得有几个地方要值得借鉴. 1)原本需要结合information_schema,performance_schema查询的方式,现在有了视图的方式,显示更加直观 2)sys schema的有些功能在早期版本可能无从查起,或者很难查询,现在这些因为新版