周五晚,一产品部电话过来,说一客户那oracle起不来了,让帮忙看下。启动的时候报了ORA-01200,类似如下:
SQL> startup ORACLE instance started. Total System Global Area 202445884 bytes Fixed Size 451644 bytes Variable Size 167772160 bytes Database Buffers 33554432 bytes Redo Buffers 667648 bytes Database mounted. ORA-01122: database file 1 failed verification check ORA-01110: data file 1: '/m/n/xxx.dbf' ORA-01200: actual file size of 20 is smaller than correct size of 50 blocks
查了下v$datafile的大小,一个是20M,一个是0.5M。所述的表空间在/tmp目录下,运维也不知道表空间从哪里来的。估计是权限管理不严格,某个家伙做了测试。
正规的解决方式是使用rman备份恢复,参见https://www.parnassusdata.com/en/node/776?language=zh-hans,只是该环境用的是DSG做的备库,不是DG,也没有RMAN备份(对于需要灾备的,强烈建议有专职DBA的,一定要上DG,别找三方)。所以就只能非正规方式了。
非正规的方式之一是使用BBED人工修复,让库起来,然后备份、恢复,一般非oracle官方的三方技术支持公司常见的搞法,其实都不能保证100%不丢数据和事务。
第三种方式是,如果表空间、数据文件的业务相对独立,可以采用数据文件offline,删除,恢复备份(无论是expdp的还是rman的都行)。经过和开发、运维反复确认,异常的数据文件肯定不是业务的,所以采用第三种方式。
先将库置为归档模式:
SQL> alter database archivelog; Database altered. SQL> archive log list; Database log mode Archive Mode Automatic archival Disabled Archive destination /oradata/F3PROD/arch1 Oldest online log sequence 2285 Next log sequence to archive 2289 Current log sequence 2289
SQL> alter database datafile 15 offline; Database altered. SQL> alter database datafile 16 offline; Database altered.
SQL> alter database open; Database altered. SQL> SQL> shutdown immediate; Database closed. Database dismounted. ORACLE instance shut down. SQL> startup mount; ORACLE instance started. Total System Global Area 1058870496 bytes Fixed Size 738528 bytes Variable Size 788529152 bytes Database Buffers 268435456 bytes Redo Buffers 1167360 bytes Database mounted. SQL> alter database noarchivelog; Database altered. SQL> archive log list; Database log mode No Archive Mode Automatic archival Disabled Archive destination /oradata/F3PROD/arch1 Oldest online log sequence 2285 Current log sequence 2289 SQL> alter database open; Database altered. SQL>
至此,库恢复正常打开,数据无任何丢失。此时可以删除15、16表空间和数据文件了。