不可终止的 Oracle 会话正在等待“来自客户端的 SQL*Net 消息”事件

2023-12-28

在 Oracle 11gR2 上,我最近遇到了一个非常有趣的情况,涉及阻塞(但空闲!)MERGE挂在 a 上的声明“来自客户端的 SQL*Net 消息”事件,导致后续并发执行MERGE通过以下方式阻止第一个语句的语句“光标:引脚 S 等待 X”事件。在 Oracle Enterprise Manager 中,可以观察到以下情况:

这种情况变得更加严重,因为上述 Session-ID 1204 无法通过以下任一方法终止:

alter system kill session 'sid,serial#';
alter system kill session 'sid,serial#' immediate;

我们的DBA有时能够杀死操作系统进程,但很多时候,整个数据库需要重新启动。幸运的是,到目前为止,仅在测试系统上进行,从未投入生产。

Note:

我知道这可能是一个与这个相当模糊的问题中报告的类似问题:Oracle 更新/插入卡住、DB CPU 为 100%、并发度高、来自客户端的 SQL*Net 等待消息 https://stackoverflow.com/q/14043668/521799。我仍然会再次报告它,因为我有一个清晰的复制路径,我将报告它作为答案。


这似乎是 Oracle 中的一个错误CLOB数据类型用作传递给的值MERGE声明的ON条款。假设这个数据库:

CREATE TABLE t (
  v INT, 
  s VARCHAR2(400 CHAR)
);

使用内联值进行复制

现在,在任何 Oracle 客户端(包括 SQL*Plus、SQL Developer 或 JDBC)中运行以下语句,这有助于非常轻松地重现问题(我使用的是 Oracle 11g XE 11.2.0.2.0):

MERGE INTO t                      
USING (
  SELECT 
    1 v, 
    CAST('abc' AS CLOB) s 
  FROM DUAL
) s 
ON (t.s = s.s) -- Using a CLOB here causes the bug.
WHEN MATCHED THEN UPDATE SET
  t.v = s.v        
WHEN NOT MATCHED THEN INSERT (v, s) 
VALUES (s.v, s.s);

这个例子很愚蠢,而且CLOB因“意外”而被束缚在这里。尽管如此,这样的语句不应在 Oracle 中创建僵尸会话,但它确实存在。我在 SQL*Plus 中运行上述语句 3 次,然后运行这个...

SELECT 
  s.sid,
  s.serial#,
  s.sql_id,
  s.event,
  s.blocking_session,
  q.sql_text
FROM v$session s
JOIN v$sql q
ON s.sql_id = q.sql_id
WHERE s.username = 'TEST'
AND UPPER(TRIM(q.sql_text)) LIKE 'MERGE%';

...我得到:

sid serial# sql_id          event                       blocking_session
9   3       82a2k4sqzy1jq   cursor: pin S wait on X     92
49  89      82a2k4sqzy1jq   cursor: pin S wait on X     92
92  13      82a2k4sqzy1jq   db file sequential read     

请注意报告的事件有何不同(“数据库文件顺序读取”)来自原始事件(“来自客户端的 SQL*Net 消息”),它使用了绑定变量

使用绑定值进行复制

var v_s varchar2(50)
exec :v_s := 'abc'

MERGE INTO t                      
USING (
  SELECT 
    1 v, 
    CAST(:v_s AS CLOB) s 
  FROM DUAL
) s 
ON (t.s = s.s) -- Using a CLOB here causes the bug.
WHEN MATCHED THEN UPDATE SET
  t.v = s.v        
WHEN NOT MATCHED THEN INSERT (v, s) 
VALUES (s.v, s.s);

上述语句在 SQL*Plus 中运行也会产生错误:

sid serial# sql_id          event                           blocking_session
8   1       4w9zuxrumumgj   SQL*Net message from client     
90  7       4w9zuxrumumgj   cursor: pin S wait on X         8
94  21      4w9zuxrumumgj   cursor: pin S wait on X         8

PL/SQL 中无法复制

有趣的是,以下 PL/SQL 语句避免了该错误:

DECLARE
  v_s CLOB := 'abc';
BEGIN
  MERGE INTO t                      
  USING (
    SELECT 
      1 v, 
      CAST(v_s AS CLOB) s 
    FROM DUAL
  ) s 
  ON (t.s = s.s) -- Using a CLOB here causes the bug.
  WHEN MATCHED THEN UPDATE SET
    t.v = s.v        
  WHEN NOT MATCHED THEN INSERT (v, s) 
  VALUES (s.v, s.s);
END;
/

我越来越:

          CAST(v_s AS CLOB) s
          *
ERROR at line 8:
ORA-06550: line 8, column 11:
PL/SQL: ORA-00932: inconsistent datatypes: expected - got CLOB
ORA-06550: line 4, column 7:
PL/SQL: SQL Statement ignored

看起来 PL/SQL 引擎可以保护客户端免受此 SQL 引擎错误的影响。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

