暂无图片
oracle中跑一个大事务,会把undo搞爆,pg和mysql中会出现什么情况呢?
我来答
分享
暂无图片 匿名用户
oracle中跑一个大事务,会把undo搞爆,pg和mysql中会出现什么情况呢?

oracle中跑一个大事务,会把undo搞爆,pg和mysql中会出现什么情况呢?

我来答
添加附件
收藏
分享
问题补充
2条回答
默认
最新
豆宇斯
MySQL可能出现innodb log buffer不够,PG WAL增大,都可能会导致性能问题
暂无图片 评论
暂无图片 有用 1
打赏 0

MYSQL 大事务也是很头痛的地方
不过 大事务主要影响从库回放
REDO LOG 不会
BINLOG 有BINLOG CACHE 缓存下

  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实例,再全库导入。

  1. 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不变。

  1. 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的频率越高。

  1. 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了。

暂无图片 评论
暂无图片 有用 0
打赏 0
回答交流
Markdown


请输入正文
提交
相关推荐
lz4压缩备份使用的前提条件是啥?
回答 1
使用的前提是要安装这个软件如果有yum的话直接yuminstalllz4
请教一下,mysql库表的类型是innodb,部分表提示innodb free 16384kB ,各位可有解决办法?
回答 1
说明下数据库的版本1、检查下innodbpagesize参数配置2、检查一下innodblargeprefix参数设置
MySQL同步到clickhouse,有方案的相关资料吗?
回答 3
clickhouse官方文档提到的两个,也就是2楼 yBmZIQzJ提到的,都不好用:1、MySQL引擎:https://clickhouse.com/docs/zh/engines/dat
mysql 同一行的两列如何报证值不相同
回答 1
已知的话是没有的。这是应该设计上控制。你这等于是比如浙江杭州金华温州湖州这样的,你不希望湖州下面出现浙江是吧?这个数据库上做不了。
MySQL root的主机和密码是什么?
回答 1
已采纳
安装的时候在初始化的error.log中。后续修改的只能自己知道了。
Mysql SQL索引优化
回答 7
首先createdate与updatedate谁的区分度更好。谁的区分度更好就决定了,这两个字段哪个排在前面。然后再看state与type这两个区分度好不好。如果也有较好的区分度,那就再往前放。如果区
如何把自定义表空间迁移到系统表空间?
回答 1
已采纳
一般都是迁出来,你居然想迁进去.参考如下命令即可altertablet1tablespaceinnodbsystem;效果图如下(root@127.0.0.1)[db20232]>createt
一台服务器上安装了mysql-clinet能使用mysqldump mydumper 直接备份远程服务器上的数据库吗
回答 1
可以的。前提是你能在本地正常连接到远程数据库,并且你所使用的用户有导出的权限
怎样使用 SELECT…INTO OUTFILE 语句?
回答 1
已采纳
mysql>usebooksalemysql>selectfrombooksintooutfile'c:/bakup/databooks.txt';mysql>selectfromc
MySQL一启动, 命令行就卡在这,这怎么解决?
回答 1
已采纳
看下log都输出什么了,/usr/local/mysql/log.err而且这个进程本身就是守护进程,可以使用mysqldsafe&启动