Oracle表空间扩展失败(包含临时表空间)、分布式等待锁、ORA-30036无法按8扩展段(在还原表空间xxx中)等问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013310119/article/details/88947001

问题描述:

在大批量同步、抽取数据的过程中,往往出现表空间扩展失败、一些很长时间未执行完的SQL,分布式等待锁等。下面就来看看如何解决这些问题。

查询时间较长的SQL并杀掉应用层回话

oracle数据库查询正在执行的sql,通过gv$ session 和gv$sqlarea两个视图:

select n.sid,n.serial#,n.program,n.terminal,n.logon_time,n.machine,n.sql_id,a.sql_text from gv$session n,gv$sqlarea a where n.sql_id=a.sql_id order by logon_time;



或者指定查询alter开头的sql:



select n.sid,n.serial#,n.program,n.terminal,n.logon_time,n.machine,n.sql_id,a.sql_text from gv$session n,gv$sqlarea a where n.sql_id=a.sql_id and a.sql_text like 'alter%' order by logon_time;

杀应用会话命令:(把上面命令查询到的sid和serial#填写到下面的语句中)

alter system kill session 'sid,serial#' immediate;

关于“ORA-02049: 超时: 分布式事务处理等待锁”的原因和解决办法

【问题思路】:
(1)首先我在数据库中刚查过数据(印刷流水号),sql为:
select visaserialno, businessno,visacode, visaname, usercode, visastatus, comcode from vsmark 
where visacode like 'DAC051A32007A(山东)'  and usercode='02110003'  for update;
(2)然后在核心系统中输入查询的印刷流水号visaserialno,在核心系统中调用接口出现 ORA-02049: 超时: 分布式事务处理等待锁 的错误。
(3)我怀疑是因为上述sql只for update而没有提交事务(commit),数据库事务你没有commit或者rollback导致事务不能统一提交。导致把错误回传给客户端让其处理。因为核心系统用的数据库和我更改的数据库是一致的。
(4)然后我把本地数据库commit,再在核心系统中调用接口。成功。
【总结】:
该参数指定等待分布式锁资源的时间,超过这个时间事务自动回滚,即在等待未释放的资源超过一定的时间,系统自动报错给客户端,就会以ORA-02049: 超时: 分布式事务处理等待锁 的方式提错给你。该值默认为60,即等待分布式锁资源60秒。从上面的测试来看,使用dblink做分布式事务时一定要及时commit或rollback,尽量在分布式应用中使用短事务为宜。dblink 作用就是让数据库中的数据负载均衡,一般情况下数据量较大的数据都会用到。

表空间扩展失败

查看用户所在表空间

数据字典中用户表:dba_users;

通过数据字典查看有多少个用户:select username from dba_users;

数据字典中表空间表: dba_tablespaces;

查看有几个表空间:select tablespace_name from dba_tablespaces;

oracle 查看用户所在的表空间:select username,default_tablespace from dba_users order by username;

-----查看表空间使用情况------
SELECT UPPER(F.TABLESPACE_NAME) "表空间名",   
D.TOT_GROOTTE_MB "表空间大小(M)",   
D.TOT_GROOTTE_MB - F.TOTAL_BYTES "已使用空间(M)",   
TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.TOT_GROOTTE_MB * 100,2),'990.99') "使用比",   
F.TOTAL_BYTES "空闲空间(M)",   
F.MAX_BYTES "最大块(M)"  
FROM (SELECT TABLESPACE_NAME,   
ROUND(SUM(BYTES) / (1024 * 1024), 2) TOTAL_BYTES,   
ROUND(MAX(BYTES) / (1024 * 1024), 2) MAX_BYTES   
FROM SYS.DBA_FREE_SPACE   
GROUP BY TABLESPACE_NAME) F,   
(SELECT DD.TABLESPACE_NAME,   
ROUND(SUM(DD.BYTES) / (1024 * 1024), 2) TOT_GROOTTE_MB   
FROM SYS.DBA_DATA_FILES DD   
GROUP BY DD.TABLESPACE_NAME) D   
WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME   
ORDER BY 4 DESC; 


--查看表空间是否具有自动扩展的能力   

SELECT T.TABLESPACE_NAME,D.FILE_NAME,   
D.AUTOEXTENSIBLE,D.BYTES,D.MAXBYTES,D.STATUS   
FROM DBA_TABLESPACES T,DBA_DATA_FILES D   
WHERE T.TABLESPACE_NAME =D.TABLESPACE_NAME   
 ORDER BY TABLESPACE_NAME,FILE_NAME; 


-修改表空间文件扩展方式:   
   ALTER DATABASE  
    DATAFILE '/u01/Oracle/oradata/orcl/ccen01.dbf' AUTOEXTEND   
    ON NEXT 50M MAXSIZE UNLIMITED


