oracle查看数据被锁及处理

本文介绍了在Oracle数据库中查询锁定表的详细方法,包括如何查看被锁的表、锁定会话的SID和SERIAL#,以及如何通过SQL命令杀死引起锁定的进程,帮助解决数据库锁表问题。

(1)锁表查询的代码有以下的形式:

select count(*) from v$locked_object;
select * from v$locked_object;

(2)查看哪个表被锁

select b.owner,b.object_name,a.session_id,a.locked_mode from v$locked_object a,dba_objects b where b.object_id = a.object_id;

(3)查看是哪个session引起的

select b.username,b.sid,b.serial#,logon_time from v$locked_object a,v$session b where a.session_id = b.sid order by b.logon_time;

(4)杀掉对应进程

执行命令:alter system kill session'1025,41';
其中1025为sid,41为serial#.
--------------------- 
作者:gongzg_test 
来源:优快云 
原文:https://blog.youkuaiyun.com/gongzg_test/article/details/80950284 
版权声明:本文为博主原创文章,转载请附上博文链接!

<think>我们正在解决Oracle表在插入数据时被定的问题。根据引用[1],我们知道在SQLServer中可以使用NOLOCK来读取不加数据,避免阻塞,但Oracle中并没有直接的NOLOCK,而是通过其他机制来实现类似效果。在Oracle中,处理问题通常可以从以下几个方面考虑:1.使用合适的隔离级别:Oracle默认的隔离级别是READCOMMITTED,可以避免脏读,但在某些情况下可能遇到等待。我们可以考虑使用更高级的隔离级别(如SERIALIZABLE)或者调整事务大小来减少冲突。2.优化事务:尽量缩短事务的执行时间,减少持有的时间。例如,将大事务拆分成小事务,及时提交。3.使用SELECT...FORUPDATENOWAIT:在需要定行进行更新时,如果不想等待,可以使用NOWAIT选项,这样如果被占用会立即返回错误,而不是等待。4.使用超时:Oracle11g及以上版本可以使用SELECT...FORUPDATEWAITn,指定等待的时间。5.避免全表:在插入数据时,Oracle通常不会定整个表(除非是某些DDL操作),而是定相关的行或块。但是,如果插入操作触发了索引维护等,可能会引起更多的。因此,优化表结构(比如索引)也很重要。6.使用并行DML:对于大数据量的插入,可以考虑使用并行操作来加快速度,从而减少定的时间(引用[2]中提到了并行查询进行高效的数据插入操作)。7.使用在线重定义表(OnlineTableRedefinition):在维护表结构时,可以使用DBMS_REDEFINITION包(如引用[5]所示)来避免长时间定表。针对插入数据时被定的问题,我们具体可以采取以下措施:1.**检查的原因**:首先,我们需要知道是什么阻塞了我们的插入操作。可以通过查询Oracle数据字典视图来查看的情况,例如v$session,v$lock,v$locked_object等。2.**减少事务大小**:如果插入大量数据,可以考虑分批插入并提交,这样每次只定少量的行,减少的持有时间。3.**使用APPEND提示**:在插入大量数据时使用/*+APPEND*/提示,使用直接路径插入,减少对数据块的竞争,并且不会生成UNDO(但注意这需要在高水位线以上分配新空间,并且提交后才能被其他事务看到)。4.**调整隔离级别**:如果业务允许,可以调整事务的隔离级别。例如,将事务设置为READCOMMITTED(默认)或SERIALIZABLE。但要注意,SERIALIZABLE隔离级别可能会导致更多的等待和ORA-08177错误(无法序列化访问)。5.**使用超时或NOWAIT**:如果我们的插入操作需要先查询然后插入,并且查询时使用了FORUPDATE,那么可以使用NOWAIT或WAIT来避免长时间等待。6.**使用并行DML**:启用并行DML(需要先执行ALTERSESSIONENABLEPARALLELDML),然后在插入语句中使用PARALLEL提示,例如:```sqlINSERT/*+PARALLEL(table_name,4)*/INTOtable_name...;```这样可以利用多个进程同时插入,加快速度,从而减少定的时间。7.**在线重定义表**:如果表需要调整结构(例如分区)以减少的影响,可以使用在线重定义(引用[5]的方法),这样在重定义过程中表仍然可以访问。8.**使用临时表**:对于需要中间处理数据,可以先将数据插入到临时表中,然后再将数据从临时表转移到主表。临时表在会话或事务结束后会自动清理,并且不会产生冲突(因为每个会话看到的是自己的临时表数据)。9.**检查外键和索引**:表上的外键约束和索引可能会在插入时导致额外的。特别是外键,如果父表正在被修改,可能会定子表的插入。可以考虑在插入时暂时禁用约束(需谨慎)或使用延迟约束(deferrableconstraints)。10.**使用数据库链接(dblink)时的问题**:如果是通过dblink在远程数据库上插入数据,需要注意分布式事务的两阶段提交,这可能会导致持续较长时间。确保网络稳定,并尽快提交。下面是一个查询当前会话的示例SQL:```sqlSELECTsid,serial#,username,osuser,machine,program,type,id1,id2,lmode,request,blockFROMv$sessionJOINv$lockONsid=sidWHEREtypeIN('TM','TX')ORDERBYsid;```如果发现阻塞的会话,可以尝试与对方会话的持有者协调提交或回滚,或者在紧急情况下使用以下命令终止会话:```sqlALTERSYSTEMKILLSESSION'sid,serial#';```但是,终止会话是最后的手段,应该谨慎使用。综上所述,解决插入数据的问题需要根据具体情况采取相应的措施。通常,优化事务、减少持有时间和使用适当的提示是常见的解决方法。根据引用[4]中提到的大数据量高并发访问的数据库优化方法,我们还需要考虑在并发情况下的数据一致性问题,避免临界点的数据错误(如示例中提到的日期临界点插入多条记录)。我们可以通过唯一约束、使用序列化隔离级别或者使用SELECTFORUPDATE来避免重复插入。例如,在临界点插入记录时,我们可以这样处理:```sqlDECLAREv_countNUMBER;BEGIN--使用FORUPDATE定该记录,防止其他会话同时插入SELECTCOUNT(*)INTOv_countFROMmy_tableWHEREdate_col=TRUNC(SYSDATE)FORUPDATE;IFv_count=0THENINSERTINTOmy_table(date_col)VALUES(TRUNC(SYSDATE));ENDIF;COMMIT;END;/```但要注意,这种方法在并发很高时可能会导致大量会话等待,因此需要谨慎使用。最后,我们生成相关问题:§§相关问题§§1.如何查询Oracle中被定的对象和会话?2.在Oracle中,如何避免在插入大量数据时长时间定表?3.什么是Oracle的并行DML?如何使用?4.Oracle中的临时表有哪几种类型?它们如何帮助解决问题?5.在Oracle中,如何安全地终止一个阻塞其他会话的进程?</think>### Oracle表插入数据时被定的解决方案 在Oracle中进行数据插入时遇到表定问题,通常由并发事务、长事务或资源争用引起。以下是系统化的解决方案: --- #### **1. 优化事务管理** - **缩短事务时间**:将大事务拆分为小批量操作,及时提交 ```sql -- 分批插入示例 BEGIN FOR i IN 1..1000 LOOP INSERT INTO target_table VALUES(...); IF MOD(i, 100) = 0 THEN -- 每100条提交一次 COMMIT; END IF; END LOOP; COMMIT; END; ``` - **使用`COMMIT`频率优化**:避免长时间未提交的事务持有[^4] --- #### **2. 使用直接路径插入** 通过`APPEND`提示减少争用: ```sql INSERT /*+ APPEND */ INTO target_table SELECT * FROM source_table WHERE condition; ``` - **优势**:直接写入数据文件,绕过buffer cache - **注意**:操作后需显式`COMMIT`,表级仅在操作期间存在 --- #### **3. 分区表优化** 对大数据量表进行分区,缩小范围: ```sql -- 创建范围分区表 CREATE TABLE sales ( id NUMBER, sale_date DATE ) PARTITION BY RANGE (sale_date) ( PARTITION p2023_q1 VALUES LESS THAN (TO_DATE('2023-04-01','YYYY-MM-DD')) ); ``` - **效果**:插入操作仅定相关分区而非全表[^5] --- #### **4. 并发控制技术** - **使用`NOWAIT`选项**: ```sql LOCK TABLE target_table IN EXCLUSIVE MODE NOWAIT; ``` 若定失败立即返回错误,避免阻塞 - **调整隔离级别**: ```sql SET TRANSACTION ISOLATION LEVEL READ COMMITTED; -- 默认级别 ``` --- #### **5. 在线重定义表** 使用`DBMS_REDEFINITION`在业务高峰期减少影响: ```sql BEGIN DBMS_REDEFINITION.START_REDEF_TABLE( uname => 'SCHEMA', orig_table => 'TARGET_TABLE', int_table => 'INTERIM_TABLE'); -- 同步数据 DBMS_REDEFINITION.SYNC_INTERIM_TABLE(...); -- 完成重定义 DBMS_REDEFINITION.FINISH_REDEF_TABLE(...); END; ``` 此方法在后台同步数据,最小化前台等待[^5] --- #### **6. 诊断争用** 查询定会话: ```sql SELECT s.sid, s.serial#, s.username, l.type, o.object_name FROM v$lock l JOIN dba_objects o ON l.id1 = o.object_id JOIN v$session s ON l.sid = s.sid WHERE o.object_name = 'TARGET_TABLE'; ``` 终止阻塞会话: ```sql ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE; ``` --- #### **7. 预防措施** - **索引优化**:减少冗余索引,因索引维护会加剧竞争 - **避免热点块**:使用`SEQUENCE`时添加`NOORDER`子句 - **监控长事务**:定期检查`V$TRANSACTION`视图 - **使用物化视图**:对高频插入的报表表采用异步更新机制 > **关键原则**:快速提交事务 + 缩小定范围 + 避免资源争用。对于持续存在的问题,需结合`AWR`报告分析根本原因[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值