参考:
https://www.iteye.com/blog/java-mans-1642954
https://blog.csdn.net/qq_42774325/article/details/82353266
https://www.cnblogs.com/l10n/p/9406052.html
今天在dmp数据时入错了;想着把表空间文件直接删了,重新入;这想当然的操作,导致后面浪费了时间;
题目说恢复并非指“恢复数据”,确切来说指的是“修复”或“复原”表空间;
环境:
oracle数据库版本:oracle11g EE 11.2.0.4.0 64bit Production
表空间路径:
/home/oracle/oradata/xxspace/
文件名:
xyz202203_1.dbf
xyz202203_2.dbf
xyz202203_3.dbf
就在服务器上直接rm,把xyz202203_*.dbf
文件删了;再重建表空间:
CREATE TABLESPACE 'XYZ202203' DATAFILE '/home/oracle/oradata/xxspace/xyz202203_1.dbf' SIZE 5g AUTOEXTEND ON NEXT 1g MAXSIZE UNLIMITED;
ORA-01543:报错,提示表空间XYZ202203
已存在;
-- 查看所有表空间
SELECT * FROM DBA_TABLESPACES;
-- 查看表空间数据文件
SELECT * FROM DBA_DATA_FILES;
-- 删除指定schema
DROP USER XYZ_202203 CASCADE;
查询看了表空间还存在;
删除表空间语法:
--oracle 删除表空间及数据文件方法
--删除空的表空间,但是不包含物理文件
drop tablespace tablespace_name;
--删除非空表空间,但是不包含物理文件
drop tablespace tablespace_name including contents;
--删除空表空间,包含物理文件
drop tablespace tablespace_name including datafiles;
--删除非空表空间,包含物理文件
drop tablespace tablespace_name including contents and datafiles;
--如果其他表空间中的表有外键等约束关联到了本表空间中的表的字段,就要加上CASCADE CONSTRAINTS
drop tablespace tablespace_name including contents and datafiles CASCADE CONSTRAINTS;
报错IO错误,找不到/home/oracle/oradata/xxspace/xyz202203_1.dbf文件;百度看了有好多是要重装oracle啥得,感觉代价太大没必要,目前这部分数据丢失影响不大,重入一遍;
于是我简单的想去服务器上补上试试:
ALTER TABLESPACE 'XYZ202203' ADD DATAFILE '/home/oracle/oradata/xxspace/xyz202203_4.dbf' SIZE 5g AUTOEXTEND ON NEXT 1g MAXSIZE 20g;
cp xyz202203_4.dbf xyz202203_1.dbf
cp xyz202203_4.dbf xyz202203_2.dbf
cp xyz202203_4.dbf xyz202203_3.dbf
# ls
xyz202203_1.dbf
xyz202203_2.dbf
xyz202203_3.dbf
xyz202203_4.dbf
# 试了还是不行,以为是未授权。安排
chmod 755 xyz202203_*
chown -R oracle xyz202203_*
chgrp -R oracle xyz202203_*
再试了下依然是IO错误,找不到文件。
搜索到一个方法,进服务器sqlplus关了数据库,重启可以恢复;
# https://blog.csdn.net/qq_42774325/article/details/82353266
sqlplus /nolog
conn sys /as sysdba
shutdown immediate
...
第一步就报错,文件损坏,想关都关不了……
虽然不影响其他正常使用,但是以后肯定有大隐患,不能埋坑必需解决掉。
只能另辟蹊径了。
经过观察发现,DBA_TABLESPACES/DBA_DATA_FILES这两表是视图,可以到sys模式下看到对应实际得表;
-- 查看所有表空间
SELECT * FROM DBA_TABLESPACES;
-- 查看表空间数据文件
SELECT * FROM DBA_DATA_FILES;
-- 实际得表或视图
DBA_TABLESPACES
DBA_DATA_FILES
sys.file$
sys.ts$
sys.v$dbfile
sys.x$kccfe
sys.x$ktfbhc
sys.x$kcfistsa
DBA_DATA_FILES 有个字段叫ONLINE_STATUS
,来自sys.x$kccfe的fetsn和festa字段解码计算出的值:SYSOFF
,SYSTEM
,OFFLINE
,ONLINE
,RECOVER
;
会不会是ONLINE状态表示表空间正在被使用,但实际文件已经被物理删除了,导致drop tablespace
语句报错失效;
能否把ONLINE变为OFFLINE试试?还真找到了;
# offline
ALTER DATABASE DATAFILE '/home/oracle/oradata/xxspace/xyz202203_1.dbf' OFFLINE DROP;
ALTER DATABASE DATAFILE '/home/oracle/oradata/xxspace/xyz202203_2.dbf' OFFLINE DROP;
ALTER DATABASE DATAFILE '/home/oracle/oradata/xxspace/xyz202203_3.dbf' OFFLINE DROP;
ALTER DATABASE DATAFILE '/home/oracle/oradata/xxspace/xyz202203_4.dbf' OFFLINE DROP;
-- 查看表空间数据文件,`ONLINE_STATUS`由`ONLINE`变成了`RECOVER`;
SELECT * FROM DBA_DATA_FILES;
# 删掉表空间文件
drop tablespace XYZ202203 including contents and datafiles;
再次查看DBA_DATA_FILES
、sys.v$dbfile
和服务器/home/oracle/oradata/xxspace/
目录,会发现表空间文件都没了。
再重建表空间:
CREATE TABLESPACE 'XYZ202203' DATAFILE '/home/oracle/oradata/xxspace/xyz202203_1.dbf' SIZE 5g AUTOEXTEND ON NEXT 1g MAXSIZE UNLIMITED;
OK
总结教训:
1.如果一开始多查查sql,直接使用drop tablespace
就没这么多事了。
2.操作要规范,使用标准sql标准流程操作数据库。
3.做的操作每一步都要明确清楚后果再动手;特别是删除前,多思考最好备份。