不可终止的 Oracle 会话正在等待“来自客户端的 SQL*Net 消息”事件 的相关文章

  • MYSQL插入GB大小的巨大SQL文件

    我正在尝试创建 Wikipedia DB 副本 大约 50GB 但在处理最大的 SQL 文件时遇到问题 我使用 linux split 实用程序将 GB 大小的文件拆分为 300 MB 的块 例如 split d l 50 enwiki 2
  • SQL 层次结构 - 解析给定节点的所有祖先的完整路径

    我有一个由邻接列表描述的层次结构 不一定有单个根元素 但我确实有数据来识别层次结构中的叶 终端 项 所以 一个看起来像这样的层次结构 1 2 4 7 3 5 6 8 9 将通过表格来描述 就像这样 NOTE 我没有能力改变这种格式 id p
  • 将文件存储在文件系统上或在 SQL Server 中存储为 varbinary(MAX)

    我知道 对于将文件作为 blob 存储在数据库中是否是不好的做法存在很多争议 但我只是想了解这对于我的情况是否有意义 我正在创建一个 ASP NET 应用程序 在一家大公司内部使用 用户需要能够将文件附加到系统中的 作业 这些文件通常是 P
  • 在 Microsoft Access 中编写查询,字段描述错误 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 这个问题是由拼写错误或无法再重现的问题引起的 虽然类似的问题可能是on topic help on topic在这里 这个问题的解决方式不
  • 收到警告:空值被聚合或其他 SET 操作消除

    我有这个架构 create table t id int d date insert into t id d values 1 getdate 2 NULL 做的时候 declare mindate date select mindate
  • 如何实现复杂的sql命令

    我在 MySQL 中有一个 sql 表 其中包含以下记录 user dob john 1 10 96 jane 3 4 97 jill 1 8 96 jack 2 9 00 jane 12 14 07 john 1 11 98 这是我要执行
  • 无效号码错误!似乎无法绕过它

    Oracle 10g 数据库 我有一张桌子叫s contact 这个表有一个字段叫做person uid This person uid字段是 varchar2 但包含某些行的有效数字和其他行的无效数字 例如 一行可能有一个person u
  • PostgreSQL 对 string\varchar 的各种清理

    我必须通过以下方式清理一些 varchar 删除特殊字符 例如 来自封闭列表 我已经成功地通过大量使用replace regexp replace来做到这一点 但我正在寻找类似于SQL Server中的东西 删除以下数字但不删除相邻的数字含
  • 在 Postgres 中以周为单位分割间隔

    这是另一个关于日期的 SQL 问题 我正在使用 PHP 和 Postgres 构建一个日历应用程序 它将显示几天 几周甚至几个月的事件 每个事件都有开始日期和结束日期 按范围选择它们不是问题 然而 如果 Postgres 可以在每周的第一天
  • C# 是否可以中断 ThreadPool 内的特定线程?

    假设我已将一个工作项排入队列ThreadPool 但是如果没有要处理的数据 从BlockingQueue 如果队列为空并且队列中不再有工作 那么我必须调用Thread Interrupt方法 如果我想中断阻塞任务 但是如何用 a 做同样的事
  • SQL - 用 varchar 替换 is null 整数

    我正在尝试用新的列替换列varchar如果 select 语句中存在空值 则为字符串 personid ISNULL personid no person 我不想更新它 只是在查询结果中将值显示为 无人 但我收到一条错误消息 将 varch
  • 如何选择集合的第一个元素作为查询的列

    表 t 有两列 a 和 b a是整数 b是集合 我想为每一行选择 a 和集合 b 的第一个值 我试过了 但没用 WITH s a b AS SELECT 1 ff FROM DUAL UNION ALL SELECT 1 ee FROM D
  • 删除超过 2 个月的分区

    我有一个基于日期字段进行分区的表 现在 我必须编写一个过程来删除所有超过 2 个月的分区 即 test date 超过 2 个月 我该怎么做 create table test table test id number test date
  • 将计算列设置为非空时遇到问题

    我在将计算列设置为时遇到问题not null 我想要实现的是C001 C002 等 同时将其设置为not null 我在论坛上读到 这可以通过使用 NULL 值的默认值 0 来实现 E g ISNULL Price Taxes 0 我尝试应
  • SQLAlchemy - 连接表关系上的 order_by

    我正在使用声明式 SQLAlchemy 并且有三个模型 Role Permission and RolePermission 在我的Role模型 我有以下内容 class Role Base name Column u NAME VARCH
  • Oracle使用with子句创建表

    我可以从使用形成的查询创建表吗with clause Sure CREATE TABLE t AS WITH some data AS SELECT 1 as some value FROM dual UNION ALL SELECT 2
  • 带有 CONTAINS 查询的PreparedStatement

    我有一个查询需要连续运行 28000 次 所以我认为使用准备好的语句可能是一个聪明的主意 这是我的查询 String requestWithFirstName SELECT SE ELEMENT ID SE LASTNAME SE FIRS
  • 为列名创建动态选择获取值 - 在 SQL Server 中

    请帮助我创建一个选择 SQL 语句 其中的结果列名称是从原始表中的列值获取的 表名是Device Part 用户可以输入很多DeviceCode其中有许多动态PartTypeName PartTypeName 值为PartInfo 这可能有
  • 如何从 SQL Server 的表中获取列名?

    我想查询一个表的所有列的名称 我发现如何做到这一点 Oracle https stackoverflow com q 452464 419956 MySQL https stackoverflow com q 193780 419956 P
  • 如何获取Oracle中命名事务的名称?

    我想在触发器中使用事务的名称 以便将其写入列中 我尝试了这个 在 SQL Developer 中 set transaction name hello select DBMS TRANSACTION LOCAL TRANSACTION ID

随机推荐