Patch Database ที่มี Data Guard มีวิธีการอย่างไร

Michikiang
Sirisoft
Published in
8 min readApr 7, 2023

กาลครั้งหนึ่งมิชิเกียงได้รับสาสน์ให้ patch Data Guard

สวัสดีอีกครั้งค่ะ เกียงนะคะ ตำแหน่ง Database Administrator อยู่ที่บริษัท Sirisoft Blog ที่แล้ว เราได้พูดถึง task เพิ่ม IP ให้ Exadata ไปเนอะ คราวนี้เราจะกล่าวถึงอีกหนึ่งงานของ DBA ที่มีความสำคัญไม่น้อย นั่นคือการ hardening ฐานข้อมูลนั่นเอง!!

นอกเหนือจากการปรับค่า parameter ให้เป็นไปตามข้อกำหนดก็มี patch database ให้เป็นเวอร์ชันล่าสุดค่ะ เผอิญว่าคราวนี้ database ที่ว่ามี Data Guard อยู่ตัวหนึ่ง เลยไม่ได้ patch คราวเดียวจบเหมือน single instance นึกดูตอนนั้นก็สนุกดี เลยอยากนำวิธีที่ใช้มาเล่าสู่กันฟังค่ะ o(*°▽°*)oo(*°▽°*)o

อารัมภบท

อะไรคือการ Hardening?

Hardening เป็นหนึ่งในวิธีเสริมสร้างความปลอดภัยให้กับระบบงานของเรา นอกจากเป็นการอุดช่องโหว่ (vulnerability) แล้ว ยังช่วยให้ประสิทธิภาพองค์รวมของระบบดีขึ้น พอความเสี่ยงลด ความมั่นใจในระบบของผู้ใช้งานและผู้ดูแลระบบจะก็ตามมาค่ะ โดยความเร่งด่วนและความจำเป็นก็สุดแล้วแต่ Service Level Agreement และ Security Policy ที่ยอมรับร่วมกันเลย

ตัวอย่างข้อปฏิบัติสำหรับการ hardening database ค่ะ

  • อัปเกรด package ที่ใช้ให้เป็นเวอร์ชันที่เหมาะสม
  • จำกัดสิทธิ์การเข้าถึงผู้ใช้งาน
  • นโยบายเปลี่ยนรหัสผ่านทุก x เดือน โดยรหัสต้องมีความซับซ้อน
  • เปิดใช้งาน audit ในระดับที่ยอมรับร่วมกัน
  • ติดตั้ง patch เพื่ออุดช่องโหว่หรือแก้ bug ที่พบเจอในเวอร์ชันก่อน ๆ ที่อาจกระทบระบบ หรือเพื่อตัดไฟต้นลม ヾ(•ω•`)oヾ(•ω•`)o

ทำความรู้จัก Data Guard อย่างคร่าว

Data Guard (DG) เป็นหนึ่งใน High Availability (HA) Solution

General DG Config

นอกเหนือจาก Primary Database ก็จะมี Standby อีกอย่างน้อยหนึ่งตัวเป็น Disaster recovery (DR) เอาไว้เผื่อกู้คืนข้อมูลหากเกิดเหตุการณ์ไม่คาดคิดขึ้นกับ Primary database และเมื่อถึงคราวจำเป็นก็สามารถทำการ switchover หรือ failover ได้

Switchover — สลับบทบาทระหว่าง primary กับ standby

Failover — promote standby ขึ้นมาเป็น primary เมื่อ primary เดิมใช้งานไม่ได้อีก

  • โดยสังเขป Primary จะมีหน้าที่ส่งข้อมูลไปยัง Standby ที่ส่วนมากจะอยู่คนละ Site
  • ฝั่ง Standby ก็จะคอย apply log เรื่อย ๆ เพื่อให้ข้อมูลทั้งสองฝั่ง sync กันที่สุดค่ะ

อธิบาย environment ที่เราเอามาทดสอบ logic

  • DC ของเราชื่อ mck_dc มี DB เวอร์ชัน 19.16 อยู่หนึ่งตัว — เป็น primary ชื่อ orcldc
  • DR ของเราชื่อ mck_dr มี DB เวอร์ชัน 19.16 อยู่สองตัว ตัวหนึ่งเป็น physical standby ชื่อ orcldr อีกตัวเป็น single instance ชื่อ orcltest

