سلسله آموزش راه‌اندازی Oracle Data Guard 19c از صفر تا Fast Failover قسمت هفتم reinstate

تا اینجایی که پیش رفتیم، اکثر شرکتها پیش میرن. اما اینجا رو فقط برخی از سازمانها پیش میرن. دلایل زیادی داره. من جمله اینکه دیتابیس اصلی ممکنه از لحاظ performance تحت تاثیر قرار بگیره. چون گارد از نوع sync و در مد high available قرار می گیره. شبکه باید کاملاً پایدار باشه و ... .

حالا بریم سراغ مهمترین هدف این مقاله: fast failover

1. بررسی وضعیت کلی Data Guard

روی یکی از نودها:

dgmgrl sys/oracle@vahiddbdc2
show configuration;

در این مرحله مطمئن شدیم که:

  • vahiddbdc2Primary

  • vahiddbPhysical Standby

  • وضعیت Configuration → SUCCESS

  • Protection Mode → در ابتدا MaxPerformance


2. ساخت سرویس اپلیکیشن روی هر دو دیتابیس (روی PDB و فقط برای PRIMARY)

روی هر دو نود (با نام دیتابیس خودش):

روی vahiddbdc2 (Primary فعلی):

srvctl add service   -db vahiddbdc2   -service APP_SERVICE   -pdb vahidpdb   -role PRIMARY   -policy AUTOMATIC

srvctl start service -db vahiddbdc2 -service APP_SERVICE

روی vahiddb (Standby فعلی):

srvctl add service   -db vahiddb   -service APP_SERVICE   -pdb vahidpdb   -role PRIMARY   -policy AUTOMATIC

روی vahiddb سرویس را دستی start نکردیم؛ چون قرار است فقط زمانی که این دیتابیس نقش PRIMARY گرفت، سرویس به‌صورت خودکار توسط Clusterware/Broker بالا بیاید.


3. بررسی سرویس‌ها در Listener

روی هر نود:

lsnrctl status

روی نود Primary باید ببینی:

Service "APP_SERVICE" ... status READY

و روی Standby سرویس APP_SERVICE نباید READY باشد (مگر این‌که اشتباهی دستی start شده باشد).


4. تنظیم Redo Transport روی SYNC برای Zero Data Loss

در dgmgrl:

EDIT DATABASE vahiddbdc2 SET PROPERTY LogXptMode='SYNC';
EDIT DATABASE vahiddb    SET PROPERTY LogXptMode='SYNC';

5. تغییر Protection Mode به MaxAvailability

در همان dgmgrl:

EDIT CONFIGURATION SET PROTECTION MODE AS MAXAVAILABILITY;

این‌جا دیگه شرط Zero Data Loss برای FSFO فراهم می‌شود، چون:

  • Protection Mode = MAXAVAILABILITY

  • Redo Transport = SYNC


6. فعال‌سازی Fast-Start Failover (FSFO)

در dgmgrl:

ENABLE FAST_START FAILOVER;

و خروجی مهم:

Enabled in Zero Data Loss Mode.
تنظیم میزان threshold
EDIT DATABASE vahiddbdc2 SET PROPERTY FastStartFailoverThreshold = 30;

7. تنظیم tnsnames.ora روی ویندوز (Oracle Client)

برای اینکه سیستم fast failover درست کار کنه، باید یک observer در جایی غیر از خود دو سرور بیاد بالا. من ویندوزی که ماشینهای مجازی هستند رو انتخاب کردم. چون روش دیتابیس نصب نبود، اوراکل کلاینت رو بصورت administrator نصب کردم. در ویندوز، در مسیر:

c:\app\client\Vahid\product\19.0.0\client_1\network\admin\

سه تا entry ساختیم:

vahiddb =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.21)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = vahiddb)
    )
  )

vahiddbdc2 =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.22)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = vahiddbdc2)
    )
  )

APP_SERVICE =
 (DESCRIPTION =
   (ADDRESS_LIST =
     (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.21)(PORT = 1521)) 
     (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.22)(PORT = 1521)) 
   )
   (CONNECT_DATA =
     (SERVICE_NAME = APP_SERVICE)
   )
   (CONNECT_TIMEOUT = 5)
   (RETRY_COUNT = 3)
   (RETRY_DELAY = 5)
   (TRANSPORT_CONNECT_TIMEOUT = 3)
 )

  • vahiddb و vahiddbdc2 → برای اتصال مدیریتی مستقیم به هر دیتابیس (sqlplus, rman, dgmgrl و …).

  • APP_SERVICE → برای برنامه‌ها (Application Connection String).


8. راه‌اندازی Observer روی ویندوز

در ویندوز:

dgmgrl 

connect sys@vahiddb

start observer;

از این لحظه:

  • Observer دائماً Primary را مانیتور می‌کند

  • اگر Primary در مدت زمان Threshold (مثلاً ۳۰ ثانیه) در دسترس نباشد → FSFO انجام می‌شود

  • Standby (vahiddb) به‌صورت خودکار Primary می‌شود

  • بعداً که دیتابیس قدیمی Primary (vahiddbdc2) برگردد، به‌صورت Auto-Reinstate دوباره به‌عنوان Standby وارد مدار می‌شود.

