可扩展性设计之 MySQL Replication(下)
Posted 熬过无人问津的日子才会有远方
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可扩展性设计之 MySQL Replication(下)相关的知识,希望对你有一定的参考价值。
四、Replication 搭建实现
mysql Replication
环境的搭建实现比较简单,总的来说其实就是四步,第一步是做好 Master
端的准备工作。第二步是取得 Master
端数据的“快照”备份。第三步则是在 Slave
端恢复 Master
的备份“快照”。第四步就是在 Slave
端设置 Master
相关配置,然后启动复制。在这一节中,并不是列举一个搭建 Replication
环境的详细过程,因为这在 MySQL
官方操作手册中已经有较为详细的描述了,我主要是针对搭建环境中几个主要的操作步骤中可以使用的各种实现方法的介绍,下面我们针对这四步操作及需要注意的地方进行一个简单的分析。
①Master 端准备工作
在搭建 Replication
环境之前,首先要保证 Master
端 MySQL
记录 Binary Log
的选项打开,因为 MySQL Replication
就是通过 Binary Log
来实现的。让 Master
端 MySQL
记录 Binary Log
可以在启动 MySQL Server
的时候使用 —log-bin
选项或者在 MySQL
的配置文件 my.cnf
中配置 log-bin[=path for binary log]
参数选项。
在开启了记录 Binary Log
功能之后,我们还需要准备一个用于复制的 MySQL
用 户 。可以通过给一个现有帐户授予复制相关的权限,也可以创建一个全新的专用于复制的帐户。当然,我还是建议用一个专用于复制的帐户来进行复制。在之前“MySQL 安全管理”部分也已经介绍过了,通过特定的帐户处理特定一类的工作,不论是在安全策略方面更有利,对于维护来说也有更大的便利性。实现 MySQL Replication
仅仅只需要“REPLICATION SLAVE
”权限即可。可以通过如下方式来创建这个用户:
root@localhost : mysql 04:16:18> CREATE USER 'repl'@'192.168.0.2'
-> IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.00 sec)
root@localhost : mysql 04:16:34> GRANT REPLICATION SLAVE ON *.*
-> TO 'repl'@'192.168.0.2';
Query OK, 0 rows affected (0.00 sec)
这里首先通过 CREATE USER
命令创建了一个仅仅具有最基本权限的用户 repl
,然后再通过 GRANT
命令授予该用户 REPLICATION SLAVE
的权限。当然,我们也可以仅仅执行上面的第二条命令,即可创建出我们所需的用户。
②获取 Master 端的备份“快照”
这里所说的 Master
端的备份“快照”,并不是特指通过类似 LVM
之类的软件所做的 snapshot
,而是所有数据均是基于某一特定时刻的,数据完整性和一致性都可以得到保证的备份集。同时还需要取得该备份集时刻所对应的 Master
端 Binary Log
的准确 Log Position
,因为在后面配置 Slave
的时候会用到。
一般来说,我们可以通过如下集中办法获得一个具有一致性和完整性的备份集以及所对应的 Log Position
:
- 通过数据库全库冷备份
对于可以停机的数据库,我们可以通过关闭 Master
端 MySQL
,然后通过 copy
所有数据文件和日志文件到需要搭建 Slave
的主机中合适的位置,这样所得到的备份集是最完整的。在做完备份之后,然后再启动 Master
端的 MySQL
。
当然,这样我们还仅仅只是得到了一个满足要求的备份集,我们还需要这个备份集所对应的日志位置才能可以。对于这样的备份集,我们有多种方法可以获取到对应的日志位置。如在 Master
刚刚启动之后,还没有应用程序连接上 Master
之前,通过执行 SHOW Master STATUS
命令从 Master
端获取到我们可以使用的 Log Position
。如果我们无法在 Master
启动之后控制应用程序的连接,那么可能在我们还没有来得及执行 SHOW Master STATUS
命令之前就已经有数据写进来了,这时候我们可以通过 mysqlbinlog
客户端程序分析 Master
最新的一个 Binary Log
来获取其第一个有效的 Log Position
。当然,如果你非常清楚你所使用的 MySQL
版本每一个新的 Binary Log
第一个有效的日志位置,自然就不需要进行任何操作就可以。
- 通过
LVM
或者ZFS
等具有snapshot
功能的软件进行“热备份”
如果我们的 Master
是一个需要满足 365 * 24 * 7 服务的数据库,那么我们就无法通过进行冷备份来获取所需要的备份集。这时候,如果我们的 MySQL
运行在支持 Snapshot
功能的文件系统上面(如 ZFS
),或者我们的文件系统虽然不支持 Snapshot
,但是我们的文件系统运行在 LVM
上面,那么我们都可以通过相关的命令对 MySQL
的数据文件和日志文件所在的目录就做一个 Snapshot
,这样就可以得到了一个基本和全库冷备差不多的备份集。
当然,为了保证我们的备份集数据能够完整且一致,我们需要在进行 Snapshot
过程中通过相关命令(FLUSH TABLES WITH READ LOCK
)来锁住所有表的写操作,也包括支持事务的存储引擎中 commit
动作,这样才能真正保证该 Snapshot
的所有数据都完整一致。在做完 Snapshot
之后,我们就可以 UNLOCK TABLES
了。可能有些人会担心,如果锁住了所有的写操作,那我们的应用不是就无法提供写服务了么?确实,这是无法避免的,不过,一般来说 Snapshot
操作所需要的时间大都比较短,所以不会影响太长时间。
那 Log Position
怎么办呢?是的,通过 Snapshot
所做的备份,同样需要一个该备份所对应的 Log Position
才能满足搭建 Replication
环境的要求。不过,这种方式下,我们可以比进行冷备份更容易获取到对应的 Log Position
。因为从我们锁定了所有表的写入操作开始到解锁之前,数据库不能进行任何写入操作,这个时间段之内任何时候通过执行 SHOW MASTER STATUS
明令都可以得到准确的 Log Position
。
由于这种方式在实施过程中并不需要完全停掉 Master
来进行,仅仅只需要停止写入才做,所以我们也可以称之为“热备份”。
- 通过
mysqldump
客户端程序
如果我们的数据库不能停机进行冷备份,而且 MySQL
也没有运行在可以进行 Snapshot
的文件系统或者管理软件之上,那么我们就需要通过 mysqldump
工具来将 Master
端需要复制的数据库(或者表)的数据 dump
出来。为了让我们的备份集具有一致性和完整性,我们必须让 dump
数据的这个过程处于同一个事务中,或者锁住所有需要复制的表的写操作。要做到这一点,如果我们使用的是支持事务的存储引擎(如 Innodb
),我们可以在执行 mysqldump
程序的时候通过添加 —single-transaction
选项来做到,但是如果我们的存储引擎并不支持事务,或者是需要 dump
表仅仅只有部分支持事务的时候,我们就只能先通过 FLUSH TABLES WITH READ LOCK
命令来暂停所有写入服务,然后再 dump
数据。当然,如果我们仅仅只需要 dump
一个表的数据,就不需要这么麻烦了,因为 mysqldump
程序在 dump
数据的时候实际上就是每个表通过一条 SQL
来得到数据的,所以单个表的时候总是可以保证所取数据的一致性的。
上面的操作我们还只是获得了合适的备份集,还没有该备份集所对应的 Log Position
,所以还不能完全满足搭建 Slave
的要求。幸好 mysqldump
程序的开发者早就考虑到这个问题了,所以给 mysqldump
程序增加了另外一个参数选项来帮助我们获取到对应的 Log Position
,这个参数选项就是 —master-data
。当我们添加这个参数选项之后,mysqldump
会在 dump
文件中产生一条 CHANGE MASTER TO
命令,命令中记录了 dump
时刻所对应的详细的 Log Position
信息。如下:
测试 dump example
数据库下的 group_message
表:
sky@sky:~$ mysqldump --master-data -usky -p example group_message >
group_message.sql
Enter password:
然后通过 grep
命令来查找一下看看:
sky@sky:~$ grep "CHANGE MASTER" group_message.sql
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000035', MASTER_LOG_POS=399;
连 CHANGE MASTER TO
的命令都已经给我们准备好了,还真够体贴的,呵呵。
如果我们是要一次性 dump
多个支持事务的表的时候,可能很多人会选择通过添加 —single-transaction
选项来保证数据的一致性和完整性。这确实是一个不错的选择。但是,如果我们需要 dump
的数据量比较大的时候,可能会产生一个很大的事务,而且会持续较长的时间。
- 通过现有某一个
Slave
端进行“热备份”
如果现在已经有 Slave
从我们需要搭建 Replication
环境的 Master
上进行复制的话,那我们这个备份集就非常容易取得了。我们可以暂时性的停掉现有 Slave
(如果有多台则仅仅只需要停止其中的一台),同时执行一次 FLUSH TABLES
命令来刷新所
有表和索引的数据。这时候在该 Slave
上面就不会再有任何的写入操作了,我们既可以通过 copy
所有的数据文件和日志文件来做一个全备份,同时也可以通过 Snapshot
(如果支持)来进行备份。当然,如果支持 Snapshot
功能,还是建议大家通过 Snapshot
来做,因为这样可以使 Slave
停止复制的时间大大缩短,减少该 Slave
的数据延时。
通过现有 Slave
来获取备份集的方式,不仅仅得到数据库备份的方式很简单,连所需要 Log Position
,甚至是新 Slave
后期的配置等相关动作都可以省略掉,只需要新的 Slave
完全基于这个备份集来启动,就可以正常从 Master
进行复制了。
整个过程中我们仅仅只是在短暂时间内停止了某台现有 Slave
的复制线程,对系统的正常服务影响很小,所以这种方式也基本可以称之为“热备份”。
③Slave 端恢复备份“快照”
上面第二步我们已经获取到了所需要的备份集了,这一步所需要做的就是将上一步所得到的备份集恢复到我们的 Slave
端的 MySQL
中。
针对上面四种方法所获取的备份集的不同,在 Slave
端的恢复操作也有区别。下面就针对四种备份集的恢复做一个简单的说明:
- 恢复全库冷备份集
由于这个备份集是一个完整的数据库物理备份,我们仅仅只需要将这个备份集通过 FTP
或者是 SCP
之类的网络传输软件复制到 Slave
所在的主机,根据 Slave
上 my.cnf
配置文件的设置,将文件存放在相应的目录,覆盖现有所有的数据和日志等相关文件,然后再启动 Slave
端的 MySQL
,就完成了整个恢复过程。
- 恢复对
Master
进行Snapshot
得到的备份集
对于通过对 Master
进行 Snapshot
所得到的备份集,实际上和全库冷备的恢复方法基本一样,唯一的差别只是首先需要将该 Snapshot
通过相应的文件系统 mount
到某个目录下,然后才能进行后续的文件拷贝操作。之后的相关操作和恢复全库冷备份集基本一致,就不再累述。
- 恢复
mysqldump
得到的备份集
通过 mysqldump
客户端程序所得到的备份集,和前面两种备份集的恢复方式有较大的差别。因为前面两种备份集的都属于物理备份,而通过 mysqldump
客户端程序所做的备份属于逻辑备份。恢复 mysqldump
备份集的方式是通过 mysql
客户端程序来执行备份文件中的所有 SQL
语句。
使用 mysql
客户端程序在 Slave
端恢复之前,建议复制出通过 —master-data
所得到的 CHANGE MASTER TO
命令部分,然后在备份文件中注销掉该部分,再进行恢复 。因为该命令并不是一个完整的 CHANGE MASTER TO
命令,如果在配置文件(my.cnf
)中没有配置 MASTER_HOST
,MASTER_USER
,MASTER_PASSWORD
这三个参数的时候,该语句是无法有效完成的。
通过 mysql
客户端程序来恢复备份的方式如下:
sky@sky:~$ mysql -u sky -p -Dexample < group_message.sql
这样即可将之前通过 mysqldump
客户端程序所做的逻辑备份集恢复到数据库中了。
- 恢复通过现有
Slave
所得到的热备份
通过现有 Slave
所得到的备份集和上面第一种或者第二种备份集也差不多。如果是通过直接拷贝数据和日志文件所得到的备份集,那么就和全库冷备一样的备份方式,如果是通过 Snapshot
得到的备份集,就和第二种备份恢复方式完全一致。
④配置并启动 Slave
在完成了前面三个步骤之后, Replication
环境的搭建就只需要最后的一个步骤了,那就是通过 CHANGE MASTER TO
命令来配置 然后再启动 Slave
了。
CHANGE MASTER TO
命令总共需要设置 5 项内容,分别为:
- MASTER_HOST:
Master
的主机名(或者 IP 地址); - MASTER_USER:
Slave
连接Master
的用户名,实际上就是之前所创建的repl
用户; - MASTER_PASSWORD:
Slave
连接Master
的用户的密码; - MASTER_LOG_FILE:开始复制的日志文件名称;
- MASTER_LOG_POS:开始复制的日志文件的位置,也就是在之前介绍备份集过程中一致提到的
Log Position
。
下面是一个完整的 CHANGE MASTER TO
命令示例:
CHANGE MASTER TO
root@localhost : mysql 08:32:38> CHANGE MASTER TO
-> MASTER_HOST='192.168.0.1',
-> MASTER_USER='repl',
-> MASTER_PASSWORD='password',
-> MASTER_LOG_FILE='mysql-bin.000035',
-> MASTER_LOG_POS=399;
执行完 CHANGE MASTER TO
命令之后,就可以通过如下命令启动 SLAVE
了:
root@localhost : mysql 08:33:49> START SLAVE;
至此,我们的 Replication
环境就搭建完成了。读者朋友可以自己进行相应的测试来尝试搭建,如果需要了解 MySQL Replication
搭建过程中更为详细的步骤,可以通过查阅 MySQL 官方手册。
总结
在实际应用场景中,MySQL Replication
是使用最为广泛的一种提高系统扩展性的设计手段。 众多的 MySQL
使用者通过 Replication
功能提升系统的扩展性之后,通过简单的增加价格低廉的硬件设备成倍甚至成数量级的提高了原有系统的性能,是广大 MySQL
中低端使用者最为喜爱的功能之一,也是大量 MySQL
使用者选择 MySQL
最为重要的理由之一。
以上是关于可扩展性设计之 MySQL Replication(下)的主要内容,如果未能解决你的问题,请参考以下文章