千家信息网

看工程师的必备技能-技术人生系列第五十一期-我和数据中心的故事

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,前言:时间一晃已经来到了6月,技术人生系列文章已经半年没有更新了,在过去的半年时间里,我们技术人生系列文章的作者们一直奋战在工作一线,同时不忘积累和总结,为我们的文章提供更深厚的底蕴;如今,技术人生系
千家信息网最后更新 2026年11月02日看工程师的必备技能-技术人生系列第五十一期-我和数据中心的故事

前言:

时间一晃已经来到了6月,技术人生系列文章已经半年没有更新了,在过去的半年时间里,我们技术人生系列文章的作者们一直奋战在工作一线,同时不忘积累和总结,为我们的文章提供更深厚的底蕴;如今,技术人生系列将携中亦课堂正式回归,依旧严谨深刻,生动再现客户现场处理问题的点点滴滴,希望在传递更多知识点的同时给大家带来更多深度的思考。

在这里,首先感谢一直以来支持技术人生系列的小伙伴们,你们的支持与转发是我们持续分享的动力。


一、 问题来了

某个周五的悠闲晚上,正在窗前思考人生的老k,接到了一个客户的问题,客户现场的DBA处理了有一些日子了,准备在周末的时间窗口重启来解决该问题,不过客户还是很谨慎的嘱咐说,估计重启后该问题可能就没法重现了,我们需要在重启前找到问题的触发根因,避免再次出现此类问题。

那么具体问题是什么呢?客户描述的信息如下:

应用在执行某些SQL的时候经常出现ORA-01410的错误,但是这样的错误只是偶尔出现,手动执行的时候并不一定能遇到,因为涉及到的表可能有多个,经过前期分析,怀疑是内存错乱导致的,预计在下个周末进行操作系统重启来解决该问题,目前可以试着从数据库层面来分析该问题,看能不能有什么发现;

从跟客户的交流来看,似乎已经被这个问题折磨了很久,而现在已经对分析这个问题的原因不报太大的希望,只是报着试一试的心态来分析这个问题;

客户只是报着试一试的心态给我们转交了这个问题,但是我们作为服务商,就必须以全力以赴的态度来解决客户的问题。

二、 摸清情况

要尽快解决问题,只能远程分析,于是我联系到客户的接口DBA,通过远程连接到客户的服务器,了解了相关环境,分析问题;具体情况如下:

操作系统:REDHAT 6

数据库:oracle 10.2.0.5 单节点

具体现象:某些表的访问报ORA-01410,很明显的对于一个SQL语句,如果在SQL中去掉该表,整个SQL就不会报错;另外存在这种情况的表有多个;该现象不会一直出现,偶尔会出现;

首先跟客户DBA沟通,拿到了几个存在该问题的SQL,直接执行这些语句,在试验很多次后,确实遇到了好几次错,特别是执行时间较长的SQL;

选取其中较简单的一个语句,其语句和执行计划如下:

这个SQL语句中,出现问题的表是XXXstatelog,这个表比较小,只有60M;

而出现的ORA-1410错误是什么呢?

[oracle@test10g ~]$ oerr ora 1410

01410, 00000, "invalid ROWID"

// *Cause:

// *Action:

ORA-1410错误是因为有无效的ROWID,ORACLE并未提示出现该类情况的可能原因;

三、 交流与搜索

现在基本情况了解了,不过客户DBA已经分析了有一些时间了,而且他们更了解整体的应用、硬件以及相关的变化情况,在接手现场问题的时候,我都习惯多与客户DBA进行更多的沟通,一方面可以借鉴他们的已有经验,避免重复发明轮子,另一方面,旁观者清,也许也可以给他们指出一些纰漏之处,发现问题的关键;总之,充分利用已有的资源来快速分析问题,更何况网络时断时续的,相关操作还需要客户帮忙执行和收集。

问:最近有做过什么变化吗?

答:数据库并未做什么调整,对于应用版本的调整了解的并不多;

问:应用端除了这个报错外,还有什么其他的问题吗,如wrong result之类的?

