MySQL主从配置

17.1 MySQL主从介绍

MySQL主从又叫做Replication、AB复制。简单讲就是A和B两台机器做主从后,在A上写数据,另外一台B也会跟着写数据,两者数据实时同步的。也就是说,当你在A机器写入一个表,再次查看B机器也会同步一个表。

MySQL主从是基于binlog的,主上须开启binlog才能进行主从。

主从过程大致有3个步骤:

  • 主将更改操作记录到binlog里。
  • 从将主的binlog事件(sql语句)同步到从本机上并记录在relaylog里。
  • 从根据relaylog里面的sql语句按顺序执行 主上有一个log dump线程,用来和从的I/O线程传递binlog 从上有两个线程,其中I/O线程用来同步主的binlog并生成relaylog,另外一个SQL线程用来把relaylog里面的sql语句落地。

主从原理图:

MySQL主从配置_第1张图片

Master:主mysql Slave:备mysql

当有数据写进主mysql中的时候,就出自动生成一个log dump thread,记录到如上讲的binlog中,然后从数据库就会和主mysql有个线程进行交互,从服务器就会读取binlog日志到Slave,然后再次生成一个relay log(中继日志),然后再次和从服务器中的SQL thread线程进程交互执行。

简单的说,就是 从服务器把主服务器上的binlog弄到自己服务器上去,然后根据这个binlog生成自己的relay日志,根据这个relay日志进行更改数据库,最终达到两边数据一致。

主从的作用;

1.数据的备份;

假如A服务器(主)突然硬件问题,宕机了。但是线上跑了很多重要的数据,我们完全可以使用B服务器(从)直接顶上。

2. 负载均衡;

我们线上的所有数据均是从A上面读取,由于压力比较大,我们可以使用B服务器分享一部分用户到自己的服务器,但是只是可以读,不可以写入数据。看图可知,数据的读取是有方向性的,如果首先从B上读取那就混乱了,数据肯定不一致了。就会导致主从失败!

17.2 准备工作

因为是实验环境,直接准备了一台虚拟机,装好MYSQL后,再克隆一台虚拟机,避免其他变量影响。

17.3 配置主

编辑配置文件添加如下参数:

[root@localhost ~]# vim /etc/my.cnf
……
server-id=180
#自定义
log_bin=yuntai01
#自定义定log前缀

编辑完成后重启mysql服务:

[root@localhost ~]# /etc/init.d/mysqld restart
Shutting down MySQL...... SUCCESS! 
Starting MySQL.................. SUCCESS! 

查看mysql库文件:

[root@localhost ~]# ls -lt /data/mysql/
总用量 110684
-rw-rw----. 1 mysql mysql 50331648 12月 14 15:30 ib_logfile0
-rw-rw----. 1 mysql mysql 12582912 12月 14 15:30 ibdata1
-rw-rw----. 1 mysql mysql    56288 12月 14 15:30 localhost.localdomain.err
-rw-rw----. 1 mysql mysql        5 12月 14 15:30 localhost.localdomain.pid
drwx------. 2 mysql mysql    4096 12月 12 18:13 zrlog
-rw-rw----. 1 mysql mysql      143 12月 12 17:45 yuntai.000001    #重要
-rw-rw----. 1 mysql mysql      16 12月 12 12:07 yuntai.index         #重要
-rw-rw----. 1 mysql mysql      56 11月  7 17:27 auto.cnf
drwx------. 2 mysql mysql    4096 11月  7 17:24 mysql
drwx------. 2 mysql mysql    4096 11月  7 17:24 performance_schema
-rw-rw----. 1 mysql mysql 50331648 11月  7 17:24 ib_logfile1
drwx------. 2 mysql mysql        6 11月  7 17:23 test

说明: 重启后生成两个前缀为yuntai01的二进制文件是实现主从的重要文件。

新建一个数据库为试验做准备:

备份一个数据库:
[root@localhost ~]# mysqldump -uroot -p123456 zrlog > /tmp/zrlog.sql
Warning: Using a password on the command line interface can be insecure.

