结论:表可能使用truncate table命令,或者指令命令覆盖。

  21号下午,查询A表时发现数据存在,但是与之关联的B表数据不存在了。一般正常来说A表的数据存在那么B表的数据是一定会存在的。在这里我已经意识到出问题了。很严重的问题。于是赶忙叫上师兄,告知该情况。

  首先,我们队整个表的数据进行了统计,发现表当中的数据仅剩3w多行,明显这个数据是不正确的。通过比对甲方的数据库内数据量,发现我们的数据量整整少了100w行😑,当时听到这个数字多少还是有点慌,但是慌没用还是要找到到底是什么地方出现了问题。

分析数据丢失原因

  因为我们有自己的数据库和甲方的数据库是区分开来的,这里暂且用A、B区分。首先将B库的数据insert到A库中是需要进过一系列数据处理的,但是在B库数据处理过程中,不会有这种大批量数据操作及truncate table操作。

  我们开始从日志入手,先是从B库insert A库的时数据处理流程中查看日志,查询20-21号的日志表中并没有发现大批量数据删除的行为,最多也就在2w左右,这也是一个正常的范围,按理来说如果是数据处理过程进行的操作那么数据处理过程是会记录数据操作量和记录的,所以需要排除是流程上出现的问题。

紧接着想出的两个方案数据闪回(oracle flashback)oracle 数据表sql操作日志配合数据闪回

  1. 数据闪回:在某一个时间点进行表数据闪回操作,可以快速恢复近期误操作。但是目前我们通过数据处理过程无法确定到底是某一个时间点进行了该操作。同时我们也是用如下操作根据时间点判定是否(猜测数据出现问题时间点)。
--1、 确定快照时间
--2、查询基于指定时间的数据快照
SELECT * FROM YOUR_TABLENAME AS OF TIMESTAMP 
TO_TIMESTAMP('2019-02-05 20:00:00', 'yyyy-mm-dd hh24:mi:ss');
--以当前时间为准,125分钟之前的数据快照
SELECT * FROM YOUR_TABLENAME AS OF TIMESTAMP SYSDATE - 125 / 1440
  1. 数据表sql操作日志:通过数据表Sql日志查询执行sql语句,执行时间,及操作类型来判定,操作类型能够看出在执行的是否是select、insert、delete 等操作。但是V$SQLAREA不记录truncate table操作。还会存在记录覆盖等问题,从20号开始 到 21号这段时间内没有看到执行A表的大批量数据操作记录。也就是说记录可能覆盖,甚至表可能使用了truncate table命令,但是如果使用truncate table命令数据表A表中的记录数量就不会是3W多条(这里因为甲方推送是增量的操作,最新增量没有3W),到这里还是很疑惑。
-- 确定快照时间
SELECT R.FIRST_LOAD_TIME,R.SQL_TEXT,R.* FROM V$SQLAREA R

无奈,最终还是未能发现到底什么原因导致及什么时候出现了该问题。

解决方案

  因为未能查到相关原因,所以首先将相关流程执行任务停止后进行处理过程排除。排查过程涉及到设计B表到A表的转换,主要涉及到会有数据删除的操作都进行view,将B表中的数据通过结合B表所在的库中相关联的表通过一定条件和排除数据,将整理后的数据全部插入B表中,最后完整的将业务流程执行一遍。

目前

  目前相关流程已经正确。历史两天。所有数据处理需要等待任务流程执行,手动操作可能要估算时间,防止不必要多次重复操作。

总结

  遇到该类型问题时,不要着急对数据表相关内容进行操作,需要排查问题如何出现,定位问题出现原因位置,通过原因去解决问题,如果未能找到问题出现原因,及时汇报上级。不要把时间浪费在自己无法处理解决的问题之上。

最后修改:2024 年 11 月 14 日
如果觉得我的文章对你有用,请随意赞赏