ITPub博客

首页 > Linux操作系统 > Linux操作系统 > DB異常處理經驗總結

DB異常處理經驗總結

原创 Linux操作系统 作者:golden_zhou 时间:2011-08-30 14:40:47 0 删除 编辑

DB異常處理經驗總結

1. Tnsping服務器異常
例: tnsping intel
C:\>tnsping intel
TNS Ping Utility for 32-bit Windows: Version 9.2.0.1.0 - Production on 08-12月-2
004 15:37:27
Copyright (c) 1997 Oracle Corporation.  All rights reserved.
已使用的參數檔案:
d:\oracle\ora92\network\admin\sqlnet.ora
TNS-03505: 無法決定名稱
A)先檢查tnsnames.ora(%ORACLE_HOME%\oracle\network\admin\tnsnames.ora)配置是否正确,INTEL =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.161.8.100)(PORT = 1526))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = intel)
    )
  )
B)若正确,再ping 10.161.8.100确认网路没问题
C)若网路通畅,则登入服务器(telnet 10.161.8.100)检查监听器是否开启
intel$lsnrctl status
LSNRCTL for Linux: Version 8.1.6.0.0 - Production on 08-DEC-2004 15:43:47
(c) Copyright 1998, 1999, Oracle Corporation.  All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC)))
TNS-01103: Protocol specific component of the address is incorrectly specified
 TNS-12541: TNS:no listener
  TNS-12560: TNS:protocol adapter error
   TNS-00511: No listener
    Linux Error: 111: Connection refused
显然,此监听已被关闭.
显示监听状态:intel$lsnrctl status
开启监听命令:intel$lsnrctl start
关闭监听命令:intel$lsnrctl stop

2. 產線掃描反應慢 
首先登入DB服务器,用top命令检查cpu负载是否过高,一般的数据库服务器负载最好是6.0以下,若负载过高,处理方法是关闭WEB先,若还没解决问题,可能是程序sql引起的锁表, 可以在Toad中kill掉, 并关掉相关程序半分

鍾,  直到改善为止, 。若也未鎖表 ,数据库系统中某些trigger,procedure等引起得数据库系统慢,可以登入Toad检查DB Link是否异常,procedure是否有invalid状态的等。還由一種情況就是index問題. Index沒有正確被

應用,或根本沒有index .   

3. 數據庫系統出現僵死狀態
用键盘直接插在Server上而不是通过共享器,确认数据库Server是否真的僵死,如果有错误信息出现,请快速纪录下错误信息,确认数据库系统僵死并通知相关人员后重新启动Server,如果数据库管理员没有赶来,请电话联系

开启数据库Listener及启动数据库系统。 

4. 數據庫歸檔文件空間不足
若数据库版本为oracle8i,归档文件空间不足时,DB会宕机,马上会报一个错误,说归档空间不足,若数据库版本为oracle9i,则不会宕机,会在日志中报归档空间不足,但必须得处理。处理方法,删除一些归档文件救急,

再增加硬盘。  

5. 表空間不能擴展
若表空间不能扩展,现象是产线某个或某些工站不能扫描,调试当中且某个表不能插入数据,在日志中也会报一个错误: 
Mon Dec  6 11:29:34 2004
ORA-1653: unable to extend table MACADMIN.INTEL_R_MACADDR_T by 256 in           tablespace ICT_DATA
Mon Dec  6 11:30:12 2004
ORA-1653: unable to extend table MACADMIN.INTEL_R_MACADDR_T by 256 in           tablespace ICT_DATA
此时处理方法:增加数据文件
SQL〉ALTER TABLESPACE ICT_DATA ADD DATAFILE '/ict/ict_data3.dbf' SIZE 2025M; 

6. Linux系統報”Too many open files”  
此为Linux系统一个参数设置问题,现在很少出现此现象,参数文件为:#/etc/sysctl.conf
intelsfcdb$cat /etc/sysctl.conf
# Disables packet forwarding
net.ipv4.ip_forward = 0
# Enables source route verification
net.ipv4.conf.default.rp_filter = 1
# Disables the magic-sysrq key
kernel.sysrq = 0
kernel.shmmax=2048000000
fs.file-max=40960
比如说原来fs.file-max = 8192,改为40960后,在root用户下执行:
[root@intelsfcdb etc]# sysctl –p 
让其生效。 