答:并没有这样的反馈;

问:这样的报错有什么规律吗?

答:只知道出现这样情况的表又五六个,并没有发现时间上、频度上有什么特别的规律;通常失败了的操作,再执行一次,好像就并没有什么问题。

看来并没有更多信息,那先思考一下吧;再看看这个报错:

[oracle@test10g ~]$ oerr ora 1410

01410, 00000, "invalid ROWID"

// *Cause:

// *Action:

两个关键信息: ROWID和invalid ;

首先,什么时候会用到ROWID呢,通常来说,ROWID是一个伪列,并不存在于表的数据块中,似乎只有索引的叶子块中才会存储ROWID用以定位数据位置;

另外,INVALID,似乎意味着存储在索引中的rowid出现了异常,或者在读到内存中后出现了混乱?

没有更多信息的情况下,不如借鉴MOS上已有的经验,看看导致ORA-1410的现象都有哪些情况,于是找到了一篇解释该类错误的文章:

其中描述了ORA-1410的触发情况:

从这里给出的一系列描述看,主要可能的原因包括: 数据块损坏、索引块损坏、内存损坏、DDL操作导致的异常以及各种bug;

从我们遇到的情况看,数据块/索引块的损坏似乎不存在,因为多次执行并不会总是出现错误;

在先不考虑bug的情况下,就只有DDL操作或者内存异常的情况了,那么是不是DDL操作导致的问题呢?

四、思考与推断

目前看到的这篇MOS文档讲述的还算比较全面,于是我先发送给客户DBA讨论;

然而,客户DBA表示,已经仔细阅读过这篇文档了,而且他们跟应用沟通过,出现问题的时段应该是不会有DDL操作,只会在晚上的固定一个时间段存在一些TRUNCATE操作;另外,他们也在自己的环境也测试过了,truncate并没有导致ORA-1410的报错,而且以过往的经验来看,以前遇到过的truncate导致的查询错误报的都是ORA-8103;所以,这里客户认为可能还是内存的问题或者ORACLE的bug导致的;看来客户DBA还是很有经验的。

对于客户的看法,我是有几分认同的:

1. ORA-1410我似乎很少遇到过,以前遇到过都是索引异常的情况;

2. 另外truncate导致SQL执行报错的情况通常报的是ORA-8103,对象不存在;

3. 如果真的是没有意识到的truncate操作,那前端业务可能已经受到影响了;

这样好像不应该是truncate导致的,但是现象上时好时坏又是怎么产生的呢?如果真的是内存中的异常,那它是怎么好的呢?它的触发条件是什么呢?

趁着与客户网络断断续续的情况,我开始了独自思考。

根据mos 文档的描述问题出现的原因主要有几类:

1. 数据库中存在着频繁的DDL 语句。

2. 某个索引或者数据块出现了损坏,也就是坏块导致的问题

3. 硬件层面,例如:内存出现了问题

4. Oracle 的bug

再仔细回顾一下这个问题的现象逐一思考各种可能原因:

1. DDL语句导致的,但是用户已经确认了DDL语句只会在特定的时间执行。

2. 某个数据块或者索引块损坏,这个可以通过下面的语句来进行判断

SQL>analyze table validate structure cascade;

在和用户确认过之后,发现着命令并没有返回坏块相关的信息,基本可以排除坏块的可能。

3. 内存层面的问题,如果是内存层面的问题,更大的可能性是当访问某个表的某一些数据块的时候会出现问题。而且硬件工程师也确认了,内存并没有问题,所以,也基本上可以排除,内存出现问题的可能性。

4. Oracle 的 bug,在 mos上进行了一些搜索之后,也没有找到类似的问题。

五、 测试与模拟

经过上面的思考后,我还是认为truncate操作导致异常的可能性更大,对于这样的case如果能重现出来,相信会非常有说服力,嗯,这样的重现应该是比较简单的,不如直接重现;

于是,我开始在自己的测试环境,同样是10g数据库,Redhat linux环境中来重现,实现操作如下:

