这个专题讲一些日常运维的异常处理
## 1. 现象
开发人员找说应用连接不上,报ORA-01555错误
[image:842 size:orig]
## 2. 原因查找
### 2.1 查看undo使用率等情况
第一反应当然是查询是否undo表空间不足
通过如下命令查询
```
SELECT round(((SELECT (NVL(SUM(bytes), 0))FROM dba_undo_extents
WHERE tablespace_name =
(select value from v$parameter
where lower(name) = 'undo_tablespace')
AND status IN ('ACTIVE', 'UNEXPIRED')) * 100) /
(SELECT SUM(bytes) FROM dba_data_files
WHERE tablespace_name =
(select value from v$parameter
where lower(name) = 'undo_tablespace')), 2) PCT_INUSE
FROM dual
```
使用率很低,而且数据库重启过,我们暂时排除
### 2.2 检查表的情况
我们首先执行手动执行该语句,在sqlplus中运行也是报错
在plsql中执行显示value error
[image:843 size:orig]
字段是clob字段,看来这就是原因了,是由于clob字段损坏导致
因为CLOB字段的undo信息是存储在clob块中的,其保留策略通过PCTVERSION(百分比) 和RETENTION(时间)字段控制
### 2.3 检查clob损坏情况
我们通过如下语句查询该clob字段是否有损坏
将<your_clob_column>替换成value error的字段名
将<your_table_with_clcob_column>替换成该字段所在的表名
```
set serverout on
exec dbms_output.enable(100000);
declare
page number;
len number;
c varchar2(10);
charpp number := 8132/2;
begin
for r in (select rowid rid, dbms_lob.getlength (<your_clob_column>) len
from <your_table_with_clcob_column>) loop
if r.len is not null then
for page in 0..r.len/charpp loop
begin
select dbms_lob.substr (<your_clob_column>, 1, 1+ (page * charpp))
into c
from <your_table_with_clcob_column>
where rowid = r.rid;
exception
when others then
dbms_output.put_line ('Error on rowid ' ||R.rid||' page '||page);
dbms_output.put_line (sqlerrm);
end;
end loop;
end if;
end loop;
end;
/
```
这时我们查出来有三行,我们记住其rowid
[image:844 size:orig]
### 2.4 跟踪01555错误
我们可以利用如下语句对该错误进行跟踪,当发生错误时alert日志会有记录并生成trace文件
```
alter system set events '1555 trace name errorstack level 3';
```
### 2.5 expdp排查clob损坏的行
如果在导出的话,clob字段损坏会导致失败,这时我们可以使用如下参数跳过指定的行
```
expdp \"/ as sysdba\" tables="ISUGDP"."TEXT_FOR_ECP" directory=DROPZONE dumpfile=table.dmp logfile=table.log QUERY=\"WHERE rowid NOT IN \(SELECT CORRUPTED_ROWID FROM CORRUPTED_ROWS\)\"
```
## 3. 解决方法
知道了原因后,如果这几行数据很重要,则需要别的恢复手段将其恢复(RMAN)
如果不需要这几行数据我们可以将其删除
```
delete from table where rowid='AAAV1RAAEAAD5dGAAC';
```
之后问题解决
## 4. 参考连接
[https://community.oracle.com/community/support/support-blogs/database-support-blog/blog/2015/12/10/ora-1555-do-you-know-how-to-resolve-this-issue](https://community.oracle.com/community/support/support-blogs/database-support-blog/blog/2015/12/10/ora-1555-do-you-know-how-to-resolve-this-issue)
[https://dbpilot.net/2018/02/05/ora-1555-snapshot-too-old-due-to-corrupted-lobs/](https://dbpilot.net/2018/02/05/ora-1555-snapshot-too-old-due-to-corrupted-lobs/)