Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 701|回复: 0

oracle大数据量更新引发的死锁问题解决方法及oracle分区和存储过程的思考

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-29 10:26:43 | 显示全部楼层 |阅读模式

    前言

    前几天上午在对数据库的一张表进行操作的时候,由于这张表是按照时间的一张统计表,正好到那天没有测试数据了,于是我想将表中所有的时间,统一更新到后一个月,于是对80w条数据的更新开始了。整个过程曲折的一批。同时学到了很多知识,在此进行记录。希望对大家有帮助。

    首先是大批量更新,由于数据已经进行了分区,开始对分区进行分析,然后大批量操作死锁,对死锁的解决,最后存储过程来解决数据的大批量插入。

    曲折的过程开始

    由于测试数据到21号就没了,21号一上去,发现开发的功能,都没有数据了,图表也都空了。查询原因发现测试数据没了。于是打算开始造数据。此时数据库已经有80多w的数据,当时想着将所有数据的collect_time时间字段向后推迟一个月,即可。当时也没想优化问题。于是写下sql。

    update i_people_collect set collect_time = collect_time+30

    此sql将表的所有时间向后推迟一个月。于是开始执行。

    此时报错:ORA-14402: 更新分区关键字列将导致分区的更改。

    于是发现此表的collect_time列进行了分区处理。

    我们可以先开启表的行移动来允许对分区字段的update 操作。sql如下

    alter table xxx enable row movement;

    之后再执行update发现可以执行,执行完毕后,记得关闭行移动。

    alter table xxx disable row movement;

    回到刚才我们执行update语句,预计会慢,但是发现执行了20分钟还没有结束。于是怀疑报错了。就强行终止。但是此时终止也不好使了。。大概是占用资源太多,不好释放。

    于是强行关掉pl/sql。重新登录。这里我们先分析一下,执行update操作为什么会这么慢。

    分区表某一行更新时,如果更新的是分区列,并且更新后的列值不属于原来的这个分区,如果开启了这个选项,就会把这行从这个分区中delete掉,并加到更 新后所属的分区。相当于一个隐式的delete+insert,但是不会触发insert/delete触发器。如果没有开启这个选项,就会在更新时报错 ORA-14402;

    这一操作产生影响的特殊之处在于这是个DML操作,是和online transaction密切相关。对于这样一个UPDATE,实际上分为3步:先从原有分区将数据删除;将原数据转移到新分区上;更新数据。

    其影响就在于以下几个方面:

    一 个UPDATE被分解为DELET、INSERT、UPDATE三个操作,增加了性能负担。其中,DELETE的查询条件与原UPDATE的查询条件相 同,新的UPDATE的查询条件是基于INSERT生成的新的ROWID,相应的Redo Log、Undo Log会增加;

    如果Update语句还涉及到了Local Index的字段的话,新、旧2个分区上的Local Index都要被更新。

    由于我们更新的是collect_time列。collect_time列又正好是分区列。于是就产生了上面的这种情况。造成执行速度十分的缓慢。

    原因分析完毕。继续说接下来发生的问题。

    重新连接到PL/Sql后,对刚才的表进行查询,发现一直执行sql,并不返回结果。于是考虑刚才的sql还在执行的问题。

    通过pl/sql的工具,会话,发现刚才的会话仍然存在,没有断开连接。这就坑爹了啊。通过会话来对连接强制结束。发现还是不能操作刚才的表。于是考虑了一下,可能是表发生了死锁。

    于是执行查询哪些表产生了死锁的sql,如下

    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;

    通过结果发现,刚才的表果然已经被锁定了。

    继续向下看是哪个用户的哪个进程造成的死锁

    --查看那个用户那个进程照成死锁 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;
    --查看连接的进程 SELECT sid, serial#, username, osuser FROM v$session;
    --查出锁定表的sid, serial#,os_user_name, machine_name, terminal,锁的type,mode SELECT s.sid, s.serial#, s.username, s.schemaname, s.osuser, s.process, s.machine, s.terminal, s.logon_time, l.type FROM v$session s, v$lock l WHERE s.sid = l.sid AND s.username IS NOT NULL ORDER BY sid;

    此时通过这些查询,我们已经能够定位是哪个进程导致了锁表的产生。同时获取到了进程的sid以及serial。

    执行中断进程的sql,

    alter system kill session'210,11562';

    讲道理,此时已经进行了进程的结束,但是发现表还是在锁着的。于是可能是查看一下造成死锁的这一进程的状态。

    select saddr, sid, serial#, paddr, username, status, machine from v$session where username is not null

    通过status发现锁定的进程的状态已经改变为KILLED,这种状态可能导致长时间的未释放资源,PMON并没有对其进行清除,等了很久仍然是锁表状态。

    于是可能需要操作系统级别的对进程进行清除。

    我们查询出会话进程在操作系统中的进程id。

    select a.spid,b.sid,b.serial#,b.username,b.status from v$process a,v$session b where a.addr=b.paddr ; 

    我们进入linux后台。通过kill -9 spid,此时执行后,发现表已经解锁了,死锁结束。呼~不容易。

    接下来问题又来了,我们如何继续更新数据呢。最终决定实用存储过程来进行增加数据。

    create or replace procedure aaa(startdate in date, days in number) as --生成的数据包含startdate当天 i number; begin i := 0; while i < days loop insert into aaa1 select sec_pkid.nextval,startdate + i, '字段名','字段名','字段名','字段名' from aaa2 t where collect_time = to_date('2018-11-09','yyyy-mm-dd'); i := i+1; commit; end loop; end aaa;

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-16 06:27 , Processed in 0.058471 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表