7. 分布式數據庫系統異常 
分布式数据库系统导致的写入不完整而数据库系统起不来,即一个程序会在一笔交易中向A , B 数据库系统分别写入数据,写入A库后必须写入B, 不然数据就会不一致,虽然说异常关闭程序,ORACEL会将数据回滚以保持数据

一致性,  但是如果程序与数据库在一台SERVER上,同时异常关闭程序与数据库系统(比如异常重启SERVER),回滚已经不可能,导致数据库挂起 。 可以查询VIEW  ---  DBA_2PC_PENDING ,  處理方法比較複雜. 見另一文

檔 .    

8. 參數設計不正確
参数指的是数据库参数:
open_cursors = 100
max_enabled_roles = 30

db_block_buffers = 76800

shared_pool_size = 105242880

large_pool_size = 614400
java_pool_size = 0
以open_cursors = 100参数为例,设置过少,客服端连接就有限制,比如说,已连上100个user,第101个user连接就会报错, 但是一般設置3000足夠, 如果程式在運行後沒有關閉cursor (java一般比較容易出現)就會導致open

cursor不夠用 . 需要改善程式 .

9. Linux系統數據文件超過2G    
Linux7.2 以下Oracle数据文件不能超过2G,若是新加的数据文件,则可以马上改回来,使用:alter database datafile ‘/data/intel/ict_data1.dbf’resize 2025m;

10. 數據庫鎖表  
现象:以拥有dba权限的用户登入Toad (7.5或更高版本的toad ,  点击 DBA-->Kill/Trace Session , 察看其中的All Locks 页,并且修改它的 refresh 时间为 5 sec , 观察20 秒左右,如果发现同一个SID在下面表格中一

直不消失(持续很长时间), 那么这个session所在的SQL可能存在问题. 
解决方案:(1).TOAD Kill;
判定session所在的SQL可能存在问题,  点击这个有问题的SID行,可以在最下面看到现在运行的SQL, 请将它copy 出来保存,或抓图也可以,目的是希望能够知道有问题的SQL语句 。纪录以上信息后,通知DBA组成员,选中

有问题的SID(如果有多个相同的有问题的SID ,逐个KILL), 快速点击按钮:kill the selected session .

  
 (2).Oracle Enterprise Manager Console Kill;
    如果方法(1)不能夠處理,請採用方法如下方法, 通知DBA组成员,以拥有dba权限的用户登入到ORACLE(客戶端或服務器端管理控制台).點擊:開始程式集Oracle OraHome Enterprise Manager ConsolLaunch

standalone, 依次展開左邊的節點, 進入到需要查看的數據庫中.
現在以Dell RAC1為例:
A.點擊該數據庫,使用拥有dba权限的用户登入, 依次展開左邊的節點.
 
B.根據方法(1)中找到的SID, 準確無誤的查看其作業系統處理作業ID. 右鍵點擊查看其詳細信息.
 

C.紀錄其對應的SQL語句, 便與事後DBA成員進行SQL分析. 之後點擊”終止階段作業”, Kill此作業.
 
(3).Kill -9強制Kill:
如果方法(1), (2)均不可以將此作業結束, 則採用第三種方法, 切記: 此方法在做之前一定要通知到DBA成員, 沒有許可, 嚴禁做此動作.
根據方法(1), (2)查出的作業系統處理作業ID, Telnet進入到相應得數據庫, kill -9 作業系統處理作業ID, 進行強制結束作業. 切記: 此方法在做之前一定要通知到DBA成員, 沒有許可, 嚴禁做此動作.

11. 數據塊損壞
运行一个计数sql语句时,报一个 ORA-01578 错,对应用相关的表 tg_bill03 做 SQL>select from tg_cdr03 where rownum<10; 这样是可以的,但做 SQL>select count(*) from tg_bill03; 时则报 ORA-01578 错。
检查 alter.log 中看到一几条报错信息:
Errors in file /oracle816/app/admin/billing/udump/ora_7281_billing.trc:
ORA-01578: ORACLE data block corrupted (file # 126, block # 88490)  
ORA-01110: data file 126: '/dev/vgjf7/rdata471'  
解决方法:这种问题的解决方法是很多的,如果你用的是归档方式,则可以基于时间点恢复来解决。不过这里介绍一种比较方便的解决方式,因为我的库没有开归档。 Metaline 关于 ORA-01578 的文字也很多,不过我看过后

总觉得都不那么实用,不能解决实际的问题。
1)、 解决这种问题的第一步是首先你要确定是什么段、哪个段坏了,是索引还是表?
A、 打开 alter.log ,找到 ORA-01578 的报错信息,并记录下 file# 及 block 的值,我这里是 126 和 88490 。
B、 执行以下语句看哪个段坏了
SQL>Select * from dba_extents
2 where file_id=
3 and between block_id and block_id+blocks-1;
这里的 F 指的是 file#,B 指的是 block#
我的显示结果指出是 tg_bill03 出现了坏块。
2) 、如果确定下来坏的是索引段,这时你就可以轻舒一口气了,只要把这个索相删除然后重建一下就可以了,如果出现坏的是表段,则应往下走了。
3)、 记录下这个表的建表语句
为我方便,建议使用 PL/SQL Developer 来完成,如果你没有可以在 http://www.allroundautomations.com/plsqldev.html 去下载一个,操作步骤是这样的。
A、 以表的 owner 用 pl/sql developer 连入 oracle
B、 在左面的树状栏中找到这个表 tg_bill03, 右击该表 ->view->View SQL, 记录下 sql ,以备以下步骤中重建索引。
4)、 实际处理了,以我的那个表为例
A、 以 tg_bill03 的 owner 连入 oracle
B、 使用诊断事件 10231
SQL> ALTER SYSTEM SET EVENTS ‘10231 trace name context forever,level 10';
C 、创建一个临时表 tg_bill_tmp 的表中除坏块的数据都检索出来
SQL>CREATE TABLE tg_bill03_tmp as select * from tg_bill03;
C、 更名原表,并把 tg_bill03_tmp 为 tg_bill03
SQL>alter table tg_bill03 rename to tg_bill03_bak;
SQL>alter table tg_bill03_tmp to tg_bill03;
D、 在 tg_bill03 上重新创建索引、约束、授权、 trigger 等对象
E、 利用表之间的业务关系,把坏块中的数据补足。

