Mysql主从同步(AB复制)

Mysql主从同步(AB复制)


实验背景:

1.配置2台MySQL服务器,实现 主-->从 同步。


2.其中Master服务器允许SQL查询、写入,Slave服务器只允许SQL查询


实验方案:

使用2台RHEL 6.4虚拟机,其中192.168.4.10是MySQL主服务器,负责提供同步源;另一台


192.168.4.20作为MySQL从服务器,通过调取主服务器上的binlog日志,在本地重做对应的库、表,实现与

主服务器的AB复制(同步)。


 提前为两台MySQL服务器安装好MySQL-server、MySQL-Client软件包,并为数据库用户root修改密码;Linux客户机上则只需安装MySQL-Client软件包即可。


实验实现:


1.初始化现有库


 为了在启用binlog日志及同步之前保持主、从库的一致性,建议进行初始化――备份主服务器上现有的库,然后导入到从服务器上。

 当现有库、表都采用MyISAM引擎时,可执行离线备份、恢复,这样更有效率;否则,可通过mysqldump等工具来实现库的导出、导入。


1)备份MySQL Master(192.168.4.10)上现有的库


 如果服务器已经启用binlog,建议对日志做一次重置,否则可忽略:

# mysql -u root -p

password://以数据库管理员登陆


mysql> RESET MASTER;                    //重置binlog日志

mysql> quit                             //退出mysql> 环境

 以备份mysql库、test库为例,导出操作如下:


#mysqldump -uroot -p -B mysql test>/root/mytest.sql

password:

//-B 导出多个

#ls //确认备份结果


2)在MySQL Slave(192.168.4.20)上导入备份的库


 先清理目标库,避免导入时冲突。主要是采用InnoDB引擎的库,授权库mysql多采用MyISAM引擎,可不做清理。

# mysql -u root -p

Enter password:                               //以数据库用户root登入

.. ..

mysql> DROP DATABASE test;                         //删除test库

Query OK, 0 rows affected (0.03 sec)

mysql> quit                                     //退出mysql> 环境

Bye


 使用scp工具下载备份文件:

#scp /dbsvr1:/root/mytest.sql .///远程复制



root@dbsvr1's password:                         //验证对方系统用户root的口令



执行导入操作:

#mysql -uroot -p <mysql.sql

password :



 导入成功后,可重新登入 mysql> 环境,确认清理的目标库已恢复:

mysql> show databases;


2.配置MySQL Master(主服务器,192.168.4.10)


1)修改/etc/my.cnf配置,重新启动MySQL服务程序


指定服务器ID号、允许日志同步:


[root@dbsvr1 mysql]# vim /etc/my.cnf

[mysqld]

log_bin=dbsvr1-bin                 //启用binlog日志,并指定文件名前缀

server_id = 10                         //指定服务器ID号

innodb_flush_log_at_trx_commit=1     //优化设置

sync-binlog=1                         //允许日志同步



重启mysql服务:

[root@dbsvr1 ~]# service mysql restart

Shutting down MySQL.. [确定]

Starting MySQL.. [确定]



2)新建一个备份用户,授予复制权限(授权用户不一定是本地用户)


需要的权限为REPLICATION SLAVE,允许其从Slave服务器访问:


mysql> GRANT REPLICATION SLAVE ON *.* TO 'replicater'@'192.168.4.%' IDENTIFIED BY 'pwd123'; //用户授权,设置密码

Query OK, 0 rows affected (0.04 sec)


3)检查Master服务器的同步状态


在已经初始化现有库的情况下,查看MASTER状态,记录下当前的日志文件名、偏移的位置(下面SLAVE发起复制时需要用到):

mysql> SHOW MASTER STATUS\G

File: dbsvr1-bin.000002             //记住当前的日志文件名

Position: 334                         //记住当前位置


3.配置MySQL Slave(从服务器,192.168.4.20)


1)修改/etc/my.cnf配置,重新启动MySQL服务程序


指定服务器ID号、允许日志同步:


[root@dbsvr2 ~]# vim /etc/my.cnf

[mysqld]

log_bin=dbsvr2-bin                   //启动SQL日志,并指定文件名前缀

.server_id = 20                   //指定服务器ID号,不要与Master的相同

innodb_flush_log_at_trx_commit=1     //优化设置

sync-binlog=1                         //允许日志同步

log_slave_updates=1      //记录从库更新,便于实现“主-从-从”链式复制


配置完成后,重启mysql服务:


# service mysql restart


2)登入 mysql> 环境,发起同步操作


mysql> CHANGE MASTER TO MASTER_HOST='192.168.4.10',  //指定主服务器


-> MASTER_USER='replicater', //同步用户和密码


-> MASTER_PASSWORD='pwd123',


-> MASTER_LOG_FILE='dbsvr1-bin.000002',     //对应Master的日志文件