Standby database จะมี 3 ประเภทหลัก ๆ ค่ะ

Physical Standby — เป็นแฝดของ primary แบบทุกระเบียบ เวลา apply log จะ apply redo ประเภทนี้จะเปิด DB แบบ read-only และเป็น real time query feature

Logical Standby — ตอนสร้างจะมีโครงเหมือน primary ทุกระเบียบ แต่สามารถแก้ไขให้โครงสร้างต่างออกไปได้ เวลา apply log จะเป็นการ execute SQL Statements, DB จึงเปิดแบบ read-write

Snapshot Standby — ประเภทนี้จะไม่ apply redo ที่รับมาจาก primary จนกว่าจะมีการแปลงกลับเป็น physical standby เหมาะกับเอาไว้ใช้ทดสอบระบบก่อนใช้จริงค่ะ

เราได้ลองทดสอบอยู่สองวิธีคือ ได้แก่…

  1. Simplicity is the best | วิธีเรียบง่าย
  • cancel sync ระหว่าง primary กับ standby ชั่วคราว
  • apply patch ที่ primary
  • รัน post-patch ตามท้าย
  • พอเรียบร้อยทุกขั้นตอนก็ sync คืน

2. Downtime minimization | ประหยัด downtime

  • patch ที่ DR โดยไม่รัน post-patch
  • switchover ให้ DB ที่ DR กลายเป็น primary
  • patch DC site
  • รัน post-patch ที่ DR
  • [optional] จะ switchover กลับหรือไม่ก็ได้

หากสามารถรับ downtime ที่มากหน่อยได้ วิธีแรกก็เป็นตัวเลือกที่ไม่เลวเลยค่ะ เพราะการดำเนินการไม่ซับซ้อน แต่ถ้าอยากลด downtime หรืออยากทดสอบย้ายแอปพลิเคชันไปต่อที่ DR วิธีที่สองก็เป็นอีกตัวเลือกที่น่าสนใจและท้าทายมากยิ่งขึ้น ╰(*°▽°*)╯╰(*°▽°*)╯

Prerequisite

เวอร์ชันของ OPatch ต้องสัมพันธ์กับ patch ที่จะ apply

OPatch — เครื่องมือที่เอาไว้ apply & rollback patches

Patch — การ upgrade ฟีเจอร์เพื่ออัปเดต, ซ่อมแซมปัญหา, แก้ไข bug, หรือเพิ่มความปลอดภัยให้กับระบบ

  • ตัวอย่างการโหลด patch DB RU เวอร์ชัน 19.18 จาก Oracle Support
Download the patch
  • แวะอ่าน README
Explore README from the extracted zip file
  • เลื่อนไปที่ section OPatch Utility จากภาพจะเห็นว่า OPatch ควรเป็นเวอร์ชัน 12.2.0.34 เป็นต้นไป
View required OPatch version
  • ตรวจสอบเวอร์ชันของ OPatch ได้จากคำสั่งนี้
cd $ORACLE_HOME/OPatch
./opatch version
Check current OPatch Version
  • จากภาพ จะเห็นว่าเวอร์ชันของเราใหม่กว่า 12.2.0.1.34 แล้ว แต่หากเวอร์ชันเก่ากว่า requirement และจำเป็นต้องอัปเกรด สามารถโหลด OPatch มาลงใหม่ได้ตามภาพด้านล่างค่ะ
Download the latest OPatch

ก่อนจะอัปเกรดเวอร์ชันให้ OPatch เราแนะนำให้ backup $ORACLE_HOME/OPatch เวอร์ชันเดิมไว้เผื่อ rollback นะคะ พอ backup แล้วก็ unzip เวอร์ชันใหม่ได้เลย พอรัน opatch version อีกครั้งก็จะเห็นเป็นเวอร์ชันล่าสุดค่ะ (★‿★)(★‿★)

#backup the previous version of OPatch
tar -cvf oracle_home_opatch_$(date +%Y-%m-%d).tar $ORACLE_HOME/OPatch

