今天小编给大家分享一下大表delete删数据导致数据库异常怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
一、问题描述
早上正在上班路上,群里客户说,有一张24G的大表,delete删了26小时还没有跑完,目前进程还在跑让帮忙处理下,停止当前进程,并保留对应条件的数据,多余数据删掉。
二、查看数据库情况
未开归档
UNDO表空间爆满
三、提出方案
经过沟通,该表为测试数据表,目前没有在使用;
于是打算rename该表,通过ctas的方式去将需要的数据捞出来,重建索引和相关约束。
存在一个问题:delete进程已经执行了26小时,如果kill进程,必然会导致undo回滚,回滚默认开启并行会导致数据库和系统负载很高,于是需要提前处理下,设置参数_fast_start_parallel_rollback_关掉UNDO并行。
--查看回滚参数设置,是否是默认并行SQL> show parameter fast_start_parallel_rollbackNAME TYPE VALUE------------------------------------ ----------- ------------------------------fast_start_parallel_rollback string LOW--LOW 代表 开启CPU*2并行--设置spfile取消并行SQL> alter system set fast_start_parallel_rollback=false;System altered.
四、执行过程
备份保留 表创建语句。
记录当前无效对象。
SELECT d.OWNER ,d.OBJECT_NAME ,d.OBJECT_TYPE ,d.statusFROM dba_objects dWHERE d.status = 'INVALID' AND d.owner = '**';
查看delete进程pid,系统级kill掉。
--查询SID, SERIAL#select s.SQL_TEXT, se.SID, se.SERIAL# from v$session se, v$sql s where s.sql_id = se.SQL_ID and username = '**' and status = 'ACTIVE' and s.SQL_TEXT like '%delete * from *****%';--数据库级kill进程alter system kill session '2953,31083';
报错
ERROR at line 1:
ORA-00031: session marked for kill
--系统级 kill进程
select spid, osuser, s.program
from v$session s,v$process p
where s.paddr=p.addr and s.sid=2953;
kill -9 105257
观察undo回滚情况
--查看等待事件select inst_id,event,count(*) from gv$session a where a.status='ACTIVE' and not (a.type = 'BACKGROUND' and a.state='WAITING' and a.wait_class='Idle') group by inst_id,event order by a.inst_id,count(*) desc;---------------------------------------------------1wait for a undo record611resmgr:cpu quantum291enq: RO - fast object reuse221enq: CR - block range reuse ckpt201free buffer waits17--查看当前数据回滚情况alter session set nls_date_format='yyyy-mm-dd hh34:mi:ss';select usn, state, undoblockstotal "Total", undoblocksdone "Done", undoblockstotal - undoblocksdone "ToDo", decode(cputime, 0, 'unknown', sysdate + (((undoblockstotal - undoblocksdone) / (undoblocksdone / cputime)) / 86400)) "Estimated time to complete" from v$fast_start_transactions where state = 'RECOVERING';---------------------------------------------------83RECOVERING9026713455902625826-4月 -21
观察系统负载,IO负载,内存使用情况
等待回滚完成,持续时间较久。
回滚成功后,rename 原表。
rename table to table_20210410;
CTAS将需要的数据捞到新表(原来的表名)中。
create table USER.TABLEnologging parallel 8tablespace TBSas select * from USER.TABLE_20210410where *** like '******%';--取消并行alter table USER.TABLE noparallel;--开启loggingalter table USER.TABLE logging;
rename索引,并重建索引。
alter index USER.INDEX1 rename to INDEX1_20210410;--重建索引create index USER.INDEX1 on USER.TABLE (***) tablespace TBS parallel 8;--取消并行alter index USER.INDEX1 noparallel;
创建约束,授权。
比对无效对象,数据是否一致
drop掉rename的表。
drop table USER.TABLE_20210410 cascade;
以上就是“大表delete删数据导致数据库异常怎么解决”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。