增加表空间大小的四种方法
Meathod1:
给表空间增加数据文件



ALTER TABLESPACE app_data ADD DATAFILE
'D:\ORACLE\PRODUCT\10.2.0\ORADATA\EDWTEST\APP03.DBF' SIZE 50M;



Meathod2:新增数据文件,并且允许数据文件自动增长


ALTER TABLESPACE app_data ADD DATAFILE
'D:\ORACLE\PRODUCT\10.2.0\ORADATA\EDWTEST\APP04.DBF' SIZE 50M
AUTOEXTEND ON NEXT 5M MAXSIZE 100M;



Meathod3:允许已存在的数据文件自动增长


ALTER DATABASE DATAFILE 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\EDWTEST\APP03.DBF'
AUTOEXTEND ON NEXT 5M MAXSIZE 100M;

Meathod4:手工改变已存在数据文件的大小

ALTER DATABASE DATAFILE 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\EDWTEST\APP02.DBF'
RESIZE 100M;



ORA-30036:无法按8扩展段(在还原表空间xxx中)

1.什么是还原表空间?
还原表空间即Undo表空间,是Oracle特有的概念,Undo表空间会自动分配Undo段,用来保存事务中DML( Insert、Update或Delete)语句的Undo数据。在Oracle9i前,管理Undo数据只能使用Rollback Segment。从Oracle9i开始,管理Undo数据不仅可以使用回滚段,还可以使用Undo表空间。而由于管理里规划回滚段太过复杂,Oracle10g已经弃用回滚段,仅使用Undo表空间来管理Undo数据。

2.什么是Undo数据?
Undo数据也称回滚数据,当执行DML语句时,事务操作过程中的数据被称为Undo数据,主要有两个作用:

确保事务一致性:如果事务发生错误或者用户想要取消数据库操作,则可以通过Rollback回到修改前的值。
提供一致性读:如表T有100条记录,用户A在表T执行了语句删除掉10条记录,尚未提交,此时用户B执行查询语句,将返回100条记录而不是90条。
 

扫描二维码关注公众号,回复: 5873630 查看本文章

3.如何解决?

言归正传,开始解决问题,首先我们查看当前实例使用的Undo表空间:

SQL> show parameter undo;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS1

可以看到,使用的Undo表空间为“UNDOTBS1”,与报错内容中的名字一致。接下来查看数据库可用的Undo表空间:

SQL> SELECT tablespace_name FROM dba_tablespaces WHERE contents='UNDO';

TABLESPACE_NAME
------------------------------
UNDOTBS1
UNDOTBS2

结果显示有两个Undo表空间可用,分别为UNDOTBS1、UNDOTBS2。我们来看看这两个表空间的使用情况:

-----查看表空间使用情况------
SELECT UPPER(F.TABLESPACE_NAME) "表空间名",   
D.TOT_GROOTTE_MB "表空间大小(M)",   
D.TOT_GROOTTE_MB - F.TOTAL_BYTES "已使用空间(M)",   
TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.TOT_GROOTTE_MB * 100,2),'990.99') "使用比",   
F.TOTAL_BYTES "空闲空间(M)",   
F.MAX_BYTES "最大块(M)"  
FROM (SELECT TABLESPACE_NAME,   
ROUND(SUM(BYTES) / (1024 * 1024), 2) TOTAL_BYTES,   
ROUND(MAX(BYTES) / (1024 * 1024), 2) MAX_BYTES   
FROM SYS.DBA_FREE_SPACE   
GROUP BY TABLESPACE_NAME) F,   
(SELECT DD.TABLESPACE_NAME,   
ROUND(SUM(DD.BYTES) / (1024 * 1024), 2) TOT_GROOTTE_MB   
FROM SYS.DBA_DATA_FILES DD   
GROUP BY DD.TABLESPACE_NAME) D   
WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME   
ORDER BY 4 DESC; 

可以看到,UNDOTBS1有两个数据文件来存储Undo数据,使用率都到达了90%以上,所剩空间已不足 

解决的办法有三个:

1.为表空间增加数据文件

alter tablespace UNDOTBS1
      add datafile '+DATADG/esbmssdb/datafile/undotbs1.4.dbf' --数据文件名
      size 100M --初始大小
      autoextend on next 1M maxsize 8192M; --自增,每次增加1M,最大为8192M

2.设置文件自动扩展

alter database 
      datafile '+DATADG/esbmssdb/datafile/undotbs1.3.dbf' 
      autoextend on next 1M maxsize 8192M;

 3.切换Undo表空间

alter system set undo_tablespace = UNDOTBS2;

注:如果数据库中只有一个可用的Undo表空间,则使用前两种方法。

猜你喜欢

转载自blog.csdn.net/u013310119/article/details/88947001