چرا سرویس جداگانه‌ی APP_SERVICE می‌سازیم؟

  • جدا کردن ترافیک اپلیکیشن از ترافیک مدیریتی

    • سرویس‌های پیش‌فرض مثل vahiddb, vahiddbdc2, vahidpdb برای استفاده مستقیم DBA و ابزارهای مدیریتی هستند.

    • با ساختن یک سرویس مستقل (APP_SERVICE) می‌گوییم:
      «هر چیزی که اپلیکیشن است، فقط از این در وارد شود.»

  • اطمینان از اتصال فقط به Primary

    • با گزینه‌ی -role PRIMARY در srvctl add service، Oracle Clusterware تضمین می‌کند که:

      • APP_SERVICE فقط جایی بالا باشد که دیتابیس در نقش PRIMARY است.

      • بعد از Switchover/Failover، سرویس به‌طور خودکار رویPrimary جدید جابه‌جا می‌شود.

    • نتیجه: اپلیکیشن هرگز اشتباهی به Standby متصل نمی‌شود.

  • هماهنگی با Data Guard Broker و FSFO

    • وقتی FSFO انجام می‌شود، فقط نقش دیتابیس عوض نمی‌شود؛
      سرویس‌ها هم باید متناسب با نقش جدید جابه‌جا شوند.

    • استفاده از سرویس Role-Based باعث می‌شود بدون تغییر Connection String، اپلیکیشن همیشه به Primary فعلی وصل شود.

  • آمادگی برای سناریوهای پیچیده‌تر

    • در آینده می‌توانی سرویس‌های مختلف برای read/write، read-only، reporting، batch و … تعریف کنی.

    • همین الگو قابل توسعه است؛ فقط نقش‌ها و Preferred/Available Instanceها تغییر می‌کنند.

چرا کانکشن‌استرینگ APP_SERVICE این‌طوری طراحی شد و در اپلیکیشن‌ها چه چیزهایی «حتماً» باید باشد؟

۱) استفاده از ADDRESS_LIST با هر دو سرور

در APP_SERVICE:

   (ADDRESS_LIST =
     (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.21)(PORT = 1521)) 
     (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.22)(PORT = 1521)) 
   )

  • این یعنی کلاینت می‌داند دو نقطه‌ی اتصال وجود دارد.

  • اگر یکی از نودها کلاً DOWN باشد (یا Listener در دسترس نباشد)، Oracle Client می‌تواند سراغ آدرس بعدی برود.

  • این ساختار، پایه‌ی Client-Side Failover است.

۲) پارامترهای زمانی (این همان «دو مورد» حیاتی برای اپلیکیشن است)

حداقل چیزهایی که برای یک اتصال سالم در محیط FSFO باید در اپلیکیشن‌ها باشد، این دو مورد است:

   (CONNECT_TIMEOUT = 5)
   (TRANSPORT_CONNECT_TIMEOUT = 3)

  • CONNECT_TIMEOUT → حداکثر زمانی که کلاینت صبر می‌کند تا به یک آدرس مشخص وصل شود.

  • TRANSPORT_CONNECT_TIMEOUT → Timeout لایه‌ی TCP قبل از اینکه حتی session نسب شود.

اگر این‌ها را نگذاری:

  • وقتی Primary قدیمی DOWN می‌شود،

  • کلاینت ممکن است مدت طولانی روی آدرس خراب «آویزان» بماند

  • حتی اگر FSFO انجام شده و Primary جدید آماده باشد، کاربر تا مدت زیادی خطا/تایم‌اوت می‌بیند.

به‌همین‌خاطر است که عملاً در برنامه‌های کاربردی باید حتماً حداقل این دو مورد تنظیم شوند؛
چه به‌صورت TNS String در فایل، چه در Connection String داخل کد.

۳) پارامترهای کمکی: RETRY_COUNT و RETRY_DELAY

   (RETRY_COUNT = 3)
   (RETRY_DELAY = 5)

  • RETRY_COUNT → چند بار تلاش مجدد

  • RETRY_DELAY → فاصله بین هر تلاش

این‌ها کمک می‌کند که وقتی یکی از نودها موقتاً قطع است یا در حال Failover است، کلاینت به‌صورت خودکار چند بار تلاش کند قبل از اینکه خطا را به برنامه برگرداند.


۴) توصیه مهم برای مقاله:

  • برای اپلیکیشن‌ها همیشه از APP_SERVICE استفاده کنید، نه vahiddb یا vahiddbdc2.

  • vahiddb و vahiddbdc2 فقط برای مدیریت، مانیتورینگ و تست دستی مناسب‌اند.

  • در محیط‌هایی که FSFO و Role-Based Services فعال هستند، تنظیم Timeoutها (حداقل CONNECT_TIMEOUT و TRANSPORT_CONNECT_TIMEOUT) بخش جدایی‌ناپذیر «طراحی Connection String» است، نه یک گزینه‌ی تزئینی.