我正在尝试查看Oracle数据库中当前正在运行哪些查询。但是,当我尝试使用表v$session
时,出现了一个错误:
这是什么原因?获取正在运行的活动进程的正确方法是什么?
我正在寻找必要的信息,以便能够取消给定用户的查询。让我举个例子:
1)用户在应用程序中执行查询。我们添加评论,以便我们可以“跟踪”该查询:
/* Query-ID-1283849 */ select * from mytable
2)现在,如果用户在查询运行时单击“取消”按钮(假设查询花了很长时间进行响应),我们将允许用户取消该查询,前提是该用户将可能不是sys用户,而是具有只读权限的“普通”用户。
这怎么办?
答案 0 :(得分:3)
在基本数据库级别,您不能杀死单个查询。您杀死单个会话。我从您的问题中推断出,您的特定用例位于应用程序内部,而不是像Sql Developer或Sql Plus这样的工具。
会话杀死可以由具有特殊数据库特权的用户来杀死会话。如果您在一个会话中运行多个查询的应用程序内部,则终止该会话将有效地终止您的应用程序,并要求a)应用程序重新启动或b)优雅地以编程方式处理已删除的会话。
如果您使用的是n层ORM框架来为您处理数据库交互,则可能处于终止会话状态,除了当前正在运行的语句之外,不会对您的应用程序产生任何影响。
应用程序中处理隔离会话和查询的另一种方法是运行多线程应用程序。每个查询都会产生一个新线程,可以杀死该线程而不必杀死会话。
基本上,简短的答案是您只能通过终止查询会话来终止查询。您查看v $ session的方法是正确的,并且对于找到任何Givel sql语句的会话ID都是必要的,您只需要让DBA授予您对v $ session和v $ sql同义词的特权即可。
特定于Sql Developer的更新,基于OP的注释进行澄清:
Sql Developer有一个选项,允许利用线程和多个连接来运行并行查询。该设置位于“工具”>“首选项”>“数据库”>“工作表”中。无论设置如何,当您单击查询取消按钮时,应用程序仍在发送会话终止请求。 GUI通常会正常启动新会话,而最终用户对此并不明智。但是有时情况会变得不正常,GUI会冻结,或者最终您将无法连接,而必须手动重新连接。
要增加复杂性,其行为取决于应用程序使用的驱动程序/客户端。过去,OCI,胖客户端和瘦客户端在杀死请求时表现出不同的行为。实际上,在Sql Developer中,您可以选择强制其使用OCI或胖驱动程序,以便避免某些行为。
我强烈建议您获得查看v $ session的权利并尝试使用它。了解有关Oracle如何管理会话的更多信息很有趣。
我刚刚发现最新版本的Oracle 18c允许杀死会话中的单个查询。我在12c上,所以我没有尝试过。 https://docs.oracle.com/en/database/oracle/oracle-database/18/admin/managing-processes.html#GUID-7D8E5E00-515D-4338-8B86-C2044F6D2957
文档中的相关部分。
5.10.5取消会话中的SQL语句您可以使用ALTER SYSTEM CANCEL SQL语句取消会话中的SQL语句。
您可以取消高负载SQL,而不是终止会话 会话中的声明。取消DML语句时,该语句 回滚。
ALTER SYSTEM CANCEL SQL中需要以下子句 声明:
SID –会话ID
SERIAL-会话序列号
以下子句在ALTER SYSTEM CANCEL SQL中是可选的 声明:
INST_ID –实例ID
SQL_ID – SQL语句的SQL ID
您可以通过查询GV $ SESSION来查看会话的此信息 视图。
以下是取消SQL语句的语法:
ALTER SYSTEM CANCEL SQL'SID,SERIAL,@INST_ID,SQL_ID';