Oracle字符乱码、数据越界访问典型Bug分析

简介: 前言: 作为乙方,在甲方客户那里验收阶段发现两个诡异Bug。以下就问题来源、问题根因、解决方案、如何避免做详细描述。

一、Bug1:Oracle读写字符乱码。

1、问题来源

Oracle数据库监听http://blog.csdn.net/laoyang360/article/details/46524519 需要获取最新插入的中文类别字符,以判定分类。单步调试发现每次接收到的都是乱码。


2、问题根因

编码格式不一致导致。


3、解决方案

第一步:查看oracle自身的编码格式,可以通过命令 select userenv('language') from dual;查看。

查看后得知,目前多家公用的oracle采用SIMPLIFIED CHINESE_CHINA.ZHS16GBK编码格式。

第二步:查看后台程序使用的编码格式,后台程序通过OTL读取、写入orcle数据库。采用了设置环境变量putenv(),写入的是

NLS_LANG=SIMPLIFIED CHINESE_CHINA.AL32UTF8,也就是UTF-8编码格式。

第三步:由于oracle编码格式已经固定,只能修改后台程序写入环境变量的格式为IMPLIFIED CHINESE_CHINA.ZHS16GBK编码格式。

第四步:查看编译工具VS2010使用的编码格式,我们知道:VC6.0默认ANSI编码,而VS2010默认UNICODE编码。UNICODE编码和GBK编码格式不一致,需要进行转换。

第五步:查了很久,最终通过转换接口utf82gbk()以及gbk2utf8()完成格式转换。

也就是说:从数据库读出数据,需要调用gbk2utf8()进行格式转换才能在VS2010下正常显示。

同样的,向数据库写入数据,需要调用utf82gbk()接口进行转换,才能确保写入oracle不会显示乱码。

并且,前台程序统一为utf8编码,统一转化才能确保没有乱码。

至于Utf8和Unicode的关系(一句话,utf8是对unicode字符集进行编码的一种编码方式。)详见知乎讨论:

http://www.zhihu.com/question/23374078



4、如何避免

1)最早设计的时候,定下数据库的编码格式,各个模块负责人按照统一格式进行处理。

2)编译器不同导致编码格式不同,需要大家统一接口进行转换。实现接口可参见如下: http://blog.csdn.net/p569354158/article/details/6567175



二、Bug2:溢出,数据越界。

1、问题来源

程序频繁执行500个任务后,页面不能显示返回数据。从界面显示的数据看,序号为67138,67139,63140的都不能显示。

但是小的序号69,70都能正常显示对应的返回数据。


2、问题根因

数据越界访问,可能在程序的某个地方采取了2个字节unsigned short存储(最大范围:0-2的16次幂-1,即:0-65535)。

问题是如何发现的:

第一步:通过数字67138等猜测数据越界,原因:67138>65535。而69,70小于65535的都显示正常。

第二步:数据库入库编号和程序日志编号一一对比。查看得知:oracle对应的数据库表最早入库序号为67138等大于65535的值,但在程序第二次返回插入的结果表里变成了1618的序号值,而该序号非pointId,而是taskId或者systemId,也就是初步断定发生了越界访问。

第三步: 研究为什么这个编号需要在数据库中唯一呢?和相关设计人员电话确认。因为后期的程序需求偏离了最早期的设计,此处在我看来完全不需要使用唯一值。只要保证每次任务下发唯一即可。因为我们的程序中由taskId索引唯一任务号,pointId的节点号为二级索引。程序使用查询表中也是,先一级索引后二级索引。

数据库中采用序列sequence进行唯一值递增判定,最大值设置的非常大 999999999999999999999999999。且两个表的触发器Trigger都调用这个序列,也就说,程序的频繁任务下发任务中,频繁执行后,几周或者几个月很容易就超过65535的序号值。

综上,基本判定程序中出现越界访问导致显示异常。


3、解决方案

1)情况着急:采取简单规避方案:更新序列Sequence当前值,当前值已经查过67000,需要回归到1重新开始。

但有个知识点是,在sqldevelop以及所有的查看工具下,该值都不能手动修改。

需要删除后重建。用 户必须具有ALTER ANY SEQUENCE 才能修改修改sequence,可以alter除start之外的所有sequence,如果想修改start值,必须drop sequence再re-create。

2)未来需要定位到哪里越界访问的,把类型至少改为unsigned int存储。


4、如何避免

定义序号类型的变量,要考虑它的源头,如何产生的,最小值、最大值是多少,再确定定义哪种类型的变量。


总结:

1.两个Bug都不难,但都需要理清思路,避免走弯路。第一个Bug梳理到改完耗时3.5h,第二个Bug耗时5h。

2.第二个Bug很诡异,在我执行完500个任务就突然不显示返回数据。程序基本没有改动任何逻辑。想了很久,排除了非传输设备的影响,非搜索程序的影响,最终定位和65535有关。


相关文章
|
25天前
|
SQL 运维 Oracle
【迁移秘籍揭晓】ADB如何助你一臂之力,轻松玩转Oracle至ADB的数据大转移?
【8月更文挑战第27天】ADB(Autonomous Database)是由甲骨文公司推出的自动化的数据库服务,它极大简化了数据库的运维工作。在从传统Oracle数据库升级至ADB的过程中,数据迁移至关重要。
36 0
|
1月前
|
数据采集 Oracle 关系型数据库
实时计算 Flink版产品使用问题之怎么实现从Oracle数据库读取多个表并将数据写入到Iceberg表
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
29天前
|
SQL 监控 Oracle
Oracle数据误删不用怕,跟我来学日志挖掘
Oracle数据误删不用怕,跟我来学日志挖掘
20 0
|
29天前
|
SQL Oracle 关系型数据库
Oracle误删数据怎么恢复?
Oracle误删数据怎么恢复?
29 0
|
1月前
|
SQL Oracle Java
实时计算 Flink版产品使用问题之采集Oracle数据时,为什么无法采集到其他TABLESPACE的表
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
1月前
|
分布式计算 Oracle 关系型数据库
实时计算 Flink版产品使用问题之获取Oracle的数据时无法获取clob类型的数据,该怎么办
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
2月前
|
SQL 存储 Oracle
TDengine 3.3.2.0 发布:新增 UDT 及 Oracle、SQL Server 数据接入
**TDengine 3.3.2.0 发布摘要** - 开源与企业版均强化性能,提升WebSocket、stmt模式写入与查询效率,解决死锁,增强列显示。 - taos-explorer支持geometry和varbinary类型。 - 企业版引入UDT,允许自定义数据转换。 - 新增Oracle和SQL Server数据接入。 - 数据同步优化,支持压缩,提升元数据同步速度,错误信息细化,支持表名修改。 - 扩展跨平台支持,包括麒麟、Euler、Anolis OS等。
84 0
|
2月前
|
Oracle 关系型数据库 MySQL
实时计算 Flink版产品使用问题之在online模式下增量抓取Oracle数据时,在archive_log切换时,出现数据丢失的情况,是什么原因
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
3月前
|
SQL 数据采集 Oracle
实时计算 Flink版产品使用问题之如何读取oracle中的blob类型的数据
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
3月前
|
Oracle 关系型数据库 数据库
实时计算 Flink版产品使用问题之连接到Oracle数据库但无法读取到数据,是什么导致的
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。