mysql 复制原理和示例
mysql 主从复制(Master-Slave)原理
mysql的复制(replication)是一个异步的复制,从一个mysql instace(称之为Master)复制到另一个mysql instance(称之Slave)。实现整个复制操作主要由三个线程(thread)完成的,其中两个线程在Slave(sql线程和IO线程),另外一个进程在Master(IO线程)上。
要实施复制,首先必须打开Master端的binary log(bin-log)功能,否则无法实现。因为整个复制过程实际上就是Slave从Master端获取该日志然后再在本端完全顺序的执行日志中所记录的各种操作。
复制的过程如下:
1、Slave上面的IO线程连接上Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
2、Master接收到来自Slave的IO线程的请求后,通过负责复制的IO进程根据请求信息读取制定日志指定位置之后的日志信息,返回给Slave的IO线程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到Master端的bin-log文件的名称以及bin-log的位置;
3、Slave的IO线程接收到信息后,将接收到的日志内容依次添加到Slave端的relay-log文件的最末端,并将读取到的Master端的 bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清楚的向Master请求具体bin-log的具体位置之后的日志记录;
4、Slave的sql线程检测到relay-log中新增加了内容后,会马上解析relay-log的内容成为在Master端真实执行时候的那些可执行的语名,并在本端执行。
mysql 主主复制(Master-Master)示例
以上介绍了主从复制的原理,而主主复制则是在主从复制的基本上,再增加一组线程(原Master增加原Slave的sql线程和io线程,原Slave增加原Master的io线程)
示例服务器配置如下:
rhel5.5 64bit系统:
1 2 | A: 192.168.80.55 B: 192.168.80.56 |
mysql数据库版本: 5.0.40
数据库datadir目录: /home/mysql/mydata
在A机上完成用户授权等操作
1、用户授权(slave 连接使用,这里使用mysql all的权限)
1 2 | mysql> grant all on *.* to 'mysql'@'%' identified by 'mysql'; mysql> flush privileges; |
然后停掉数据库,并将/home/mysql/mydata 目录打包并传至B机解包
2、两机均修改配置文件my.cnf
A机注意以下内容,无该项则增加:
1 2 3 4 5 6 7 8 9 | [mysqld] log-bin=mysql-bin relay-log=mysql-relay-bin log-slave-updates=1 # A机使用server id 为1,两机需要使用不同值 server-id = 1 auto-increment-increment = 2 # A机使用auto-increment-offset为1,两机需要使用不同值 auto-increment-offset = 1 |
B机注意以下内容,无该项则增加
1 2 3 4 5 6 7 8 9 | [mysqld] log-bin=mysql-bin relay-log=mysql-relay-bin log-slave-updates=1 # B机使用server id 为2,两机需要使用不同值 server-id = 2 auto-increment-increment = 2 # B机使用auto-increment-offset为2,两机需要使用不同值 auto-increment-offset = 2 |
3、两机数据库启动,启动复制
注意:使用CHANGE MASTER的方式需要从MASTER获取binlog信息,比如当前A机要做为B机的Slave,需要在B机执行, 然后获取file和position
1 2 3 4 5 6 | mysql> SHOW MASTER STATUS; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000004 | 534 | | | +------------------+----------+--------------+------------------+ |
在A机上:
1 2 | mysql> CHANGE MASTER TO MASTER_HOST='192.168.80.56', MASTER_PORT=3306, MASTER_USER='mysql', MASTER_PASSWORD='mysql', MASTER_LOG_FILE='mysql-bin.000004',MASTER_LOG_POS=534; mysql> START SLAVE; |
同样的,B机要做为A机的Slave的时候,需要获取A机的binlog信息,
1 2 3 4 5 6 | mysql> SHOW MASTER STATUS; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000005 | 98 | | | +------------------+----------+--------------+------------------+ |
在B机上:
1 2 | mysql> CHANGE MASTER TO MASTER_HOST='192.168.80.55', MASTER_PORT=3306, MASTER_USER='mysql', MASTER_PASSWORD='mysql',MASTER_LOG_FILE='mysql-bin.000005',MASTER_LOG_POS=98; mysql> START SLAVE; |
完成以上之后,mysql的复制就算配置完成了,可在两机上分别执行
1 | mysql> SHOW SLAVE STATUS\G |
显示结果中,slave的两个线程都在运行,就表明复制是成功的,这样就在两机上任意的更新都将更新到两个数据库上(当然并不推荐两边都更新,因为可能带来冲突)
1 2 | Slave_IO_Running: Yes Slave_SQL_Running: Yes |