体验Mysql复制之一主多从单向架构

作者:renfeng416  发布日期:2014-03-12 11:45:40

上一篇文章,介绍了Mysql复制的基本原理:http://renfeng.blog.51cto.com/7280443/1371514

这篇文章来做下Mysql复制的实验,体验一主多从单向复制的架构

 

Mysql复制的配置过程,相对而言,相对简单。主要分为三个步骤

1. 在master mysql上创建复制账户,并赋予相应权限,用于slave mysql连接

2. master与slave配置

3. slave连接master,开始复制

 

先说下我的实验环境:

 

IP地址 mysql版本 角色分配 server id
192.168.1.170 5.1.66 master 170
192.168.1.180 5.1.66 slave 180
192.168.1.190 5.1.66 slave

190

注:确保mysql的版本一致,且为一个稳定版本,此外保证server id唯一(实验中我为了好区分,使用了IP地址的后缀为server id)

 

 

一、Master端的配置

1. 在主服务器上为复制设置一个连接账户。该账户必须授予REPLICATION SLAVE权限。如果账户仅用于复制(推荐这样做),则不需要再授予任何其它权限。

 

 

mysql> grant replication slave on *.* to 'renf'@'192.168.1.180' identified by 'pwd123';
Query OK, 0 rows affected (0.00 sec)
mysql> grant replication slave on *.* to 'renf'@'192.168.1.190' identified by 'pwd123';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

2.配置master端

打开二进制日志,指定唯一的servr ID

[root@one ~]# vi /etc/my.cnf       编辑文件,添加以下二行
[mysqld]
log-bin=Mysql-bin           #启用二进制日志,并指定生成log文件名
server-id=170               #指明server id,master的server id必须在1-253之间,且唯一
binlog-do-db=ceres          #需要同步的数据库,默认同步所有库
binlog-ignore-db=mysql      #忽略同步的数据库,若有多个,如下写多行
binlog-ignore-db=information-schema

重启mysqld服务,使其生效

[root@one ~]# service mysqld restart
Stopping mysqld:                                           [  OK  ]
Starting mysqld:                                           [  OK  ]

查看日志情况

mysql> show master status
    -> ;
+------------------+----------+--------------+--------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB         |
+------------------+----------+--------------+--------------------------+
| Mysql-bin.000001 |      106 | ceres        | mysql,information-schema |
+------------------+----------+--------------+--------------------------+
1 row in set (0.00 sec)

File列显示日志名,而Position显示偏移量。在该例子中,二进制日志值为Mysql-bin.000001,偏移量为106,记录该值。以后设置从服务器时需要使用这些值。它们表示复制坐标,从服务器应从该点(也可以是任何点)开始从主服务器上进行新的更新。

 

二、配置slave端--使用配置文件,同步

配置slave 192.168.1.180端

修改/etc/my.cnf(若在/etc目录下无my.cnf文件,从/user/share/mysql目录中拷贝my-medium.cnf 到/etc并修改成my.cnf)

[root@two ~]# vi /etc/my.cnf
[mysqld]
server-id=180   #server id,唯一
master-host=192.168.1.170  #master主机
master-user=renf  #master主机用户复制的账户
master-password=pwd123  #master主机用户复制账户的密码
master-port=3306  #同步端口
master-connect-retry=60 #断开重新连接等待时间
replicate-do-db=ceres #同步数据库
replicate-ignore-db=mysql  #忽略需要同步数据库
replicate-ignore-db=information-sceme
relay-log=slave-relay-bin  #生成日志文件

配置slave 192.168.1.190端,仅有server-id不同,若有多个slave,保证server-id不同即可

[root@two ~]# vi /etc/my.cnf
[mysqld]
server-id=190 
master-host=192.168.1.170 
master-user=renf 
master-password=pwd123 
master-port=3306 
master-connect-retry=60
replicate-do-db=ceres
replicate-ignore-db=mysql 
replicate-ignore-db=information-sceme
relay-log=slave-relay-bin 

重启mysqld服务

查看slave的状态

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.170
                  Master_User: renf
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: Mysql-bin.000001
          Read_Master_Log_Pos: 106
               Relay_Log_File: slave-relay-bin.000004
                Relay_Log_Pos: 660
        Relay_Master_Log_File: Mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: ceres
          Replicate_Ignore_DB: mysql,information-sceme
                                                                                                                                                                                                                                                                                                                                           

可以看到配置的主mySQL是哪个服务器,复制账号,只要Slave_IO_Running和Slave_SQL_Running是yes说明配置成功。

Slave_IO_running负责从主服务器上读取BINLOG日志并写入从服务器的中继日志中。

Slave_SQL_running此进程负责读取并且执行中继日志中的BINLOG日志。

 

测试

1. master创建一张表,并插入2行数

mysql> use ceres;
Database changed
mysql> create table test (id int,name varchar(255));
Query OK, 0 rows affected (0.14 sec)
mysql> insert into test (id,name) values (1,'lvx');
Query OK, 1 row affected (0.00 sec)
mysql> insert into test (id,name) values (2,'cdeng');
Query OK, 1 row affected (0.00 sec)
mysql> select * from test;
+------+-------+
| id   | name  |
+------+-------+
|    1 | lvx   |
|    2 | cdeng |
+------+-------+
2 rows in set (0.00 sec)
mysql> show master status
    -> ;
+------------------+----------+--------------+--------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB         |
+------------------+----------+--------------+--------------------------+
| Mysql-bin.000001 |      515 | ceres        | mysql,information-schema |
+------------------+----------+--------------+--------------------------+
1 row in set (0.00 sec)

