delete 大表后kill session是否会recover?

本文详细介绍了在使用SQL进行大表数据删除操作时,未执行完即杀掉session后,系统中smon进程占用CPU超过60%的现象。通过深入分析,发现这是由于回滚数据导致的性能问题。文章提供了测试过程和解决方案,强调了在处理大事务时应注意的事项,以及如何避免和解决此类问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天是2013-10-15,论坛有个朋友提这个问题:

简单介绍下情景: DELETE 一张大表数据,未执行完,就把session 杀掉了。
kill session 后。smon占CPU 仍然超过60%,难道是在回滚数据?

我的测试过程:

session 1:
SQL> select count(*) from amy;

COUNT(*)
----------
1047140

SQL> select * from v$mystat where rownum<2;

SID STATISTIC# VALUE
---------- ---------- ----------
46 0 0
session 2:
SQL> select sid,serial#,username from v$session where username is not null;

SID SERIAL# USERNAME
---------- ---------- ------------------------------
37 127 SYS
46 15 RHYS
48 11 SYS
50 23 SYS
然后再rhys下删除amy表:
SQL> delete from amy;
delete from amy
*
ERROR at line 1:
ORA-00028: your session has been killed
ORA-00028: your session has been killed


SQL>
在session 2 然后kill 该session:
SQL> alter system kill session '46,15';

System altered.

SQL> select usn,xacts,latch,extents,gets,waits,hwmsize,status,curext,curblk from v$rollstat where xacts>0;

USN XACTS LATCH EXTENTS GETS WAITS HWMSIZE STATUS CUREXT CURBLK
---------- ---------- ---------- ---------- ---------- ---------- ---------- --------------- ---------- ----------
3 1 0 106 82251 10 402776064 ONLINE 102 393

SQL>
select usn,xid,slt,state,undoblocksdone,undoblockstotal,cputime,parentslt,rcvserSQL> vers from v$fast_start_transactions;

USN XID SLT STATE UNDOBLOCKSDONE UNDOBLOCKSTOTAL CPUTIME PARENTSLT RCVSERVERS
---------- ---------------- ---------- ---------------- -------------- --------------- ---------- ---------- ----------
3 0300000068050000 0 RECOVERING 4479 14624 16 0 1
3 03001F0065050000 31 RECOVERED 3953 3953 58 1

SQL> r
1* select usn,xid,slt,state,undoblocksdone,undoblockstotal,cputime,parentslt,rcvservers from v$fast_start_transactions

USN XID SLT STATE UNDOBLOCKSDONE UNDOBLOCKSTOTAL CPUTIME PARENTSLT RCVSERVERS
---------- ---------------- ---------- ---------------- -------------- --------------- ---------- ---------- ----------
3 0300000068050000 0 RECOVERING 4479 14624 17 0 1
3 03001F0065050000 31 RECOVERED 3953 3953 58 1
结论:没错,是需要回滚,有时候大的事务回滚导致很严重的性能问题,有时候为了加快速度,设置fast_start_parallel_rollback 为high

