drds 解决问题_C++应用适配DRDS小结

前言

C++实现的业务系统已经支持MYSQL版本,本次改造主要适配DRDS(介绍见DRDS应用开发指南)。DRDS兼容MYSQL语法,适配起来很方便。DRDS本身不提供C++的客户端,本次使用社区版MYSQL客户端。对于DRDS涉及基本的SQL操作,无需改造就可以运行。有些特殊的使用方法需要单独处理,实录如下:

问题及处理思路

1. MYSQL/DRDS兼容处理

本次改造直接使用MYSQL封装的DBC来支持SQL操作。如果存在差异,提供单独接口。在业务侧,构造数据库链接时,根据配置来指定数据库类型MYSQL/DRDS。不兼容的SQL,在业务侧根据数据库类型执行不同条件分支来实现。

2. stmt

不支持

DROP/CREATE

问题描述:以前MYSQL的DBC封装采用stmt以提高性能。使用stmt来执行DROP/CREATE的SQL语句时,会提示语法错误(1064)。

错误信息

问题分析:MYSQL的官网信息Error: 1064 SQLSTATE: 42000 (ER_PARSE_ERROR)Message: %s near '%s' at line %d。参与资料《MySQL 的 C API预处理语句》,猜测应该服务端不支持stmt方式执行DROP/CTRATE。【1064是通用错误? 】

解决思路:

1)技术验证mysql_query方式可以执行DROP/CREATE语句。

2)使用mysql_query方式实现一套区别于stmt接口,对于报错语句在DRDS下使用新接口执行。

3. DROP/CREATE的跨库事务问题

问题描述:MYSQL的DBC封装时通过mysql_autocommit来关闭自动提交,由应用统一来控制事务提交。在这种场景下执行DROP/CREATE操作分库表,会报以下错误:TDBException: ERROR_MSG=TDBException: [c7622f788c01000-4][10.135.237.68:3306][cc]ERR-CODE: [TDDL-4603][ERR_ACCROSS_DB_TRANSACTION] Transaction accross db is not supported in current transaction policy, transaction node is: CC_1515572409568KAQTCC_SSYA_0000_RDS, but this sql execute on: CC_1515572409568KAQTCC_SSYA_0008_RDS. More: [http://middleware.alibaba-inc.com/faq/faqByFaqCode.html?faqCode=TDDL-4603]. you can use 'show warnings' for more detail message.

问题分析:DRDS的官网信息对该错误进行详尽描述。对于DROP/CREATE,如果mysql_autocommit是自动提交,DROP/CREATE操作跨库表,可以正确执行。

解决思路:一般情况下,一个业务程序只使用一个数据库链接,mysql_autocommit设置手动提交在连接初期就确定好了,为了防止影响别的SQL,不能直接修改链接的事务方式。在执行DROP/CREATE函数里面,调用mysql_query之前,通过mysql_autocommit设置自动提交;之后恢复数据库链接提交方式。

通过2,3方法,解决对垮库表CREATE/DROP操作。

4. stmt 不支持特殊SELECT语句

问题描述:在业务验证时,stmt不支持特殊的SELECT,如下支持:

SELECT DISTINCT CONCAT(A,B,'C',D) CREATE_SQL FROM TABA WHERE A='A' AND B='B'

不支持:

SELECT 1 FROM TABLE_NAME

SELECT FILE_ID_SEQ..NEXTVAL SEQ_VALUE FROM DUAL

SELECT FILE_ID_SEQ.NEXTVAL SEQ_VALUE

使用stmt方式执行时,报类似2的错误。

解决思路:同2,使用mysql_query来实现一套单独接口。特别的,SELECT对于事务性没有要求,即使手动提交也可以执行。

5. 表不存在的返回码问题

问题描述:利用SELECT 1 FROM TABLE_NAME来检测表不存在。MYSQL的错误码是1146。即Error: 1146 SQLSTATE: 42S02 (ER_NO_SUCH_TABLE)。而DRDR使用mysql_errno错误码1064,并且包含一个TDDL-4007。客户端与C++显示错误信息一致。

使用Navicate查询表不存在的错误信息

解决思路:对于DRDS,当判断表不存在时,错误码是1064(感觉像个通用错误码?)。需要从错误信息里判断TDDL-4007来确认表不存在。

通过4和5,SELECT 1 FROM TABLE_NAME来判断表不存在搞定。

6.

DRDS提供SIMPLE序列返回类型问题

问题描述:DRDS提供SIMPLE序列和BIGINT字段返回类型都是8(MYSQL_TYPE_LONGLONG longlong)但是buffer里面数值格式不一致,SIMPLE序列返回时字符串格式,BIGINT字段返回long long整形格式。(MYSQL的MYSQL_TYPE_LONGLONG是long long整形格式)

解决思路:对于DRDS,提供一个单独接口专门处理DRDS提供SIMPLE序列返回值问题。

通过4和6,可以搞定序列取值问题。

7.

stmt方式执行insert时偶尔失败问题

问题描述:C++程序有个insert语句有时候成功,有时候不成功。问题出在varchar(255),文件名是字符串时候就有问题,改成数字就可以了。一开始怀疑是字符集,设置为UTF8也有类似问题。INSERT INTO EVENT_FILELIST

(FILE_ID, FILE_NAME, FILE_SIZE, CREATED_DATE, STATE, STATE_DATE, RATING_FLOW_ID,EVENT_SRC_ID)

VALUES

(      ?,          ?,          ?, STR_TO_DATE(            ?,'%Y%m%d%H%i%S'),      ?, STR_TO_DATE(          ?,'%Y%m%d%H%i%S'),              ?,            ?)

2018-02-09 16:54:34 [DETAIL] > CCBS:Get Exception:File[/home/v90ocs1/src90/billing/proc/TGatherFileOper.cpp] Line[194]

Exception Message=TDBException: ERROR_MSG=TDBException: TDBQuery::Execute()  mysql_stmt_execute failed. errno:4998, errmsg:[c78e06d11800000-37d][10.135.236.60:3306][cc]ERR-CODE: [TDDL-4998][ERR_NOT_SUPPORT] parameter of mysqltype:-32514 fullblob:false encode:latin1 not support yet! More: [http://middleware.alibaba-inc.com/faq/faqByFaqCode.html?faqCode=TDDL-4998]

解决思路:同事走查代码发现缺少memset,MYSQL的dbc封装存在缺陷。MYSQL下无问题,DRDS存在问题。

缺少memset

8. set方式支持存在部分问题

图片发自简书App

小结

本次C++主要解决查询并自动建表,以及获取序列等功能。DRDS提供额外特性,可以满足特许需求,也存在和MYSQL的语法差异。需要做一些特殊来解决这些问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值