由于备份失误等各种原因,遇到了磁盘损坏的问题,导致数据库存储的数据文件有问题,从原来服务器上的数据文件拷贝出来也是有问题的。
拷贝的数据文件如下:
[root@ibopo-center-db seelinux]# ls
cms6_zgq_data.dbf interact_data.dbf zgq_wlwz_data.dbf cms6_zgq_temp.dbf interact_temp.dbf wlkj_app_data.dbf wlkj_app_temp.dbf zgq_wlwz_temp.dbf
以及日志文件:
[root@ibopo-center-db orcl]# ls
control01.ctl redo01.log redo03.log system01.dbf system03.dbf undotbs01.dbf
example01.dbf redo02.log sysaux01.dbf system02.dbf temp01.dbf users01.dbf
文件都比较大,以上是从服务器硬盘上拷贝的数据,你只需要知道数据有损坏。
恢复的过程,遇到了各种各样的问题,毕竟是第一次遇到这种问题。
我先在新给的一台虚拟机上做实验,安装好oracle,建立一个相同的实例orcl,由于新的虚拟机上有相同的示例orcl,为了不影响实验,我先删除之前的orcl实例,就想刚安装好的oralce数据库一样。
切换到oracle 用户,su - oracle
使用dbca进行删除orcl实例。
dbca -silent -deleteDatabase -sourcedb orcl
使用dbca快速建立一个orcl的实例。
dbca -silent -createDatabase -templateName $ORACLE_HOME/assistants/dbca/templates/General_Purpose.dbc -gdbName orcl -sid orcl -sysPassword huangbaokang -systemPassword huangbaokang -datafileDestination /u01/hbk/oraData -characterSet UTF8 -automaticMemoryManagement true
执行上述命令,在/u01/hbk/oraData会建立orcl实例的相关文件,并会自动启动oracle实例,所以要先关闭oracle,然后删除生成的所有文件,并把我们拷贝的数据文件和日志文件全部放回/u01/hbk/oraData/orcl目录下。
sql>shutdown immediate
[root@ibopo-center-db orcl]# cd /u01/hbk/oraData/orcl/
[root@ibopo-center-db orcl]# rm -rf *
使用scp也好,ftp也好,把文件放在该目录,放好之后,注意要改变用户所属组(chown oracle:oinstall *)。
[root@ibopo-center-db orcl]# cd /u01/hbk/oraData/orcl/
[root@ibopo-center-db orcl]# ll
总用量 83910456
-rw-r----- 1 oracle oinstall 10013908992 11月 23 16:29 cms6_zgq_data.dbf
-rw-r----- 1 oracle oinstall 30416896 11月 23 15:53 cms6_zgq_temp.dbf
-rw-r----- 1 oracle oinstall 10076160 11月 23 16:49 control01.ctl
-rw-r----- 1 oracle oinstall 104865792 11月 23 11:50 example01.dbf
-rw-r----- 1 oracle oinstall 52436992 11月 23 11:50 interact_data.dbf
-rw-r----- 1 oracle oinstall 30416896 11月 21 21:51 interact_temp.dbf
-rw-r----- 1 oracle oinstall 576724992 11月 23 16:29 lob_hbk_data.dbf
-rw-r----- 1 oracle oinstall 2147484160 11月 23 11:45 redo01.log
-rw-r----- 1 oracle oinstall 2147484160 11月 23 16:49 redo02.log
-rw-r----- 1 oracle oinstall 2147484160 11月 23 11:16 redo03.log
-rw-r----- 1 oracle oinstall 1111498752 11月 23 16:48 sysaux01.dbf
-rw-r----- 1 oracle oinstall 34319900672 11月 23 16:47 system01.dbf
-rw-r----- 1 oracle oinstall 4194312192 11月 23 11:50 system02.dbf
-rw-r----- 1 oracle oinstall 24536686592 11月 23 15:44 system03.dbf
-rw-r----- 1 oracle oinstall 30416896 11月 23 16:00 temp01.dbf
-rw-r----- 1 oracle oinstall 1782587392 11月 23 16:49 undotbs01.dbf
-rw-r----- 1 oracle oinstall 5251072 11月 23 11:50 users01.dbf
-rw-r----- 1 oracle oinstall 1939873792 11月 23 11:50 wlkj_app_data.dbf
-rw-r----- 1 oracle oinstall 30416896 11月 21 21:51 wlkj_app_temp.dbf
-rw-r----- 1 oracle oinstall 681582592 11月 23 11:50 zgq_wlwz_data.dbf
-rw-r----- 1 oracle oinstall 30416896 11月 23 11:26 zgq_wlwz_temp.dbf
接下来是进行数据库还原操作(recovery)
先启动到nomout阶段
sql>startup nomount
执行还原
sql>recover database
打开数据库
sql>alter database open;
再把相关表空间加上(这些过程其实就是通过重建控制文件使数据库启动,参考我的博客https://blog.csdn.net/huangbaokang/article/details/83992400)
以下可以从提供的博客的trc文件找到。
ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/hbk/oraData/orcl/temp01.dbf'
SIZE 30408704 REUSE AUTOEXTEND ON NEXT 655360 MAXSIZE 32767M;
ALTER TABLESPACE CMS6_ZGQ_TEMP ADD TEMPFILE '/u01/hbk/oraData/orcl/cms6_zgq_temp.dbf'
SIZE 30408704 REUSE AUTOEXTEND ON NEXT 655360 MAXSIZE 32767M;
ALTER TABLESPACE ZGQ_WLWZ_TEMP ADD TEMPFILE '/u01/hbk/oraData/orcl/zgq_wlwz_temp.dbf'
SIZE 30408704 REUSE AUTOEXTEND ON NEXT 655360 MAXSIZE 32767M;
ALTER TABLESPACE WLKJ_APP_TEMP ADD TEMPFILE '/u01/hbk/oraData/orcl/wlkj_app_temp.dbf'
SIZE 30408704 REUSE AUTOEXTEND ON NEXT 655360 MAXSIZE 32767M;
ALTER TABLESPACE INTERACT_TEMP ADD TEMPFILE '/u01/hbk/oraData/orcl/interact_temp.dbf'
SIZE 30408704 REUSE AUTOEXTEND ON NEXT 655360 MAXSIZE 32767M;
经过这样恢复之后,使用exp导出报了如下错
依然是数据库坏损坏问题,当使用了exp导出,或者oracle自带的dbv检测工具,
通过以下语句,可以查询当前数据块已损坏
select * from v$database_block_corruption;
发现有一大堆的数据块损坏,根据文件号和块号,查询具体损坏信息
select tablespace_name,segment_type,owner,segment_name from dba_extents where file_id=6 and 939960 between block_id and block_id+blocks-1;
每一个块都这样去检查,汇总得到的情况,有TABLE类型的坏块,和INDEX类型的坏块,和LOBSEGMENT类型的坏块。
由于被修复好了,上面的图其实是当时遇到问题所截图,图片信息在此略。
针对索引类型的坏块,直接删除重建索引即可解决问题。针对表类型的坏块,使用10231事件,配合exp导出,再次删除原来的表,然后导入会原来的数据库,参考我的博客https://blog.csdn.net/huangbaokang/article/details/84031845
alter system set events='10231 trace name context forever,level 10';
但是遇到用10231事件解决不了TABLE类型的坏块,期间还遇到连imp都导了不了。期间遇到了如下错误
把db_recovery_file_dest_size调大。
SQL> show parameter db_recovery_file_dest_size
这里显示的是默认安装oracle的大小,调大到30G
SQL> alter system set db_recovery_file_dest_size=30G;
System altered.
期间还遇到检查点不能完成的问题。以下图片从其他网站拷贝的,只是描述类似的问题
然后我有学习了如何扩大redo.log的空间,当时我的是50M,不够,我给它加到2G.
参考我的博客https://blog.csdn.net/huangbaokang/article/details/84330685
具体用到的命令如下:
--select group#,members,bytes/1024/1024,status from v$log;
--select member from v$logfile;
--alter system switch logfile;
--alter system checkpoint;
--alter database add logfile group 3('/u01/hbk/oraData/orcl/redo03.log') size 2048M;
--alter database drop logfile group 5
通过扩大了redo表空间之后才顺利使用imp命令导入成功表了。
特难搞的是LOBSEGMENT类型的坏块,由于当时对LOB类型字段的表存储不是很了解,期间熬夜加班查看了大量的相关类型博客,了解到它的存储特征跟普通字段不一样。
期间使用空块的处理方式,最终解决了我的问题,博客参考
https://blog.csdn.net/sdulsj/article/details/52993052
相关命令:
--CREATE TABLE corr_rows (row_id ROWID,error_code NUMBER);
--CREATE TABLE corr_rows (row_id ROWID,error_code NUMBER);
--DECLARE
-- n NUMBER;
-- ERROR_CODE NUMBER;
-- corr_rows NUMBER := 0;
-- ora_1578 EXCEPTION;
-- PRAGMA EXCEPTION_INIT(ora_1578,-1578);
--begin
-- for cursor_lob in (select rowid rid, title_pic
-- FROM a_content_text) LOOP
-- begin
-- n := dbms_lob.instr(cursor_lob.title_pic, hextoraw('01234567'));--这里有的博客填889911,我没搞懂这里的值是啥意思
-- EXCEPTION
-- WHEN ora_1578 THEN
-- corr_rows := corr_rows + 1;
-- INSERT INTO corr_rows
-- VALUES
-- (cursor_lob.rid, 1578);
-- COMMIT;
-- WHEN OTHERS THEN
-- ERROR_CODE := SQLCODE;
-- corr_rows := corr_rows + 1;
-- INSERT INTO corr_rows
-- VALUES
-- (cursor_lob.rid, ERROR_CODE);
-- COMMIT;
-- END;
-- END LOOP;
-- dbms_output.put_line('Corrupted rows: ' || corr_rows);
--END;
--/
--update a_content_text
-- set title_pic = empty_blob()
-- WHERE ROWID in( select row_id from corr_rows);
--commit
建立新的表空间进行LOB类型字段的存储。
create tablespace lob_hbk
logging
datafile '/u01/hbk/oraData/orcl/lob_hbk_data.dbf'
size 50m
autoextend on
next 50m maxsize 20480m
extent management local;
ALTER TABLE A_CONTENT_TEXT MOVE LOB("TITLE_PIC") STORE AS hbk (
tablespace "LOB_HBK"
ENABLE STORAGE IN ROW CHUNK 8192 PCTVERSION 10);
--重建索引
alter index A_CONTENT_TEXT_PK rebuild tablespace LOB_HBK
终于搞定了这个难题,写篇心得,挺有成就感的,当了会公司应急解决问题的功臣哈哈(有点自傲了^_^
),希望老板年底给我多发点奖金哈哈,毕竟这个数据库平台有十几个网站在跑,要是没解决,相关的网站客户绝对是会给公司带来不好的印象。