一、简介

Mysql作为目前世界上使用最广泛的免费数据库,相信所有从事系统运维的工程师都一定接触过。但在实际的生产环境中,由单台Mysql作为独立的数据库是完全不能满足实际需求的,无论是在安全性,高可用性以及高并发等各个方面。

因此,一般来说都是通过主从复制(Master-Slave)的方式来同步数据,再通过读写分离(MySQL-Proxy)来提升数据库的并发负载能力 这样的方案来进行部署与实施的。
如图所示:
Mysql数据库主从复制配置 - 图1

在一主多从的数据库体系中,多个从服务器采用异步的方式更新主数据库的变化,业务服务器在执行写或者相关修改数据库的操作是在主服务器上进行的,读操作则是在各从服务器上进行。如果配置了多个从服务器或者多个主服务器又涉及到相应的负载均衡问题,关于负载均衡具体的技术细节还没有研究过,今天就先简单的实现一主一从的主从复制功能。

Mysql主从复制的实现原理图大致如下(来源网络):
Mysql数据库主从复制配置 - 图2

MySQL之间数据复制的基础是二进制日志文件(binary log file)。一台MySQL数据库一旦启用二进制日志后,其作为master,它的数据库中所有操作都会以“事件”的方式记录在二进制日志中,其他数据库作为slave通过一个I/O线程与主服务器保持通信,并监控master的二进制日志文件的变化,如果发现master二进制日志文件发生变化,则会把变化复制到自己的中继日志中,然后slave的一个SQL线程会把相关的“事件”执行到自己的数据库中,以此实现从数据库和主数据库的一致性,也就实现了主从复制。

二、实现MySQL主从复制所需的配置

  • 主服务器:
    • 开启二进制日志
    • 配置唯一的server-id
    • 获得master二进制日志文件名及位置
    • 创建一个用于slave和master通信的用户账号
  • 从服务器:
    • 配置唯一的server-id
    • 使用master分配的用户账号读取master二进制日志
    • 启用slave服务

三、操作步骤

演示环境:

数据库 IP地址 管理员用户 密码
主数据库 172.16.0.10 root 123456
从数据库 172.16.0.20 root 123456

建议:主从数据库版本最好一致,主从数据库内数据保持一致。

主数据库配置

  1. 修改mysql配置
    找到主数据库的配置文件my.cnf(或my.ini),一般在/etc/mysql/my.cnf,然后在[mysqld]部分插入如下两行:

    1. [mysqld]
    2. log-bin=/opt/binlog/master-bin #开启二进制日志并设置存储路径
    3. server-id=1 #设置server-id

  2. 注:保存二进制日志的路径需将所有权设置为mysql:mysql,否则启动会报错。server-id所有数据库唯一不能重复。

  3. 重启mysql并创建用于同步的用户账号
    打开mysql会话:

    [root@localhost ~]# mysql -hlocalhost -uroot -p123456
    

  4. 创建用户并授权:
    演示用户:bakuser
    演示密码:12345678

    mysql> CREATE USER 'bakuser'@'172.16.0.10' IDENTIFIED BY '12345678';       #创建用户
    mysql> GRANT REPLICATION SLAVE ON *.* TO 'bakuser'@'172.16.0.10';        #分配权限
    mysql> flush privileges;     #刷新权限
    
  5. 查看master状态,记录二进制文件名(mysql-bin.000003)和位置(73)

    mysql > SHOW MASTER STATUS;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000003 | 73       | test         | manual,mysql     |
    +------------------+----------+--------------+------------------+
    

从数据库配置

  1. 修改mysql配置
    同样找到my.cnf配置文件,添加server-id

    [mysqld]
    server-id=2         #设置server-id,必须唯一
    

  2. 注:从服务器可以不开启二进制日志。

  3. 配置同步
    重启mysql服务再连到从服务器的mysql服务器上查看从服务器的中继日志是否在启动状态:

    MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE '%relay%';
    +----------------------------------+-----------------------+
    | Variable_name                    | Value                 |
    +----------------------------------+-----------------------+
    | innodb_recovery_update_relay_log | OFF                   |
    | max_relay_log_size               | 0                     |
    | relay_log                        | /opt/binlog/relay-bin |-->此处表明中继日志已启用
    | relay_log_index                  |                       |
    | relay_log_info_file              | relay-log.info        |
    | relay_log_purge                  | ON                    |
    | relay_log_recovery               | OFF                   |
    | relay_log_space_limit            | 0                     |
    | sync_relay_log                   | 0                     |
    | sync_relay_log_info              | 0                     |
    +----------------------------------+-----------------------+
    10 rows in set (0.00 sec)
    

  4. 主服务器参数:

    # MASTER_HOST='172.16.0.10' --主服务器的IP地址
    # MASTER_USER='bakuser' --主服务器上授权复制的用户名
    # MASTER_PASSWORD='12345678' --主服务器上授权用名的密码
    # MASTER_LOG_FILE='mysql-bin.000001' --主服务器上的日志文件
    # MASTER_LOG_POS=10 --主服务器上日志文件的位置
    

  5. 执行同步SQL语句:

    mysql> CHANGE MASTER TO
     ->     MASTER_HOST='172.16.0.10',
     ->     MASTER_USER='bakuser',
     ->     MASTER_PASSWORD='12345678',
     ->     MASTER_LOG_FILE='mysql-bin.000001',
     ->     MASTER_LOG_POS=10;
    
  6. 启动slave同步进程

    mysql>start slave;
    
  7. 查看slave状态

    MariaDB [(none)]> SHOW SLAVE STATUS\G;
    *************************** 1. row ***************************
                Slave_IO_State: Waiting for master to send event
                   Master_Host: 172.16.0.10
                   Master_User: bakuser
                   Master_Port: 3306
                 Connect_Retry: 60
               Master_Log_File: master-bin.000001
           Read_Master_Log_Pos: 1031
                Relay_Log_File: relay-bin.000003
                 Relay_Log_Pos: 530
         Relay_Master_Log_File: master-bin.000001
              Slave_IO_Running: Yes
             Slave_SQL_Running: Yes
                     ...
              Master_Server_Id: 1
    1 row in set (0.00 sec)
    
  8. 验证配置
    Slave_IO_RunningSlave_SQL_Running都为YES的时候就表示主从同步设置成功了。接下来就可以进行一些验证了,如在主master数据库创建表或插入数据等,在slave数据库的相同数据表中查看是否有新增的数据即可验证主从复制功能是否有效,还可以关闭slave,然后再修改master,看slave是否也相应修改(停止slave后,master的修改不会同步到slave),就可以完成主从复制功能的验证了。

  9. 还可以用到的其他相关参数
    master开启二进制日志后默认记录所有库所有表的操作,可通过配置来指定只记录指定数据库或指定表的操作,具体可在mysql配置文件的[mysqld]可添加修改如下选项: ```

    不同步哪些数据库

    binlog-ignore-db = mysql
    binlog-ignore-db = test
    binlog-ignore-db = information_schema

只同步哪些数据库,除此之外的不同步其他数据库

binlog-do-db = game ```

参考文章: 1.MySQL主从复制(Master-Slave)实践 - 博客园 2.MariaDB主从复制 - 博客园