新建几个数据库:
[root@localhost ~]# mysql -uroot -p123456
mysql> create database yuntai01;
Query OK, 1 row affected (0.00 sec)
mysql> create database yuntai02;
Query OK, 1 row affected (0.00 sec)

mysql> quit
Bye

将备份的数据恢复到新建的数据库中:
[root@localhost mysql]# mysql -uroot -p123456 yuntaitest < /tmp/test.sql

创建一个用于同步数据的用户:

[root@localhost mysql]# mysql -uroot -p123456
Welcome to the MySQL monitor.
mysql> grant replication slave on *.* to 'repl'@'192.168.2.181' identified by '123456';
Query OK, 0 rows affected (0.01 sec)
#IP 192.168.2.181 为“从”的IP

mysql> flush tables with read lock;
Query OK, 0 rows affected (0.12 sec)
#锁定数据表(目的是暂时使其不能继续写,保持现有状态用于同步)

mysql> show master status;
+-----------------+----------+--------------+------------------+-------------------+
| File            | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------+----------+--------------+------------------+-------------------+
| yuntai01.000001 |      542 |              |                  |                  |
+-----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
#记住file和position(设置主从同步时会使用)
mysql> quit
Bye

查看当前的数据库,准备备份

[root@localhost ~]# cd /data/mysql
[root@localhost mysql]# ls
auto.cnf  ib_logfile0  localhost.localdomain.err  mysql              test          yuntai01        yuntai01.index  yuntai.index
ibdata1  ib_logfile1  localhost.localdomain.pid  performance_schema  yuntai.000001  yuntai01.000001  yuntai02        zrlog

#我们的数据库:yuntai01 yuntai02 zrlog,我们把这几个数据库全部备份并同步。

备份主库中所有数据库:

[root@localhost mysql]# mysqldump -uroot -p123456 zrlog > /tmp/zrlog.sql
[root@localhost mysql]# mysqldump -uroot -p123456 yuntai01 > /tmp/yuntai01.sql
[root@localhost mysql]# mysqldump -uroot -p123456 yuntai02 > /tmp/yuntai02.sql

数据对比

[root@localhost mysql]# ls -lt /tmp/*.sql
-rw-r--r--. 1 root root  1262 12月 14 15:54 /tmp/yuntai02.sql
-rw-r--r--. 1 root root  1262 12月 14 15:54 /tmp/yuntai01.sql
-rw-r--r--. 1 root root 10072 12月 14 15:53 /tmp/zrlog.sql

[root@localhost mysql]# ls -lt
总用量 110692
......
drwx------. 2 mysql mysql    4096 12月 14 15:50 zrlog
drwx------. 2 mysql mysql      20 12月 14 15:38 yuntai02
drwx------. 2 mysql mysql      20 12月 14 15:38 yuntai01
......

17.4 配置从

编辑从MySQL的配置文件添加如下参数:

配置server-id=181,要求和主不一样。bin_log就不需要配置了,二进制文件只需要在主服务器上面配置即可。

[root@localhost ~]# vim /etc/my.cnf
……
server-id=181
#添加到最后

重启配置文件
[root@localhost ~]# /etc/init.d/mysqld restart
Shutting down MySQL...... SUCCESS! 
Starting MySQL.............................. SUCCESS! 

将主中备份的数据发送到从中

[root@localhost ~]# scp 192.168.2.180:/tmp/*.sql /tmp/     ##此IP为MySQL主的IP地址
The authenticity of host '192.168.2.180 (192.168.2.180)' can't be established.
ECDSA key fingerprint is 17:2a:d4:3f:ff:02:39:05:e4:c2:02:44:73:5e:88:64.
Are you sure you want to continue connecting (yes/no)? yes
#输入yes
Warning: Permanently added '192.168.2.180' (ECDSA) to the list of known hosts.
[email protected]'s password: 
#输入180机器的root密码
yuntai01.sql                                                                                                                                                100% 1262    1.2KB/s  00:00    
yuntai02.sql                                                                                                                                                100% 1262    1.2KB/s  00:00    
zrlog.sql                                                                                                                                                    100%  10KB  9.8KB/s  00:00  

