mysql数据校验过程中的字符集问题处理

场景:
主库DB:utf8字符集
备库DB:gbk字符集

需求:
校验主备数据是否一致,并且修复

校验过程:
设置主库连接为utf8,设置备库连接为gbk,分别进行查询,将返回的的结果集按记录逐字段比较。

显示结果:
原本相同的汉字字符,数据校验认为不一致。

原因分析:
对于主库而已,由于建立连接的字符集为UTF8,则返回的汉字字符编码为UTF8格式;对于备库而言则是GBK格式,而程序中通过字符串比较函数strcasecmp进行比较,显然不同的字符集编码,相同的字符有不同的二进制,因此结果肯定不会相等。

进一步分析:
那么对于这种情况,建立连接应该采用哪种字符集呢?GBK or UTF8。其实选择任何一种字符集都是OK的,只要是访问主库和备库的字符集保持一致即可,唯一的区别在于,若选择的字符集与客户端的字符集不一致,可能导致无法正常显示字符,即字符显示为乱码。

我们以客户端的字符集为例,详细说说三种情况:【这里的客户端可以认为是SecureCRT】
备注:绿色框代表DB字符集,黄色框代表连接字符集,橙色框代表客户端
第一种情况:

就是上述的情况,主库返回字符的GBK编码,备库返回字符的UTF8编码,因此进行字段比对,则会出现误差。

第二种情况:

访问主库的连接不变,备库连接由UTF8变为GBK,因此进行返回时,数据库会将DB的字符集转为GBK返回给客户端,那么对于客户端而已,相同字符都是通过GBK编码表示,因此二进制相等,校验结果正确。

第三种情况:

访问主库和备库的连接都是UTF8,因此对于主库而已,返回给客户端的字符编码由GBK转为UTF8,此时主库和备库都是UTF8编码,校验结果正确。但由于客户端实质是GBK编码方式显示,因此返回的汉字字符都是乱码,但不影响校验结果的正确性。

修复:

既然选择与主备库任一一个相同的字符集去访问,都不会影响校验结果的正确性,那么影响修复呢?由于UTF8的编码范围比GBK编码范围要大,因此若采用GBK连接访问UTF8编码DB,有可能出现部分字符GBK不能表示的情况。

我们拿第二种情况说明,此时主库为GBK,备库为UTF8,使用GBK访问UTF8。假设存在UTF8转为GBK过程中部分字符丢失,这时候主备库肯定是不一致的,因为存在部分字符GBK无法表示。 假设修复语句如下:

Update  t set c1=master_value  where  c1=slave_value  and id=?

其中t表示表名,id是主键表示某一行,master_value为主库c1列的值,slave_value为备库c1列的值。此时,slave_value由于UTF8转为GBK已经丢失,因此语句执行最终影响0行记录,无法修复。

结论:

客户端访问两个不同字符集库进行数据校验时,连接采用表示范围更大的字符集。比如我们常用的字符集表示范围如下:

Latin<gb2312<gbk<utf8

附:mysql客户端与服务器通信时字符集编码转换流程

相关参数:

– character_set_client:客户端来源数据使用的字符集

– character_set_connection:连接层字符集

– character_set_results:查询结果字符集

– character_set_database:当前选中数据库的默认字符集

– character_set_system:系统元数据(字段名等)字符集

1.客户端请求服务器

1)将client的字符集转为connection字符集

2)将connection字符集转为DB内部的字符集

2.服务器返回结果给客户端

1)将DB内部字符集转为connection字符集

2)将connection字符集转为character_set_results字符集

3.设置字符集命令:set names 字符编码

指定客户端与服务器通信的字符集,包括请求与返回。

SET NAMES 'x'  等价于:

SET character_set_client = x;

SET character_set_results = x;

SET character_set_connection = x;

附图:

(0)