<think>我们正在讨论如何在Nebula Graph中终止所有会话。根据用户的问题,他可能遇到了需要批量管理会话的情况,比如终止所有会话以释放资源或解决某些问题。 根据引用[4],我们看到有提到“批量会话管理:终止慢查询的利器”,但具体如何终止所有会话,引用中并没有直接给出命令。不过,我们知道在Nebula Graph中,可以使用`SHOW SESSIONS`查看当前所有会话,然后使用`KILL SESSION(session_id)`来终止指定会话。但是,要终止所有会话,我们需要获取所有会话ID并逐一终止。 然而,Nebula Graph并没有提供一条命令直接终止所有会话,因此我们需要通过以下步骤实现: 1. 使用`SHOW SESSIONS`命令获取所有会话的ID。 2. 将获取到的会话ID逐一通过`KILL SESSION`命令终止。 注意:不能终止自己的当前会话(否则会断开连接导致后续命令无法执行)。 另外,引用[2]中提到了客户端配置,其中`client.retry`等参数,但这对终止会话没有直接帮助。 因此,我们可以这样操作: 步骤1:连接到Nebula Graph服务(使用Nebula Console,如引用[1]所述)。 步骤2:执行`SHOW SESSIONS`,获取所有会话的ID(注意排除当前会话,但通常`SHOW SESSIONS`不会显示当前会话,因为当前会话正在执行这个命令,但为了安全,我们可以先记录当前会话ID,然后跳过它)。 步骤3:编写一个循环,对每个会话ID执行`KILL SESSION <session_id>`。 但是,在Nebula Console中,我们无法直接执行循环,所以需要借助脚本(如Shell脚本或Python脚本)来实现。 示例脚本(Python): ```python from nebula3.gclient.net import ConnectionPool from nebula3.Config import Config # 配置 config = Config() config.max_connection_pool_size = 10 # 地址和端口 addresses = [('192.168.1.100', 9669)] # 根据实际情况修改 # 用户和密码 username = 'root' password = 'nebula' # 连接池 pool = ConnectionPool() pool.init(addresses, config) # 获取会话 with pool.session_context(username, password) as session: # 获取当前会话ID(注意:这个会话就是我们正在使用的,不能终止自己) current_session_id = session.session_id() # 执行SHOW SESSIONS result = session.execute('SHOW SESSIONS') if not result.is_succeeded(): print(f"获取会话失败: {result.error_msg()}") exit(1) # 遍历结果 for row in result: session_id = row.as_string() # 跳过当前会话 if session_id == current_session_id: continue # 执行KILL SESSION kill_query = f'KILL SESSION "{session_id}"' kill_result = session.execute(kill_query) if kill_result.is_succeeded(): print(f"已终止会话: {session_id}") else: print(f"终止会话{session_id}失败: {kill_result.error_msg()}") # 关闭连接池 pool.close() ``` 注意:上述脚本中,我们首先获取了当前会话的ID,然后在终止其他会话时跳过了当前会话。这样就不会把自己终止掉。 另外,在Nebula Graph中,会话ID是一个字符串,所以我们在KILL SESSION时需要用双引号括起来。 但是,如果用户希望使用命令行(而不是脚本)快速终止所有会话,可以这样做(假设当前没有太多会话,且可以手动操作): 1. 执行`SHOW SESSIONS`,将会话ID记录下来。 2. 然后对每个会话ID执行`KILL SESSION <session_id>`。 但这种方法在会话数量多时不现实,所以建议使用脚本。 另外,引用[4]中还提到了`SHOW JOB`和`RECOVER JOB`,但这是用于作业管理的,与会话管理无关。 因此,总结来说,终止所有会话需要通过获取会话列并逐个终止,且注意不要终止当前正在使用的会话。 **注意**:终止会话会导致该会话中正在执行的操作被中断,请谨慎操作。 §§相关问题§§ 1. Nebula Graph中如何查看当前活动的会话? 2. 终止Nebula Graph会话会对集群产生什么影响? 3. 如何防止Nebula Graph中某些会话长时间占用资源? 4. Nebula Graph的会话管理机制是怎样的?</think>### 如何在 Nebula Graph 中终止所有会话 #### **方法 1:通过 Nebula Console 逐个终止** 1. **获取所有会话 ID** 使用 `SHOW SESSIONS` 命令查看当前所有会话: ```sql SHOW SESSIONS; ``` 输出示例: ``` | SessionID | UserName | SpaceName | ... | |---------------|----------|-----------|-----| | 1698304000000 | root | basketball| ... | | 1698304000001 | user1 | nba | ... | ``` 2. **批量终止会话** 对每个会话 ID 执行终止命令(需逐条执行): ```sql KILL SESSION "1698304000000"; KILL SESSION "1698304000001"; ``` > **注意**:此方法适用于会话数较少的场景[^4]。 --- #### **方法 2:通过脚本批量终止(推荐)** 使用 Python 脚本自动终止所有会话: ```python from nebula3.gclient.net import ConnectionPool from nebula3.Config import Config config = Config() config.max_connection_pool_size = 5 pool = ConnectionPool() pool.init([('192.168.1.100', 9669)], config) # 替换为实际 Graph 地址 with pool.session_context('root', 'nebula') as session: # 获取所有会话 ID result = session.execute('SHOW SESSIONS') if not result.is_succeeded(): print(f"查询失败: {result.error_msg()}") exit(1) # 终止非当前会话 for row in result: session_id = row.values[0].as_string() if session_id != str(session.session_id()): # 跳过当前会话 kill_cmd = f'KILL SESSION "{session_id}"' kill_result = session.execute(kill_cmd) print(f"终止会话 {session_id}: {'成功' if kill_result.is_succeeded() else '失败'}") ``` **脚本说明**: 1. 自动跳过当前执行脚本的会话,避免自终止 2. 需安装 Python 客户端:`pip install nebula3-python` 3. 替换 `192.168.1.100:9669` 为实际 Graph 服务地址[^2] --- #### **方法 3:重启 Graph 服务(强制终止)** 1. 停止服务: ```bash sudo /usr/local/nebula/scripts/nebula.service stop graphd ``` 2. 重新启动: ```bash sudo /usr/local/nebula/scripts/nebula.service start graphd ``` > **注意**:此方法会终止**所有会话**并重置连接,但可能导致正在执行的查询中断[^1]。 --- ### **关键注意事项** 1. **权限要求** 执行 `KILL SESSION` 需要 `DBA` 角色权限(默认仅 `root` 用户有此权限)[^4]。 2. **会话恢复** 终止会话后: - 未提交的事务自动回滚 - 客户端会收到 `NotAuthenticated` 错误(错误码 `E_BAD_USERNAME_PASSWORD`) 3. **监控建议** 定期检查会话状态: ```sql SHOW SESSIONS WHERE Duration > 3600; -- 查看超过1小时的会话 ``` --- ### **预防会话堆积** 1. **设置会话超时** 在 `nebula-graphd.conf` 中配置: ```conf --session_idle_timeout_secs=1800 # 30分钟无操作自动断开 --session_reclaim_interval_secs=60 # 每分钟检查一次 ``` 2. **客户端优化** 在客户端配置中增加重试和超时设置(参考引用[2]配置): ```yaml client: retry: 3 retryInitialInterval: 1s ``` > **警告**:生产环境谨慎使用 `KILL SESSION`,可能影响业务连续性。建议优先优化查询和配置超时机制[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值