前言:
MySQL内建的复制功能是构建大型,高性能应用程序的基础
通过将MySQL的某一台主机(master)的数据复制到其他主机(slaves)上,并重新执行一遍来执行
复制过程中一台服务器充当主服务器,而其他一个或多个其他服务器充当从服务器
简单来说:就是在开启主从复制后,从库将主库日志复制过来放到自己的中继日志然后将此日志


目录

  • 1、MySQL支持的复制类型
  • 2、为什么要做主从复制
  • 3、主从复制基本架构
  • 4、主从复制原理
  • 5、MySQL复制常用的拓扑结构
  • 配置MySQL数据库一主两从的主从复制
  • 环境准备
  • 1)设置server-id值并开启binlog参数
  • 2)在从服务器上需要开启的功能
  • 3) 建立同步账号
  • 4)锁表设置只读
  • 5)查看主库状态 这一步很重要,后续很需要
  • 6)备份数据库数据(在mysql执行Linux命令需要加上system)
  • 7)将备份的数据库通过scp传递给另外两台从服务器
  • 8)在另外两台从主机上解压传递到的数据库
  • 9)设定从库与主库同步
  • 10)启动从库同步开关,和查看从库信息
  • 6、主从状况监测主要参数
  • 7、常见状态错误排除
  • 8、生产环境其他常用设置


1、MySQL支持的复制类型

基于语句(statement)的复制
在主服务器上执行SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。
基于行(row)的复制
把改变的内容复制过去,而不是把命令在从服务器上执行一遍。从MySQL 5.0开始支持。
混合型(mixed)的复制
默认采用基于语句的复制,一旦发现基于语句的无法精确复制时,就会采用基于行的复制。

2、为什么要做主从复制

灾备
数据分布
负载平衡
读写分离
提高并发能力

3、主从复制基本架构

主从复制基本架构图:

sql server 主从复制数据库 教程 数据库主从复制配置_运维

4、主从复制原理

主要基于MySQL二进制日志
主要包括三个线程(2个I/O线程,1个SQL线程)

主从复制原理图

sql server 主从复制数据库 教程 数据库主从复制配置_数据库_02

1、MySQL将数据变化记录到二进制日志中;//也就是bin-log日志中
2、Slave将MySQL的二进制日志拷贝到Slave的中继日志中;
3、Slave将中继日志中的事件在做一次,将数据变化,反应到自身(Slave)的数据库

详细步骤:
1、从库通过手工执行change master to 语句连接主库,提供了连接的用户一切条件
(user 、password、port、ip),并且让从库知道,二进制日志的起点位置(file名 position 号); start slave
2、从库的IO线程和主库的dump线程建立连接。
3、从库根据change master to 语句提供的file名和position号,IO线程向主库发起binlog的请求。
4、主库dump线程根据从库的请求,将本地binlog以events的方式发给从库IO线程。
5、从库IO线程接收binlog events,并存放到本地relay-log中,传送过来的信息,会记录到master.info中
6、从库SQL线程应用relay-log,并且把应用过的记录到relay-log.info中,默认情况下,已经应用过的relay 会自动被清理purge

开启之后
检查主库的my.cnf有没有开启bin-log日志,然后检查主库有没有配置server-id
检查主库有没有对同步用户进行授权;

5、MySQL复制常用的拓扑结构

主从类型(Master-Slave)
主主类型(Master-Master)
级联类型(Master-Slave-Slave)

配置MySQL数据库一主两从的主从复制

环境准备

两台机器一主一从。
主库(MySQL Master):[ip为192.168.95.120 port为3306]
从库(MySQL Slave ) :[ip为192.168.95.130 port为3306]
主库配置

1)设置server-id值并开启binlog参数

(每一个主机都要开启,并且server-id不能一样)

vim /etc/my.cnf
[mysqld]
log_bin = mysql-bin
server_id = 11

2)在从服务器上需要开启的功能

//开启日志功能
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/node1-slow.log
long_query_time=3

#开启日志文件和server id
log_bin=mysql-bin
server_id=12
//开启GTID
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1

重启数据库

3) 建立同步账号

在主库上建立同步账号

mysql> grant replication slave on *.* to 'rep'@'192.168.142.%' identified by '123456';
mysql> show grants for 'rep'@'192.168.142.%';

4)锁表设置只读

为后面备份准备,注意生产环境要提前申请停机时间;

mysql> flush tables with read lock;

提示:如果超过设置时间不操作会自动解锁。

mysql> show variables like '%timeout%';
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| connect_timeout             | 10       |
| delayed_insert_timeout      | 300      |
| have_statement_timeout      | YES      |
| innodb_flush_log_at_timeout | 1        |
| innodb_lock_wait_timeout    | 50       |
| innodb_rollback_on_timeout  | OFF      |
| interactive_timeout         | 28800    |
| lock_wait_timeout           | 31536000 |	//等待时间很长也可以自己解锁
| net_read_timeout            | 30       |
| net_write_timeout           | 60       |
| rpl_stop_slave_timeout      | 31536000 |
| slave_net_timeout           | 60       |
| wait_timeout                | 28800    |
+-----------------------------+----------+
13 rows in set (0.16 sec)

