当前位置:网站首页>故障007:dexp导数莫名中断
故障007:dexp导数莫名中断
2022-08-01 11:34:00 【帅ちいさい宝】
故障007:dexp导数莫名中断
DM技术交流QQ群:940124259
1. 问题描述
某单位现场的乙方实施人员,近期一直被dexp导出数据过程中反复出现“Code:-70037 字符串不完整”
的错误所困惑,每次那两张始终导出失败,持续两个月找不到错误的关键点和突破口。按常理来说,数据导出是多么简单的事儿,恰好相反,往往越简单的事越让你怀疑人生,也是前期做事马虎导致今日的结局。
好,本人不再卖关子啦!造成此次导不出数据的原因,其一dexp在导出数据过程中会对里面的数据进行校验,字符缺失断码,会无情地中断导出,连个商量的余地没得(请不要吐槽,微笑面对人生^_^);其二表中某些行的数据确实存在不合法的字符,即字符乱码,诱发前因,是他们原先从MySQL迁移数据时,未严格检查数据,很多字符串被截断。
提前告知问题出现的原因,有点让大伙儿读不下去的感觉,认为了解即完毕。可否认真读完本人的辛苦之作,实实在在了解问题的来龙去脉,掌握到分析问题和解决问题的思路。谦虚使人进步,切记!!!现场见过太多自以为是DBA,或开发人员,总觉得自己很牛B.A.I,而实际面对问题时,挠脑袋,学了这么多方法,看了这么多书,为何用不上呢。
上菜,截图
他尝试管理工具右键导出,又尝试过dexp命令行导出,二者皆抛错中断后续的导出操作。
2. 见招拆招
2.1 抽样精准定位错误行
尽量缩小数据导出报错的范围,剔出行为特征明显的报错的第一行(首次触发报错的行位置)。得到这一行的位置,接下来排查更容易。
思路:
- 综合分析表中比较有特征的数据内容,比如这里按日期时间恒定常量值分组,观察数据分布,依次从小数据量中抽取异常内容记录行。
- 逐步限定数据行范围导出,直到从中取出第一次出现数据中断导出的位置,于是在管理工具中通过分页查询方式,定位查询出相应行记录。
-- 1. 通过自己的经验,选出具备特征的分组列,首先了解表中的数据分布情况(此处截图省略,懂核心思想即可)
select to_char(trunc(ds_create_time)), count(*)
from "YJSCP"."graduate_recruit_enroll_resume"
group by to_char(trunc(ds_create_time))
order by 1 desc;
-- 2. 专门挑2022-03-31那天的数据(4百多条)导出测试
-- rownum<=100 rownum<=80 rownum<=70 rownum<=73 逐步接近目标真相(当然也可以编写脚本弄,这里出错的表不多,所以没必要浪费时间写脚本自动抓出)
./dexp "YJSCP"/'"xxxxxxxx"'@LOCALHOST:5237 DIRECTORY=/tmp \
FILE=res5.dmp feedback=1 \
TABLES="\"YJSCP\""."\"graduate_recruit_enroll_resume\"" \
QUERY="WHERE to_char(trunc(ds_create_time))='2022-03-31' and rownum<=80" LOG=exp_2022_07_27_10_58_09.log \
LOG_WRITE=N
-- 当时已定位到73-74行,进入下一步细致的内容分析
2.2 大胆推测、与人交流
观察某一条错误行的数据内容特征,专门找字符类型的字段,特别检查是否有特殊字符(XML格式/HTML格式/类似C编程语言),属于首当其冲的观察点。
和懂业务表设计的实施人员沟通,了解一些字段的含义,如果有字段注释的话,另当别论,或者字段名称易读懂的,都可以推测哪些字段可能存在数据内容异常。
为啥强调试着了解表中各字段的含义?假如一张表一百多个字段,很多列是字符文本类型,人工慢慢排查,时间太长,效率极低。能短时间内快速排查定位某些字段,岂不是很爽呢。
所以说做技术的人,不要光埋头苦干的研究(有些情况可能被理解为瞎琢磨),也要学会人与人之间的沟通,技术交流。
-- 1. 通过分页查询定位到出错行的范围
select top 73,2
from "YJSCP"."graduate_recruit_enroll_resume"
where to_char(trunc("ds_create_time")) = '2022-03-31'
-- 2.焦点移到字符类型较长的字段内容(此次案例:jcqk)
-- 其他内容已做胶敏处理。发现jcqk文本内容末尾有一个乱码的字符。
-- 3.进一步确认乱码的规律
-- 普通人可能想用like '%乱码符号',这个是不行的。
-- 这个忘截图,结论是:乱码的字符规律的是以EF或EFBF编码的字符出现,我们应当转成二进制观察。
SELECT *FROM (
SELECT
"graduate_recruit_enroll_resume_id",
"ds_create_user_name",
ds_create_time,
RIGHTSTR(jcqk, 4) linestr, -- 取后4个字符
RAWTOHEX (rightstr(jcqk, 1)) bytestr, -- 取最后一个字符的二进制编码
ROWNUM rn -- 记录行号
FROM
SYSDBA."graduate_recruit_enroll_resume"
WHERE
trunc("ds_create_time", 'DD') = date'2022-03-31'
) WHERE rn IN (74, 311, 381); -- 取报错行,观察字符编码规律
-- 4. 核查夹杂在文本中的乱码字字符
/** 严谨的操作,是应该继续检查文本中间部分是否存在乱码。 事实上,当时场景,没往后续进行下去,针对以上末尾乱码已做修正三处问题后,再次dexp导出2022-03-31的数据不再报错,问题基本得到了解决。 特别提示:最好备份一下原表,用备份的那张表做测试修正。不要想当然在生产库的业务表上乱搞。 **/
给小伙伴们更自信的辨别,关于EF BF编码对应的各种字符集下的字符描述。
参考网址: https://www.haomeili.net/Code/DeCoding?bytes=EFBF&isHex=True
2.3 DTS迁移备份原表
不管你用什么样的方式备份表都可以,目的是保证数据的安全性。我的另一目的,通过DTS工具迁移一次表作为备份表,看DTS工具能否自动处理掉乱码的字符,省得后面手工核对和修复数据。当时蹿出这一想法,少做事且干得好,何乐而不为?可惜通过本人的验证,DTS迁移备份方案行不通,只得手工找出问题的数据行,修复乱码的字段。
第二个目的虽然未达到我的预期效果,但第一目的肯定达到的,保护原数据,测试修复备份表数据。
当时将该表迁移备份到SYSDBA用户模式下,进行全表的定位跟踪,筛选问题行。
SELECT *FROM (
SELECT
"graduate_recruit_enroll_resume_id",
"ds_create_user_name",
ds_create_time,
RIGHTSTR(jcqk, 4) linestr,
RAWTOHEX (rightstr(jcqk, 1)) bytestr,
ROWNUM rn -- 这个行号比较准确的,因为未走任何索引扫描输出,是以rowid形式的聚焦表。(小伙伴细节都要考虑哟,写得每种SQL一定要符合当时场景)
FROM
SYSDBA."graduate_recruit_enroll_resume"
WHERE
-- trunc("ds_create_time", 'DD') = date'2022-03-14'
)
WHERE bytestr IN ( 'EF', 'EFBF');
DBvear客户端管理工具,检索问题数据行截图
2.4 了解错误产生的逻辑(可选)
验证导出时,每一个错误输出是否跟行记录有关,即有几行存在异常数据,则打印多少次同样的错误。(可选内容)
本人喜欢研究得更透一点,多增加一节对数据报错的验证和猜想。
举例:拿2022-03-31一天的数据导出观察,报错三次字符不完整,符合本人的预想结果。这个结论对以后你处理类似的报错信息,有着一个大概的信息掌控。
./dexp "YJSCP"/'"xxxxxxxx"'@LOCALHOST:5237 DIRECTORY=/tmp \
FILE=res5.dmp feedback=1 \
TABLES="\"YJSCP\""."\"graduate_recruit_enroll_resume\"" \
QUERY="WHERE to_char(trunc(ds_create_time))='2022-03-31'" LOG=exp_2022_07_27_10_58_09.log \
LOG_WRITE=N
2.5 修复数据再验证导出
既然符合起初有多少次报错就会有多少行的数据错误问题的推断,2.4小节查询结果共有34处字符乱码,在之前乙方的导出日志中比较后,是符合结论的,那么就尝试修复问题行数据。
修复后再尝试导出整张表,如果不再报错,已经完成我们此次的修复目标,否则继续深挖文本中间的乱码。
-- 1. 修复乱码行
update SYSDBA."graduate_recruit_enroll_resume" a
SET jcqk = leftstr(jcqk, LENGTH(jcqk) - 1)
WHERE RAWTOHEX (rightstr(jcqk, 1)) IN ('EF', 'EFBF');
COMMIT;
-- 2. 尝试导出整张表
./dexp "SYSDBA"/'"xxxxxx"'@LOCALHOST:5237 DIRECTORY=/tmp \
FILE=res5.dmp feedback=1 TABLES="\"SYSDBA\""."\"graduate_recruit_enroll_resume\"" \
LOG=exp_2022_07_27_10_58_09.log LOG_WRITE=N
2.6 生产库的数据修复任务
数据修复整个前沿操作全部弄完,至于生产库上业务表这个事,得让他们自己协调找个时间做数据修复 。
方法和步骤都教给他们,千叮咛万嘱咐,一定要事先做好备份再操作。
备份:可以整库备份,可以表物理备份,可以表复制一份,可以DTS迁移备份到其他模式下等等。。。。。
3. 心得分享
边栏推荐
- Qt get all files in a folder
- Solve vscode input! Unable to quickly generate skeletons (three methods for the new version of vscode to quickly generate skeletons)
- NIO‘s Sword(思维,取模,推公式)
- [CLion] CLion always prompts "This file does not belong to any project target xxx" solution
- R语言诊断ARIMA模型:forecast包构建了一个ARIMA模型、使用checkresiduals函数诊断ARIMA模型、并进行结果解读(拟合较差的ARIMA模型具有的特点)
- 千万级乘客排队系统重构&压测方案——总结篇
- MNIST是什么(plist是什么意思)
- pandas connects to the oracle database and pulls the data in the table into the dataframe, filters all the data from the current time (sysdate) to one hour ago (filters the range data of one hour)
- Complete Raiders of JS Data Type Conversion
- [Open class preview]: Research and application of super-resolution technology in the field of video image quality enhancement
猜你喜欢
随机推荐
redis6 跟着b站尚硅谷学习
Small application project works WeChat gourmet recipes applet graduation design of finished product (1) the development profile
JWT
MySQL常用语句总结
Kaitian aPaaS mobile phone number empty number detection [Kaitian aPaaS battle]
《MySQL核心知识》第6章:查询语句
C语言实现!20000用4秒计算
华硕和微星多款产品将升级英特尔Arc A380和A310显卡
R语言ggplot2可视化:使用ggpubr包的ggscatter函数可视化散点图、使用xscale函数指定X轴坐标轴度量调整方式、设置x轴坐标为scientific使用科学计数法显示坐标值
正则表达式
DBPack SQL Tracing 功能及数据加密功能详解
C#/VB.NET 将PPT或PPTX转换为图像
Ts-Map 类的使用
Qt获取文件夹下所有文件
【倒计时5天】探索音画质量提升背后的秘密,千元大礼等你来拿
JS数据类型转换完全攻略
C#/VB.NET 将PPT或PPTX转换为图像
The difference between undefined and null in JS
图解MySQL内连接、外连接、左连接、右连接、全连接......太多了
Promise学习(一)Promise是什么?怎么用?回调地狱怎么解决?