เมื่อ Database เกิดอาการ hang และเราไม่สามารถ login เพื่อเข้าไปตรวจสอบหรือแก้ไข
จะมีวิธีการที่แนะนำดังนี้ (เรียงตามลำดับผลกระทบจากน้อยไปมาก)
- วิธีที่ 1 เข้า SQLPlus ด้วย option Prelim และ เก็บ diagnostic information ต่างๆ เพื่อวิเคราะห์ problem
หลังจากได้ diagnostic information ต่างๆแล้ว สามารถใช้วิธีที่ 2 หรือ 3 หรือ 4 เพื่อให้ Database เริ่มทำงานใหม่
- วิธีที่ 2 เข้า SQLPlus ด้วย option Prelim และ shutdown abort
- วิธีที่ 3 Kill Oracle background process ทั้งหมด ของ Database ที่ต้องการ
- วิธีที่ 4 Restart Server
ตัวอย่าง เหตุการณ์ทดสอบ
Database ชื่อ dbtest1
Session ที่ต้องการสังเกตุ
SQL> begin
loop
null;
end loop;
end;
/
พบ process ใช้งาน %CPU = 99.4
--> top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
31006 oracle 20 0 1346m 58m 53m R 99.4 3.1 2:26.03 oracle_31006_db
23328 oracle 20 0 1328m 44m 41m S 0.4 2.4 0:27.50 ora_mmnl_dbtest
23302 oracle 20 0 1330m 34m 28m S 0.2 1.8 0:43.55 ora_dia0_dbtest
23364 oracle 20 0 1350m 25m 21m S 0.2 1.3 0:00.76 ora_arc3_dbtest
26573 root 20 0 99.7m 3640 2652 S 0.2 0.2 0:01.21 sshd
--> ps -eo user,pid,ppid,cmd |grep 31006
oracle 31006 1 oracledbtest1 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
oracle 32065 31824 grep 31006
และตอนนี้ไม่สามารถ login เข้า SQLPlus เพราะ Database hung
วิธีที่ 1
--> export ORACLE_SID=dbtest1
--> sqlplus -prelim / as sysdba
ตัวอย่าง การใช้ oradebug ตรวจสอบ process PID = 31006 ว่าตอนนี้กำลังใช้ query อะไรทำงานอยู่หรือไม่
Debug PID ที่ต้องการตรวจสอบ
SQL> oradebug setospid 31006
แสดง trace file
SQL> oradebug tracefile_name
/oracle/diag/rdbms/dbtest1/dbtest1/trace/dbtest1_ora_31006.trc
แสดง SQL ที่ process PID = 31006 กำลังใช้งานอยู่
SQL> oradebug current_sql
begin
loop
null;
end loop;
end;
Close trace
SQL> oradebug close_trace
อ่าน trace file ด้วยคำสั่งของ OS
--> vi /oracle/diag/rdbms/dbtest1/dbtest1/trace/dbtest1_ora_31006.trc
Trace file /oracle/diag/rdbms/dbtest1/dbtest1/trace/dbtest1_ora_31452.trc
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
Build label: RDBMS_12.2.0.1.0_LINUX.X64_170125
ORACLE_HOME: /oracle/product/12.2.0/dbhome_1
System name: Linux
Node name: oradb12c.localdomain
Release: 2.6.32-573.el6.x86_64
Version: #1 SMP Thu Jul 23 15:44:03 UTC 2015
Machine: x86_64
Instance name: dbtest1
Redo thread mounted by this instance: 1
Oracle process number: 24
Unix process pid: 31452, image: oracle@oradb12c.localdomain (TNS V1-V3)
*** 2019-11-26T04:30:42.158025+07:00
*** SESSION ID:(68.10681) 2019-11-26T04:30:42.158049+07:00
*** CLIENT ID:() 2019-11-26T04:30:42.158054+07:00
*** SERVICE NAME:(SYS$USERS) 2019-11-26T04:30:42.158059+07:00
*** MODULE NAME:(sqlplus@oradb12c.localdomain (TNS V1-V3)) 2019-11-26T04:30:42.158064+07:00
*** ACTION NAME:() 2019-11-26T04:30:42.158068+07:00
*** CLIENT DRIVER:(SQL*PLUS) 2019-11-26T04:30:42.158072+07:00
Received ORADEBUG command (#2) 'current_sql' from process '31226'
*** 2019-11-26T04:30:42.158105+07:00
Finished processing ORADEBUG command (#2) 'current_sql'
...
....
.....
:q
สามารถดู option การใช้งานอื่นๆของ oradebug ได้จาก เปิด help
SQL> oradebug help
วิธีที่ 2
--> export ORACLE_SID=dbtest1
--> sqlplus -prelim / as sysdba
สั่ง Shutdown abort
SQL> shutdown abort
วิธีที่ 3
แสดง PID ของ process ทั้งหมด ตามชื่อ Database
GREP -V GREP เป็นคำสั่งสำหรับเอา process จากคำสั่ง GREP ออก
--> ps -ef | grep dbtest1 | grep -v grep | awk '{print $2}'
33738
33740
33746
....
......
........
Kill PID ของ process ทั้งหมด ตามชื่อ Database
--> kill -9 `ps -ef | grep dbtest1 | grep -v grep | awk '{print $2}'`
Remove RAM segment ที่ใช้งานอยุ่
--> ipcs -pmb
วิธีที่ 4
ใช้คำสั่ง shutdown หรือ restart OS
คำสั่ง shutdown
--> init 0
คำสั่ง restart
--> init 6