概括的讲,主从同步就是,从库先导入主库的某一个位置点的备份,然后根据主库的binlog日志再不停地通过增量执行增删改,达到与主库一致。

工作原理:

  1. Master开启binlog功能(日志功能);

  2. 把Master某个时间点的整库备份导入到Slave中,备份时最好使用master-data=1这个参数;

  3. 在Master上分配一个REPLICATION SLAVE的帐号用于同步;

  4. MASTER包含一个IO进程,SLAVE的MySQL包括了IO进程和SQL进程(但这两个进程没有关联);

  5. SLAVE发起复制请求并提供MASTER_LOG_FILE和MASTER_LOG_POS。

  6. MASTER的主进程通过验证后,把任务交给IO进程,并根据MASTER_LOG_FILE和MASTER_LOG_POS开始,不停的向SLAVE发送来自binlog的后续日志(主动推送);

  7. SLAVE的IO进程接收到这些日志后,存放到relay日志文件中,并在master.info文件中登记最新接收到的MASTER_LOG_FILE和MASTER_LOG_POS。

  8. SLAVE的SQL进程循环地从relay日志读取并执行,使SLAVE的库达到与MASTER库一致;

具体部署步骤

  1. 开启Master的binlog功能;

        在my.cnf中,配置log-bin=路径+前缀;如

        log-bin = /disk2/mysql_multi_instances/3308/mysql-bin

        MySQL会在 /disk2/mysql_multi_instances/3308/这个目录下,生产binlog数据文件,前缀是mysql-bin,后缀是六位数字。

    2.    备份Master数据库

            [root@vmtest ~]# mysqldump -uroot -p -h 127.0.0.1 -P 3308 -F -A -B -x --add-drop-database --events --master-data=1|gzip >3308.sql.gz

            -F切割binlog(可选)

            -A全部数据库

            --add-drop-database 在CREATE DATABASE前插入DROP DATABASE,适合于整库备份的情况

            -x锁表

            -B可以指定多个DBNAME,但如果整库备份的话,也可以不指定,甚至不写

            --events 导出时包含事件排程(event scheduler),如果不加,可能会有警告;总而言之可加可不加。

            --master-data最最重要的参数,在导出的内容中插入

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000101', MASTER_LOG_POS=3658;

这类语句,据说SLAVE可以根据这句自行判断MASTER_LOG_FILE和MASTER_LOG_POS,可是在我的测试中发现还是需要手工指定一下;anyway,设定这个参数你可以很容易查到FILE和POS,何乐而不为,这个参数有两个值1和2,1就是上面的效果,2就是把上面的效果注释掉作为参考。FILE和POS也可以在MASTER上查到

mysql> show master status;+------------------+----------+--------------+------------------+| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |+------------------+----------+--------------+------------------+| mysql-bin.000101 |     3658 |              |                  |+------------------+----------+--------------+------------------+

            3. Master上分配帐号用于同步

                mysql> grant replication slave on *.* to rep@'192.168.5.%' identified by 'jet';

                注意是 replication slave的权限(两个单词)

            4. SLAVE把整库的备份文件导入库文件。

                [root@lab ~]# gzip -d 3308.sql.gz 

                [root@lab ~]# mysql -uroot -p < 3308.sql

            5. SLAVE上编写CHANGE MASTER语句

                mysql> CHANGE MASTER TO  

                             MASTER_HOST='192.168.5.103',  

                             MASTER_USER='rep',   

                             MASTER_PASSWORD='jet‘, 

                             MASTER_PORT=3308,

                             MASTER_LOG_FILE='mysql-bin.000101',

                             MASTER_LOG_POS=107;

                注意,这些资料必须严格核对。

            7. SLAVE上执行slave start,然后查看状态

mysql> show slave status\G;*************************** 1. row ***************************               Slave_IO_State: Waiting for master to send event                  Master_Host: 192.168.5.103                  Master_User: rep                  Master_Port: 3308                Connect_Retry: 60              Master_Log_File: mysql-bin.000101          Read_Master_Log_Pos: 3658               Relay_Log_File: mysqld-relay-bin.000024                Relay_Log_Pos: 252        Relay_Master_Log_File: mysql-bin.000101             Slave_IO_Running: Yes            Slave_SQL_Running: Yes              Replicate_Do_DB:           Replicate_Ignore_DB:            Replicate_Do_Table:        Replicate_Ignore_Table:       Replicate_Wild_Do_Table:   Replicate_Wild_Ignore_Table:                    Last_Errno: 0                   Last_Error:                  Skip_Counter: 0          Exec_Master_Log_Pos: 3658              Relay_Log_Space: 554              Until_Condition: None               Until_Log_File:                 Until_Log_Pos: 0           Master_SSL_Allowed: No           Master_SSL_CA_File:            Master_SSL_CA_Path:               Master_SSL_Cert:             Master_SSL_Cipher:                Master_SSL_Key:         Seconds_Behind_Master: 0Master_SSL_Verify_Server_Cert: No                Last_IO_Errno: 0                Last_IO_Error:                Last_SQL_Errno: 0               Last_SQL_Error: 1 row in set (0.00 sec)

                其中最重要的是Slave_IO_Running: Yes 和 Slave_SQL_Running: Yes,这两个都YES,才代表同步会话正确连接;在测试中,我在CHANGE MASTER语句中没有手工指定FILE和POS,启动slave后,只有Slave_IO_Running: Yes,而Slave_SQL_Running: No,这样的同步是有问题的,同时也会在状态界面上显示执行失败的SQL语句;后来我把slave stop,并重新指定FILE和POS,再slave start就正常了。

另外,也可以看到SLAVE上会多了master.info文件和relay日志文件

[root@lab ~]# ll /var/lib/mysql/{master.info,mysqld-relay*}-rw-rw----. 1 mysql mysql  73 Jan 24 22:12 /var/lib/mysql/master.info-rw-rw----. 1 mysql mysql 302 Jan 24 22:12 /var/lib/mysql/mysqld-relay-bin.000023-rw-rw----. 1 mysql mysql 252 Jan 24 22:12 /var/lib/mysql/mysqld-relay-bin.000024-rw-rw----. 1 mysql mysql  52 Jan 24 22:12 /var/lib/mysql/mysqld-relay-bin.index

其实,那些relay日志文件也是binlog文件,可以用mysqlbinlog查看;而master.info文件则是文本文件,用于登记关于master的一些参数

[root@lab ~]# less /var/lib/mysql/master.info 

15

mysql-bin.000101

3658

192.168.5.103

rep

jet

3308

60

0

0

0