11 January 2020

Connecting to a Hung Database

เมื่อ 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