【问题标题】:charsets in MySQL replicationMySQL 复制中的字符集
【发布时间】:2011-03-03 21:08:48
【问题描述】:

如何确保复制将使用 latin1 而不是 utf-8?

我正在 Linux 系统上的 MySQL 5.1.22 服务器(主)和 FreeBSD 系统上的 MySQL 5.1.42 服务器(从)之间迁移。我的复制效果很好,但是当我的 varchars 中有非 ascii 字符时,它们会变得“奇怪”。 Linux/MySQL-5.1.22 显示以下字符集变量:

character_set_client=latin1
character_set_connection=latin1
character_set_database=latin1
character_set_filesystem=binary
character_set_results=latin1
character_set_server=latin1
character_set_system=utf8
character_sets_dir=/usr/share/mysql/charsets/
collation_connection=latin1_swedish_ci
collation_database=latin1_swedish_ci
collation_server=latin1_swedish_ci

当 FreeBSD 显示时

character_set_client=utf8
character_set_connection=utf8
character_set_database=utf8
character_set_filesystem=binary
character_set_results=utf8
character_set_server=utf8
character_set_system=utf8
character_sets_dir=/usr/local/share/mysql/charsets/
collation_connection=utf8_general_ci
collation_database=utf8_general_ci
collation_server=utf8_general_ci

从 MySQL CLI 设置这些变量中的任何一个都没有效果,并且在 my.cnf 或命令行中设置它们会使服务器无法启动。

当然,两台服务器都以相同的方式创建有问题的表,在本例中使用 DEFAULT CHARSET=latin1。举个例子吧:

CREATE TABLE `test` (
  `test` varchar(5) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1

当我在 master 上做时,在 Latin1 终端中,“INSERT INTO test VALUES ('æøå')”,当我从基于 Latin1 的终端中选择它时,这变成了奴隶

+--------+
| test   |
+--------+
| æøå    |
+--------+

在复制从属设备上基于 UTF-8 的终端上,测试包含:

+--------+
| test   |
+--------+
| æøå    |
+--------+

所以我的结论是转换为utf8,即使表定义是latin1。这是一个正确的结论吗?

当然,在 master 上,在一个 latin1 终端上,它仍然说:

+------+
| test |
+------+
| æøå  | 
+------+

由于两个系统字符集都是 utf-8,如果我将两个终端都设置为 utf-8 并在使用 utf-8 终端的主设备上再次执行“INSERT INTO test VALUES ('æøå')”,在从设备上使用utf-8 我得到:

+------------+
| test       |
+------------+
| æøà     |
+------------+

如果我的结论是正确的,我所有复制的数据都被转换为utf8(如果是utf8,它被视为latin1并转换为utf8),而表中的所有旧数据,正如CREATE TABLE所暗示的那样,拉丁语1。如果不是因为遗留应用程序依赖它是 latin1 的事实,我很乐意将它全部转换为 utf-8,所以我需要在它们仍然存在时将其保留在 latin1 中。

如何确保复制读取 latin1、将其视为 latin1 并将其作为 latin1 写入从属设备?

干杯

尼克

【问题讨论】:

    标签: mysql utf-8 character-encoding replication iso-8859-1


    【解决方案1】:

    不支持在全局 character_set_% 和 collat​​ion% 参数不同的服务器之间进行复制。

    http://dev.mysql.com/doc/refman/5.6/en/replication-features-charset.html

    -- on both servers check the output of...
    SHOW VARIABLES LIKE 'char%';
    SHOW VARIABLES LIKE 'collat%';
    

    如果集合和排序规则不同,复制不仅会失败,而且在转换集合/排序规则期间会导致排序顺序不同和字符丢失。如果使用基于语句的复制,排序顺序会影响插入/更新等内容。

    您最好将新服务器配置为使用与旧服务器相同的集合和排序规则。这将确保复制正常工作。您还需要确保数据库、表和列在主从之间都具有相同的排序规则。迁移到新服务器后,您可以使用 5.6 在线模式更改或 percona 工具包中的 pt-online-schema-change 等工具修改集合和排序规则。

    我还建议运行 percona 的 pt-table-checksum 以确保您的表在复制或初始导出/导入期间没有分歧。

    有关差异影响的更多信息,请参见此处:

    对于使用 Amazon RDS 的任何人,请记住默认 mysql 5.6 设置使用混合 utf8(mb3) 和 latin1(用于服务器和数据库)。如果从非 RDS 复制到/从 RDS(匹配源/目标服务器),您应该使用自定义参数组覆盖那些。

    【讨论】:

      【解决方案2】:

      一般来说,你必须在slave上使用完全相同的配置文件和mysql版本(除了在升级/迁移场景,以及一些需要在slave上不同的东西,比如server_id)。

      您需要编写数据库设置脚本,以便您的数据库服务器成为软件部署的一部分。所有数据库服务器(包括非生产环境中的服务器)都必须使用完全相同的配置。

      未能同步配置将导致意外错误。

      我不知道您为什么觉得需要在不同的服务器上运行不同的操作系统,但如果您这样做,您的运营人员的生活将会变得更加困难。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-15
        • 2010-09-20
        相关资源
        最近更新 更多