1. 创建表,生成更多数据,创建索引

create table test0611 as select * from dba_objects ;

insert into test0611 as select * from test0611;--执行多次

create index T0611_IDX1 on test0611(object_id);

2. 构造通过索引访问数据的语句

因为rowid只有在索引中才会用到,我们这里使用hint的方式,让SQL执行过程中先访问索引,再通过索引返表,这是一个比较差的执行计划这个SQL执行时间会比较长;

3. 在进行上述查询的过程中,我们在另一个会话中执行trauncate操作

truncate table test0611;

4. 观察第2步的查询操作,确认是否出现报错

先后执行了几次上述模拟案例测试,并未能重现ORA-1410的错误或者其他错误,查询正常完成。问题似乎陷入了僵局,难道truncate 语句真的不是问题的原因? 我们反过来想一下,如果要推翻自己的分析,最直接的办法就是拿到更多的证据来证明自己的分析是错误的。那就再来搜集更多的信息吧。

六、 意外发现与解决问题

在自己的环境没能快速重现出问题来,看来还得到生产环境继续挖掘其他线索,争取在重启前搜集足够的信息;

在查看的过程中,意外发现,这个环境上竟然部署了OGG(oracle goldengate),而它是作为源端将整个SCHEMA的表同步到目标端的ORACLE实例,这似乎给定位问题带来了转机: 如果是内存层面的异常,理论上是不会传导到ogg目标端的ORACLE实例上的;而如果是表本身或者索引本身的问题,那么在ogg目标端的ORACLE实例上也就应该能重现;

接下来,我们就在ogg目标数据库上执行相关查询,经过半个小时的测试发现,同样的语句在ogg目标数据库上也会报错,不过与生产环境不同的是,报错信息是ORA-8103;

[oracle@11g dmp]$ oerr ora 8103

08103, 00000, "object no longer exists"

// *Cause: The object has been deleted by another user since the operation

// began, or a prior incomplete recovery restored the database to

// a point in time during the deletion of the object.

// *Action: Delete the object if this is the result of an incomplete

// recovery.

ORA-8103就比较熟悉了,通常是因为对象被drop掉或者truncate掉导致的;同时,我们发现目标数据库的版本是11g的数据库,顿时我们觉得问题就简单多了,在11g数据库中,存在一个参数enable_ddl_logging来控制是否将DDL操作记录到alert日志中,而这源端的10g数据库时没有这个功能的;

于是,我们在目标端数据库实例中调整了该参数后,alert日志中很快就捕捉到了truncate的信息;

Tue Jun 01 20:11:18 2018

ALTER SYSTEM SET enable_ddl_logging=TRUE SCOPE=BOTH;

Tue Jun 01 20:16:34 2018

truncate table XXXstatelog

至此,似乎就真相大白了,正是应用在代码里加了truncate的操作,比较频繁的truncate操作导致相关表的查询出现报错中断,接下来客户DBA要做的就是和开发沟通其truncate操作的目的,并对此进行相应的调整;

将频繁的truncate操作去掉,改成定期的truncate操作后,便没有再在业务时间段出现ORA-1410或者ORA-8103的错误了,这样事情就告一段落了。

七、 研究与重现

客户的问题是解决了,但是新的疑惑又开始萦绕在我的脑中,只不过现在没有客户的压力,没有时间的紧迫性,可以静下心来慢慢研究这个问题:

1. 为什么在我的环境中测试,truncate并没有影响到select操作,而客户环境中的truncate操作却影响到了select操作,那么这种区别来自于哪呢?

2. 对于10g环境报错信息为ORA-1410,而对于11g环境,则报的是ORA-8103,这两者的区别又是什么呢?

要回答第一个问题,我们还是先要了解一下truncate操作对表/索引到底做了什么:

1) 对于普通的堆表来说,truncate操作只是截断了表和索引,主要是修改了数据字典信息和段头信息;

2) 对于我们简单的通过索引访问表数据的情况,在查询过程中执行truncate了后,truncate修改了段头信息,而我们需要访问的具体的索引块和数据块都没有发生改变情况下,自然是不会发生报错的;

