MySQL5.5-主从复制配置

作者:聂勇 欢迎转载,请保留作者信息并说明文章来源!

在大型的互联网系统中,读的请求非常频繁,单个数据库节点不能满足读的要求,常见的做法是:读写分离,将读操作分布至多个数据库从节点。
除了高性能外,高可用和容灾也是不容忽视的要求,许多系统会做数据备份,通过主从复制将数据备份至另一台物理服务器或者异地机房。
MySQL支持多种类型的数据复制:

  • 基于语句的复制:技术成熟、复制数据高效,但在一些特殊场景(如:语句中含有now()等表示当前时间的函数)中会导致数据不一致。
  • 基于行的复制:基于表的变化记录行信息,是最安全的复制方式,如果语句更新了大量的行,会生成很大的日志,效率受影响。
  • 混合模式:兼顾基于语句和基于行的优点,正常情况下用基于语句来复制数据,对于不安全的语句采用基于行的方式来复制数据。

MySQL的复制过程:Master输出bin log(二进制日志),Slave拉取bin log写入本地的relay log(中继日志),然后解析重放操作。详细步聚如下:
主从复制示意图

  1. Master提交事务之前,将改变的内容串行地写入bin log。
  2. Slave通过I/O线程连接到Master,请求从指定日志文件的指定位置开始拉取内容。
  3. Master收到请求后,通过自身的I/O线程读取指定文件的指定位置后面的内容并返回给Slave。
  4. Slave收到响应后,将日志内容写入本地的relay log。
  5. Slave的SQL线程解析relay log,还原操作(在Slave端重放Master的操作),保持数据一致。

一、环境

  • RedHat 5.x / CentOS 5.x
  • GCC 4.1.2
  • MySQL Master 5.5.43,已经存在数据,IP地址为192.168.56.102,监听端口为19826
  • MySQL Slave 5.5.43,新建的实例(无数据),IP地址为192.168.56.102,监听端口为19836。

二、配置服务器ID和二进制日志

说明:

  • Master和Slave必须用不同的服务器ID,如果有多个Slave,每个Slave的服务器ID也必须唯一。
  • Master必须输出bing log。

1、配置Master

打开Master的配置文件my.cnf:

1
vi /home/nieyong/local/mysql-5543/data/data19826/my.cnf

修改内容:

1
2
3
4
[mysqld]
server-id = 26 #[必须]服务器ID,在集群中必须唯一
log-bin = /home/nieyong/local/mysql-5543/data/data19826/data/mysql-bin #[必须]二进制日志输出
binlog_format = mixed #[可选]配置为混合模式

2、配置Slave

打开Slave的配置文件my.cnf:

1
vi /home/nieyong/local/mysql-5543/data/data19836/my.cnf

修改内容:

1
2
3
4
[mysqld]
server-id = 36 #[必须]服务器ID,在集群中必须唯一
log-bin = /home/nieyong/local/mysql-5543/data/data19836/data/mysql-bin #[必须]二进制日志输出
binlog_format = mixed #[可选]配置为混合模式

注:配置完成后,重启master和slave。

三、授权和复制配置

1、配置Master

1)登陆Master。

1
mysql -S /home/nieyong/local/mysql-5543/data/data19826/tmp/mysql.sock -u root -pmaster123456

2)在Master建立用于主从复制的账号并授权。

1
2
CREATE USER 'repl_user'@'%' IDENTIFIED BY 'repl_123456';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';

结果如下:
创建主从复制账号并授权

3)导出Master的数据库。
在操作系统命令行执行如下命令:

1
mysqldump -S /home/nieyong/local/mysql-5543/data/data19826/tmp/mysql.sock -u root -pmaster123456 --master-data=2 --all-databases > /home/nieyong/db19826.sql

说明:

  • –master-data=2 表示输出change master to 语句并在前面加上注释符(#),在Slave上执行change master to 时会用到。

4)查看Master状态。

1
show master status;

结果如下:
查看Master状态

2、配置Slave

1)登陆Slave。
在操作系统命令行执行如下命令:

1
mysql -S /home/nieyong/local/mysql-5543/data/data19836/tmp/mysql.sock -u root -pslave123456

2)导入数据库。
在mysql命令行执行如下命令:

1
source /home/nieyong/db19826.sql

3)查看Slave状态。
在mysql命令行执行如下命令:

1
show slave status;

查看Slave状态

4)配置复制。
在mysql命令行执行如下命令:

1
2
3
4
5
6
7
change master to
master_host='192.168.56.102',
master_port=19826,
master_user='repl_user',
master_password='repl_123456',
master_log_file='mysql-bin.000008',
master_log_pos=107;

说明:db19826.sql中有一行内容记录导出数据时bin log日志文件及其位置。

5)启动Slave线程。
在mysql命令行执行如下命令:

1
start slave;

6)查看Slave状态。
在mysql命令行执行如下命令:

1
show slave status\G

mysql输出如下信息:

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.56.102
                  Master_User: repl_user
                  Master_Port: 19826
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000008
          Read_Master_Log_Pos: 107
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 253
        Relay_Master_Log_File: mysql-bin.000008
             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: 107
              Relay_Log_Space: 403
              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: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 26
1 row in set (0.00 sec)

注:Slave_IO_Running和Slave_SQL_Running必须都是Yes,否则就说明存在错误,主从同步没有配置成功。

四、验证

1、查看Master的进程

在Master的mysql命令行输入如下命令:

1
show full processlist\G

查看Master的进程

2、查看Slave的进程

在Slave的mysql命令行输入如下命令:

1
show full processlist\G

查看Slave的进程

3、主从数据复制校验

1、在Master新建一个表,SQL语句如下:

1
2
3
4
5
6
7
8
9
10
CREATE TABLE account_cp
(
cp_id int PRIMARY KEY NOT NULL,
cp_name varchar(50) NOT NULL,
cp_status tinyint DEFAULT 0 NOT NULL,
ctime bigint NOT NULL,
creator varchar(20) NOT NULL,
mtime bigint,
modifier varchar(20)
);

然后再插入一条记录:

1
insert into account_cp(cp_id, cp_name, cp_status, ctime, creator) values(1, '傲风的博客', 0, 0, 'nieyong');

2、进入Slave查看,同样可以看到新增了一个表account_cp,并且存在一条一样的记录。

五、参考资料