数据库长时间运行后,因断电、操作系统、物理存储等的原因可能会造成数据库内部的逻辑或物理错误,我们可以使用一般的方式尝试修复。
对于sqlserver 我们可以使用DBCC命令:
-- sqlserver use dbName GO --exec sp_dboption @databasename, N'single', N'true' --将目标数据库置为单用户状态 ALTER DATABASE dbName SET SINGLE_USER WITH ROLLBACK IMMEDIATE GO DBCC CHECKDB(dbName, REPAIR_ALLOW_DATA_LOSS) GO DBCC CHECKDB(dbName, REPAIR_REBUILD) GO --exec sp_dboption @databasename, N'single', N'false'--将目标数据库置为多用户状态 ALTER DATABASE dbName SET MULTI_USER GO
官方参考:
https://msdn.microsoft.com/zh-cn/library/ms176064.aspx
http://blogs.msdn.com/b/apgcdsd/archive/2014/05/05/dbcc-checkdb.aspx
对于Oracle可以使用DBMS_REPAIR.SKIP_CORRUPT_BLOCKS跳过坏块后,读取并重建数据表。
常见的物理坏块(Physical Block Corruptions)有块头和块尾信息不一致(Fractured/Incomplete),checksum值无效,数据块信息全部为0等情况,并且可能伴随错误ORA-1578和ORA-1110 。
为了及时发现物理坏块和准确定位坏块产生的原因,oracle建议设置初始化参数DB_BLOCK_CHECKSUM=TYPICAL(默认值)。一般情况下,物理坏块是由于底层OS/disk系统错误/损坏,导致数据块被修改,数据块标志为坏块(corruption)。
1. 当前数据库初始化参数配置DB_BLOCK_CHECKSUM=TYPICAL,因此从disk读取数据块时校验checksum:
SQL> show parameter DB_BLOCK_CHECKSUM
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_block_checksum string TYPICAL
2. 查询表dept时发现有坏块,报错信息ORA-1578和ORA-1110,坏块为file # 4, block # 133
SQL> select * from dept;
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 4, block # 133)
ORA-01110: data file 4: '/u01/app/oracle/oradata/orcl/users01.dbf'
修复数据坏块的方法可以通过备份恢复或者DBMS_REPAIR.SKIP_CORRUPT_BLOCKS跳过坏块,后者貌似执行起来更方便:
SQL> alter session set db_file_multiblock_read_count=1;
SQL> execute DBMS_REPAIR.SKIP_CORRUPT_BLOCKS('SCCOT','DEPT');
SQL> create table dept_new as select * from dept;
官方参考:https://blogs.oracle.com/Database4CN/entry/oracle%E6%95%B0%E6%8D%AE%E5%BA%93%E5%9D%8F%E5%9D%97_corruption_%E7%89%A9%E7%90%86%E5%9D%8F%E5%9D%97