#Unzip the newer version
cd $ORACLE_HOME
unzip -oq "PATH_TO_FILE/p6880880_190000_Linux-x86-64.zip"
cd $ORACLE_HOME/OPatch
./opatch version
Example of the previous OPatch version at DR Site
Example of the OPatch version after unzipping at DR Site

เริ่ม Patch แบบแรกกันเลย

Note: ก่อน patch ครั้งนี้ DB ทั้งที่ DC และ DR ของเราเป็นเวอร์ชัน 19.16

DB Version at DR Site
DB Version at DC Site

Simplicity is the best | วิธีเรียบง่าย

ณ DR Site — ตรวจสอบให้แน่ใจว่า OPatch version เหมาะสม

  1. Cancel sync กับ DC
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

2. ปิด Listener ทุกตัว

Listener — โปรเซสหนึ่งที่เป็นตัวกลางระหว่างผู้ใช้งาน (client) และ DB คอยรับ connection request มาและบริหารจัดการ network traffic

#ex. lsnrctl stop LISTENER_DG_DR
lsnrctl stop [LISTENER_NAME]

3. ปิด database และ exit ออกจาก session

SHUTDOWN IMMEDIATE;
EXIT

4. Backup ORACLE_HOME ไว้เผื่อ rollback

cd $ORACLE_HOME
tar -cvf oracle_home_bak_$(date +%Y-%m-%d).tar $ORACLE_HOME

5. Apply Patch ในที่นี้จะเป็น RU Patch เวอร์ชัน 19.18

#Apply RU Patch
#change into preferred directory or make a new directory if needed
#mkdir /u01/software
cd /u01/software/
unzip -oq "PATH_TO_PATCH_FILE/p34765931_190000_Linux-x86-64.zip"
cd "/u01/software/34765931/"
export PATH=$ORACLE_HOME/OPatch:$PATH

#perform prerequisite check
opatch prereq CheckConflictAgainstOHWithDetail -ph ./

#apply the patch
opatch apply -silent
Applying the patch

หากสำเร็จ ผลสุดท้ายจะเป็นประมาณภาพด้านล่างค่ะ

Reminder: เนื่องจาก DB ที่ DR ของเราเป็นตัว standby อยากจะเก็บไว้เผื่อทำ disaster recovery เท่านั้น ตอนเราเปิดขึ้นมาเลยจะเปิดแค่ mount หรือ read-only ค่ะ

The patch is applied successfully
DB Version at DR

หากมี patch อื่น ๆ ที่ต้องการ apply เพิ่มก็สามารถทำวิธีการเดิมได้เลย

#Apply OJVM Patch
cd /u01/software/
unzip -oq "PATH_TO_PATCH_FILE/p34786990_190000_Linux-x86-64.zip"
cd "/u01/software/34786990/"
export PATH=$ORACLE_HOME/OPatch:$PATH

#perform prerequisite check
opatch prereq CheckConflictAgainstOHWithDetail -ph ./

#apply the patch
opatch apply -silent

ณ DC Site — เช็คให้แน่ใจว่า OPatch tools เป็นเวอร์ชันที่สัมพันธ์กับ Patch ที่จะ Apply

6. ปิด Listener ทุกตัว

#ex. lsnrctl stop LISTENER_DG_DC
lsnrctl stop [LISTENER_NAME]

7. ปิด database และ exit ออกจาก session

SHUTDOWN IMMEDIATE;
EXIT

8. Backup ORACLE_HOME ไว้เผื่อ rollback

cd $ORACLE_HOME
tar -cvf oracle_home_bak_$(date +%Y-%m-%d).tar $ORACLE_HOME

9. Apply Patch ในที่นี้จะเป็น RU Patch เวอร์ชัน 19.18

#Apply RU Patch
#change into preferred directory or make a new directory if needed
#mkdir /u01/software
cd /u01/software/
unzip -oq "PATH_TO_PATCH_FILE/p34765931_190000_Linux-x86-64.zip"
cd "/u01/software/34765931/"
export PATH=$ORACLE_HOME/OPatch:$PATH

#perform prerequisite check
opatch prereq CheckConflictAgainstOHWithDetail -ph ./

#apply the patch
opatch apply -silent
Performing prerequisite check
Applying patch

10. เปิด listener กลับคืนมา

