这个专题讲一些日常运维的异常处理 ## 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/)