-> MASTER_LOG_POS=334;                         //对应Master的日志偏移位置(可以从主的show master status 查看)


Query OK, 0 rows affected, 2 warnings (0.12 sec)


然后执行START SLAVE(较早版本中为SLAVE START)启动复制:


mysql> START SLAVE;                             //启动复制



通过上述连接操作,MASTER服务器的设置信息自动存为master.info文件,以后每次MySQL服务程序时会自动调用并更新,无需重复设置。查看master.info文件的开头部分内容,可验证相关设置:


3)检查Slave服务器的同步状态


通过SHOW SLAVE STATUS语句可查看从服务器状态,确认其中的IO线程、SQL线程正常运行,才能成功同步:



mysql> SHOW SLAVE STATUS\G //查看slave的状态


......

Slave_IO_Running: Yes             //IO线程应该已运行

Slave_SQL_Running: Yes             //SQL线程应该已运行

//2个yes表示成功


4.测试主从同步效果

1)在Master上操作数据库、表、表记录

新建newdb库、newtable表,随意插入几条表记录:

mysql> CREATE DATABASE newdb;                         //新建库newdb

Query OK, 1 row affected (0.04 sec)

mysql> USE newdb;                                     //切换到newdb库

Database changed

mysql> CREATE TABLE newtable(id int(4));             //新建newtable表

Query OK, 0 rows affected (0.14 sec)

mysql> INSERT INTO newtable VALUES(1234),(5678);     //插入2条表记录

Query OK, 2 rows affected (0.05 sec)

Records: 2 Duplicates: 0 Warnings: 0

mysql> SELECT * FROM newtable;                         //确认表数据

+------+

| id |

+------+

| 1234 |

| 5678 |

+------+

2 rows in set (0.00 sec)



2)在Slave上确认自动同步的结果

直接切换到newdb库,并查询newtable表的记录,应该与Master上的一样,这才说明主从同步已经成功生效:

mysql> USE newdb;                                     //直接切换到newdb库

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

Database changed

mysql> SELECT * FROM newtable;                     //输出表记录

+------+

| id |

+------+

| 1234 |

| 5678 |

+------+

2 rows in set (0.02 sec)


3)在Master服务器上可查看Slave主机的信息

mysql> SHOW SLAVE HOSTS;

+-----------+------+------+-----------+--------------------------------------+

| Server_id | Host | Port | Master_id | Slave_UUID |

+-----------+------+------+-----------+--------------------------------------+

| 20 | | 3306 | 10 | 2f62f59d-7e71-11e3-bb5d-000c299422aa |

+-----------+------+------+-----------+--------------------------------------+



5.将Slave服务器设为只读


 一般来说,为了避免写入冲突,采用主、从复制结构时,不应该允许用户从Slave执行数据库写入操作,这样会导致双方数据的不一致性。


 正因为如此,我们可以把Slave数据库限制为只读模式,这种情况下有SUPER权限的用户和SLAVE同步线程才能写入。相关验证操作及效果可参考以下过程。


1)新建一个测试用户rwuser(不能用root测试)


在Master上建立即可,会自动同步到Slave上:


mysql> GRANT all ON newdb.* TO rwuser@localhost IDENTIFIED BY '1234567';


Query OK, 0 rows affected (0.14 sec)


2)未启用只读前,验证从Slave写入

在Slave上以rwuser登入(不要用root哦):


[root@dbsvr2 ~]# mysql -u rwuser -p



mysql> CREATE TABLE booker(id int(12));         //成功创建booker表

Query OK, 0 rows affected (0.08 sec)

mysql> SHOW TABLES;

+-----------------+

| Tables_in_newdb |

+-----------------+

| booker |

| newtable |

+-----------------

但是在Master上却看不到,导致主、从上的newdb出现不一致:


完成上述验证后,在Slave上删除booker表,确保双方一致:


2)修改/etc/my.cnf文件,重载配置

[root@dbsvr2 ~]# vim /etc/my.cnf

[mysqld]

.. ..

read_only=1                                     //启动只读模式

[root@dbsvr2 ~]# service mysql restart         //重启服务

Shutting down MySQL..                                 [确定]

Starting MySQL...                                     [确定]

3)再次在Slave上验证数据库写入操作

仍然是以rwuser登入(不要用root哦)来验证,当尝试创建新表时会被拒绝:


mysql> CREATE TABLE booker(id int(12));     //新建表的写入操作失败

ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement




1.4 扩展


1.为Slave指定报告给Master的主机名


1)在Slave上启用 --report-host 选项


修改/etc/my.cnf配置文件,添加“report_host=主机名”即可启用,以便向Master报告本机的主机名:

[root@dbsvr2 ~]# vim /etc/my.cnf

[mysqld]

.. ..

report_host=dbsvr2                               //报告指定的主机名

[root@dbsvr2 ~]# service mysql restart         //重启服务

