前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >pt-osc改表过程中的中文乱码问题

pt-osc改表过程中的中文乱码问题

作者头像
AsiaYe
发布2020-08-10 15:23:35
1.5K0
发布2020-08-10 15:23:35
举报
文章被收录于专栏:DBA随笔
//

pt-osc改表过程中的中文乱码问题

//

下午使用pt-osc工具对线上表进行变更的时候,发现了一个问题,在对latin1字符集进行变更的时候,变更完毕之后的表的中文注释都变成了'?',无法正常显示了。于是在测试环境上进行了实验。

代码语言:javascript
复制
mysql> show create table latin_test1\G
*************************** 1. row ***************************
       Table: latin_test1
Create Table: CREATE TABLE `latin_test1` (
  `id` int(11) NOT NULL,
  `name` varchar(10) DEFAULT NULL COMMENT '任务名称',
  PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

# pt指令
pt-online-schema-change --user=dba_admin --password=xxxxxxxx -h127.0.0.1 -P4306 --alter " ADD index idx_name(name)  " D=yeyz,t=latin_test1 --alter-foreign-keys-method=auto --recursion-method=none --print --charset=latin1 --execute

首先创建一张字符集为latin1的表,它包含id和name两个字段,然后对这个表的name字段添加索引,变更的pt指令如上文,其中:

--charset=latin1

当我们变更完成之后,发现变更的新表内容变成:

代码语言:javascript
复制
mysql> show create table latin_test1\G
*************************** 1. row ***************************
       Table: latin_test1
Create Table: CREATE TABLE `latin_test1` (
  `id` int(11) NOT NULL,
  `name` varchar(10) DEFAULT NULL COMMENT '????',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

可以看到,comment的值变成了'????',而不是我们之前的任务名称。

出现这个情况之后,我重新做了一个测试,在pt工具的指令中,将--charset参数改成了utf8,pt指令如下:

代码语言:javascript
复制
pt-online-schema-change --user=dba_admin --password=xxxxxxx -h127.0.0.1 -P4306 --alter " modify name varchar(10) DEFAULT NULL COMMENT '任务名称' " D=yeyz,t=latin_test1 --alter-foreign-keys-method=auto --recursion-method=none --print --charset=utf8 --execute  

执行完成之后,结果如下:

代码语言:javascript
复制
mysql> show create table latin_test1\G
*************************** 1. row ***************************
       Table: latin_test1
Create Table: CREATE TABLE `latin_test1` (
  `id` int(11) NOT NULL,
  `name` varchar(10) DEFAULT NULL COMMENT '任务名称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

这个结果中,我们可以看到2点:

1、我们的表latin_test1的字符集仍旧是latin1,而没有被改成utf8的字符集

2、表中的中文注释已经可以显示了。

--charset这个参数在pt-osc这个工具中,指的是使用哪种字符集去连接数据库,如果使用utf8的话,那么在连接到数据库之后,会首先执行set names utf8;它指定了客户端和服务器之间传递字符的编码规则为UTF8。如果我们使用latin1这个字符集,则说明pt-osc工具和mysql交互的字符集是latin1,而这个字符集是无法保存汉字的,所以结果中就出现了????的字眼。

除此之外,今天还专门看了下pt-osc工具创建的三个触发器的内容,触发器的内容不是单纯的将主库上的动作原封不动的搬迁到从库上,它的创建规则如下:

(1)对于DELETE操作,pt工具使用DELETE IGNORE在新表进行删除,当新有数据时,我们才进行操作,也就是说,当在后续导入过程中,如果删除的这个数据还未导入到新表,那么我们可以不在新表执行操作,因为在以后的导入过程中,原表中改行数据已经被删除,已经没有数据,那么这条记录也就不会导入到新表中; (2)对于INSERT操作,所有的INSERT INTO全部转换为REPLACE INTO,当有新数据插入到原表时,如果触发器还未把原表数据同步到新表,而这条数据已经被pt工具导入到新表了,再次insert就会发生报错,那么我们就可以利用replace into进行覆盖,这样数据也是一致的 (3)对于UPDATE操作,所有的UPDATE也转换为REPLACE INTO,因为当更新的数据的行还未同步到新表时,新表是不存在这条记录的,直接update肯定会报错,那么我们就只能插入该条数据,如果已经同步到新表了,那么也可以进行覆盖插入,所有数据与原表也是一致的;

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DBA随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档