可以使用以下两个方法来查询阻塞会话的语句和被阻塞的语句:
-
使用系统视图/表:可以查询系统视图/表,如v$session、v$lock和v$transaction等,以获取有关正在运行的会话和锁定信息。例如,使用v$session视图来查看当前活动的会话和其状态,使用v$lock视图来查看所有加锁资源的信息。
-
使用Oracle Trace功能:可以使用Oracle Trace功能来跟踪正在执行的SQL语句并记录它们的执行计划和统计数据。通过分析跟踪文件,可以确定哪些语句是阻塞会话的原因以及被阻塞的语句。可以使用DBMS_MONITOR包中的TRACE_ENABLE和TRACE_DISABLE存储过程来启用或停用跟踪功能。
更详细的回复
查询阻塞会话的语句与被阻塞的语句通常需要执行以下步骤:
- 通过以下查询获取当前活动的会话 ID 以及它们正在执行的语句:
SELECT s.session_id, s.login_name, t.text
FROM sys.dm_exec_sessions s
CROSS APPLY sys.dm_exec_sql_text(s.most_recent_sql_handle) AS t
WHERE s.status = 'running'
- 确定哪些会话是阻塞的。通过以下查询找出所有阻塞的会话的 ID 以及它们在等待的资源类型和名称:
SELECT blocking_session_id, wait_type, resource_description
FROM sys.dm_exec_requests
WHERE blocking_session_id <> 0
- 对于每个阻塞的会话,找到阻塞它的语句。通过以下查询找出与特定会话相关的 SQL 语句:
SELECT text
FROM sys.dm_exec_sql_text(sql_handle)
WHERE statement_start_offset =
(
SELECT MAX(statement_start_offset)
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle)
WHERE session_id = <blocking_session_id>
)
- 找到被阻塞的语句。对于每个被阻塞的会话,可以使用与第三步相同的查询来查找其语句。
以下是一个示例代码,该代码将上述步骤组合在一起,并获取当前所有阻塞会话及其相关的 SQL 语句:
SELECT
blocking.session_id AS blocking_session_id,
blocked.session_id AS blocked_session_id,
blocked.login_name AS blocked_login_name,
blocked.host_name AS blocked_host_name,
blocked.program_name AS blocked_program_name,
blocked.status AS blocked_status,
blocking.wait_type AS wait_type,
blocking.resource_description AS resource_description,
blocking.text AS blocking_text,
blocked.text AS blocked_text
FROM sys.dm_exec_requests AS blocking
JOIN sys.dm_exec_requests AS blocked ON blocking.blocking_session_id = blocked.session_id
CROSS APPLY (
SELECT text FROM sys.dm_exec_sql_text(blocking.sql_handle)
) blocking
CROSS APPLY (
SELECT text FROM sys.dm_exec_sql_text(blocked.sql_handle)
) blocked
WHERE blocking.blocking_session_id <> 0;