مقدمه:
از مشکلات بزرگ در پایگاه داده ها، session های غیرفعال می باشند که نه تنها کاری انجام نمی دهند بلکه منابع پایگاه داده را درگیر کرده و به آن بر نمی گردانند. این مشکل هنگامی پر رنگ خواهد شد که تعداد این session ها زیاد بشوند و پایگاه داده دچار کمبود منابع شود.
سناریوهای حذف seesion های بلااستفاده از پایگاه داده اوراکل
در پایگاه داده اوراکل برای رفع این مشکل چند راهکار وجود دارد که در ادامه به برخی از آنها اشاره می شود.
در ابتدا باید به این نکته اشاره کرد که Inactive Session ها به دو دسته زیر تقسیم می شوند:
Dead Connection : ارتباطی که از سمت کاربر یا سامانه ارتباطی ندارد.
Idle Connection : ارتباط خود را حفظ کرده اما در این ارتباط فعالیتی صورت نمی گیرد.
حذف کردن Dead Connection با استفاده از SQLNET.ora :
با تنظیم پارامتر زیر در فایل Sqlnet.ora می توان از نوع connection ها را حذف کرد.
SQLNET.EXPIRE_TIME=minutes
این تنظیم را در سمت client انجام دهید
حذف کردن Idle Connection ها با استفاده از profile :
ابتدا پارامتر زیر را تنظیم می کنیم
alter system set resource_limit=true scope=both;
پارامترهای زیر را بر روی Profile مورد نظر اعمال می کنیم .
alter profile customers_profiles limit idle_time 30;
استفاده از Job ها:
در این روش ما اسکریپت نویسی خواهیم کرد و مزیت این روش انعطاف پذیری بیشتری می باشد که به ما می دهد. در این روش می توان علاوه بر اینکه مشخص کرد فقط کاربرهای محدودیت برایشان این اتفاق بیفتد می توان دیگر موارد مانند ماشینی که از روی آن ارتباط برقرار شده و …. را هم به عنوان شرط اعمال کرد.
به مثال زیر توجه کنید.
CONN sys@pdb1 as sysdba
CREATE USER admin_tasks_user IDENTIFIED BY MyPassword1;
GRANT ALTER SYSTEM TO admin_tasks_user;
GRANT SELECT ON v_$session TO admin_tasks_user;
ALTER USER admin_tasks_user ACCOUNT LOCK;
CONN sys@pdb1 as sysdba
CREATE OR REPLACE PROCEDURE admin_tasks_user.kill_old_report_sessions AS
BEGIN
FOR cur_rec IN (select ‘alter system kill session ”’ || sid || ‘,’ || serial# || ”” AS ddl
from v$session
where LOWER(module) = ‘financial reports’
and username = ‘REPORTS_USER’
and logon_time < SYSDATE-(1/24) ) LOOP
BEGIN EXECUTE IMMEDIATE cur_rec.ddl;
EXCEPTION
WHEN OTHERS THEN
— You probably need to log this error properly here.
— I will just re-raise it.
RAISE;
END;
END LOOP;
END;
/
GRANT EXECUTE ON admin_tasks_user.kill_old_report_sessions TO test;
بعد از ساخت sp مورد نظر، برای اجرای آن، job می سازیم.
CONN test/test@pdb1
EXEC admin_tasks_user.kill_old_report_sessions;
BEGIN DBMS_SCHEDULER.create_job
( job_name => ‘test.kill_old_report_sessions_job’,
comments => ‘Kill old reports if they have been running for longer than 1 hour.’,
job_type => ‘PLSQL_BLOCK’,
job_action => ‘BEGIN admin_tasks_user.kill_old_report_sessions; END;’,
start_date => SYSTIMESTAMP,
repeat_interval => ‘freq=hourly; byminute=0,15,30,45; bysecond=0;’,
enabled => TRUE);
END;
/