mysql同步之3
手册来源:MySQL手册版本 5.0.20,出处:http://imysql.cn,转载请注明译者和出处,并且不能用于商业用途,违者必究。6.5 不同MySQL版本之间的同步兼容性
最早的二进制格式是在MySQL 3.23中开发出来的。在MySQL 4.0中改进了,MySQL 5.0又改进了。在配置同步时需要升级服务器的话,它们之间的因果关系在"6.6 Upgrading a Replication Setup"中描述了。
如果只关心同步,任何MySQL 4.1.x版本和MySQL 4.0.x是一样的,因为它们都使用相同格式的二进制日志。所以,这些版本是互相兼容的,它们之间可以无缝地运行同步。一个例外的情况是,MySQL 4.0.0到4.0.2由于开发的较早,无法和后来的版本互相兼容,所以不要使用它们(它们是4.0版本的alpha系列。它们之间的兼容性在发布包的手册中均有相关文档)。
下表展示了不同版本的MySQL之间的master/slave同步兼容性。
Master Master Master
3.23.33 and up 4.0.3 and up or any 4.1.x 5.0.0
Slave 3.23.33 and up yes no no
Slave 4.0.3 and up yes yes no
Slave 5.0.0 yes yes yes
一个通常的规则是,我们建议使用最近的MySQL版本,因为同步兼容性一直在改善。我们也建议master和slave都使用同一个版本。
6.6 升级同步
如果升级服务器时涉及到配置同步,升级设置的步骤跟当前版本以及升级后的版本不同而异。
6.6.1 升级同步到 4.0 或 4.1
本节适用于从MySQL 3.23升级到4.0或者4.1的情况。4.0的服务器必须是4.0.3或者更新,"6.5 Replication Compatibility Between MySQL Versions"中提到了。
把master从MySQL 3.23升级到4.0或4.1时,首先要确认这个master的所有slave都已经是4.0或4.1了,否则的话,要先升级slave:挨个关闭,升级,重启,重启同步等。
通过以下步骤可以实现安全地升级,假定master要升级到3.23,而slave已经是4.0或4.1了。注意,master升级后,不要重启使用任何旧的二进制日志的同步,因为它会干扰到4.0或4.1 slave的同步。
1. 在master上执行 FLUSH TABLES WITH READ LOCK 语句,阻止所有的更新。
2. 等到所有的slave都跟上了master的数据更新。在master上执行 SHOW MASTER STATUS 语句取得二进制日志以及偏移位置。然后,再slave用这些值执行 SELECT MASTER_POS_WAIT() 语句,它会阻止slave上的同步且返回它已经同步的偏移位置。然后在slave上执行 STOP SLAVE 语句。
3. 关闭master,将它升级到MySQL 4.0或4.1。
4. 重启master,记下它的新的二进制文件名。可以在master上执行 SHOW MASTER STATUS 语句来取得这些信息。然后在每个slave上都执行如下语句:
mysql> CHANGE MASTER TO MASTER_LOG_FILE='binary_log_name',
-> MASTER_LOG_POS=4;
mysql> START SLAVE;
6.6.2 升级同步到 5.0
本节适用于从MySQL 3.23,4.0或4.1升级到5.0的情况。4.0的服务器必须是4.0.3或者更新,"6.5 Replication Compatibility Between MySQL Versions"中提到了。
首先,注意到MySQL 5.0还是alpha发布系列。它在各方面都比旧版本好(更容易升级一些同步中重要的会话变量,例如 sql_mode;详情请看"C.1.3 Changes in release 5.0.0 (22 Dec 2003: Alpha")。不过,它还没经过广泛测试。由于是alpha版本,我们不建议用于任何生产环境(现在已经可以用于生产了,译者注)。
把master从MySQL 3.23,4.0或4.1升级到5.0.0时,首先要确认这个master的所有slave都已经是5.0.0了,否则的话,要先升级slave:挨个关闭,升级,重启,重启同步等。5.0.0的slave可以读取升级前写入的执行语句的中继日志。升级完后的slave创建的中继日志就是5.0格式了。
当所有的slave都升级完了,关闭master,升级到5.0.0,然后重启。5.0.0的master也可以读取旧格式的二进制日志。slave能识别旧的格式并且合理处理它们。master上新建的二进制日志都是5.0.0格式的。slave也能识别这格式。
换言之,在升级到5.0.0时无需特殊的规定,除非在升级master到5.0.0之前slave必须使用旧版本的。注意,把5.0.0降级到旧版本中不能自动地做了:必须确保所有的5.0.0格式二进制日志和中继日志都已经处理完了,然后才能把它们删除完成降级。
6.7 同步特性及已知问题
以下列出了同步支持什么,不支持什么。附加的 InnoDB 特殊相关的信息以及同步请看"16.7.5 InnoDB and MySQL Replication"。
* AUTO_INCREMENT, LAST_INSERT_ID(), 和 TIMESTAMP 的值都能被正常同步。
* USER(), UUID(), 和 LOAD_FILE() 函数都完完全全地同步到slave,因此可能不大可靠。MySQL 4.1.1以前的版本中的 CONNECTION_ID() 函数也是如此。从MySQL 4.1.1及更高以后,新的 PASSWORD() 函数可以正常同步,当然了,slave必须是4.1.1或更高或者不同步它。如果有旧版本的slave必须要同步 PASSWORD() 函数,那么master启动时必须增加 --old-password 选项,这样在master上就用旧的方法来实现 PASSWORD() 了(注意,MySQL 4.1.0的 PASSWORD() 函数实现跟其他的版本都不同,最好不要同步4.1.0)。
* 从MySQL 4.0.14开始同步 FOREIGN_KEY_CHECKS 变量。从5.0.0开始同步 sql_mode, UNIQUE_CHECKS,和 SQL_AUTO_IS_NULL 变量。 SQL_SELECT_LIMIT 和 table_type 变量目前还不能被同步。
* 现在讨论使用不同字符集的MySQL服务器间同步的问题。
1. 首先,在master和slave上必须总是使用同样的全局字符集以及校验字符集(--default-character-set, --default-collation 都是相关的全局变量)。否则,slave上可能会出现键重复(duplicate-key)的错误,因为用master的字符集认为该键可能是唯一的,但是用slave的字符集则未必然。
2. 第二,如果master必须低于MySQL 4.1.3,则会话(session)的字符集必须和全局值一样(也就是说,不能执行 SET NAMES, SET CHARACTER SET 等语句),因为这些对字符集的修改在slave不能识别。如果master是4.1.3或者更新,slave也是这样的话,那么会话字符集就可以随便修改了(执行 NAMES, CHARACTER SET, COLLATION_CLIENT, COLLATION_SERVER 等),并且这些修改都会被记录到二进制日志中,然后同步到slave上,它就知道怎么做了。该会话还会阻止试图修改这些全局变量的操作;就如前面所说,master和slave必须使用同样的全局字符集。
3. 如果在master上有和全局变量 collation_server 不一样字符集的数据库,那么就要设计 CREATE TABLE 语句使得数据表不隐式地使用该数据库的默认字符集,因为这目前还是一个bug(Bug #2326);一个变通的办法是在 CREATE TABLE 语句中显式地声明数据表的字符集以及校验字符集。
* 有时可能会把master上的事务表同步到slave后变成非事务表。例如,可以在slave上把master的 InnoDB 表当成 MyISAM 表。不过,slave在一个 BEGIN/COMMIT 区块中停止的话就有问题了,因为slave会从 BEGIN 重新开始。这个问题已经放到TODO中,很快会被修复。
* 更新语句中如果用到了用户自定义变量(例如变量 @var_name)的情况下,在MySQL 3.23和4.0不能被正确同步。在 4.1 这已经修复了。注意,从MySQL 5.0开始,用户变量就不区分大小写了。在做MySQL 5.0和旧版本间的同步需要考虑到这个问题。
* 从4.1.1以及更新版本中,slave可以用SSL方式连接到master。
* 在master上执行的 CREATE TABLE 语句如果包括了 DATA DIRECTORY或 INDEX DIRECTORY 子句,那么它也会应用于slave上。如果slave上不存在对应的目录或者没有权限时便出现问题。从MySQL 4.0.15开始,有个 sql_mode 选项叫 NO_DIR_IN_CREATE。如果slave的SQL模式包含这个选项,那么它在同步 CREATE TABLE 语句前会忽略前面提到的2个子句。结果就是 MyISAM 的数据和索引文件都只能放在该表的数据库目录下。
* 尽管没听说过发生过类似的情况,不过理论上确实存在这种可能性:如果一个查询被设计为非确定方式的修改数据,那么可能导致master和slave的数据不一致。那么,就把决定的权力交给查询优化器吧。(通常这不是一个好的做法,甚至超出了同步的范围,详情请看"1.8.7.3 Open Bugs and Design Deficiencies in MySQL")
* 在MySQL 4.1.1之前,FLUSH, ANALYZE TABLE, OPTIMIZE TABLE,和 REPAIR TABLE 语句没有写入到二进制日志中,因此也不会同步到slave上。这通常不会引发问题,因为它们并没有修改数据。不过在特定情况下可能导致问题。如果同步 mysql 数据库下的权限表,在更新时不是用 GRANT 语句,那么必须在slave上执行那么必须在slave上执行 FLUSH PRIVILEGES 语句才能使之生效。同样地,如果还有一个 MyISAM 表是 MERGE 表的一部分,那么必须在slave上手工执行 FLUSH TABLES 语句。从MySQL 4.1.1开始,这些语句都写入二进制日志了(除非指定选项 NO_WRITE_TO_BINLOG 或它的同名选项 LOCAL)。一些例外的情况是 FLUSH LOGS, FLUSH SLAVE, 和 FLUSH TABLES WITH READ LOCK (它们中的任何一个同步到slave的话都可能导致问题)。例子可见"14.5.4.2 FLUSH Syntax"。
* MySQL只支持一个master多个slave的机制。以后我们会增加一个表决算法,如果当前master出现问题时能自动切换。同时也会引进一个"代理"进程来帮助将 SELECT 查询发送到不同的slave上达到负载均衡。
* 当服务器关闭,重启后,所有的 MEMORY (HEAP) 表都清空了。从MySQL 4.0.18开