求 perl 高手,解决 pt-table-sync 的一个 json 字段的中文乱码问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
hetal
V2EX    程序员

求 perl 高手,解决 pt-table-sync 的一个 json 字段的中文乱码问题

  •  
  •   hetal 2024-05-10 17:33:24 +08:00 1578 次点击
    这是一个创建于 526 天前的主题,其中的信息可能已经有所发展或是发生改变。

    官方都 2 年了这个 bug 一直没有解决,看了一下 pt-table-sync 的 perl 代码,1 万多行,后面发现应该是 perl 的 DBI 的问题

    15 条回复    2025-09-15 14:06:41 +08:00
    xycc
        1
    xycc  
       2024-05-11 16:13:21 +08:00
    https://metacpan.org/pod/DBD::mysql#mysql_enable_utf8
    源代码太长了,看不了,我搜了下 DBI->connect,只有一处,在 2256 行,你把上面 2229 行的 mysql_enable_utf8 改成 mysql_enable_utf8mb4 试试?
    hetal
        2
    hetal  
    OP
       2024-05-11 21:43:41 +08:00
    @xycc 感谢,都试过了,有 2 ,3 个地方涉及到编码问题,都没有效果~~,他不是普通字段的编码问题,就只有 json 字段的编码问题~~
    zhanglintc
        3
    zhanglintc  
       2024-05-12 16:28:05 +08:00
    大概就是`sub process_rows`方法 3564 行那里,拼出来的$sql 有问题:


    以官方那个 bug 为例:
    ```
    DB<3> x $sql
    0 'UPDATE `pt-sync`.`t_article` SET `topics`=\'["中国", "美国", "China", "USA"]\', `title`=\'\x{6D4B}\x{8BD5}\x{4E2D}\x{6587} test Chinese\' WHERE `pk_article`=\'11\' LIMIT 1'
    ```

    很明显 title 那里是类似`\x{6D4B}`的字符串,而 topics 是`中国`。但是我还是不知道怎么改。。。
    感觉可能可以在这里自己编码一下。
    zhanglintc
        4
    zhanglintc  
       2024-05-12 17:48:57 +08:00
    改了下,简单测试 OK ,晚点改一版试试
    zhanglintc
        5
    zhanglintc  
       2024-05-12 23:40:07 +08:00
    试试这个改法,生成 sql 语句前直接手动改下编码。

    链接: https://pan.baidu.com/s/1L0R4S6FHYzOpJQyBDNsHYg?pwd=xz3q 提取码: xz3q 复制这段内容后打开百度网盘手机 App ,操作更方便哦

    文件版本不一定完全一致,参考着看一下。
    zhanglintc
        6
    zhanglintc  
       2024-05-12 23:47:21 +08:00
    存个测试代码:./pt-table-sync --verbose --execute --databases 'pt-sync' h=192.168.33.10,P=3306,u=root,p=@Az123456 h=192.168.33.11,P=3306,u=root,p=@Az123456
    hetal
        7
    hetal  
    OP
       2024-05-13 10:51:49 +08:00
    感谢,我试试
    hetal
        8
    hetal  
    OP
       2024-05-13 11:06:48 +08:00
    确实可以了,真是感谢;
    我觉得您可以给官方提一个 pull 啦,他们 2 年都没有搞定这个 bug 。
    zhanglintc
        9
    zhanglintc  
       2024-05-13 12:58:56 +08:00
    @hetal #8 我这个改法虽然解决了你这个问题,但是感觉不是特别好,真要提 PR 还得斟酌斟酌。
    hetal
        10
    hetal  
    OP
       2024-05-13 14:26:02 +08:00
    @zhanglintc 您考虑得很周到,diff 了一下代码,是固定 utf8 编码,如果能动态根据 mysql 或 参数--charset 来判定,估计就能满足官方的需求了
    zhanglintc
        11
    zhanglintc  
       2024-05-14 20:35:59 +08:00
    Code uploaded into GitHub.
    Permanent link see :https://github.com/zhanglintc/pt-table-sync-bug-fix
    hetal
        12
    hetal  
    OP
       2024-05-14 21:01:22 +08:00
    @zhanglintc 赞~~~~
    dandankele
        13
    dandankele  
       36 天前
    @zhanglintc 老哥。。pt-archiver 也有类似问题,能否照这思路帮忙改一下,官方都 5 年没动静了。。原问题: https://forums.percona.com/t/when-pt-archiver-archives-mysql-json-fields-garbled-characters-appear/39307
    hetal
        14
    hetal  
    OP
       35 天前
    @dandankele 可以 diff 一下 pt-table-sync 的修改,应该比较好改了
    dandankele
        15
    dandankele  
       33 天前   1
    @hetal 好的感谢,大致的参照了下上面老哥的处理方式做了调整。。好像是 json 类型字段并没有做 utf8 解码,问题在于 perl 的 DBI 的库 https://github.com/perl5-dbi/DBD-mysql/issues/309 ,希望给后人留下一些有用信息
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2520 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 11:54 PVG 19:54 LAX 04:54 JFK 07:54
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86