配置MySQL

配置MySQL环境
[root@localhost ~]# export PATH=$PATH:/usr/local/mysql/bin/
#这是将命令路径暂时加入环境变量,系但是统重启后该变量会失效,最好将其加入环境变量配置文件

[root@localhost ~]# vim /etc/profile
…… #添加
export PATH=$PATH:/usr/local/mysql/bin/

[root@localhost ~]# source /etc/profile  //刷新刚刚的配置文件,否则不生效

制定账户,设置密码
[root@localhost ~]# mysqladmin -uroot password '123456'  

创建对应的MySQL库

[root@localhost ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.6.35 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, 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 database yuntai01;
Query OK, 1 row affected (0.00 sec)

mysql> create database yuntai02;
Query OK, 1 row affected (0.00 sec)

mysql> create database zrlog;
Query OK, 1 row affected (0.00 sec)

mysql> quit
Bye

恢复数据库

[root@localhost ~]# mysql -uroot -p123456 zrlog< /tmp/zrlog.sql 
[root@localhost ~]# mysql -uroot -p123456 yuntai01< /tmp/yuntai01.sql 
[root@localhost ~]# mysql -uroot -p123456 yuntai02< /tmp/yuntai02.sql 

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

mysql> show databases;
+--------------------+
| Database          |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test              |
| yuntai01          |
| yuntai02          |
| zrlog              |
+--------------------+
7 rows in set (0.08 sec)

配置从服务器

mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)

重要步骤
mysql> change master to master_host='192.168.2.180', master_user='repl', master_password='123456', master_log_file='yuntai01.000001', master_log_pos=542;
Query OK, 0 rows affected, 2 warnings (0.06 sec)
# master_host:主MySQL IP、master_user:主MySQL上交互用的用户名
# master_log_file:主服务器上面show master status的文件名、master_log_pos:show master status的position值

检测主从是否建立成功

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G     #成功的话会显示如下内容
*************************** 1. row ***************************
              Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.2.180
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: yuntai01.000002
          Read_Master_Log_Pos: 120
              Relay_Log_File: localhost-relay-bin.000005
                Relay_Log_Pos: 282
        Relay_Master_Log_File: yuntai01.000002
            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: 120
              Relay_Log_Space: 11178
              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: 180
                  Master_UUID: d14c4924-c39d-11e7-93c6-000c2914f61b
            Master_Info_File: /data/mysql/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)
mysql> show slave status\G  看是否有
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
还需关注
Seconds_Behind_Master: 0  //为主从延迟的时间
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

配置中出现过的错误

            Slave_IO_Running: No
            Slave_SQL_Running: Yes
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 1593
                Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.
#报错中也有显示

主要原因是5.6中引入了UUID的概念,各个mysql service的uuid要保证不能一样。

[root@localhost ~]# cd /data/mysql/
[root@localhost mysql]# ls
auto.cnf  ib_logfile0  localhost.localdomain.err  localhost-relay-bin.000002  master.info  performance_schema  test      yuntai02
ibdata1  ib_logfile1  localhost.localdomain.pid  localhost-relay-bin.index  mysql        relay-log.info      yuntai01  zrlog
[root@localhost mysql]# vim auto.cnf 
[auto]
server-uuid=d14c4924-c39d-11e7-93c6-000c2914f68b     #随意改动2个字母或数字后保存

[root@localhost mysql]# /etc/init.d/mysqld restart

到主服务器解开锁表

[root@localhost mysql]#  mysql -uroot -p123456
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

到这里,MySQL的主从配置就完成了。

17.5 测试主从同步

参数介绍

主服务器:
binlog-do-db=     //仅同步指定的库
binlog-ignore-db=    //忽略指定的库

