存储过程被锁

可用SYS登录,然后查询如下语句:
查找存储过程OPERATIONDATA_IMP被哪些session锁住而无法编译
select *  FROM dba_ddl_locks where name =upper('OPERATIONDATA_IMP');
从而得到session_id,然后通过
select t.sid,t.serial# from v$session t 
where t.sid=&session_id;
得到sid和serial#
最后用alter system kill session 'sid,serial#';  kill 相关session即可。
<think>我们讨论的是MySQL,但用户提供的引用中提到了Oracle和SQL Server的表查询方法。用户现在的问题是:如何查看存储过程中的? 在MySQL中,存储过程执行时产生的与其他SQL语句产生的本质上相同,但可能需要结合存储过程执行的多条语句来分析。 由于存储过程可能包含多个SQL语句,每个语句都可能获取,因此我们需要在存储过程执行时监控的情况。 方法: 1. 首先确定存储过程执行时涉及的事务(MySQL存储过程默认在自动提交模式下运行,但也可以在事务内执行)。 2. 在存储过程执行期间,通过查询`INFORMATION_SCHEMA`中的表来监控。 但是,由于存储过程是一个整体,我们很难在存储过程内部某条语句执行时暂停并查看状态。因此,我们可以采取以下步骤: 步骤1:开启一个会话执行存储过程(为了模拟,可以在存储过程中加入一些等待时间,以便观察状态) 步骤2:在另一个会话中查询信息 具体操作: 1. 修改存储过程:在关键位置添加等待语句(如SLEEP(10))以便有足够时间查看状态。 2. 执行存储过程的同时,在另一个会话中使用查询语句监控。 示例: 假设有一个存储过程如下: ```sql DELIMITER $$ CREATE PROCEDURE test_proc() BEGIN START TRANSACTION; UPDATE table1 SET col1 = 'value1' WHERE id = 1; -- 执行更新,可能获得行 -- 在这里我们加入等待时间 DO SLEEP(10); -- 等待10秒,便于观察 UPDATE table2 SET col2 = 'value2' WHERE id = 2; COMMIT; END$$ DELIMITER ; ``` 在第一个会话中执行: ```sql CALL test_proc(); ``` 在第二个会话中,我们可以查询信息: 在MySQL 5.7中: ```sql SELECT * FROM information_schema.INNODB_LOCKS; -- 当前存在的 SELECT * FROM information_schema.INNODB_LOCK_WAITS; -- 等待 ``` 在MySQL 8.0中: ```sql SELECT * FROM performance_schema.data_locks; -- 取代INNODB_LOCKS SELECT * FROM performance_schema.data_lock_waits; -- 取代INNODB_LOCK_WAITS ``` 此外,我们还可以结合进程和事务信息: ```sql -- 查看当前事务(包括存储过程中的事务) SELECT * FROM information_schema.INNODB_TRX; -- 查看进程列表,找到存储过程执行的线程 SHOW PROCESSLIST; ``` 如果我们想查看存储过程中每条语句执行时的情况,则需要在存储过程中加入多条SLEEP,并在每个SLEEP期间查询状态。但这种方法比较繁琐。 另一种方法是使用性能模式(Performance Schema)在MySQL 5.6+中开启事件监控,但配置较为复杂。 简单总结:查看存储过程中的,实际上就是在存储过程执行期间(特别是执行到某条SQL语句时)通过系统表查询信息。由于存储过程是连续执行的,我们需要在其执行过程中(比如通过等待)来查询。 注意:在存储过程中使用SLEEP()只是为了方便观察,实际生产环境中一般不这样做。 特别注意:在MySQL中,存储过程执行时,每条语句都会在事务中执行(如果使用了事务,则整个存储过程在一个事务中;否则默认自动提交,每条语句一个事务)。因此,的持有时间取决于事务的提交和语句的执行。 引用说明:用户提供的引用[1]是Oracle的解方法,引用[2][3][4]是SQL Server的表查询方法,不适用于MySQL。因此,我们的回答基于MySQL的系统视图。 因此,最终回答如下: </think>### 在MySQL中查看存储过程状态方法 在MySQL中,存储过程执行时产生的与其他SQL语句相同,但需要通过特定方法监控其执行过程中的状态。以下是详细操作指南: --- #### **1. 定位存储过程执行的事务** 首先查找正在执行存储过程的事务: ```sql SELECT trx_id AS 事务ID, trx_mysql_thread_id AS 线程ID, trx_query AS 当前SQL, trx_state AS 事务状态 FROM information_schema.INNODB_TRX WHERE trx_query LIKE 'CALL%'; -- 过滤存储过程调用 ``` **关键输出**: - `线程ID`:关联到进程列表 - `事务状态`:`RUNNING`(运行中)/`LOCK WAIT`(等待)[^1] --- #### **2. 查看存储过程涉及的** 关联事务与信息(MySQL 8.0+): ```sql SELECT tl.ENGINE_TRANSACTION_ID AS 事务ID, tl.OBJECT_NAME AS 表名, tl.LOCK_TYPE AS 类型, tl.LOCK_MODE AS 模式, tl.LOCK_STATUS AS 状态, p.INFO AS 存储过程调用 FROM performance_schema.data_locks tl JOIN information_schema.PROCESSLIST p ON tl.ENGINE_TRANSACTION_ID = ( SELECT trx_id FROM information_schema.INNODB_TRX WHERE trx_mysql_thread_id = p.ID ) WHERE p.INFO LIKE 'CALL%'; -- 过滤存储过程调用 ``` **类型说明**: | 类型 | 说明 | |---------|------| | `TABLE` | 表级 | | `RECORD` | 行级 | | `EXCLUSIVE` | 排他 | | `SHARED` | 共享 | --- #### **3. 强制终止阻塞的存储过程** 当存储过程时,通过线程ID终止: ```sql -- 先查询阻塞线程 SELECT * FROM sys.innodb_lock_waits; -- 终止特定线程 KILL [线程ID]; ``` > **注意**:线程ID来自`INNODB_TRX.trx_mysql_thread_id`或`PROCESSLIST.ID`[^1][^4] --- #### **4. 调试技巧:添加监控点** 在存储过程中插入监控语句: ```sql DELIMITER $$ CREATE PROCEDURE test_proc() BEGIN -- 业务逻辑前 SELECT '监控点1' AS debug_point; -- 业务SQL UPDATE orders SET status = 1 WHERE id = 100; -- 查看当前状态 SELECT * FROM sys.innodb_lock_waits; -- MySQL 8.0+ -- 业务逻辑后 SELECT '监控点2' AS debug_point; END$$ DELIMITER ; ``` --- ### **关键注意事项** 1. **权限要求**:需`PROCESS`权限查询系统表 2. **版本差异**: - MySQL 5.7:使用`information_schema.INNODB_LOCKS` - MySQL 8.0+:使用`performance_schema.data_locks` 3. **执行时机**:只在存储过程**运行时**存在,执行结束自动释放 4. **范围**:存储过程内的`SELECT ... FOR UPDATE`或`UPDATE`语句会产生行/表 --- ####
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值