复制
从另一个服务器开始复制
前面的设置都是嘉定主备库均为刚刚安装好且都是默认的数据,也就是说两台服务器上数据相同,并且知道当前主库的二进制日志。这不是典型的案例,大多数情况下有一个已经运行了一段时间的主库,然后用一台新安装的备库与之同步,此时这台备库还没有数据。有几种办法来初始化备库或者从其他服务器克隆到备库。包括从主库复制数据、从另外一台备库克隆数据,以及使用最近的一次备份来启动备库,需要由三个条件来让主库和备库保持同步:
- 1.在某个时间点的主库的数据快照
- 2.主库当前的二进制日志文件,和获得数据快照时在该二进制日志文件中的偏移量,我们把这两个值称为日志文件坐标(log file coordinates)。通过这两个值可以确定二进制日志的位置。可以通过SHOW MASTER STATUS命令来获取这些值
- 3.从快照时间到现在的二进制日志
下面是一些从别的服务器克隆备库的方法:
- 1.使用冷备份
最基本的方法是关闭主库,把数据复制到备库.重启主库后,会使用一个新的二进制文件,我们在备库通过执行CHANGE MASTER TO 指向这个文件的起始处。这个方法的缺点很明显:在复制数据时需要关闭主库 - 2.使用热备份
如果仅使用了MyISAM表,可以在主库运行时使用mysqlhotcopy或rsync来复制数据 - 3.使用mysqldump
如果只包含InnoDB表,那么可以使用以下命令来转储主库数据并将其加载到备库,然后设置相应的二进制日志坐标
$ mysqldump --single-transaction --all-databases --master-data=1--host=server1 \| mysql --host=server2
选项–single-transaction使得转储的数据为事务开始前的数据。如果使用的是非事务型表,可以使用–lock-all-tables选项来获得所有表的一致性转储
- 4.使用快照或备份
只要知道对应的二进制日志坐标,就可以使用主库的快照或者备份来初始化备库(如果使用备份,需要确保从备份的时间点开始的主库二进制日志都要存在)。只需要把备份或快照恢复到备库,然后使用CHANGE MASTER TO指定二进制日志的坐标。也可以使用LVM快照、SAN快照、EBS快照——任何快照都可以 - 5.使用Percona Xtrabackup
Percona的Xtrabackup是一款开源的热备份工具。它能够再备份时不阻塞服务器的操作,因此可以在不影响主库的情况下设置备库。可以通过克隆主库或另一个已存在的备库的方式来建立备库。创建一个备份(不管是从主库还是从别的备库),并将其转储到目标机器,然后根据备份获得正确的开始复制的位置。
5.1 如果是从主库获得备份,可以从xtrabackup_binlog_pos_innodb文件中获得复制开始的位置
5.2 如果是从另外的备库获得备份,可以从xtrabackup_slave_info文件重获得复制开始的位置。 - 6.使用另外的备库
可以使用任何一种提及的克隆或者拷贝技术来从任意一台备库上将数据克隆到另外一台服务器。但是如果使用的是mysqldump,–master-data选项就会不起作用。此外,不能使用SHOW MASTER STATUS来获得主库的二进制日志坐标,而是在获取快照时使用SHOW SLAVE STATUS来获取备库在主库上的执行位置。使用另外的备库进行数据克隆最大的缺点是,如果这台备库的数据已经和主库不同步,克隆得到的就是脏数据。
不要使用LOAD DATA FROM MASTER或者LOAD TABLE FROM MASTER!这些命令过时、缓慢,并且非常危险,并且只适用于MyISAM存储引擎。
不管选择哪种技术,都要能熟练运用,要记录详细的文档或编写脚本。因为可能不止一次需要做这样的事情。甚至当错误发生时,也需要能够处理
推荐的复制配置
有许多参数来控制复制,其中一些会对数据安全和性能产生影响。推荐一种"安全"的配置,可以最小化问题发生的概率。在主库上二进制最重要的选项是sync_binlog:
sync_binlog=1
如果开启该选项,MySQL每次在提交事务前会将二进制日志同步到磁盘上,保证在服务器崩溃时不会丢失事件。如果禁止该选项,服务器会少做一些工作,但二进制日志文件可能在服务器崩溃时损坏或丢失信息。在一个不需要作为主库的备库上,该选项带来了不必要的开销。它只适用于二进制日志,而非中继日志。如果无法容忍服务器崩溃导致表损坏,推荐使用InnoDB。在表损坏无关紧要时,MyISAM是可以接受的,但在一次备库服务器崩溃重启后,MyISAM表可能已经处于不一致状态。一种可能是语句没有完全应用到一个或多个表上,那么即使修复了表,数据也可能是不一致的。
如果使用InnoDB,强烈推荐设置如下选项:
innodb_flush_logs_at_trx_commit #Flush every log write
innodb_support_xa=1 # MySQL 5.0 and newer only
innodb_safe_binlog # MySQL 4.1 only,rounghly equivalent to innodb_support_xa
这些事MySQL5.0及最新版本中的默认配置,我们推荐明确指定二进制日志的名字,以保证二进制日志名在所有服务器上是一致的,避免因为服务器名的变化导致日志文件名变化。你可能认为以服务器名来命名二进制日志无关紧要,但经验表明,当在服务器间转移文件、克隆新的备库、转储备份或者其他一些你想象不到的场景下,可能会导致很多问题。为了避免这些问题,需要给log_bin选项指定一个参数。可以随意地给一个绝对路径,但必须明确地指定基本的命名:
log_bin=/var/lib/ysql/mysql-bin # Good,specifies a path and base name
# log_bin # Bad, base name will be server's hostname
在备库上,我们同样推荐开启如下配置选项,为中继日志制定绝对路径:
relay_log=/path/to/logs/relay-bin
skip_slave_start
read_only
通过设置relay_log可以避免中继日志文件基于机器名来命名,防止之前提到的可能在主库发生的问题。制定绝对路径可以避免多个MySQL把本中存在的Bug,这些Bug可能会导致中继日志在一个意料外的位置创建。skip_slave_start选项能够阻止备库在崩溃后自动启动复制。这可以给你一些机会来修复可能发生的问题。如果备库在崩溃后自动启动并且处于不一致的状态,就可能导致更多的损坏,最后将不得不把所有数据丢弃,并重新开始配置备库。
read_only选项可以阻止大部分用户更改非临时表,除了复制SQL线程和其他拥有超级权限的用户之外,这也是要尽量避免给正常账号授予超级权限的原因之一。
即使开启了所有我们建议的选项,备库仍然可能在崩溃后被中断,因为master.info和中继日志文件都不是崩溃安全的。默认情况下甚至不会刷新到磁盘,直到MySQL5.5版本才有选项来控制这种行为。如果正在使用MySQL5.5并且不会介意额外的fsync()导致的性能开销,最好设置以下选项:
sync_master_info=1
sync_relay_log=1
sync_relay_log_info=1
如果备库与主库的延迟很大,备库的IO线程可能会写很多中继日志文件,SQL线程在重放完一个中继日志中的事件后会尽快将其删除(通过relay_log_purge选项来控制)。但如果延迟非常严重,IO线程可能会把整个磁盘撑满。解决办法是配置relay_log_space_limit变量。如果所有中继日志的大小之和超过这个值,IO线程会停止,等待SQL线程释放磁盘空间。
尽管听起来很美好,但有一个隐藏的问题。如果备库没有从主库上获取所有的中继日志,这些日志可能在主库崩溃时丢失。早先这个选项存在一些Bug,使用率也不高,所以用到这个选项遇到Bug的风险会更高。除非磁盘空间真的非常紧张,否则最好让中继日志使用其需要的磁盘空间,这也是为什么没有将relay_log_space_limit列入推荐配置选项的原因