5)查看主库状态 这一步很重要,后续很需要

查看主库状态,即当前日志文件名和二进制日志偏移量
主从复制会基于mysql-bin 来复制

mysql> show master status;
+------------------+----------+--------------+------------------+----------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                            |
+------------------+----------+--------------+------------------+----------------------------------------------+
| mysql-bin.000017 | 22989540 |              |                  | 5df41ab1-ad1b-11ec-84f9-000c290eccc5:1-80175 |
+------------------+----------+--------------+------------------+----------------------------------------------+
1 row in set (0.00 sec)

6)备份数据库数据(在mysql执行Linux命令需要加上system)

创建目录备份到此目录并添加时间备份

mysql> system mkdir -p /server/backup
mysql> system  mysqldump -uroot -p -A -B |gzip > /server/backup/mysql_bak.$(date +%F).sql.gz
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. 
mysql>

7)将备份的数据库通过scp传递给另外两台从服务器

[root@node1 ~]# scp /server/backup/mysql_bak.$(date +%F).sql.gz 192.168.142.154:/root
root@192.168.142.154's password: 
mysql_bak.2022-05-08.sql.gz    
[root@node1 ~]# scp /server/backup/mysql_bak.$(date +%F).sql.gz 192.168.142.139:/root
root@192.168.142.139's password: 
mysql_bak.2022-05-08.sql.gz

8)在另外两台从主机上解压传递到的数据库

[root@node2 ~]# zcat mysql_bak.2022-05-08.sql.gz  | mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.

[root@node3 ~]# zcat mysql_bak.2022-05-08.sql.gz | mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.

在另外的两台从库上配置

9)设定从库与主库同步

mysql> change master to
    -> master_host='192.168.142.153',
    -> master_user='rep',
    -> master_password='123456',
    -> master_log_file='mysql-bin.000017',
    -> master_log_pos=22989540;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> change master to
    -> master_host='192.168.142.153',
    -> master_user='rep',
    -> master_password='123456',
    -> master_log_file='mysql-bin.000017',
    -> master_log_pos=22989540;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

10)启动从库同步开关,和查看从库信息

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

检查状态:
mysql> show slave status\G

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.142.153
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000017
          Read_Master_Log_Pos: 22989540
               Relay_Log_File: node3-relay-bin.000003
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000017
             Slave_IO_Running: Yes		//主要看这两个有没有开启yes
            Slave_SQL_Running: Yes		//主要看这两个有没有开启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: 22989540
              Relay_Log_Space: 527
              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: 11
                  Master_UUID: 5df41ab1-ad1b-11ec-84f9-000c290eccc5
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           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: 5df41ab1-ad1b-11ec-84f9-000c290eccc5:1-80175
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)

ERROR: 
No query specified

6、主从状况监测主要参数

Slave_IO_Running: IO线程是否打开 YES/No/NULL
    Slave_SQL_Running: SQL线程是否打开 YES/No/NULL
    Seconds_Behind_Master: NULL #和主库比同步的延迟的秒数

配置完成后可以创建数据库查看主从同步信息

主库上创建数据库test

sql server 主从复制数据库 教程 数据库主从复制配置_数据库_03


从库1上查询数据库test

sql server 主从复制数据库 教程 数据库主从复制配置_服务器_04


在从库2上查询是否有test数据库

sql server 主从复制数据库 教程 数据库主从复制配置_mysql_05

7、常见状态错误排除

发现IO进程错误,检查日志,排除故障:
# tail localhost.localdomain.err 
...
2015-11-18 10:55:50 3566 [ERROR] Slave I/O: 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. Error_code: 1593
找到原因:从5.6开始复制引入了uuid的概念,各个复制结构中的server_uuid得保证不一样
解决方法:(从库是克隆机器)
修改从库的uuid
[root@node1 ~]# vim /var/lib/mysql/auto.cnf 
	server-uuid=	//这里数字可以改一下;位数要一样长,一定不能删除

常见状态错误排除
show slave status;报错:Error xxx doesn’t exist
解决方法:
stop slave;
set global sql_slave_skip_counter = 1;
start slave;

8、生产环境其他常用设置

1、配置忽略权限库同步参数(设置某些数据库不想同步过去的)
binlog-ignore-db='information_schema mysql test'

2、从库备份开启binlog
log-slave-updates
log_bin = mysql-bin
expire_logs_days = 7(日志保存时间)
应用场景:级联复制或从库做数据备份。

3、从库只读
read-only来实现
innodb_read_only = ON或1,或者innodb_read_only
结论:当用户权限中没有SUPER权限(ALL权限是包括SUPER的)时,从库的read-only生效!