#ex. lsnrctl start LISTENER_DG_DC
lsnrctl start [LISTENER_NAME]
Starting LISTENERs

11. เปิด database

12. เช็ค patch ที่ apply ใน ORACLE_HOME

Cd $ORACLE_HOME/bin
opatch lsinventory

อาจจะยาวเฟื้อยหน่อย แต่ผลที่ได้คือจะเห็นรายการ patch ค่ะ

Result of opatch lsinventory

13. รัน post-patch command

cd $ORACLE_HOME/OPatch
./datapatch -verbose

Datapatch — เครื่องมือ post-patch ที่ perform SQL หรือ PL/SQL Actions โดยอัตโนมัติเพื่ออัปเดตความเปลี่ยนแปลงให้กับ data dictionary

Data dictionary — รายการที่เก็บข้อมูล/รายละเอียดต่าง ๆ ของ database เช่นข้อมูล relation ระหว่างเทเบิล ขนาดของ field ฯลฯ

Result of the post-patch command

14. เช็คเวอร์ชันใน DB จะเห็นว่าอัปเดตจาก 19.16 เป็น 19.18 แล้ว

SELECT TO_CHAR(ACTION_TIME, 'YYYY-MM-DD HH24:MI') AS ACTION_TIME,ACTION,STATUS,
DESCRIPTION,PATCH_ID
FROM SYS.DBA_REGISTRY_SQLPATCH
ORDER BY ACTION_TIME;
Patches applied
cd $ORACLE_HOME/bin
opatch lspatches
List patches applied

ณ DR Site

15. Sync Primary-Standby

--Sync
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;

--Check log applied time
SELECT SEQUENCE#,TO_CHAR(FIRST_TIME,'DD-MON-YYYY HH24:MI:SS') "LOG APPLIED TIME"
FROM V$LOG_HISTORY
WHERE FIRST_TIME=(SELECT MAX(FIRST_TIME) FROM V$LOG_HISTORY);
Sync and check log applied time at DR

เช็คกับทาง DC ว่า log applied ตรงกันก็เป็นอันเรียบร้อย

Check log applied time at DC

หากมี Patch อื่น ๆ ที่ต้องการ Apply อีกก็ทำซ้ำข้อที่ 6–15 ได้เลยค่ะ ในที่นี้เรา Apply OJVM patch อีกตัว ผลลัพธ์สุดท้ายจะเป็นแบบนี้ทั้งข้าง DC และ DR ค่ะ

Final result after applying all patched needed
List patches
DB Version at DC

ลอง Patch แบบ Switch over ดูบ้าง o(* ̄▽ ̄*)ブ

Downtime minimization | ประหยัด downtime

  1. [DR — Standby] Patch DR สามารถทำตามข้อ 1–7 ของการ patch แบบแรกได้เลย
  2. [DC — Primary] Switchover ไป DR
Check switchover status at DC

หากมีการ configure Data Guard Broker ไว้ก็สั่งแบบนี้ได้เลยค่ะ

dgmgrl user/password

SWITCHOVER TO DESTINATION_DB_NAME

หากไม่มี สามารถใช้คำสั่งนี้แทนได้ค่ะ

ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN;
Switchover to DR

3. [DR — Primary] Switch DR ขึ้นเป็น Primary

--Switch to Primary
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
--Restart
SHUTDOWN IMMEDIATE;
STARTUP;
Switchover status at DR right after executing the command at DC to switchover to the physical standby
Switchover status at DR after switching to Primary

4. [DC — Standby] Exit from SQL*Plus และปิด listener ทั้งหมด

#ex. lsnrctl stop LISTENER_DG_DC
lsnrctl stop [LISTENER_NAME]

Backup ORACLE_HOME ไว้เผื่อ rollback

cd $ORACLE_HOME
tar -cvf oracle_home_bak_$(date +%Y-%m-%d).tar $ORACLE_HOME

Apply Patch ตัวแรก ในที่นี้จะเป็น RU Patch เวอร์ชัน 19.18

#Apply RU Patch
#change into preferred directory or make a new directory if needed
#mkdir /u01/software
cd /u01/software/
unzip -oq "PATH_TO_PATCH_FILE/p34765931_190000_Linux-x86-64.zip"
cd "/u01/software/34765931/"
export PATH=$ORACLE_HOME/OPatch:$PATH

