5

在我的生产数据库中,警报相关的表是使用默认的“拉丁语”字符集创建的,因此,当我们尝试在表中插入日文字符时会出错。我们需要将表和列的默认字符集更改为 UTF8。由于这些表有大量数据,Alter 命令可能需要很长时间(在我的本地数据库中使用相同数量的数据需要 5 小时)并锁定表会导致数据丢失。我们能否计划一种机制将 Charset 更改为 UTF8,而不会丢失数据。

更改大型数据表的字符集的更好方法是什么?

4

3 回答 3

6

您可以查看 Percona Toolkit::online-chema-change 工具: pt-online-schema-change
它正是这样做的 - “在不阻塞读取或写入的情况下更改表的结构” - 有一些限制(仅限 InnoDB 表等)和涉及的风险。

于 2014-12-16T13:40:40.947 回答
6

我在 mysql 手册http://dev.mysql.com/doc/refman/5.1/en/alter-table.html上找到了这个:

在大多数情况下,ALTER TABLE 会制作原始表的临时副本。MySQL 等待其他正在修改表的操作,然后继续。它将更改合并到副本中,删除原始表并重命名新表。在执行 ALTER TABLE 时,其他会话可以读取原始表。在 ALTER TABLE 操作开始后开始的对表的更新和写入会停止,直到新表准备好,然后自动重定向到新表,没有任何失败的更新

所以是的 - 在这样做时尽量减少停机时间是很棘手的。这取决于您的表的使用情况,是否有更多的读/写?

我能想到的一种方法是使用某种复制。因此,创建一个使用 UTF-8 的新 Alert 表,并找到一种将原始表复制到新表而不影响可用性/吞吐量的方法。当复制完成(或足够接近)时,通过重命名来切换表?

当然,这说起来容易做起来难——如果可能的话,需要更多的学习。

于 2013-01-25T05:51:15.727 回答
1

当您设置复制发出停止从命令并更改表时,在其他机器或实例上创建数据库的复制副本。如果您有多个表,则在每次对话之间您可以考虑再次发出 start slave 以同步两个数据库。(如果您不这样做,同步可能需要更长的时间)当您完成转换时,复制的副本可以替换您的旧生产数据库并删除旧数据库。这是我发现减少停机时间的方法。

于 2015-04-30T10:26:42.020 回答