美文网首页MySQL&DBs
MySQL主从同步

MySQL主从同步

作者: 传棋Jaking | 来源:发表于2018-03-16 21:05 被阅读219次

    MySQL主从同步

    环境:
    master IP : 10.83.3.102
    slave IP : 10.83.3.103

    Distributor ID: Debian
    Description: Debian GNU/Linux 9.3 (stretch)
    Release: 9.3
    Codename: stretch

    mysql Ver 14.14 Distrib 5.7.21, for Linux (x86_64) using EditLine wrapper

    在master上操作

    更改配置文件

    root@newbie-unknown85882:~# vim /etc/mysql/mysql.conf.d/mysqld.cnf
    #在配置文件里添加:
    bind-address = 10.83.3.102 #master ip
    #bind-address是MySQL用来监听某个单独的TCP/IP连接,只能绑定一个IP地址,被绑定的IP地址可以映射多个网络接口。这里的配置也可以写成bind-address = 0.0.0.0,表示接受所有IPv4地址。
    server-id = 1 #在master-slave架构中,每台机器节点都需要有唯一的server-id
    log_bin = /var/log/mysql/mysql-bin.log #开启binlog
    root@newbie-unknown85882:~# systemctl restart mysql
    

    创建主从同步的mysql user

    root@newbie-unknown85882:~# mysql
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 2
    Server version: 5.7.21-log MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql> create user 'slave'@'10.83.3.103' identified by 'slavemima';
    Query OK, 0 rows affected (0.01 sec)
    #创建slave用户,并指定该用户只能在10.83.3.103上登录。
    
    mysql> grant replication slave on *.* to 'slave'@'10.83.3.103';
    Query OK, 0 rows affected (0.01 sec)
    #为slave赋予replication slave权限。
    
    mysql> 
    

    为MySQL加读锁

    为了使主库与从库的数据保持一致,先为MySQL加入读锁,使其变为只读。

    mysql> flush tables with read lock;
    Query OK, 0 rows affected (0.00 sec)
    

    记录master replication log的位置,稍后会用到

    mysql> show master status;
    +------------------+----------+--------------+------------------+------------------------------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
    +------------------+----------+--------------+------------------+------------------------------------------+
    | mysql-bin.000001 |      617 |              |                  | 43425f23-2760-11e8-a564-52540035ed32:1-2 |
    +------------------+----------+--------------+------------------+------------------------------------------+
    1 row in set (0.00 sec)
    

    将master DB中现有的数据导出

    root@newbie-unknown85882:~# mysqldump -u root -p --all-databases --master-data > dbdump.sql
    Enter password: 
    Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events. 
    root@newbie-unknown85882:~# ls
    adduser.sh   backend2.py         cloudinit.sh  __pycache__  公共  视频  文档  音乐
    backend1.py  cloudinit-Linux.sh  dbdump.sql    sarfile      模板  图片  下载  桌面
    

    解开master DB的读锁

    mysql> unlock tables;
    Query OK, 0 rows affected (0.00 sec)
    

    将dbdump.sql文件复制到slave

    root@newbie-unknown85882:~# sz dbdump.sql
    rz
     zmodem trl+C ȡ
    
      100%     768 KB  768 KB/s 00:00:01       0 Errors
    #由于我使用的两台机之前做了一些防火墙规则,现在用不了scp传输文件。可以选择用lrzsz工具将文件下载到本地,然后再上传到相应的地方。
    root@newbie-unknown85882:~# scp dbdump.sql root@10.83.3.103:/tmp
    ssh: connect to host 10.83.3.103 port 22: Connection refused
    lost connection
    root@newbie-unknown85882:~# apt-get install -y lrzsz
    正在读取软件包列表... 完成
    正在分析软件包的依赖关系树       
    正在读取状态信息... 完成       
    lrzsz 已经是最新版 (0.12.21-8)。
    升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 86 个软件包未被升级。
    
    root@newbie-unknown85883:/tmp# rz
    rz waiting to receive.
     zmodem trl+C ȡ
    
      100%     768 KB  768 KB/s 00:00:01       0 Errors
    #已把dbdump.sql文件上传到slave。
    root@newbie-unknown85883:/tmp# ls
    dbdump.sql  hwcheck  systemd-private-a03ad6a9e7364c728d51dc0473e45e7c-apache2.service-eWAliD
    

    在slave上操作

    更改配置文件

    root@newbie-unknown85883:~# vim /etc/mysql/mysql.conf.d/mysqld.cnf
    #在配置文件里添加:
    bind-address = 10.83.3.103 #slave ip
    server-id = 2 #在master-slave架构中,每台机器节点都需要有唯一的server-id
    log_bin = /var/log/mysql/mysql-bin.log #开启binlog
    root@newbie-unknown85883:~# systemctl restart mysql
    
    

    导入master DB的dbdump.sql文件,使master-slave数据一致

    root@newbie-unknown85883:~# systemctl restart mysql
    root@newbie-unknown85883:~# mysql -u root -p < /tmp/dbdump.sql 
    Enter password: 
    

    使slave与master建立连接,从而实现MySQL主从同步

    root@newbie-unknown85883:~# mysql
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 3
    Server version: 5.7.21-log MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql> stop slave;
    Query OK, 0 rows affected, 1 warning (0.01 sec)
    mysql> change master to
        -> master_host='10.83.3.102',
        -> master_user='slave',
        -> master_password='slavemima',
        -> master_log_file='mysql-bin.000001',
        -> master_log_pos=617;
    Query OK, 0 rows affected, 2 warnings (0.04 sec)
    
    mysql> start slave;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> 
    #master_log_file='mysql-bin.000001'和master_log_pos=617的值是从master上 show master status得到的。
    
    

    设置从库为只读模式

    mysql> show global variables like "%read_only%";
    +-----------------------+-------+
    | Variable_name         | Value |
    +-----------------------+-------+
    | innodb_read_only      | OFF   |
    | read_only             | OFF   |
    | super_read_only       | OFF   |
    | transaction_read_only | OFF   |
    | tx_read_only          | OFF   |
    +-----------------------+-------+
    5 rows in set (0.03 sec)
    
    mysql> set global read_only=1;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show global variables like "%read_only%";
    +-----------------------+-------+
    | Variable_name         | Value |
    +-----------------------+-------+
    | innodb_read_only      | OFF   |
    | read_only             | ON    |
    | super_read_only       | OFF   |
    | transaction_read_only | OFF   |
    | tx_read_only          | OFF   |
    +-----------------------+-------+
    5 rows in set (0.00 sec)
    

    分别在master和slave上放通3306端口

    #先在master上操作
    root@newbie-unknown85882:~# vim /etc/network/iptables.up.rules 
    # Generated by iptables-save v1.6.0 on Thu Feb  8 09:48:16 2018
    *filter
    :INPUT ACCEPT [0:0]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [31:3088]
    -A INPUT -s 10.83.3.104/32 -p tcp -m tcp --dport 3000 -j ACCEPT
    -A INPUT -s 10.83.3.103/32 -p tcp -m tcp --dport 3000 -j ACCEPT
    -A INPUT -s 10.83.3.11/32 -p tcp -j ACCEPT
    -A INPUT -s 192.168.0.0/16 -p tcp -m multiport --dports 8888,8889,8890,9500,9999,35000 -j ACCEPT
    -A INPUT -s 172.16.0.0/12 -p tcp -m multiport --dports 8888,8889,8890,9500,9999,35000 -j ACCEPT
    -A INPUT -s 10.0.0.0/8 -p tcp -m multiport --dports 8888,8889,8890,9500,9999,35000,3306 -j ACCEPT #在这里添加3306
    -A INPUT -s 127.0.0.0/8 -p tcp -m multiport --dports 8888,8889,8890,9500,9999,35000 -j ACCEPT
    -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    -A INPUT -s 127.0.0.1/32 -j ACCEPT
    -A INPUT -p icmp -j ACCEPT
    -A INPUT -p tcp -m tcp --dport 32200 -j ACCEPT
    -A INPUT -j DROP
    COMMIT
    # Completed on Thu Feb  8 09:48:16 2018
    root@newbie-unknown85882:~# iptables-restore</etc/network/iptables.up.rules
    #然后在slave上也执行同样的操作
    
    root@newbie-unknown85883:~# telnet 10.83.3.102 3306
    Trying 10.83.3.102...
    Connected to 10.83.3.102.
    Escape character is '^]'.
    N
    5.7.21-log
              X?CuSD\�<m   yDi9 mysql_native_password
    ^CConnection closed by foreign host.
    #在slave上测试,能连通master的3306端口。
    

    确保master和slave都开启GTID事务

    root@newbie-unknown85883:~# vim /etc/mysql/mysql.conf.d/mysqld.cnf
    #在配置文件中添加:
    gtid_mode = on
    enforce_gtid_consistency = 1
    
    
    mysql> show variables like '%gtid_mode%';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | gtid_mode     | ON    |
    +---------------+-------+
    1 row in set (0.00 sec)
    

    测试:

    现在MySQL主从同步已经配置好了,但是测试的过程中可能会出现各种问题导致不能同步数据。这时候需要查看配置文件是否正确,查看错误日志获取关键信息以便解决问题。

    分别在master和slave上执行show master status;和show slave status\G;

    mysql> show master status;
    +------------------+----------+--------------+------------------+------------------------------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
    +------------------+----------+--------------+------------------+------------------------------------------+
    | mysql-bin.000007 |      194 |              |                  | 43425f23-2760-11e8-a564-52540035ed32:1-4 |
    +------------------+----------+--------------+------------------+------------------------------------------+
    
    mysql> show slave status\G;
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 10.83.3.102
                      Master_User: slave
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000007
              Read_Master_Log_Pos: 672
                   Relay_Log_File: newbie-unknown85883-relay-bin.000002
                    Relay_Log_Pos: 633
            Relay_Master_Log_File: mysql-bin.000007
                 Slave_IO_Running: No
                Slave_SQL_Running: Yes
    

    当Slave_IO_Running或者Slave_SQL_Running显示非“Yes”状态的时,说明配置有错误,需要查看配置或者错误日志。

    cat /var/log/mysql/error.log
    2018-03-16T11:20:00.929581Z 7 [ERROR] Slave I/O for channel '': The replication receiver thread cannot start because the master has GTID_MODE = ON and this server has GTID_MODE = OFF. Error_code: 1593
    

    我是在slave上查看错误日志的,由this server has GTID_MODE = OFF可得知slave的GTID没有开启,这时候需要更改配置文件开启GTID。

    什么是GTID?
    GTID(Global Transaction ID)是对于一个已提交事务的编号,并且是一个全局唯一的编号。它的官方定义如下:GTID = source_id :transaction_id每一个 GTID 代表一个数据库事务。在上面的定义中,source_id 表示执行事务的主库uuid(server_uuid),transaction_id 是一个从 1 开始的自增计数,表示在这个主库上执行的第 n 个事务。MySQL 只要保证每台数据库的 server_uuid 全局唯一,以及每台数据库生成的 transaction_id 自身唯一,就能保证 GTID 的全局唯一性。

    纠正了错误后继续测试:

    在master上操作

    mysql> show master status;
    +------------------+----------+--------------+------------------+------------------------------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
    +------------------+----------+--------------+------------------+------------------------------------------+
    | mysql-bin.000007 |      359 |              |                  | 43425f23-2760-11e8-a564-52540035ed32:1-5 |
    +------------------+----------+--------------+------------------+------------------------------------------+
    1 row in set (0.00 sec)
    

    由master上查出的信息得知,master replication log的位置和Position和我们之前查的不一样了,那么要以现在的为准。

    在slave上操作

    mysql> stop slave;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> change master to
        -> master_host='10.83.3.102',
        -> master_user='slave',
        -> master_password='slavemima',
        -> master_log_file='mysql-bin.000007',
        -> master_log_pos=359;
    Query OK, 0 rows affected, 2 warnings (0.04 sec)
    
    mysql> start slave;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | newbie             |
    | performance_schema |
    | sys                |
    +--------------------+
    5 rows in set (0.00 sec)
    

    现在所有的配置都已完成且正确,接下来就是最关键的测试,同步测试。

    在master上操作

    mysql> create database test;
    Query OK, 1 row affected (0.01 sec)
    
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | newbie             |
    | performance_schema |
    | sys                |
    | test               |
    +--------------------+
    6 rows in set (0.01 sec)
    

    在slave上操作

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | newbie             |
    | performance_schema |
    | sys                |
    | test               |
    +--------------------+
    6 rows in set (0.01 sec)
    

    由此可知,在master上创建一个test库,slave会同步创建相应的test库!MySQL主从同步配置成功!

    相关文章

      网友评论

        本文标题:MySQL主从同步

        本文链接:https://www.haomeiwen.com/subject/xjgrqftx.html