چند وقت پیش با مشکل "wait for a undo record" از دستهبندی Other و حدود ۴۰۰ سشن همزمان در پایگاه داده Oracle مواجه شدم. این مشکل باعث شده بود تعدادی از Undo Segments بدون حرکت باقی بمانند و عملیات عادی دیتابیس مختل شود.
مراحل حل مشکل
ابتدا متوجه شدم که با وجود نمایش تعداد undo segments در ویوی v$rollname، نتیجهای از جستجو با join بر روی ویوی v$transaction حاصل نمیشد. بنابراین، اقدام به ایجاد یک tablespace undo جدید کردم.
در ادامه، متوجه شدم که حدود ۲۸۰٬۰۰۰ extent از undo tablespace قبلی با همان undo segment number یا usn بدون تغییر باقی ماندهاند. این undo segments همچنان فعال بودند و از ویوی v$rollname استخراج شده بودند.
قبل از شروع هرگونه عملیاتی، میتوانید از جستجوی زیر برای بررسی وضعیت undo segments استفاده کنید:
select segment_id,tablespace_name, status, segment_name from dba_rollback_segs where status != 'OFFLINE';
در مشکل پیش آمده برای من، وضعیت Pending Offline باقی مانده بود و هیچ تغییری در تعداد undo segments مشاهده نمیشد. انجام مراحل بالا کمک کرد تا مشکل بهطور کامل رفع شود.
برای رفع این مشکل، مراحل زیر را انجام دادم:
-
ایجاد یک PFILE جدید با پارامترهای زیر:
*.undo_management=manual
*._offline_rollback_segments=(UNDO SEGMENT NAME)
*.undo_tablespace=undo
-
(در اینجا UNDO SEGMENT NAME باید با name در ویوی v$rollname جایگزین شود.)
استارت مجدد دیتابیس در حالت Restrict:
sqlplus / as sysdba
startup restrict pfile='NEW PFILE'
حذف rollback segment مشکلدار و tablespace مرتبط:
drop rollback segment "UNDO SEGMENT NAME";
drop Tablespace undo including contents and datafiles;
-
در صورتی که tablespace undo جدید را قبلاً ایجاد نکردهاید، اینجا میتوانید آن را بسازید و در SPFILE اصلی نیز تغییرات لازم را اعمال کنید.
پیشنهادات برای دیتابیسهای پرکار
در صورت داشتن دیتابیسهای پرترافیک، توصیه میشود از پارامترهای زیر در فایل پیکربندی استفاده کنید تا از درگیری بیشتر UNDO جلوگیری شود:
job_queue_processes=0
همچنین، دیتابیس را در حالت restrict استارت کنید تا بتوانید بدون ایجاد مشکل، عملیات فوق را انجام دهید.