首先主服务器把数据变化记录到主日志,然后从服务器通过i/o线程读取主服务器上的主日志,并且把它写入到从服务器的中继日志中,接着sql线程读取中继日志,并且在从服务器上重放,从而实现mysql复制。具体如下图所示:
mysql复制
整个过程反映到从服务器上,对应三套日志信息,可在从服务器上用如下命令查看:
master_log_file & read_master_log_pos:下一个传输的主日志信息。
relay_master_log_file & exec_master_log_pos:下一个执行的主日志信息。
relay_log_file & relay_log_pos:下一个执行的中继日志信息。
理解这些日志信息的含义对于解决故障至关重要,后文会详细阐述。
先在主服务器上创建复制账号:
然后设置主服务器配置文件(缺省:/etc/my.cnf):
注:一定要保证主从服务器各自的server_id唯一,避免冲突。
client requested master to start replication from impossible position
因为日志数据已经丢失了,所以此类问题基本上不能处理,只能重新安装同步从服务器。
接下来设置从服务器配置文件(缺省:/etc/my.cnf):
下面最重要的步骤是如何克隆一份主服务器的数据:
如果数据库使用的是myisam表类型的话,可按如下方式操作:
有了数据文件,传输到从服务器上并导入:
当然,整个过程也可以利用管道符一次性操作:
因为我们开始设置了master-data=1,所以系统会自动设置参数:master_log_file和master_log_pos,我们还需要设置剩下的参数:
如果数据量很大的话,mysqldump会非常慢,此时直接拷贝数据文件能节省不少时间:
在拷贝之前要先锁定数据,然后再获得相关的日志信息(file & position):
接下来拷贝数据文件时,如果是myisam表类型的话,直接拷贝即可;如果是innodb表类型的话,一定要先停止mysql服务再拷贝,否则拷贝文件可能无法使用。把拷贝的数据文件直接复制到从服务器的数据目录。
最后还需要再指定一下日志信息:
注:不要在my.cnf配置文件里设置master_user和master_password,因为最终生效的是change master to生成的master.info文件里的信息。
在主服务器上直接拷贝数据文件虽然很快,但需要锁表或者停止服务,这会影响线上服务。如果先前已经有了从服务器,那么可以用旧的从服务器做母本来克隆新的从服务器:
先在旧的从服务器上查询日志信息:
我们需要的是其中的relay_master_log_file & exec_master_log_pos。
然后在旧的从服务器上按照前面的方法得到数据,并在新的从服务器上还原。
接着在新的从服务器上设置日志信息:
不管用那个方法,最后记得在从服务器上启动复制,并检查工作是否正常:
如果io线程和sql线程都显示yes,就可以感谢上帝了:
slave_io_running: yes
slave_sql_running: yes
如果显示no,则说明某些配置步骤有问题,请重新对照一遍前面所说的步骤。
问题:主从复制不止何故停止了,我该怎么办?
答案:复制错误多半是因为日志错误引起的,所以首先要搞清楚是主日志错误还是中继日志错误,从错误信息里一般就能判断,如果不能可以使用类似下面的mysqlbinlog命令:
如果没有错误,则不会有任何输出,反之如果有错误,则会显示出来。
如果是主日志错误,需要手动找到正确的日志信息,重新change master to即可:
如果是中继日志错误,只要在从服务器使用show slave status结果中的日志信息重新change master to即可,系统会抛弃当前的中继日志,重新下载:
至于为什么使用的是relay_master_log_file & exec_master_log_pos,参见概述。
有时候由于bug或者在从服务器执行了写操作可能会造成键重复错误,错误信息如下:
error ‘duplicate entry …’ for key … on query
问题:主服务器宕机了,如何把从服务器提升会主服务器?
答案:在一主多从的环境总,需选择数据最新的从服务器做新的主服务器。如下图所示:
提升从服务器为主服务器
在一主(server1)两从(server2,、server3)环境中,server1宕机后,等到server2和server3把宕机前同步到的日志都执行完,比较master_log_file和read_master_log_pos就可以判断出谁快谁慢,因为server2从server1同步的数据(1582)比server3从server1同步的数据(1493)新,所以应该提升server2为新的主服务器,那么server3在change master to到server2的时候应该使用什么样的参数呢?1582-1493=89,而server2的最后的二进制日志位置是8167,所以答案是8167-89=8078。
主从服务器中的表可以使用不同的表类型。比如主服务器可以使用innodb表类型,提供事务,行锁等高级特性,从服务器可以使用myisam表类型,内存消耗少,易备份等优点。还有一个例子,一台主服务器如果同时带很多个从服务器的话,势必会影响其性能,此时可以拿出一台服务器作为从服务器代理,使用blackhole表类型,只记录日志,不写数据,由它带多台从服务器,从而提升性能。
主从服务器中的表可以使用不同的键类型。比如主服务器用innodb,键用varchar的话节省空间,从服务器使用myisam,键用char提高速度,因为myisam有静态表一说。
主从服务器中的表可以使用不同的索引。主服务器主要用来应付写操作,所以除了主键和唯一索引等保证数据关系的索引一般都可以不加,从服务器用来应付读操作,所以可以针对查询特征设置索引,甚至不同的从服务器可以针对不同的查询设置不同的索引。
有一些优秀的工具可以让你的得到事半功倍的效果,详细内容请参考各自文档:
<a href="http://mysql-mmm.org/" target="_blank">multi-master replication manager for mysql</a>
<a href="http://www.percona.com/software/percona-xtrabackup/" target="_blank">percona xtrabackup</a>
<a href="http://code.openark.org/forge/openark-kit" target="_blank">openark kit</a>
<a href="http://www.percona.com/software/percona-toolkit" target="_blank">percona toolkit</a>
<a href="http://code.google.com/p/tungsten-replicator/" target="_blank">tungsten-replicator</a>
说明:本文参考了下面列出的书籍中相关的内容:
<a href="http://www.amazon.com/high-performance-mysql-optimization-replication/dp/0596101716/" target="_blank">high performance mysql: optimization, backups, replication, and more</a>
<a href="http://www.amazon.com/mysql-high-availability-building-centers/dp/0596807309/" target="_blank">mysql high availability: tools for building robust data centers</a>
希望我的总结能让大家少走一些弯路。