ORA-12520 突然出现TNS服务异常无法连接排查思路

AI摘要
本文是一篇Oracle数据库运维知识分享,核心是提供一套完整的SQL脚本,用于诊断和解决数据库会话(连接)打满的问题。文章从监控会话使用率、定位占用者,到安全地终止会话,给出了清晰的操作步骤和常见错误规避方法,旨在帮助DBA或开发者快速处理连接数过载的紧急情况。

一、SHOW PARAMETER 的纯 SQL 等价写法 ✅

1️⃣ 查看 processes

SELECT name, value
FROM v$parameter
WHERE name = 'processes';

2️⃣ 查看 sessions

SELECT name, value
FROM v$parameter
WHERE name = 'sessions';

二、查看当前连接 / 会话使用情况(重点)

当前会话数

SELECT COUNT(*) AS current_sessions
FROM v$session;

按状态统计

SELECT status, COUNT(*)
FROM v$session
GROUP BY status;

三、判断是否“已经打满”(你现在最关心的)

会话使用率

SELECT
  s.cnt AS current_sessions,
  p.value AS max_sessions,
  ROUND(s.cnt / p.value * 100, 2) AS usage_percent
FROM
  (SELECT COUNT(*) cnt FROM v$session) s,
  (SELECT value FROM v$parameter WHERE name = 'sessions') p;

如果 usage_percent > 80%
👉 已经是高危状态


四、找出“谁”把连接打满(非常关键)

按用户

SELECT username, COUNT(*) cnt
FROM v$session
WHERE username IS NOT NULL
GROUP BY username
ORDER BY cnt DESC;

按程序 / 客户端

SELECT program, COUNT(*) cnt
FROM v$session
GROUP BY program
ORDER BY cnt DESC;

👉 一眼就能看到是不是跑批账号 / 定时任务


五、查看长时间占用的会话(可用于止血)

SELECT
  sid,
  serial#,
  username,
  status,
  program,
  last_call_et
FROM v$session
WHERE status = 'ACTIVE'
  AND last_call_et > 1800
ORDER BY last_call_et DESC;

六、杀会话(纯 SQL)

ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;

⚠️ 优先杀:

  • 跑批账号
  • 非核心业务
  • 持续 ACTIVE 的会话

七、Listener / ORA-12520 的判断逻辑(给你一个对照)

现象 判断
新连接报 ORA-12520 processes / sessions 不够
老连接还能跑 listener 无 handler
跑批时间段才出现 并发 / 泄露
停任务后恢复 根因在任务

八、如果你现在 连 DB 都连不上(极端情况)

1️⃣ 让 DBA 用 SYSDBA 本地登录

sqlplus / as sysdba

2️⃣ 执行:

ALTER SYSTEM SET processes = 600 SCOPE=SPFILE;
ALTER SYSTEM SET sessions  = 660 SCOPE=SPFILE;

二、先用【标准 SQL】把 SID / SERIAL# 查对(关键)

✅ 正确查询方式(你照抄)

SELECT
  sid,
  serial#,
  username,
  status,
  program,
  last_call_et
FROM v$session
WHERE username IS NOT NULL
ORDER BY last_call_et DESC;

你会看到类似:

SID SERIAL# USERNAME STATUS PROGRAM
123 45678 BATCH_USER ACTIVE JDBC Thin Client

三、正确的 KILL SESSION 写法(一字不能错)

✅ 唯一正确格式

ALTER SYSTEM KILL SESSION '123,45678' IMMEDIATE;

📌 关键规则:

  • 单引号 ' 必须有

  • 逗号 , 中间不能有空格

  • 前面是 SID,后面是 SERIAL#

  • 数字,不要加引号


四、最常见的 3 种错误示例(你可能踩过)

❌ 错误 1:只写 SID

ALTER SYSTEM KILL SESSION '123';

👉 ORA-00026


❌ 错误 2:顺序写反了

ALTER SYSTEM KILL SESSION '45678,123';

👉 ORA-00026


❌ 错误 3:中间有空格

ALTER SYSTEM KILL SESSION '123, 45678';

👉 ORA-00026(有些版本会直接报)


五、会话“瞬间消失”的坑(很常见)

你可能是这样操作的:

  1. SELECT 查到一条会话

  2. 复制 SID / SERIAL#

  3. 执行 KILL SESSION

  4. 报 ORA-00026

👉 原因
这个会话在你执行前 已经自己结束了

🔍 验证方法

再执行一次查询:

SELECT *
FROM v$session
WHERE sid = 123;

如果 查不到,说明不是你杀失败,而是它已经没了


六、杀不掉怎么办?(更强手段)

🔥 标记为 DISCONNECTED(推荐)

ALTER SYSTEM DISCONNECT SESSION '123,45678' IMMEDIATE;

KILL SESSION 更彻底
Oracle 会立刻断开客户端


七、你现在可以这样一步步来(稳)

① 查

SELECT sid, serial#, username, program
FROM v$session
WHERE username = '跑批账号名';

② 确认还存在

SELECT 1
FROM v$session
WHERE sid = 123
  AND serial# = 45678;

③ 再杀

ALTER SYSTEM KILL SESSION '123,45678' IMMEDIATE;

八、如果你连 ALTER SYSTEM 都执行不了

那就是 权限问题,需要:

GRANT ALTER SYSTEM TO your_user;

或让 DBA 执行。

本作品采用《CC 协议》,转载必须注明作者和本文链接
每天一点小知识,到那都是大佬,哈哈
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!