3) 而我们将truncate的数据块覆盖掉,或者让我们的查询需要访问到段头信息时,ORA-1410或者ORA-8103的报错就出来了;

理解了上面的几点,我们再来重现错误,就很简单了;下面我们来构建几个重现场景:

首先构造两张表,其中T06182表比较大,T06183表比较小,在object_id列上存在索引:

构造查询用的语句:

测试场景一:

一个会话执行简单的查询,另一个会话在查询期间执行了truncate操作,truncate操作完成后,查询能继续完成而没有报错;

(注:truncate的完成时间是11:13:59,在查询过程中,查询未受影响)

测试场景二:

一个会话执行简单的查询,另一个会话在查询期间执行truncate操作,truncate操作完成后,继续执行flush buffer cache 的操作,出现ORA-1410报错;

(注:truncate完成时间是11:22:06,flush buffer_cache的开始时间是11:22:15,同期查询报错)

测试场景三:

一个会话执行简单的查询,另一个会话在查询期间执行truncate操作,truncate操作完成后,继续执行 insert操作,出现ORA-1410报错;

(注:truncate完成时间是11:20:05,insert执行时间是11:20:16,同期查询报错,truncate后插入数据,extent被重用,导致访问数据时报错)

对于第二个问题,其实在充分理解了ORA-1410和ORA-8103的错误后,我们也就能知道他们的共同之处了,看起来只是在10g报ORA-1410,而11g报ORA-8103;

可以看到,同样的case,在11g数据库环境中出现的是ORA-8103错误;

而且MOS上还可以找到类似的一些文章来说明这个问题:



小 结


从整个问题来看,其实就是一系列truncate引发的问题,在最开始阶段怀疑到最后确认问题,中间走了一些弯路,导致问题的分析显得有些复杂;马后炮的来看,其实如果怀疑到truncate,我们直接去查看对象的last_ddl_time和DATA_OBJECT_ID,就可以直接的定位了;亦或者在处理问题时没有那么紧张,仔细阅读MOS 的1410.1文档,也能很快的确定几个方向,并逐一去确认;然而,这正是高压力下实时处理问题和事后分析的区别所在,庆幸的是,正好因为这个问题还算费了一些时间,反而让我进一步试图去重现问题,反思整个过程,进而有了更多发现,总结一下,也是一线工程师的一些必备技能,写给自己也分享给大家:

1. 对于原理的理解,在解决问题特别是想重现故障的时候,极为重要,否则很有可能出现重现达不到预期效果而导致错误结论的情况;

2. 对于实时处理问题,即使压力再大,时间再赶,对于不了解的细节,对于未读过的文章,还是需要静下心来仔细阅读,否则就有可能错失那个让你一蹴而就的知识点;

3. 试着去重现你遇见的问题,这会比解决问题让你印象更加深刻。


问题 数据 客户 查询 情况 时间 索引 错误 信息 数据库 环境 语句 内存 分析 更多 测试 目标 原因 文章 时候 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 天津市摩尔互联网科技 互联网科技工作委员会主任 蓝思科技飞鸽互联网 互联网科技官网 上海互联网科技有限公司 互联网的科技创新 合肥互联网科技公司 电子科技大学互联网 科技类的互联网平台 联恩商钥互联网科技有限公司 恒银科技与互联网金融 深圳市优智互联网科技有限公司 洛阳共同富裕互联网科技有限公司 互联网科技大赛获奖感言 区块链结合互联网科技 21世纪互联网科技成就 广州有谷有贝互联网科技有限公司 中国科技和美国互联网 互联网科技大佬云集 科技发展第三阶段互联网时代 苏州互联网科技贷款公司 长亮科技 互联网金融 互联网科技咨询 隆华科技工业互联网 互联网科技商业 互联网5g黑科技有哪些 速维有品互联网信息科技(苏州)有限公司 互联网科技创新的路径 广东鹅鹅鹅互联网科技有限公司 第三届互联网大会安防黑科技
0