12. 存儲過程打叉 
用sfis1用户登入数据库,进行compile即可

13. 資料被異常刪除,引起產線異常
通過ip trace 系統追蹤刪除信息 ,也就是说通过记录登入数据库user的信息,某个时间段,资料被删除,那么此时间段内有哪些user登入过数据库,即为怀疑对象。Ip trace系统是数据库中的trigger,只要有客户端登入数

据库,就会记录此客户端的ip,登入时间等信息。并写入到sfis1.LOGIN_LOG_TRACE table中。
使用Flashback Query的样例
     1: SELECT * FROM tableName AS OF
TIMESTAMP (SYSTIMESTAMP - INTERVAL '60' MINUTE) WHERE ….;
2: SELECT * FROM tableName AS OF
TIMESTAMP TO_TIMESTAMP(‘20070920083059’,‘yyyymmddhh24miss’) WHERE …..;
3: SELECT * FROM tableName AS OF SCN 4122650073 WHERE …..;
4: 使用DBMS_FLASHBACK包
    dbms_flashback.enable_at_time(to_timestamp('20-FEB-2002','DD-MON-YY'));
SELECT salary FROM employees WHERE employee_id = 205;
SELECT COUNT(*) FROM employees;
dbms_flashback.disable;

14. 服務器時間異常
现象:服务器的时间与当前的时间不一致,甚至相差几个少时。
处理方法:使用时间同步服务器(10.161.8.200),Linux下用root登入,执行#ntpdate 10.161.8.200,windows下执行, C:\>net time \\dmd-it-022 /setsntp:10.161.8.200。 

15. Listener開啟後,同一實例有兩個監聽  
    通过命令$lsnrctl status,查看监听服务,发现 
Services Summary...
asdrma                has 1 service handler(s)
asdrma                has 1 service handler(s)
   rma           has 1 service handler(s)
rma           has 1 service handler(s)
则用Toad登入数据库时,会发生数据库对换的情况,比如说,本来要登入asdrma,事实上登入后,发现是RMA的资料库。 
解决办法:更改监听器端口(/u01/product/oracle/network/admin/listener.ora)
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS_LIST =
        (ADDRESS = (PROTOCOL = TCP)(HOST = 10.161.8.40)(PORT = 1783))
        (ADDRESS = (PROTOCOL = TCP)(HOST = 172.22.0.26)(PORT = 1526))
      )
    )
  )

16. 異常停電導致控制文件不一致 .
 方法:  切換Standby , 將Standby 歸檔恢復到production DB上最後一個歸檔文件 , 然後激活Standby 資料庫, 修改ip 及監聽器 Listener . 

