一次生产意外引发的Oracle存储管理方式探究

存储
C系统是一个业务繁忙的批量作业系统,每天加工超过300GB的数据,是一个数据量大、加工时效要求高的系统。为提高效率,应用大量使用"CTAS+分区交换"替代大事务的"DELETE+INSERT"操作进行数据归档。

一次意外的 ORA-01652

C系统是一个业务繁忙的批量作业系统,每天加工超过300GB的数据,是一个数据量大、加工时效要求高的系统。为提高效率,应用大量使用"CTAS+分区交换"替代大事务的"DELETE+INSERT"操作进行数据归档。

[[207791]]

某日日终跑批时,在表空间TBS(剩余空间约2.7TB)上新建表T1(约1GB)时,出现“表空间不足”的错误。报错信息如下:

ORA-01652 文档解释是: Failed to allocate an extent of the required number of blocks for a temporary segment in the tablespace indicated。

为什么说意外

1、系统每天监控表空间使用量,始终保持使用率在80%以内。表空间TBS剩余2.7TB,总空间13TB。

2、通过CTAS(Create Table As Select)新建的T1表,记录数为七百多万,数据大小约为1G。

以上似乎说明:存储空间容量看起来没问题。

继续验证分析

经过反复检查验证,发现:当给select 语句加上只取40万条记录的限制,可成功创建N张T2(58MB)表;但是当把记录数限制放大到50万(72MB)的时候,就出现ORA-01652错误。

为什么2.7G的可用空间却建不了1GB的表?

为什么建n张58MB的表可以,一张72MB的表就不行呢?

以下我们根据ORACLE数据库的表空间管理方式,并进行验证来解析这个问题。

表空间的管理方式

图1 oracle 数据的存储结构

如图1所示:Oracle存储层级:TABLESPACE>SEGMENT(TABLE/INDEX/PARTITION)->EXTENT->BLOCKS。

在ORACLE数据库中,表空间中的空闲空间是以extent的形式组织的,分配空间时也是按照extent分配的。extent存在两种管理方式:SYSTEM、UNIFORM,需要在创建表空间时指定。

当新建一张表(或者一个分区)时,系统就为该表空间分配一个初始EXTENT,并按需不断新增EXTENT。新EXTENT的大小根据表空间的管理方式确定,如下图:

系统剩余空间分析

本例中,由于TBS表空间管理方式为 SYSTEM,通过dba_free_space 对TBS剩余空间分布进行分析:

发现剩余表空间的EXTENT分布如下:

问题定位

 

根据以上分析,由于表空间碎片化严重,剩余的2.7TB空间中,已经没有大于8M的EXTENT,所以出现 ORA-01652错误。这就解释了上面我们提出的两个问题:

1)为什么2.7G的可用空间却建不了1GB的表?(缺少>=8MB的EXTENT)

2)为什么建n张58MB的表可以(<=1MB的EXTENT充足),一张72MB的表就不行呢?(缺少>=8MB的EXTENT)

解决方案

临时应急方案:

拓展表空间或者清理部分数据,增加大于8M/64M的空闲EXTENT数量。

解决方案:

将表空间管理方式由SYSTEM改为UNIFORM。

实施步骤:

1)申请13T临时存储空间进行过渡。

2)新建表空间TBS3,新表空间采用uniform size空间管理方式,size设置为2M

3)逐渐将TBS中的数据表挪到TBS3(alter table xxxx move tablespace TBS3),需要注意的是:对于包含long或LOB类型的表,无法通过alter table move的方式进行移动,得通过数据泵导入导出。

4)调整完成后,删除TBS表空间,释放存储空间并归还。

拓展阅读--行内表空间碎片化的监控

目前行内对于ORACLE数据库表空间碎片化触发告警需要同时满足以下条件:

1、可用EXTENT(<32MB) / 全部可用表空间 > 40%;

2、可用EXTENT(>32MB)总计小于20GB;

在本例中,由于系统每日空间需求较大,可用EXTENT(>32MB)为20GB时,无法满足一个跑批日的空间需求,因此对于这类应用,需要适当调整监控阈值。

拓展思考

在使用EXTENT管理使用SYSTEM方式时:

1、当sql执行时加入parallel的hint后,是否会加快碎片化速度?

2、当使用alter table move ...... compress ...... 后,是否可以减少表空间的碎片化?

责任编辑:武晓燕 来源: 厦开系统联盟
相关推荐

2018-12-06 16:25:39

数据库服务器线程池

2019-01-21 11:17:13

CPU优化定位

2019-12-12 10:38:10

mysql数据库nnodb

2022-06-01 06:17:42

微服务Kafka

2020-11-03 07:34:12

Kafka后端工程师

2021-03-01 06:14:50

环境高并发延迟

2020-09-25 07:57:42

生产事故系统

2018-07-18 15:37:24

数据库DB2故障处理

2019-11-18 13:42:55

MySQL数据库迁移

2019-09-05 09:17:37

MySQL数据库线程

2019-08-19 01:34:38

数据库SQL数据库优化

2021-11-01 17:29:02

Windows系统Fork

2019-11-22 08:05:01

数据库mysql分区

2022-10-25 18:00:00

Redis事务生产事故

2021-01-12 07:57:36

MySQLBinlog故障处理

2017-08-24 17:37:18

DNS缓存分析

2019-08-15 11:30:06

SQL数据库ASH

2020-12-15 11:18:43

系统磁盘lvm数据库

2018-12-27 09:09:35

2019-11-04 10:37:53

MongoDB宕机日志
点赞
收藏

51CTO技术栈公众号