Shutting down MySQL..                                 [确定]

Starting MySQL...                                     [确定]

2)在Master上查看效果

当执行SHOW SLAVE HOSTS语句时,输出的信息中会包含Slave提供的名称:

mysql> SHOW SLAVE HOSTS;

+-----------+--------+------+-----------+--------------------------------------+

| Server_id | Host | Port | Master_id | Slave_UUID |

+-----------+--------+------+-----------+--------------------------------------+

| 20 | dbsvr2 | 3306 | 10 | 2f62f59d-7e71-11e3-bb5d-000c299422aa |

+-----------+--------+------+-----------+--------------------------------------+

1 row in set (0.00 sec)



2.指定哪些库参与主从复制


有两种途径,任选其中一种即可:


?在Master上限制,采用binlog-do-db、binlog-ignore-db选项,指定对哪些库记录或不记录二进制日志,不记录的自然就无法被Slave读取,从而也就相当于不参与同步。

?在Slave上限制,采用replicate-do-db、replicate-ignore-db选项,指定对哪些库执行复制或排除复制。

上述设置参数中,记录与不记录属于互斥选项,不要同时设置;复制与不复制也是互斥选项,不要同时设置。

当设置多条replicate-do-db或replicate-ignore-db时,需要特别注意:这种情况下Master的跨库操作(比如UPDATE 库名.表名 .. ..)不会被同步,从而易导致后续同步报错中断。要解决这个问题,可改用(或合用)以下两个选项:

?replicate-wild-do-table=库名.%

?replicate-wild-ignore-table=库名.%

以只同步mysql、test库为例,相关操作及效果可参考下列过程。

1)在Slave上调整设置,只同步mysql库、test库

.[root@dbsvr2 ~]# vim /etc/my.cnf

.[mysqld]

.. ..

replicate_do_db=mysql                             //同步mysql库

replicate-wild-do-table=mysql.%                 //含跨库更新

replicate_do_db=test                             //同步test库

replicate-wild-do-table=test.%                 //含跨库更新

                                                   //其他未指定的库将被忽略

[root@dbsvr2 ~]# service mysql restart         //重启服务

Shutting down MySQL..                                 [确定]

.Starting MySQL...                                     [确定]

2)在Master上分别操作test库、newdb库,

在test库中新建synctb表:

mysql> CREATE TABLE test.synctb(id int(4),name varchar(12));

Query OK, 0 rows affected (0.14 sec)

mysql> INSERT INTO test.synctb VALUES(1,'Jerry');         //插入一条测试记录

Query OK, 1 row affected (0.03 sec)

mysql> SELECT * FROM test.synctb;                         //确认表记录

+------+-------+

| id | name |

+------+-------+

| 1 | Jerry |

+------+-------+

1 row in set (0.00 sec)

在newdb库中新建notsynctb表:

mysql> CREATE TABLE newdb.notsynctb(id int(4),name varchar(12));

Query OK, 0 rows affected (0.09 sec)

mysql> INSERT INTO newdb.notsynctb VALUES(1,'Mike');     //插入一条测试记录

Query OK, 1 row affected (0.01 sec)

mysql> SELECT * FROM newdb.notsynctb;                     //确认表记录

+------+------+

| id | name |

+------+------+

| 1 | Mike |

+------+------+

1 row in set (0.00 sec)

3)在Slave上观察同步结果

Master上对test库的操作已同步到Slave:

mysql> select * from test.synctb;

+------+-------+

| id | name |

+------+-------+

| 1 | Jerry |

+------+-------+

1 row in set (0.00 sec)

Master上对newdb库的操作被Slave忽略,未执行同步:

mysql> SELECT * FROM newdb.notsynctb;

ERROR 1146 (42S02): Table 'newdb.notsynctb' doesn't exist



实验总结:

  1、主从服务器my.cnf的参数配置,在生产环境中,还可以根据需要设置更详细的同步选项。比如,指定当主、从网络中断时的重试超时时间(slave-net-timeout=60 )等,具体可参考MySQL手册。


 2、一旦启用SLAVE复制,当需要修改MASTER信息时,应先执行STOP SLAVE停止复制,然后重新修改、启动复制。


 3、若START SLAVE直接报错失败,请检查CHANGE MASTER相关设置是否有误,纠正后再

重试;若IO线程或SQL线程有一个为“No”,则应检查服务器的错误日志,分析并排除故障后重启主从复制。


 4、.指定哪些库参与主从复制


有两种途径,任选其中一种即可:


?在Master上限制,采用binlog-do-db、binlog-ignore-db选项,指定对哪些库记录或不记录二进制日志,不记录的自然就无法被Slave读取,从而也就相当于不参与同步。

?在Slave上限制,采用replicate-do-db、replicate-ignore-db选项,指定对哪些库执行复制或排除复制。



你可能感兴趣的:(数据库,服务器,主从同步,AB复制)