一、简单概述
ROLL 表空间完全由 DM 数据库自动维护,用户无需干预。该表空间用来存放事务运行过程中执行 DML(数据操作语言)操作之前的值,从而为访问该表的其他用户提供表数据的读一致性视图。
ROLL 表空间的 DBF 文件,称为 ROLL 文件。ROLL 文件用于保存系统的回滚记录,提供事务回滚时的信息。回滚文件可被分为若干回滚段,每个事务的回滚页在回滚段中各自挂链,页内则顺序存放回滚记录。
回滚表空间的管理和用户表空间的管理基本是一样的,区别是回滚空间的空间名固定为ROLL,不可修改。可增加和扩展回滚空间中的回滚文件,设置回滚空间的扩展属性。
二、缩小表空间
调小UNDO_RETENTION参数,减少保留时间。
尝试逐渐缩小表空间大小
--一点点降
ALTER TABLESPACE ROLL RESIZE DATAFILE '/data/dmdata/DAMENG/ROLL.DBF' TO 50G;
增删改表数据,没有提交的话,就会先放到ROLL表空间中,提交后会清空,他的大小和总数据量没有关系,和一次修改数据的量有关系,并且如果不够用的话是会自动扩展的。
查询未提交的事务
SELECT
T1.SQL_TEXT,
T1.STATE,
T1.TRX_ID,
T2.INS_CNT,
T2.UPD_CNT,
T2.DEL_CNT,
T2.UPD_INS_CNT
FROM
V$SESSIONS T1,
V$TRX T2
WHERE
T1.TRX_ID = T2.ID
AND T1.STATE = 'IDLE'
AND T2.STATUS = 'ACTIVE'
AND (INS_CNT > 0
OR UPD_CNT > 0
OR DEL_CNT > 0
OR UPD_INS_CNT > 0);
三、关联参数
PSEG_RECV:动态系统级参数,默认值3。
系统故障重启时,对活动事务和已提交事务的处理方式。
- 0:跳过回滚活动事务和 PURGE 已经提交事务的步骤。在回滚表空间出现异常、损坏、系统无法正常启动时,可将 PSEG_RECV 设置为 0,让系统启动;但存在一定风险,未提交事务的修改将无法回滚,破坏事务的原子性;另外,已提交未 PURGE 的事务,将导致部分存储空间无法回收;
- 1:回滚活动事务并 PURGE 已经提交事务;
- 2:延迟 PURGE 已提交事务,延迟回滚活动事务;
- 3:回滚活动事务,延迟 PURGE 已提交事务
UNDO_RETENTION:动态系统级参数,默认值90。
事务提交后回滚页保持时间,单位秒。取值范围 0~86400
注:类型为 DOUBLE,可支持毫秒
ENABLE_IGNORE_PURGE_REC:动态会话级,默认值2。
当返回 EC_RN_NREC_PURGED(-7120)错误(回滚记录版本太旧,无法获取用户记录)时的处理策略;
- 0:报错;
- 1:忽略这一条记录,继续执行;
- 2:报错并生成日志;
- 3:忽略这一条记录,继续执行,并生成日志
四、常用SQL
4.1 查询ROLL表空间数据文件使用情况
SELECT
TS.NAME AS TABLESPACE_NAME,
DF.PATH AS DATAFILE_PATH,
ROUND(DF.TOTAL_SIZE * PAGE / 1024.0 / 1024.0, 2) AS DATAFILE_TOTAL_MB,
ROUND((DF.TOTAL_SIZE -DF.FREE_SIZE) * PAGE / 1024.0 / 1024.0, 2) AS DATAFILE_USED_MB,
ROUND(DF.FREE_SIZE * PAGE / 1024.0 / 1024.0, 2) AS DATAFILE_FREE_MB,
ROUND(LEAST(DF.TOTAL_SIZE, GREATEST((DF.FREE_PAGE_NO -1), 4096)) * PAGE / 1024.0 / 1024.0, 2) AS DATAFILE_MINSIZE
FROM
V$TABLESPACE TS,
V$DATAFILE DF
WHERE
DF.GROUP_ID = TS.ID
AND TS.NAME = 'ROLL'
ORDER BY
TS.ID,
DF.ID;
查询结果的最后一列 DATAFILE_MINSIZE 是根据 FREE_PAGE_NO 这个数据估算出的可能数据文件最小尺寸,只作为参考值,如果收缩表空间文件的话,可能收缩到更小的尺寸。
4.2 当前回滚段正在使用的大小
SELECT ROUND(SUM(N_USED_PAGES) * PAGE / 1024.0 / 1024.0, 2) AS ROLL_USED_MB FROM V$PSEG_ITEMS;
4.3 定位占用ROLL的事务
有时候在一些实际项目中会遇到回滚文件异常增大的情况,一般来说都是由于大事务造成的,而如何找出这个大事务对应的操作则是比较关键的问题。达梦其实提供了关于回滚段相关的动态性能视图,V$PSEG_COMMIT_TRX会记录已经提交但还没有purge的事务信息,而V$PSEG_ITEMS则会记录回滚系统中相应回滚项的信息,也就是正在执行的事务对应的回滚信息。
以下SQL帮助我们在大事务提交后分析确定出对应的SQL操作,仅限从事务提交后,回滚purge之前,因为一旦超过UNDO_RETENTION后V$PSEG_COMMIT_TRX中对应登记的事务信息就被清除了:
SELECT
I.N_USED_PAGES * PAGE / 1024 / 1024 USED_ROLL_SPACE_MB,
H.TOP_SQL_TEXT,
P.ITEM_NTH,
P.TRX_ID,
P.CMT_TIME,
H.AFFECTED_ROWS
FROM
V$PSEG_COMMIT_TRX P,
V$SQL_HISTORY H,
(SELECT TOP 1 * FROM V$PSEG_ITEMS ORDER BY N_USED_PAGES DESC) I
WHERE
P.TRX_ID = H.TRX_ID
AND I.NTH = P.ITEM_NTH
AND I.N_USED_PAGES > 0
AND AFFECTED_ROWS > 0
ORDER BY
USED_ROLL_SPACE_MB DESC;
在做增删改查操作过程中,V$PSEG_ITEMS使用到的页数是动态在增加的,但是对应的NTH_ITEM必须在此事务提交后才能在V$PSEG_COMMIT_TRX中捕获到,而需要找到对应这个耗费回滚段空间的SQL必须先获取到对应的TRX_ID,才能在V$SQL_HISTORY或LOG_COMMIT日志中找到对应SQL,故在大事务执行过程中无法抓到对应SQL操作,只要当大事务提交后才能抓到对应SQL以及它使用过的ROLL空间大小;
需要注意的是,V$PSEG_ITEMS记录的是回滚项对应正在使用的PAGES,而繁忙的生产系统其中一个回滚项(默认一个实例有17个回滚项)可能会有多个I/D/U操作都已提交但还没有被purge(例如还没有到UNDO_RETENTION时间),所以这个联合查询查出来对应是一个回滚项中多个还没有来得及被purge的事务所占用的回滚空间总大小,具体是哪个SQL还需具体分析,但这时已经把范围缩到很小了比较容易确定是哪个SQL操作引发的。值得注意的是,我们不能完全按照影响行数来判断,因为CALL的影响行数记录值永远是1,无法得知真实影响行数。
下面举个栗子说明一下:
(1)首先查看17个回滚项对应的信息,主要关注u_used_pages字段
select * from v$pseg_items;

(2)然后查看以下测试表T3占用空间情况:

(3)执行delete操作,删除10,230,000条记录

(4)再查看V$PSEG_ITEMS发现NTH_ITEM=10对应使用了12522个page
我们可以换算一下,12522*32k/1024/1024=391MB,比T3表实际占用空间要稍微小一些,考虑到其他的一些空间消耗,作为查找占用回滚段空间的操作是没有问题的。

(5)commit提交后,使用上述sql进行查询对应的事务操作:

上述方法虽然只能在事务提交后,且回滚purge前查到,但大事务造成的回滚文件大小增加都会相当迅猛,所以我们可以配合监控回滚文件大小来使用,则可以更加精准找到对应大事务操作。
注意
当出现大事务时,log_commit日志中一定会出现大量分配回滚段的信息:而当大事务执行完并commit后,经过
UNDO_RETENTION时间后,日志一定会出现大量purge操作,与此同时我们可以发现,做purge这个操作对应的TRX_ID记录的就是当初大事务的TRX_ID:

