kettle导出表结构 生成建表sql_6月数据库技术通讯:不规范SQL引发大量TX锁

为了及时共享行业案例,通知共性问题,达成共享和提前预防,我们整理和编辑了《云和恩墨技术通讯》,通过对过去一段时间的知识回顾,故障归纳,以期提供有价值的信息供大家参考。同时,我们也希望能够将热点事件、新的产品特性及其他有价值的信息聚集起来,为您提供具有前瞻性的支持信息,保持对于当前最新的数据库新闻和事件的了解,其中包括重要数据库产品发布、警报、更新、新版本、补丁等。

墨天轮文档:《云和恩墨技术通讯(6月刊)》:https://www.modb.pro/doc/4551?YYF(复制到浏览器中打开即可下载)

以下截取部分页面:

6db2282da16f7c5e0047841b6da1b472.png
54bd806ac8c02ad4cc57720207166da5.png

以下列出其中一个频发问题。

在数据库日常运维中,由于开发人员的一个不规范操作,很有可能会对生产业务造成不可估量的损失,下面是一个由于SQL写法不规范引发大量TX锁的案例:

问题描述

某客户数据库5月14日上午8点半突发大范围业务堵塞,大量进程等待TX锁。

62ff19380c2e24bb2c586d4d3d16bb68.png

问题分析

第一步找到HOLDER:

db209a5b99a05eb2f6a38387265f5472.png

HOLDER进程总是空闲状态,杀掉以后后面的SESSION也会进入空闲HOLDER。堵塞不会减少。所以我们当时分析应该是由于业务部主动提交引发的问题,但随后征得业务人员同意杀掉所有锁相关进程后全部会话依然会进入等待新的EVENT 为:“transaction”。

第二步分析数据库事务

a07f950e4a2a520984b3e7c66ca3390e.png

经过分析:发现了当时有大事务回滚,根据分析回滚段查询到了相关的表为,owner.tab_info这是业务的核心表, 根据这张表反查ASH信息,我们发现了一条SQL执行了14小时, 这个SQL语句引发的大事务回滚。SQL文本如下:

updateowner.tab_info set col1='018',COL2=10,COL3=null where col4 in (select col4 fromowner.tab_init)

第三步分析问题原因

首先IN字句里的语法有问题,(select col4 from owner.tabinit)根本无法执行,因为这张表上根本没有col4列。所以单独执行直接报错了,而且表owner.tabinit也是一个很简单的小表,业务人员的原意也是只修复个别错误的数据。ORACLE数据库在子查询还是会优先找子查询中表自身的列,如果找不到相关列就会自动引用父查询的列。那么这条语句的语义就变了,原本的SQL等效于

update owner.tab_info set col1='018',COL2=10,COL3=nullwhere col4 in (select col4 from dual)

或者

update owner.tab_info set col1='018',COL2=10,COL3=nullwhere col4 =col4

业务人员原本是想做个别条的维护,没想到做成了全表更新,导致了一个天大的事务回滚引发了这个故障。

问题解决
  1. 业务运维人员停止相关业务更新数据。
  2. 创建一张新表,COPY老表的所有数据,并按照原表创建索引。
  3. 导出并导入原表的统计信息。
  4. 切换表名,RENAME。
  5. 通知业务重启业务进行观察。

我们合理使用了并行、统计信息导出导入、导出建表、建索引语句等技术半小时内完成了这个20G表,数千万条记录的表的切换,恢复业务后一切正常。

回过头来想想一身冷汗,如果这个表没那么大,这个语句就执行成功了,可能会导致整个系统数据被全部该乱,造成数据紊乱的损失。所以开发阶段编写SQL时一定要通过别名指定列名,明确每一列的具体出处,才能防范这种问题再次发生。另外,在系统方面,我们也设想能通过实现代理+阻断的方式由系统阻断这类SQL,禁止往生产分发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值