相关推荐

  • mysql数据校验过程中的字符集问题处理

    场景:主库DB:utf8字符集备库DB:gbk字符集 需求:校验主备数据是否一致,并且修复 校验过程:设置主库连接为utf8,设置备库连接为gbk,分别进行查询,将返回的的结果集按记录逐字段比较. 显示结果:原本相同的汉字字符,数据校验认为不一致. 原因分析:对于主库而已,由于建立连接的字符集为UTF8,则返回的汉字字符编码为UTF8格式:对于备库而言则是GBK格式,而程序中通过字符串比较函数strcasecmp进行比较,显然不同的字符集编码,相同的字符有不同的二进制,因此结果肯定不会相等. 进

  • MySQL 数据持久化过程讲解

    目录 1. 过程简述 2. 内存中的操作 3. 磁盘的持久化 3.1 事务日志的作用 3.2 表结构的两步存储 1. 过程简述 理解MySQL数据的持久化过程,能很好的帮助我们加深对于MySQL底层的理解,在本文,我们以一种通俗的方式梳理一下这个过程,帮助大家建立起初步的认识,如果大家感兴趣,可以去深入学习与研究这个过程. MySQL数据的存储总体上可以分为两部分,内存中的存储过程以及硬盘的持久化存储,这里,就涉及到了内存中buffer poll和redo log以及磁盘上的事务日志和表结构,在

  • MySQL 处理插入过程中的主键唯一键重复值的解决方法

    本篇文章主要介绍在插入数据到表中遇到键重复避免插入重复值的处理方法,主要涉及到IGNORE,ON DUPLICATE KEY UPDATE,REPLACE:接下来就分别看看这三种方式的处理办法. IGNORE 使用ignore当插入的值遇到主键(PRIMARY KEY)或者唯一键(UNIQUE KEY)重复时自动忽略重复的记录行,不影响后面的记录行的插入, 创建测试表 CREATE TABLE Tignore (ID INT NOT NULL PRIMARY KEY , NAME1 INT )d

  • SpringBoot服务端数据校验过程详解

    这篇文章主要介绍了SpringBoot服务端数据校验过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 对于任何一个应用而言,客户端做的数据有效性验证都不是安全有效的,而数据验证又是一个企业级项目架构上最为基础的功能模块,这时候就要求我们在服务端接收到数据的时候也对数据的有效性进行验证.为什么这么说呢?往往我们在编写程序的时候都会感觉后台的验证无关紧要,毕竟客户端已经做过验证了,后端没必要在浪费资源对数据进行验证了,但恰恰是这种思维最为容易

  • Python操作ES的方式及与Mysql数据同步过程示例

    目录 Python操作Elasticsearch的两种方式 mysql和Elasticsearch同步数据 haystack的使用 Redis补充 Python操作Elasticsearch的两种方式 # 官方提供的:Elasticsearch # pip install elasticsearch # GUI:pyhon能做图形化界面编程吗? -Tkinter -pyqt # 使用(查询是重点) # pip3 install elasticsearch https://github.com/e

  • MySQL MGR搭建过程中常遇见的问题及解决办法

    MGR搭建过程中遇到的一些故障 实际中我一共部署了三套MGR环境,分别是单机多实例的MGR环境,多机同网段的MGR环境,多机不同网段的MGR环境,部署的过程大同小异,但是还是有一些有出入的地方,这里把部署过程遇到的故障列举出来,供大家参考,如果能有幸解决您在部署时候的问题,那是极好的. 01 常见故障1 [ERROR] Plugin group_replication reported: 'This member has more executed transactions than those

  • Spring boot通过切面,实现超灵活的注解式数据校验过程

    目录 通过切面,实现超灵活的注解式数据校验 Spring MVC的校验方式 通过切面实现自己的注解式数据校验 Spring boot aop注解数据权限校验 注解类 AOP切面 使用 通过切面,实现超灵活的注解式数据校验 在企业系统的开发中,用户表单输入的场景是会经常遇见的,如何让数据校验脱离于业务代码逻辑,谁也不想在逻辑代码里对字段逐一判断.... Spring MVC的校验方式 在使用Spring MVC时的时候,直接使用hibernate-validator的注解,如下: public c

  • MySQL数据归档小工具mysql_archiver详解

    一.主要概述 MySQL数据库归档历史数据主要可以分为三种方式:一.创建编写SP.设置Event:二.通过dump导入导出:三.通过pt-archiver工具进行归档.第一种方式往往受限于同实例要求,往往被大家舍弃.第二种,性能相对较好,但是归档表较多时运维也是比较头疼的事.所以很多DBA往往采用第三种方式--pt-archiver. pt-archiver是Percona-Toolkit工具集中的一个组件,是一个主要用于对MySQL表数据进行归档和清除的工具.它可以将数据归档到另一张表或者是一

  • mysql 数据备份与恢复使用详解(超完整详细教程)

    目录 一.前言 二.数据备份策略 1.全备 2.增备 3.差异备份 三.数据备份类型 1.冷备 2.热备 3.温备 四.前置准备 五.mysqldump 数据备份命令使用 1.命令格式 2.案例演示 3.其他重要参数选项补充 六.mysqldump 数据恢复 1.全量恢复 2.全量备份中恢复单库 3.从某个数据库中恢复单表数据 4.使用dump + binlog进行数据恢复 七.物理备份 八.表的导出与导入 1. 使用SELECT…INTO OUTFILE导出文本文件 2. 使用mysqldum

  • Linux下PHP+MYSQL+APACHE配置过程 (摘)第1/2页

    需要软件如下:  apache: http://www.apache.org  mysql: http://www.mysql.com  php: http://www.php.net/downloads.php  gd: http://www.boutell.com/gd/#buildgd  ZendOptimizer http://www.zend.org/products/zend_optimizer  Gettext http://ftp.gnu.org/pub/gnu/gettext/

随机推荐