#perform prerequisite check
opatch prereq CheckConflictAgainstOHWithDetail -ph ./

#apply the patch
opatch apply -silent
Performing prerequisite check
Applying patch

เปิด listener

#ex. lsnrctl start LISTENER_DG_DC
lsnrctl start [LISTENER_NAME]

เปิด database ขึ้นมาเป็น standby

STARTUP NOMOUNT;

ALTER DATABASE MOUNT STANDBY DATABASE;
Opening the database at DC Site as a Standby

ถึงตรงนี้สามารถทดสอบ Sync กับ DR — Primary ได้ค่ะ

--Check switchover status, there should be a gap between both side's logs
SELECT SWITCHOVER_STATUS FROM V$DATABASE;

--View log applied sequence before syncing
SELECT SEQUENCE# ,TO_CHAR(FIRST_TIME,'DD-MON-YYYY HH24:MI:SS') "LOG APPLIED TIME"
FROM V$LOG_HISTORY
WHERE FIRST_TIME=(SELECT MAX(FIRST_TIME) FROM V$LOG_HISTORY);

--Sync
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;

--View log applied after syncing
SELECT SEQUENCE# ,TO_CHAR(FIRST_TIME,'DD-MON-YYYY HH24:MI:SS') "LOG APPLIED TIME"
FROM V$LOG_HISTORY
WHERE FIRST_TIME=(SELECT MAX(FIRST_TIME) FROM V$LOG_HISTORY);
Syncing new standby (at DC) with new primary at (DR)

5. [DR — Primary] รัน post-patch command

cd $ORACLE_HOME/OPatch
./datapatch -verbose

หลังจากนั้นก็ switchover ให้ DC เป็น Primary เหมือนเดิมก็เป็นอันจบค่ะ พวกโฟลเดอร์ทั้งหลายที่ unzip ออกมาที่ /u01/software หรือไฟล์ซิปที่ backup OPatch และ $ORACLE_HOME ก็สามารถลบได้ถ้าทดสอบแล้วไม่มีปัญหาอะไรให้ต้อง rollback

--With DG Broker
dgmgrl user/password

SWITCHOVER TO DESTINATION_DB_NAME
--Without DG Broker
---At DR
ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN;
SHUTDOWN IMMEDIATE;
STARTUP NOMOUNT;
ALTER DATABASE MOUNT STANDBY DATABASE;

---At DC
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
SHUTDOWN IMMEDIATE;
STARTUP;

---At DR
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;

หากต้อง rollback ก็กลับไปที่โฟลเดอร์ที่พวกเรารัน opatch apply แล้วสั่ง opatch rollback ได้ค่ะ

#rollback OJVM Patch
cd "/u01/software/34786990/"
opatch rollback -id 34786990 -silent

#rollback RU Patch
cd "/u01/software/34765931/"
opatch rollback -id 34765931 -silent

— แต่เนื่องจากของเรามี database UAT อีกเครื่องที่ DR และด้วยอะไรหลาย ๆ อย่างทำให้ไม่สะดวก apply patch ที่ DR เราจึง switchover กลับไป DC แล้วรัน data patch ที่นั่นแทนค่ะ

[DC — Primary] หากต้องการ apply patch เพิ่มก็ทำซ้ำข้อที่ 2–5 ได้เลยค่ะ

ผลลัพธ์สุดท้ายของเราที่ Patch 2 ตัว (RE & OJVM) จะออกมาหน้าตาแบบนี้

Result after patching at DC
Result after patching at DR

จบกันไปแล้วสำหรับการ patch database แบบ Data Guard environment ค่ะ ไว้คราวหน้าได้ทำอะไรสนุก ๆ จะแวะเวียนมาแบ่งปันใหม่นะคะ! หากสนใจงาน DBA ไม่ว่าจะเป็น services หรือมาร่วมงานกับเราก็ติดต่อมาได้ตามช่องทางด้านล่างนี้เลยนะคะ ขอให้ทุกคนโชคดีค่ะ (*^▽^*)(*^▽^*)

Webpage | Facebook | Line | LinkedIn

DBA Job Description

--

--