
اگر مدیر پایگاه داده Oracle باشید، احتمالاً بارها برایتان پیش آمده که بخواهید بدانید همین الان چه Queryهایی در دیتابیس در حال اجرا هستند. این بررسی هنگام کند شدن دیتابیس، شناسایی Queryهای طولانی، پیدا کردن Sessionهای فعال و تشخیص Lock بسیار کاربردی است.
در این مقاله آموزش اوراکل، دستورات اصلی برای مشاهده SQLهای در حال اجرا در Oracle را بررسی میکنیم.
گاهی یک Session در Oracle باعث ایجاد Lock، اجرای SQL سنگین، مصرف منابع یا متوقف شدن عملیات سایر کاربران میشود. در این شرایط میتوان Session را با دستورهای مدیریتی Oracle قطع کرد.
پیشنهاد می کنم این مقاله زیر رو حتما مطالعه کنی.
در این مقاله شما می خوانید
مشاهده Queryهای در حال اجرا در Oracle
برای مشاهده Queryهای فعال، باید اطلاعات Sessionها را از V$SESSION دریافت کرده و آن را به V$SQL متصل کنیم:
SELECT
s.sid,
s.serial#,
s.username,
s.machine,
s.program,
s.module,
s.sql_id,
s.last_call_et AS elapsed_sec,
s.event,
s.blocking_session,
q.sql_fulltext
FROM v$session s
LEFT JOIN v$sql q
ON q.sql_id = s.sql_id
AND q.child_number = s.sql_child_number
WHERE s.status = 'ACTIVE'
AND s.username IS NOT NULL
AND s.sid <> SYS_CONTEXT('USERENV', 'SID')
ORDER BY s.last_call_et DESC;
این دستور اطلاعات مهم زیر را نمایش میدهد:
SIDوSERIAL#: شناسه SessionUSERNAME: نام کاربر دیتابیسSQL_ID: شناسه Query در OracleSQL_FULLTEXT: متن کامل دستور SQLELAPSED_SEC: مدتزمان اجرای Call فعلیEVENT: رویدادی که Session منتظر آن استBLOCKING_SESSION: شناسه Session مسدودکننده
نکته مهم این است که ACTIVE بودن Session همیشه به معنی مصرف CPU نیست. ممکن است Session به علت Lock، عملیات ورودی و خروجی یا رویداد دیگری در حالت انتظار باشد.
مشاهده Query یک Session مشخص در Oracle
اگر SID مربوط به Session را میدانید، با دستور زیر میتوانید Query همان Session را مشاهده کنید:
SELECT
s.sid,
s.serial#,
s.status,
s.sql_id,
s.event,
q.sql_fulltext
FROM v$session s
LEFT JOIN v$sql q
ON q.sql_id = s.sql_id
AND q.child_number = s.sql_child_number
WHERE s.sid = 123;
بهجای عدد ۱۲۳، مقدار SID موردنظر را قرار دهید.
این دستور زمانی مفید است که یک Session خاص باعث کندی دیتابیس شده یا مصرف منابع آن بالا باشد.
مشاهده آخرین Query اجراشده در Oracle
گاهی Session در وضعیت INACTIVE قرار دارد و Query فعالی ندارد. در چنین شرایطی میتوانید با استفاده از PREV_SQL_ID آخرین دستور اجراشده توسط آن Session را پیدا کنید:
SELECT
s.sid,
s.serial#,
s.username,
s.prev_sql_id,
q.sql_fulltext
FROM v$session s
LEFT JOIN v$sql q
ON q.sql_id = s.prev_sql_id
AND q.child_number = s.prev_child_number
WHERE s.sid = 123;
تفاوت این دو ستون بهصورت خلاصه:
SQL_ID: دستور SQL فعلی SessionPREV_SQL_ID: آخرین دستور SQL اجراشده توسط Session
مشاهده Sessionهای Block شده در Oracle
یکی از دلایل رایج کند شدن Queryها، وجود Lock و مسدود شدن Session توسط Session دیگری است. برای مشاهده Sessionهای Block شده از دستور زیر استفاده کنید:
SELECT
sid,
serial#,
username,
sql_id,
event,
blocking_instance,
blocking_session,
seconds_in_wait
FROM v$session
WHERE blocking_session IS NOT NULL
ORDER BY seconds_in_wait DESC;
اگر ستون BLOCKING_SESSION دارای مقدار باشد، یعنی Session موردنظر توسط Session دیگری مسدود شده است.
مشاهده درصد پیشرفت Queryهای طولانی در Oracle
برای مشاهده پیشرفت برخی عملیاتهای طولانی، مانند Scanهای بزرگ، Backup یا Restore، میتوانید از V$SESSION_LONGOPS استفاده کنید:
SELECT
sid,
serial#,
opname,
ROUND(sofar * 100 / NULLIF(totalwork, 0), 2) AS progress_pct,
elapsed_seconds,
time_remaining,
message
FROM v$session_longops
WHERE totalwork > ۰
AND sofar < totalwork
ORDER BY start_time DESC;
توجه داشته باشید که همه Queryها در V$SESSION_LONGOPS ثبت نمیشوند. این View فقط عملیاتی را نمایش میدهد که Oracle قابلیت ثبت پیشرفت آنها را دارد.
مشاهده Queryهای در حال اجرا در Oracle RAC
در محیط Oracle RAC باید بهجای Viewهای V$ از GV$ استفاده کنید تا اطلاعات تمام Instanceها نمایش داده شود:
SELECT
s.inst_id,
s.sid,
s.serial#,
s.username,
s.machine,
s.program,
s.sql_id,
s.last_call_et AS elapsed_sec,
s.event,
s.blocking_instance,
s.blocking_session,
q.sql_fulltext
FROM gv$session s
LEFT JOIN gv$sql q
ON q.inst_id = s.inst_id
AND q.sql_id = s.sql_id
AND q.child_number = s.sql_child_number
WHERE s.status = 'ACTIVE'
AND s.username IS NOT NULL
ORDER BY s.inst_id, s.last_call_et DESC;
در Oracle RAC هر Session با ترکیب زیر بهصورت دقیق شناسایی میشود:
INST_ID + SID + SERIAL#
دسترسی لازم برای مشاهده Queryهای فعال
کاربری که این دستورات را اجرا میکند باید مجوز مشاهده Viewهای سیستمی را داشته باشد:
GRANT SELECT ON v_$session TO monitor_user;
GRANT SELECT ON v_$sql TO monitor_user;
GRANT SELECT ON v_$session_longops TO monitor_user;
در محیط عملیاتی بهتر است فقط دسترسیهای موردنیاز به کاربر مانیتورینگ داده شود و از اعطای مجوزهای گسترده خودداری کنید.
سوالات متداول درباره مشاهده Queryهای در حال اجرا در Oracle
برای مشاهده Queryهای در حال اجرا باید اطلاعات Sessionهای فعال را از V$SESSION دریافت و با استفاده از SQL_ID به V$SQL متصل کنیم.
در V$SESSION وضعیت Session، نام کاربر، مدت اجرا و اطلاعات انتظار نگهداری میشود و V$SQL متن کامل دستور SQL را در اختیار ما قرار میدهد.
Sessionهایی با وضعیت ACTIVE در حال اجرای دستور یا منتظر یک رویداد مانند Lock یا I/O هستند.
برای شناسایی Queryهای طولانی میتوان Sessionهای فعال را براساس ستون LAST_CALL_ET مرتب کرد. این ستون برای Session فعال، مدتزمان سپریشده از شروع Call جاری را برحسب ثانیه نشان میدهد.
همچنین V$SESSION_LONGOPS درصد پیشرفت و زمان تقریبی باقیمانده برخی عملیاتهای طولانی مانند Full Scan، Backup و Restore را نمایش میدهد.
البته تمام Queryهای طولانی الزاماً در این View ثبت نمیشوند.
در V$SESSION ستون BLOCKING_SESSION شناسه Session مسدودکننده را نشان میدهد.
اگر این ستون دارای مقدار باشد، Session موردنظر معمولاً به دلیل یک Lock منتظر Session دیگری مانده است. ستونهای EVENT، WAIT_CLASS و SECONDS_IN_WAIT نیز نوع انتظار و مدتزمان آن را مشخص میکنند.
در محیط Oracle RAC باید BLOCKING_INSTANCE را هم بررسی کرد تا Instance مربوط به Session مسدودکننده مشخص شود.
ستون SQL_ID شناسه دستور SQL فعلی Session را نشان میدهد، اما PREV_SQL_ID مربوط به آخرین دستور اجراشده در همان Session است.
زمانی که Session فعال است معمولاً برای مشاهده Query جاری از SQL_ID استفاده میشود.
اگر Session در وضعیت INACTIVE باشد یا اجرای دستور به پایان رسیده باشد، PREV_SQL_ID برای پیدا کردن آخرین Query اجراشده کاربرد دارد.
جمعبندی
برای مشاهده Queryهای در حال اجرا در Oracle، بهترین روش استفاده همزمان از V$SESSION و V$SQL است.
با این روش میتوانید متن SQL، کاربر اجراکننده، مدت اجرای Query، وضعیت انتظار و Session مسدودکننده را مشاهده کنید.
در محیطهای Single Instance از V$SESSION و V$SQL و در محیط Oracle RAC از GV$SESSION و GV$SQL استفاده کنید.
همچنین برای بررسی Lockها میتوانید ستون BLOCKING_SESSION و برای مشاهده پیشرفت بعضی عملیاتهای طولانی از V$SESSION_LONGOPS کمک بگیرید.
سؤالی درباره این مقاله داری؟
اگر نکتهای در این مقاله برات مبهم بود یا خواستی بیشتر بدونی، همین حالا برام بنویس تا دقیق و صمیمی پاسخت رو بدم — مثل یه گفتوگوی واقعی 💬
برو به صفحه پرسش و پاسخ
دیدگاهتان را بنویسید