رفع خطای 978 در SQL Server Always On: دیتابیس غیرقابل دسترس در Availability Group
خطای 978 در SQL Server که با شرح “Database participating in availability group is not accessible” نمایش داده میشود، نشاندهنده یک مشکل حیاتی در پایداری و دسترسی به دیتابیسها در محیطهای SQL Server Always On Availability Groups (AG) است. این خطا به طور خاص به زمانی اشاره دارد که یک دیتابیس، با وجود اینکه جزئی از یک گروه دسترسی (Availability Group) است، به هر دلیلی قابل دسترسی نبوده یا در وضعیت نامناسبی قرار دارد. بروز این خطا میتواند منجر به اختلال در عملیات تجاری، از دست رفتن دسترسی به دادهها و عدم تحقق اهداف RPO/RTO (Recovery Point Objective/Recovery Time Objective) شود. درک عمیق علتهای این مشکل و داشتن یک رویکرد سیستماتیک برای رفع آن برای هر مدیر دیتابیس (DBA) که با Always On کار میکند، ضروری است. این مقاله به بررسی جامع دلایل، سناریوهای رایج و روشهای گام به گام رفع خطای 978 میپردازد.
توضیحات کلی درباره ارور 978 در SQL Server Always On
هنگامی که خطای 978 رخ میدهد، SQL Server گزارش میدهد که یک دیتابیس که قرار است در یک Availability Group به طور فعال در دسترس باشد، در حال حاضر قابل دسترسی نیست. این وضعیت میتواند هم در کپی اولیه (Primary Replica) و هم در کپیهای ثانویه (Secondary Replicas) رخ دهد و پیامدهای متفاوتی دارد. در کپی اولیه، عدم دسترسی به دیتابیس به معنای توقف کامل عملیات خواندن و نوشتن برای آن دیتابیس است که منجر به از کار افتادن سرویسها میشود. در کپیهای ثانویه، این خطا اغلب به مشکلات همگامسازی، عدم توانایی در بازیابی یا اعمال تراکنشها (redo) یا مشکلات دیگری اشاره دارد که مانع از آماده شدن دیتابیس برای عملیات خواندن یا تبدیل شدن به کپی اولیه در صورت Failover میشود. این خطا بسیار جدی است زیرا سلامت کلی و پایداری راهکار High Availability (HA) و Disaster Recovery (DR) شما را زیر سوال میبرد و نیازمند بررسی فوری است.
دلایل اصلی بروز خطای 978: عدم دسترسی به دیتابیس در Availability Group
خطای 978 میتواند ناشی از طیف وسیعی از مشکلات باشد که بیشتر آنها به وضعیت سلامت دیتابیس، همگامسازی بین رپلیکاها، یا زیرساختهای مرتبط با SQL Server Always On مربوط میشوند. شناسایی دقیق علت ریشهای برای رفع موثر مشکل حیاتی است. در ادامه به بررسی مهمترین دلایل میپردازیم:
1. مشکلات همگامسازی و انتقال داده (Data Movement Issues)
یکی از شایعترین دلایل، اختلال در فرآیند همگامسازی لاگ تراکنشها بین کپی اولیه و کپیهای ثانویه است. این مشکل میتواند به دلایل زیر رخ دهد:
- پایین بودن عملکرد I/O در رپلیکای ثانویه: اگر دیسکهای رپلیکای ثانویه قادر به پردازش و اعمال لاگهای تراکنش با سرعت کافی نباشند، صف بازخوانی (Redo Queue) انباشته شده و دیتابیس در وضعیت غیرقابل دسترسی قرار میگیرد.
- مشکلات شبکه: تأخیر بالا، قطع شدن ارتباط یا پهنای باند ناکافی بین رپلیکاها میتواند مانع از ارسال و دریافت به موقع لاگها شود و منجر به عدم همگامسازی و بروز خطا گردد.
- پایین بودن عملکرد CPU یا حافظه در رپلیکای ثانویه: پردازش لاگها و بهروزرسانی دیتابیس در کپی ثانویه نیاز به منابع سیستمی دارد. کمبود این منابع میتواند باعث عقب ماندن و بروز خطا شود.
- توقف دستی یا خودکار انتقال داده: گاهی اوقات انتقال داده (Data Movement) به صورت دستی یا به دلیل بروز یک خطای بحرانی در AG به حالت “PAUSED” در میآید که این امر منجر به عدم دسترسی دیتابیس میشود.
2. وضعیت نامناسب دیتابیس (Database State)
دیتابیس ممکن است به دلایل مختلفی در وضعیتهایی غیر از “ONLINE” قرار گیرد که منجر به خطای 978 میشود:
- وضعیت RESTORING/RECOVERING: اگر دیتابیس در حال بازیابی از بکآپ یا در حال تکمیل فرآیند Recovery پس از راهاندازی SQL Server باشد، ممکن است در Always On به عنوان غیرقابل دسترس شناسایی شود.
- وضعیت SUSPECT یا OFFLINE: خرابی دیتابیس، مشکلات فایلهای دادهای یا لاگ، یا آسیب دیدگی فیزیکی یا منطقی میتواند دیتابیس را به وضعیت SUSPECT یا OFFLINE ببرد که به معنای عدم دسترسی کامل است.
- عدم موفقیت Failover: در سناریوی Failover، اگر دیتابیس نتواند به درستی در کپی جدید اولیه آنلاین شود، این خطا رخ میدهد.
3. مشکلات مجوزها (Permissions Issues)
حساب سرویس SQL Server (SQL Server Service Account) نیاز به مجوزهای کافی برای دسترسی به فایلهای داده و لاگ دیتابیس دارد. اگر این مجوزها تغییر کرده یا به درستی تنظیم نشده باشند، SQL Server نمیتواند دیتابیس را به درستی mount کند یا به آن دسترسی داشته باشد، حتی اگر دیتابیس در Availability Group باشد.
4. کمبود منابع سیستمی (Resource Exhaustion)
کمبود فضای دیسک (Disk Space) برای فایلهای داده یا لاگ تراکنش (به ویژه در رپلیکاهای ثانویه که ممکن است به فضای بیشتری برای نگهداری لاگها نیاز داشته باشند)، یا فشار شدید بر منابع CPU و RAM میتواند منجر به عدم پایداری دیتابیس و بروز این خطا شود.
5. خرابی دیتابیس (Database Corruption)
خرابی فایلهای داده یا لاگ تراکنش میتواند باعث شود SQL Server نتواند دیتابیس را به درستی پردازش کند، حتی اگر دیتابیس در AG ثبت شده باشد. این خرابیها میتوانند منجر به وضعیت SUSPECT یا عدم دسترسی مستقیم شوند.
راهکارهای عملی برای رفع خطای 978 در SQL Server Always On
رفع خطای 978 نیازمند یک رویکرد سیستماتیک و گام به گام است. برای شناسایی و رفع ریشه مشکل، باید اطلاعات کافی از وضعیت کلی AG و دیتابیسهای مرتبط جمعآوری شود.
مرحله 1: بررسی وضعیت کلی Availability Group
اولین گام، بررسی سلامت عمومی Availability Group و رپلیکاهای آن است. این کار را میتوان از طریق SQL Server Management Studio (SSMS) و یا با استفاده از DMVهای SQL Server انجام داد.
- بررسی از طریق SSMS: به بخش Always On High Availability در Object Explorer بروید و داشبورد Availability Group را بررسی کنید. وضعیت سلامت (Health) و همگامسازی (Synchronization) را برای تمامی رپلیکاها و دیتابیسها مشاهده کنید. به دنبال هر گونه علامت هشدار یا خطای قرمز باشید.
- بررسی از طریق SQL Query: از Query زیر برای به دست آوردن اطلاعات دقیقتر در مورد وضعیت همگامسازی رپلیکاها و دیتابیسها استفاده کنید. این کوئری اطلاعاتی مانند سلامت همگامسازی، وضعیت همگامسازی، حجم صف بازخوانی (Redo Queue) و حجم صف ارسال لاگ (Log Send Queue) را ارائه میدهد.
SELECT
ag.name AS 'Availability Group Name',
dr.replica_server_name AS 'Replica Server Name',
drs.synchronization_health_desc AS 'Synchronization Health',
drs.synchronization_state_desc AS 'Synchronization State',
drs.redo_queue_size AS 'Redo Queue Size (KB)',
drs.log_send_queue_size AS 'Log Send Queue Size (KB)',
drs.is_local AS 'Is Local Replica'
FROM
sys.availability_groups ag
JOIN
sys.dm_hadr_availability_replica_states ars ON ag.group_id = ars.group_id
JOIN
sys.dm_hadr_database_replica_states drs ON ars.replica_id = drs.replica_id
JOIN
sys.availability_replicas dr ON drs.replica_id = dr.replica_id
ORDER BY
ag.name, dr.replica_server_name;
در این کوئری، ستونهای Synchronization Health
و Synchronization State
بسیار مهم هستند. به دنبال وضعیتهایی مانند NOT_HEALTHY
یا NOT SYNCHRONIZING
باشید. همچنین، مقادیر بالای Redo Queue Size
یا Log Send Queue Size
نشاندهنده عقبماندگی در همگامسازی هستند.
مرحله 2: بررسی وضعیت دیتابیسهای خاص و لاگ خطای SQL Server
پس از بررسی کلی، بر دیتابیسهایی که خطای 978 را تجربه میکنند، تمرکز کنید. لاگ خطای SQL Server (SQL Server Error Log) در هر رپلیکا، منبع ارزشمندی برای یافتن علتهای ریشهای است. به دنبال پیامهای خطا یا هشدار مرتبط با دیتابیس مورد نظر باشید.
- بررسی وضعیت دیتابیس: با استفاده از کوئری زیر، وضعیت دقیق دیتابیس مورد نظر را بررسی کنید.
SELECT
name AS 'Database Name',
state_desc AS 'Database State',
is_in_standby AS 'Is In Standby',
is_read_only AS 'Is Read Only',
is_supplemental_logging_enabled AS 'Is Supplemental Logging Enabled'
FROM
sys.databases
WHERE
name = 'YourDatabaseName'; -- نام دیتابیس خود را اینجا جایگزین کنید
اگر state_desc
وضعیتهایی مانند RESTORING
، RECOVERING
، OFFLINE
یا SUSPECT
را نشان میدهد، شما دلیل عدم دسترسی را پیدا کردهاید و باید برای رفع آن اقدام کنید.
- بررسی فضای دیسک: مطمئن شوید که فضای دیسک کافی در تمامی رپلیکاها، به ویژه برای فایلهای داده و لاگ دیتابیس وجود دارد. پر شدن دیسک میتواند منجر به وضعیتهای SUSPECT یا OFFLINE شود.
مرحله 3: بررسی و ازسرگیری انتقال داده (Data Movement)
اگر در بررسیهای اولیه مشخص شد که انتقال داده متوقف شده است، باید آن را از سر بگیرید. این اتفاق معمولاً در رپلیکاهای ثانویه رخ میدهد.
ALTER DATABASE [YourDatabaseName] SET HADR RESUME;
این دستور را بر روی رپلیکایی که انتقال داده در آن متوقف شده است، اجرا کنید. پس از اجرای دستور، وضعیت همگامسازی را مجدداً بررسی کنید.
مرحله 4: بررسی وضعیت شبکه و فایروال
مشکلات شبکه بین رپلیکاها میتواند باعث بروز خطای 978 شود. مطمئن شوید که:
- ارتباط شبکه برقرار است: از دستور
ping
برای تست ارتباط بین سرورها استفاده کنید. - پورتهای لازم باز هستند: پورتهای Listener AG (به طور پیشفرض 1433) و پورت EndPoint AG (به طور پیشفرض 5022) باید در فایروال سیستم عامل و فایروالهای شبکه باز باشند.
- تأخیر شبکه (Network Latency) قابل قبول است: تأخیر بالا میتواند بر همگامسازی تأثیر منفی بگذارد.
مرحله 5: بررسی مجوزهای سرویس SQL Server
مطمئن شوید که حساب سرویس SQL Server دارای مجوزهای کافی (Full Control) بر روی پوشههای حاوی فایلهای داده (MDF) و لاگ (LDF) دیتابیس است. همچنین، اگر فایلهای دیتابیس در اشتراکهای شبکه (Network Shares) قرار دارند (که کمتر رایج است)، حساب سرویس باید به آن اشتراکها نیز دسترسی داشته باشد.
مرحله 6: اقدامات پیشرفته و رفع مشکلات پیچیده
اگر مراحل بالا به حل مشکل منجر نشد، باید به سراغ اقدامات پیشرفتهتر بروید:
- Force Failover (با احتیاط!): اگر کپی اولیه به طور کامل از کار افتاده و دیتابیس در آن غیرقابل دسترسی است، میتوانید یک Forced Failover را به یکی از کپیهای ثانویه انجام دهید. توجه داشته باشید که این کار میتواند منجر به از دست رفتن داده شود (Data Loss) اگر رپلیکای هدف کاملاً همگام نباشد. پس از Failover، دیتابیس باید در رپلیکای جدید آنلاین شود.
- حذف و اضافه مجدد دیتابیس به AG: اگر فقط یک دیتابیس خاص به طور مداوم مشکل دارد و راهکارهای دیگر کارساز نیستند، میتوانید آن را از Availability Group حذف کرده و سپس مجدداً اضافه کنید. این فرآیند شامل بکآپگیری کامل، بکآپ لاگ، بازیابی با گزینه NORECOVERY در رپلیکای ثانویه و سپس پیوستن به AG است.
- بررسی خرابی دیتابیس (Corruption): اگر دیتابیس در وضعیت SUSPECT قرار دارد، باید با استفاده از دستور
DBCC CHECKDB
به بررسی و رفع خرابی دیتابیس بپردازید. این کار میتواند زمانبر و پیچیده باشد و ممکن است نیاز به بازیابی از بکآپ داشته باشد. - راهاندازی مجدد سرویس SQL Server: در برخی موارد، راهاندازی مجدد سرویس SQL Server در رپلیکای مشکلدار میتواند مسائل موقتی را حل کند. این کار را به عنوان آخرین چاره و با برنامهریزی قبلی انجام دهید.
با پیروی از این مراحل و بررسی دقیق لاگها و وضعیتهای سیستمی، میتوانید به طور موثر خطای 978 را در SQL Server Always On شناسایی و رفع کنید و از پایداری و دسترسی دیتابیسهای خود اطمینان حاصل نمایید. هر مرحله باید با دقت و با در نظر گرفتن تأثیر آن بر محیط تولید انجام شود.