快速实现 MySQL 的主从同步

前言

  • 因最近服务器运营商时常出现流量问题,导致公司网站服务异常,为了解决这个问题,打算做一下异地容灾。

方案

  • 说是说异地容灾,其实就是将网站服务部署在不同机房服务器上。当机房 A 的服务异常后,可以快速切换到机房 B 所在服务继续给用户提供服务。

MySQL 的主从

  • 要实现这个,我们需要将数据库做到主从同步,确切的说是主主互备,而非主从。因为对于主从的架构,在机房 A 异常,机房 B 提供服务时,机房 A 的数据库没法和机房 B 实现同步。目前的方案是手动使其读取机房 B 的 MySQL 服务的 binlog

主从部署

  • 加上 A 是主(master),B 是从(slave)

建立 slave 的 MySQL 账户

  • B 要想同步 A 的数据,需以 slave 的身份去获取其 binlog,所以,需要在 A 上有一个账户 repl(你可以用你喜欢的字符串作为用户名)。我们手动建立该 MySQL 用户:
grant replication slave on *.* to 'repl'@'198.74.198.198' identified by '123passwd';
flush privileges;
  • 198.74.198.198 是 A 的服务器 ip,123passwdrepl 用户的密码。flush privileges; 是让授权生效。

确保 A 到 B 是连通的,B 到 A 也是连通的

  • 这里提供一种方法,就是在 B 服务器上使用 repl 用户名通过 MySQL 客户端连接 A 的 MySQL 服务:
mysql -h 198.74.198.198 -u repl -p 123passwd
  • 其中 198.74.198.198 表示远程数据库服务器所在 ip
  • 如果能不能连接上,可以根据报错信息,去谷歌搜索报错原因,然后解决。

查看主数据库当前状态

  • 要想从 A 上同步数据到 B,我们需要确定从哪个点开始同步。因此查看一下 A(主)的数据状态,使用命令 show master status
mysql> show master status;
+------------------+-----------+--------------+------------------+-------------------+
| File             | Position  | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+-----------+--------------+------------------+-------------------+
| mysql-bin.000005 | 397747713 |              |                  |                   |
+------------------+-----------+--------------+------------------+-------------------+

配置 slave

  • 知道从哪个点开始同步之后,我们就可以将这一点告诉 B:
change master to master_host='198.74.198.198',master_port=3306,master_user='repl',master_password='123passwd',master_log_file='mysql-bin.000005',master_log_pos=397747713;

开始同步

  • 此时,我们在 B 上,用 MySQL 客户端连接上本地的 MySQL 服务,直行命令,让其开始同步:
start slave;

查看同步状态

  • 你让它同步,它不一定能正常执行你的命令,此时我们需要查看同步状态:
show slave status\G;
  • 它会给你一些提示:
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 154.223.189.198
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000005
          Read_Master_Log_Pos: 397747713
               Relay_Log_File: host-172-16-7-145-relay-bin.000002
                Relay_Log_Pos: 12488
        Relay_Master_Log_File: mysql-bin.000005
             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: 397759918
              Relay_Log_Space: 12673
              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: 1
                  Master_UUID: xxxxxxx
             Master_Info_File: /www/server/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
1 row in set (0.00 sec)
  • 一大堆内容,但我们只需确认其中的两项为 yes 即可
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
  • 当两项都为 yes,表示同步正常执行了。

QA

  1. The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).
    解决:更改 server-id 参数

2.Last_SQL_Error: Error 'xxx doesn't exist' on query ...
解决:将主服务器上的数据库重新导入到从服务器上,数据库结构即可。只需保证库和表存在。

3.通过命令连接远程数据库服务,查看是否可以连接 ssh -v -p3306 xxx.xxx.xxx.xxx

4.尝试使用当前服务上的MySQL客户端连接远程MySQL服务 mysql -h xxx.xxx.xxx.xxx -u username -p somepassword,其中 xxx.xxx.xxx.xxx 表示远程数据库服务器所在 ip

参考资料

  • https://blog.csdn.net/csdnhsh/article/details/92224317
  • https://www.cnblogs.com/ygqygq2/p/6045279.html

你可能感兴趣的:(快速实现 MySQL 的主从同步)