17. system文件丟失.
方法:如果有備份及歸檔文件,則拷貝備份的system文件到正式庫中,并在startup mount之後進行recover,再open即ok。
如無備份,則注意不要關閉資料庫進程,關閉監聽并通知管理員關閉AP系統,且避免system文件所在磁盤有文件創建,以免覆蓋system01文件所在位置,那樣將無法恢復。在確保以上事情沒出現時,進行下面操作:
1) 執行ps –ef |grep SID,找到DBWR進程的pid號
2) 根據查找到的PID號,到對應的/proc/PID/fd目錄中,使用ls –alh查看
 
找到對應的system01文件,如有誤刪除則會在文件后加(deleted)標記
3) 到此就發現了system01文件的編號,那么要找到就要使用cat /proc/PID/fd/19 > /u01/system01.dbf,這裡要尤其注意,不要將cat出來的system01文件放在原system01同磁盤上,如原來的在raid1上,則cat出來的

要放在raid5上
4) 拷貝cat出來的文件到原路徑中
5) 關閉資料庫,一般使用shutdown immediate是無法關閉的,需要使用shutdown abort來關閉
6) 開啟資料庫,使用startup mount命令將資料庫開啟到mount狀態,然後recover datafile 1(1代表的是system01在oracle中的文件編號);等recover成功完成直接open就恢復完成。
7) 如果刪除了較長時間,那么在第六步,可能在recover的時候會出現redo 不一致的錯誤時,則需要看recover到哪個歸檔的時候出現了這個錯誤。然後關閉數據庫,重新copy 恢復出來的system01文件覆蓋剛剛recover

出錯的,再startup mount開啟到mount狀態,使用recover database until time '2004-04-22 10:05:00'(時間可設定在recover出錯之前)進行不完全恢復,然後使用alter database open resetlogs;來強行重置文件頭及

數據庫,如開啟沒有問題則恢復完成,建議立即進行全庫導出或者建立standby。
8) 在第七步中,如過open resetlogs出錯,則需要加入隱含參數_allow_resetlogs_ corruption=true來強行開啟資料庫。因關閉資料庫的時候使用的是shutdown abort,那么有可能存在回滾段需要recover的情況,這

個時候有可能會報回滾段錯誤,那么就需要刪除原undo空間,重新創建一個undo,步驟為:
a) 設置*.undo_management='MANUAL'
b) 指定回滾空間為system,*.undo_tablespace=’system’
c) 設置隱含參數_corrupted_rollback_segments=(_SYSSMU1$,_SYSSMU2$, _SYSSMU3$,_SYSSMU4$,_SYSSMU5$,_SYSSMU6$,_SYSSMU7$,_SYSSMU8$,_SYSSMU9$,_SYSSMU10$,_SYSSMU11$) 及_offline_rollback_

segments=true
d) 開啟資料庫,然後drop tablespace xxx including contents and datafiles;并新建undotbs2的undo空間
e) 去掉隱含參數,并修改undo_management為auto,undo_tablespace為undotbs2,開啟數據庫ok。
9) 如果還遇到數據庫smon進程在清理表空間臨時段出錯,并在報錯100次后自動關閉數據庫,則需要加入event='10061 trace name context forever, level 10'事件來屏蔽smon進程對表空間臨時段的清理,然後開啟數

據庫就不會報錯,但是表空間中的臨時段的清理工作將會停止,使用Select * from dba_segments where segment_type='TEMPORARY'能查到有哪些表空間臨時段沒有清理,会发现这样类似AA.BBBBB的临时段,这是Oracle在创

建数据(或索引)段过程中生成的临时段,由于创建过程因某种原因(用户中断或空间不够大)失败而造成的。段名中的AA为数据文件的file_id,BBBBB为数据块的block_id。可用以下方法清除(只要这个段没有被锁住):
alter session set events 'immediate trace name DROP_SEGMENTS level TS#+1'
         其中 TS# = TS$.TS#
如果想清除所有表空间的临时段,则
TS# = 2147483647 
然後關閉數據庫,屏蔽添加的event,正常開啟就ok。如不使用清理,也可將改block上的表move到別的表空間,然後直接屏蔽event,重啟數據庫。
10) 最後屏蔽所有添加的隱含參數,到此,文件誤刪除的恢復就完成了。

最後,建議立即建立standby,并測試激活standby是否可用且正常,有可能的話也立即進行全庫導出。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25198367/viewspace-706229/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2011-03-09

  • 博文量
    238
  • 访问量
    308397