通过查看master状态,可了解当前使用日志文件仍然为Mysql-bing.000001,偏移量为515

2. 查看slave端,是否已经更新

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.170
                  Master_User: renf
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: Mysql-bin.000001
          Read_Master_Log_Pos: 515
               Relay_Log_File: slave-relay-bin.000004
                Relay_Log_Pos: 660
        Relay_Master_Log_File: Mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: ceres
          Replicate_Ignore_DB: mysql,information-sceme

观察master_log_file与read_master_log_pos值,与master完全一样。则说明已同步完成

查看数据,确实如此。

 

三、配置slave端,---使用change master to语句同步

slave与master同步,除了使用配置文件来进程操作,还可以手动使用change master to语句,该语句完全可以取代对配置文件的修改,而且它可以为slave指定不同的master,而不需要停止服务器。

关闭192.168.1.180虚拟机,并恢复快照

修改/etc/my.cnf文件添加以下行

log_bin           = mysql-bin
server_id         = 2

server_id是必须的,而且唯一。slave没有必要开启二进制日志,但是在一些情况下,必须设置,例如,如果slave为其它slave的master,必须设置bin_log。

 

接下来让slave连接master

mysql> change master to
    -> master_host='192.168.1.170',
    -> master_user='renf',
    -> master_password='pwd123',
    -> master_log_file='Mysql-bin.000001',
    -> master_log_pos=0;

这些信息在主服务器用mysql > SHOW MASTER STATUS,得知。

MASTER_LOG_POS的值为0,因为它是日志的开始位置。然后,可以用SHOW SLAVE STATUS语句查看slave的设置是否正确

mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State:
                  Master_Host: 192.168.1.170
                  Master_User: renf
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: Mysql-bin.000001
          Read_Master_Log_Pos: 4
               Relay_Log_File: mysqld-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: Mysql-bin.000001
             Slave_IO_Running: No
            Slave_SQL_Running: No
              .......
          Seconds_Behind_Master: NULL

Slave_IO_State, Slave_IO_Running, 和Slave_SQL_Running表明slave还没有开始复制过程。日志的偏移量位置为4而不是0,这是因为0只是日志文件的开始位置,并不是日志位置。实际上,MySQL知道的第一个事件的位置是

 

开始复制,运行

mysql> start slave;

查看复制情况

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.170
                  Master_User: renf
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: Mysql-bin.000001
          Read_Master_Log_Pos: 515
               Relay_Log_File: mysqld-relay-bin.000003
                Relay_Log_Pos: 660
        Relay_Master_Log_File: Mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
.....
  Seconds_Behind_Master: 0

注意,slave的I/O和SQL线程都已经开始运行,而且Seconds_Behind_Master不再是NULL。日志的位置增加了,意味着一些事件被获取并执行了。如果你在master上进行修改,你可以在slave上看到各种日志文件的位置的变化,同样,你也可以看到数据库中数据的变化。

 

可查看master和slave上线程的状态。

在master上,你可以看到slave的I/O线程创建的连接:

mysql> show processlist \G
*************************** 3. row ***************************
     Id: 10
   User: renf
   Host: 192.168.1.190:54806
     db: NULL
Command: Binlog Dump
   Time: 1181
  State: Has sent all binlog to slave; waiting for binlog to be updated
   Info: NULL
*************************** 4. row ***************************
     Id: 11
   User: renf
   Host: 192.168.1.180:37943
     db: NULL
Command: Binlog Dump
   Time: 214
  State: Has sent all binlog to slave; waiting for binlog to be updated
   Info: NULL

上2行为处理slave的I/O线程的连接

在slave上运行该语句

mysql> show processlist \G;
*************************** 1. row ***************************
     Id: 1
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 4930
  State: Has read all relay log; waiting for the slave I/O thread to update it
   Info: NULL
*************************** 2. row ***************************
     Id: 2
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 362
  State: Waiting for master to send event

行2为I/O线程的状态,行1为SQL线程的状态

 

四、从另一个master初始化slave前面做的实验是新安装的master和slave,所以,slave与master有相同的数据。但是,大多数情况却不是这样的,例如,你的master可能已经运行很久了,而你想对新安装的slave进行数据同步,甚至它没有master的数据。此时,有几种方法可以使slave从另一个服务开始,例如,从master拷贝数据,从另一个slave克隆,从最近的备份开始一个slave。Slave与master同步时,需要三样东西:(1)master的某个时刻的数据快照;(2)master当前的日志文件、以及生成快照时的字节偏移。这两个值可以叫做日志文件坐标(log file coordinate),因为它们确定了一个二进制日志的位置,你可以用SHOW MASTER STATUS命令找到日志文件的坐标;(3)master的二进制日志文件。可以通过以下几中方法来克隆一个slave:(1) 冷拷贝(cold copy)停止master,将master的文件拷贝到slave;然后重启master。缺点很明显。(2) 热拷贝(warm copy)如果你仅使用MyISAM表,你可以使用mysqlhotcopy拷贝,即使服务器正在运行。(3) 使用mysqldump使用mysqldump来得到一个数据快照可分为以下几步:<1>锁表:如果你还没有锁表,你应该对表加锁,防止其它连接修改数据库,否则,你得到的数据可以是不一致的。如下:mysql> FLUSH TABLES WITH READ LOCK;<2>在另一个连接用mysqldump创建一个你想进行复制的数据库的转储:shell> mysqldump --all-databases --lock-all-tables >dbdump.db<3>对表释放锁。mysql> UNLOCK TABLES;

Tag标签: Mysql   单向架构  
  • 专题推荐

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规