مقدمه:

از مشکلات بزرگ در پایگاه داده ها، 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;

/