从服务器:
replicate_do_db=    //同步指定的库
replicate_ignore_db=  //忽略指定的库
replicate_do_table=    //同步指定的表
replicate_ignore_table=  //忽略指定的表
#建议只使用下面2个语句,使用参数“replicate_wild_”,使匹配更精确,提升使用性能。
replicate_wild_do_table=  如yuntai.%,支持通配符    
replicate_wild_ignore_table=    

#如果想定义的话,将上面语句写入Mysql的my.cnf配置文件中
  • 假如在主服务器上面有很多数据库,但是我只想同步yuntai01这个库
# vim /etc/my.cnf
......
binlog-do-db=yuntai01
要是多个的话就用英文状态下的逗号去分隔;
  • 或者有时候数据库比较多,我就一个yuntai02库不需要同步
# vim /etc/my.cnf
......
binlog-ignore-db=yuntai02
  • 有时候我们需要在同步的时候忽略一些临时的表,这些表对我们的用处不大。我们可以在从服务器上编辑
# vim /etc/my.cnf
......
replicate_wild_do_table=yuntai01.%,yuntai02.%

开始测试

主操作

mysql> show databases;
+--------------------+
| Database          |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test              |
| yuntai01          |
| yuntai02          |
| zrlog              |
+--------------------+
7 rows in set (0.00 sec)

mysql> use yuntai01
Database changed
mysql> show tables;
Empty set (0.00 sec)

从操作,查看相同数据情况

同上,略

mysql> use yuntai01
Database changed
mysql> show tables;
Empty set (0.00 sec)

主上,尝试往yuntai01库导入内容

mysql> quit
Bye
[root@localhost mysql]# mysql -uroot -p123456 yuntai01 < /tmp/zrlog.sql
Warning: Using a password on the command line interface can be insecure.
[root@localhost mysql]# mysql -uroot -p123456
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9398
Server version: 5.6.35-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, 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> use yuntai01;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+--------------------+
| Tables_in_yuntai01 |
+--------------------+
| comment            |
| link              |
| log                |
| lognav            |
| plugin            |
| tag                |
| type              |
| user              |
| website            |
+--------------------+
9 rows in set (0.00 sec)

mysql> select count(*) plugin;
+--------+
| plugin |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)

再次去从上查看

同上,略
mysql> select count(*) plugin;
+--------+
| plugin |
+--------+
|      1 |
+--------+
1 row in set (0.01 sec)

主上删除表格plugin

mysql> drop table plugin;
Query OK, 0 rows affected (0.00 sec)

从上查看表格plugin

mysql> show tables;
+--------------------+
| Tables_in_yuntai01 |
+--------------------+
| comment            |
| link              |
| log                |
| lognav            |
| tag                |
| type              |
| user              |
| website            |
+--------------------+
8 rows in set (0.00 sec)

plugin表格果然没有了!

表示测试成功,mysql的确同步了。

千万别在从server上面删除任何数据,一旦删除也就意味着数据不是一致的,主从就失败了!

如果主从这么失败了,如何再次恢复呢?

  1. 先把主server上面的数据与从server上面的数据保持一致,刚刚从server删除了什么数据,现在也需要把主server上面的数据也删除,为的就是数据一致!
  2. 首先主server上面操作
mysql> show master status;
+-----------------+----------+--------------+------------------+-------------------+
| File            | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------+----------+--------------+------------------+-------------------+
| yuntai01.000001 |    10863 |              |                  |                  |
+-----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

记住Position值
  1. 从server上操作使用新的Postion值
mysql> stop slave;
mysql> change master to master_host='192.168.2.180', master_user='repl', master_password='123456', master_log_file='yuntai01.000001', master_log_pos=10863;
  1. 再次启动从,查看状态
mysql> start slave;

mysql> show slave status\G

具体思路

  • 保证数据一致性的前提下,如上操作,如果主表格还在写入导致的数据不符,在不影响业务的情况下,可以锁主表
  • 实在是数据不一致的前提下,建议直接重新备份,然后再次导入,再次change master即可

转载于:https://my.oschina.net/zhouyuntai/blog/1590115

你可能感兴趣的:(MySQL主从配置)