MySQL5.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));

mysql> insert into t1(name) select name from t1;

mysql> insert into t1(name) select name from t1;

mysql> insert into t1(name) select name from t1;

mysql> insert into t1(name) select name from t1;

这时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;

mysql> delete from t1 limit 1;

mysql> delete from t1 limit 1;

mysql> delete from t1 limit 1;

再查看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了。

时间: 2024-10-12 19:17:12

MySQL5.7新特性——在线收缩undo表空间的相关文章

Oracle11g 新特性:优化Rman备份UNDO表空间

Oracle11gR1的新特性,Rman备份UNDO表空间时排除已经提交的会话对应的数据,提高了Rman备份的效率. 官方文档:http://docs.oracle.com/cd/B28359_01/server.111/b28279/chapter1.htm#AREANO02323 我们知道,UNDO表空间主要用于存储前镜像数据,这些数据在回滚以及恢复过程中可能被用到.但是一个生产数据库的UNDO表空间可能会变得非常巨大,而备份完整的UNDO数据文件在恢复时一般可能用到的比例很小. 测试一下:

Oracle 12.2新特性----在线move表

Oracle12.2版本之前,对表做move操作时会对表加exclusive锁,表上无法执行DML操作.虽然move操作有ONLINE子句,但只适用于IOT表,不适用于堆表.这就意味着在对表做move操作时,无法执行任何DML操作,如果对关键表做move操作时只能停业务来完成.到了Oracle12.2版本,推出了一个新特性----在线move表,对于普通堆表可以在move过程中执行DML操作. 下面以11.2.0.4和12.2.0.1这两个版本为对比,观察这一新特性. 1.11.2.0.4版本的

mysql5.7新特性探究

一.MySql5.7增加的特性 1.MySql服务方面新特性 1) 初始化方式改变 MySql5.7之前版本初始化方式: scripts/mysql_install_db MySql5.7版本初始化方式: [[email protected] mysql_new]# ./bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql_new/ --datadir=/usr/local/mysql_new/data/ 2015-10-

mysql-5.6新特性

1. undo log undo log分离到独立的表空间,并放到单独的文件目录下:这给我们部署不同IO类型的文件位置带来便利,对于并发写入型负载,我们可以把undo文件部署到单独的高速存储设备上. 1.1. 设置 vim /etc/my.cnf [mysqld] innodb_undo_directory=/data/undolog innodb_undo_log=128 innodb_undo_tablespaces=16 1.2. 说明 innodb_undo_directory 用来指定

MySQL5.7新特性——gtid基础

1.MySQL5.7 新特性:gtid复制 ①:GTID是什么 是事务的ID,唯一识别号,全局唯一. 随事务记录到Binary Log中,用来标识事务. 每个事务有一个Gtid_log_event. ②:GTID的构成 UUID + Sequence Number 注意:Sequence Number是MySQL服务器内部的一个事务顺序号.一个MySQL服务器上的事务不会有重复的顺序号(保证服务器内唯一). 每个MySQL服务器有一个全局唯一的UUID. ③:GTID的目的 简化复制的使用过程和

在线扩大数据库UNDO表空间

用oracle账号登陆ORACLE数据库服务器 方法一: 查看表空间的名字及文件所在位置: select tablespace_name, file_id, file_name,round(bytes/(1024*1024),0) total_space from dba_data_files order by tablespace_name; 修改数据库datafile文件到新的大小 alter database datafile '\oracle\oradata\undotab1.dbf'

[MySQL5.6 新特性] 全局事务标示符(GTID)

GTID的全称为 global transaction identifier  , 可以翻译为全局事务标示符,GTID在原始master上的事务提交时被创建.GTID需要在全局的主-备拓扑结构中保持唯一性,GTID由两部分组成: GTID = source_id:transaction_id source_id用于标示源服务器,用server_uuid来表示,这个值在第一次启动时生成,并写入到配置文件data/auto.cnf中 transaction_id则是根据在源服务器上第几个提交的事务来

MySQL5.6 新特性之GTID【转】

转自 MySQL5.6 新特性之GTID - jyzhou - 博客园http://www.cnblogs.com/zhoujinyi/p/4717951.html 背景: MySQL5.6在5.5的基础上增加了一些改进,本文章先对其中一个一个比较大的改进"GTID"进行说明. 概念: GTID即全局事务ID(global transaction identifier),GTID实际上是由UUID+TID组成的.其中UUID是一个MySQL实例的唯一标识.TID代表了该实例上已经提交的

Oracle创建新undo表空间最佳实践(包含段检查)

在处理一则ORA-600 [4194]案例时,参考MOS文档:Step by step to resolve ORA-600 4194 4193 4197 on database crash (文档 ID 1428786.1) 1.对于ORA 600[4194]的解释 2.创建新undo表空间最佳实践(包含段检查) 1.对于ORA 600[4194]的解释: The following error is occurring in the alert.log right before the da