其他问题

Java 应用创建数据访问代理连接失败

检查以下几个要点:

  • 白名单:是否在 ODP 上将应用服务器 IP 加入了白名单,以及在物理数据库上将 ODP 实例 IP 加入了白名单。

  • MySQL 客户端:如果直接使用命令行方式可以连接 ODP,说明网络和配置都是正确的。

  • JDBC Driver for MySQL(mysql-connector-java)版本是否为 5.1.x,目前经过 ODP 兼容性完整测试的版本为 5.1.30 和 5.1.40。

如何修改当前 Session 的 OB 执行超时时间

可通过以下方式进行修改:

  • 在执行的 SQL 语句中带上 select /*+query_timeout(100000000000),trx_timeout(100000000000)*/ 的 Hint。ODP 会将该 Hint 透传到 OB 去。该 SQL 语句所运行的 Session 的超时时间就会改变。

  • 在 ODP 控制台上配置如下参数,更改每条新连接的超时时间。这种修改方法在 OB 侧用 show parameters like "timeout" 是看不到的。但是 ODP 新建的 session 都会带上这些参数。连接

SQL 执行超时:SocketTimeoutException 错误

原因:该问题一般是由于慢 SQL 导致。

解决方案

  • 如果 SQL 执行确实需要较长时间,则需要调整应用端和 ODP 的 socketTimeout 参数。

    • 修改应用端 socketTimeout 参数:应用端

    • 修改数据访问代理 socketTimeout 参数:数据访问代理

  • 如果 SQL 执行耗时非预期时间,则需要分析 ODP 的执行耗时日志 logs/zdalproxy/sql-digest.log,且需要前往物理库进一步分析慢 SQL 原因。

批量更新报错 bad SQL grammar [], Syntax error

现象:使用 MyBatis 对 ODP 进行批量更新,出现 bad SQL grammar [], Syntax error 错误。当前批量更新写法如下:批量更新

原因:根据上述的写法,实际上产生的 SQL 语句是 multisql 类型,也就是用分割符 ; 分割开的多条 update 语句。ODP 不支持这种multisql类型的语句,因此会出现语法错误。

解决方案:在实际业务中,批量更新使用多条 update 语句一条一条去更新,不仅性能差而且容易造成阻塞。因此建议通过 case when 编写成一条 SQL 语句来执行,语法示例如下:

UPDATE mytable
   SET myfield = CASE id
         WHEN 1 THEN 'value'
         WHEN 2 THEN 'value'
         WHEN 3 THEN 'value'
END
WHERE id IN (1,2,3)

MyBatis 也是完全支持这种写法的,示例如下:

<update id="updateByBatch" parameterType="java.util.List">
     UPDATE t_goods
     SET NODE_ID = CASE
          <foreach collection="list" item="item" index="index">
               WHEN GOODS_ID = #{item.goodsId} THEN #{item.nodeId}
          </foreach>
     END
     WHERE GOODS_ID IN
          <foreach collection="list" index="index" item="item" open="("separator=","close=")">
                #{item.goodsId}
          </foreach>
</update>

ODP 是否支持影子表?例如 zdal 的影子表是在表名后加“_t”

ODP 目前不支持自定义后缀。