使用 Symmetricds 时出现 Firebird 错误

Posted

技术标签:

【中文标题】使用 Symmetricds 时出现 Firebird 错误【英文标题】:Firebird errors when using Symmetricds 【发布时间】:2018-03-29 02:48:41 【问题描述】:

我正在使用 symmetricds 免费版来复制我的 firebird 数据库。当我通过创建新的(空白)数据库进行演示时,它运行良好。但是当我在现有的数据库(有数据)上进行配置时,发生了错误。

我使用 Firebird-2.5.5.26952_0 32bit & symmetric-server-3.9.5,操作系统是 Windows Server 2008 Enterprise。

我已经搜索了一整天,但没有找到解决这个问题的方法。任何人请帮忙。谢谢你的时间。

更新: 初始加载时,Symmetric 执行在 firebird DB 中声明 UDF 的语句:

declare external function sym_hex blob   
  returns cstring(32660) free_it 
  entry_point 'sym_hex' module_name 'sym_udf

它导致了错误,因为我现有的数据库字符集是 UNICODE_FSS,CSTRING 的最大长度是 10922。当我通过将字符集更新为 NONE 来解决问题时,它工作正常。但这不是一个安全的解决方案。仍在努力寻找更好的。

还有一件事,任何人都知道其他用于复制 Firebird 数据库的开源工具,我在 here 中尝试了很多,并且只有 Symmetric 工作。

【问题讨论】:

问题跟踪器中有一个未解决的错误:symmetricds.org/issues/view.php?id=2369 :/ 能否将日志级别降低到 DEBUG 并获取引发异常的 sql 语句? @BorisPavlović “将日志记录级别降低到调试”是什么意思?我在寻找解决方案时看到了这个问题,似乎没有人可以解决它:) 请将错误、日志和代码发布为文本,而不是屏幕截图。 1) 请务必将所有请求和错误以文本形式放入您的问题中。屏幕截图很难重复使用,并且会在不确定的短时间内过期和删除。 2)请将您在 cmets 中提到的其他数据也放入问题文本中。没有人喜欢阅读长长的评论墙来获取数据碎片。 3) 将此讨论与关键数据链接到您在 Symmetrics 上打开的错误报告中,否则如果 Symmetrics 团队会调查它 - 他们永远不会知道那些额外的细节。 【参考方案1】:

问题似乎是 Firebird 中的一个错误,其中 CSTRING 的长度应该以字节为单位,但实际上它使用字符。您的数据库似乎将UTF8(或UNICODE_FSS)作为其默认字符集,这意味着每个字符最多可占用4 个字节(UNICODE_FSS 为3 个字节)。 CSTRING 的最大长度为 32767 字节,但如果以字符为单位计算 CSTRING,则最大值突然减少到 8191 个字符(或 32764 个字节)(或 10922 个字符,UNICODE_FSS 为 32766 个字节)。

解决此问题的方法是使用不同的默认字符集创建数据库。或者,您可以(暂时)更改默认字符集:

对于火鸟 3:

    将默认字符集设置为单字节字符集(例如NONE)。 最好使用NONE 以避免意外的音译问题

    alter database set default character set NONE;
    
    断开连接(重要的是,由于元数据缓存,您可能需要断开所有当前连接!) 设置 SymmetricDS 以创建 UDF

    将默认字符集设置回UTF8(或UNICODE_FSS

    alter database set default character set UTF8;
    
    再次断开连接

使用 Firebird 2.5 或更早版本时,您需要执行直接系统表更新(在 Firebird 3 中不再可能),使用:

第 2 步:

update RDB$DATABASE set RDB$CHARACTER_SET_NAME = 'NONE'

第 4 步:

update RDB$DATABASE set RDB$CHARACTER_SET_NAME = 'UTF8'

替代方案是 SymmetricDS 将其初始化更改为

DECLARE EXTERNAL FUNCTION SYM_HEX
    BLOB
    RETURNS CSTRING(32660) CHARACTER SET NONE FREE_IT
    ENTRY_POINT 'sym_hex' MODULE_NAME 'sym_udf';

或者也许是字符集 BINARY 而不是 NONE,因为这似乎更接近 UDF 的意图。

【讨论】:

看看他的cmets,马克。他声称他的新数据库没有字符集,而不是他的旧数据库。听起来很奇怪…… @Arioch'我错过了那条评论。但是,他们说它适用于一个新的空白数据库,而不是现有数据库,并且与这个答案和他们提到的每个字符集相匹配。 @Arioch'当我创建新的空白数据库进行测试时,我没有设置字符集,将其保留为默认值(无)。旧数据库是很久以前有人创建的,使用字符集UNICODE_FSS,我们的数据库有太多的unicode数据,现在我必须复制这个旧数据库:) @Jacky 默认字符集仅指定添加(创建)新列时使用的字符集,而不指定显式字符集。 @MarkRotteveel 无论如何,感谢update RDB$DATABASE set RDB$CHARACTER_SET_NAME = 'NONE' 声明,在第 3 步停止并且工作正常。当我将 charset 更新回 UNICODE_FSS(第 4 步)时,对称停止工作。

以上是关于使用 Symmetricds 时出现 Firebird 错误的主要内容,如果未能解决你的问题,请参考以下文章

SymmetricDS:保持单独的自动增量计数器

Spring Boot 应用程序中的 SymmetricDS

如何区分使用 SymmetricDS 通过 FTP 传输的 CSV 中的更改数据

如何在 symmetricDS 社区版运行时动态添加引擎

将 SymmetricDS 与 Azure SQL 数据库一起使用时的权限问题

更新由 symmetricds 同步的表