mysql —复制

Posted 范儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql —复制相关的知识,希望对你有一定的参考价值。

mysql的扩展

读写分离

   复制:每个节点都有相同的数据集

    向外扩展

    二进制日志

    单向

复制的功用:

    数据分布

    负载均衡读

    备份

    高可用和故障切换

    MySQL升级测试

MySQL复制相关概念

  主从复制:主节点将数据同步到多个从节点

  级联复制:主节点将数据同步到一个从节点,其他的从节点在向从节点复制数据

  同步复制:将数据从主节点全部同步到从节点时才返回给用户的复制策略叫同步复制

  异步复制:只要数据写入到主节点就立即返回给用户同步完成

  读写分离:在前端加一个调度器,负责将改变数据的语句和查询数据的语句分开调度,把写操作调度到主节点,读操作调度到从节点

主节点:

  dump Thread:为每个Slave的I/O Thread启动一个dump线程,用于向其发送binary log events

从节点

  I/O Thread:向Master请求二进制日志事件,并保存于中继日志中

  SQL Thread:从中继日志中读取日志事件,在本地完成重放

跟复制功能相关的文件:

  master.info:用于保存slave连接至master时的相关信息,例如账号、密码、服务器地址等

  relay-log.info(中继日志):保存在当前slave节点上已经复制的当前二进制日志和本地replay log日志的对应关系

复制架构:

  一主一从

  一主多从

  主主复制

  环状复制

  级联复制

  多主一从

简单的一主一从架构实现

主服务器配置

~]# vim /etc/my.cnf
    [mysqld]
    log_bin
    binlog_format=ROW
    server_id=1
~]# systemctl restart mariadb
~]# mysql
MariaDB [(none)]> grant replication slave on *.* to lv(从服务接收的用户)@\'192.168.130.%\' identified by \'centos\'; #授权同步账号
Query OK, 0 rows affected (0.01 sec)

MariaDB [(none)]> show master logs;
+--------------------+-----------+
| Log_name | File_size           |
+--------------------+-----------+
| mariadb-bin.000001 | 19578633 |
| mariadb-bin.000002 | 395 | #记录此位置,从服务器从这里开始同步

+--------------------+-----------+
2 rows in set (0.00 sec)

​ 2)从服务器配置

~]# vim /etc/my.cnf
    [mysqld]
    server_id=2  #服务器ID唯一
    relay_log=relay-log #relay log的文件路径,默认值hostname-relay-bin
    relay_log_index=relay-log.index #默认值hostname-relay-bin.index
    read_only=ON
~]# systemctl restart mariadb #重启服务
~]# mysql
MariaDB [(none)]> CHANGE MASTER TO
    -> MASTER_HOST=\'192.168.130.8\',  #指定主节点IP
    -> MASTER_USER=\'lv\',  #同步用户的用户名
    -> MASTER_PASSWORD=\'centos\',  #同步用户的密码
    -> MASTER_PORT=3306, #数据库的端口号
    -> MASTER_LOG_FILE=\'mariadb-bin.000002\', #以上记录的文件
-> MASTER_LOG_POS=395, #位置
-> MASTER_CONNECT_RETRY=10; #重试时间10秒
MariaDB [(none)]
> START SLAVE; #开始主从复制

​ 3)测试

在主节点上生成一些数据:
MariaDB [(none)]> CREATE DATABASE testdb;
MariaDB [(none)]> use testdb
MariaDB [testdb]> create table testlog (id int auto_increment primary key,name char(20),age int default 20);
MariaDB [testdb]> delimiter $$
MariaDB [testdb]> create procedure pro_testlog()
    -> begin
    -> declare i int;
    -> set i = 1;
    -> while i < 100000
    -> do insert into testlog(name,age) values (concat(\'testuser\',i),i);
    -> set i = i +1; 
    -> end while;
    -> end$$
MariaDB [testdb]> delimiter ;
MariaDB [testdb]> START TRANSACTION;
MariaDB [testdb]> CALL pro_testlog;
MariaDB [testdb]> COMMIT;
在从节点上查看同步情况:
MariaDB [(none)]> SELECT COUNT(*) FROM testdb.testlog;
+----------+
| COUNT(*) |
+----------+
|    99999 |  #同步成功
+----------+
MariaDB [(none)]> SHOW SLAVE STATUS\\G
*************************** 1. row ****************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.130.8
                  Master_User: lv
                  Master_Port: 3306
                Connect_Retry: 10
              Master_Log_File: mariadb-bin.000002
          Read_Master_Log_Pos: 10389814
               Relay_Log_File: relay-log.000002
                Relay_Log_Pos: 10389944
        Relay_Master_Log_File: master1-bin.000002
             Slave_IO_Running: Yes  #IO线程已启动
            Slave_SQL_Running: Yes  #SQL线程已启动
        Seconds_Behind_Master: 0    #主从复制的时间差
             Master_Server_Id: 1

旧数据库新加从服务器

​ 1)主服务器配置

~]# vim /etc/my.cnf
    [mysqld]
    log_bin
    binlog_format=ROW
    log-basename=master1
    server_id=1 #为当前节点设置一个全局惟的ID号
~]# systemctl restart mariadb
~]# mysqldump -uroot -pcentos -A -F --single-transaction --master-data=1 > full.sql
~]# scp full.sql root@192.168.130.7:/root/
~]#mysql
MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO testuser(从服务接收的用户)@\'192.168.130.7\' IDENTIFIED BY \'centos\';

​ 2)从服务器配置~]# vim /etc/my.cnf

    [mysqld]
    server_id=2  #为当前节点设置一个全局惟的ID号
    relay_log=relay-log  
    read_only=ON
~]# systemctl restart mariadb
~]# vim full.sql  #在备份的SQL文件中加入以下信息
CHANGE MASTER
TO MASTER_HOST=\'192.168.130.8\',
MASTER_USER=\'testuser\',
MASTER_PASSWORD=\'centos\',
MASTER_PORT=3306,
MASTER_LOG_FILE=\'mariadb-bin.000003\',# 已默认的
MASTER_LOG_POS=245, #已默认的
MASTER_CONNECT_RETRY=10;
~]# mysql < full.sql  #导入SQL的同时配置已经完成
MariaDB [(none)]> SELECT COUNT(*) FROM testdb.testlog;
+----------+
| COUNT(*) |
+----------+
|    99999 |
+----------+
MariaDB [(none)]> START SLAVE;  #启动同步复制
MariaDB [(none)]> show slave status\\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.130.8
Master_User: testuser
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: mariadb-bin.000003
Read_Master_Log_Pos: 401
Relay_Log_File: relay-log.024649
Relay_Log_Pos: 531
Relay_Master_Log_File: mariadb-bin.000003
Slave_IO_Running: Yes #IO线程已启动
Slave_SQL_Running: Yes #SQL线程已启动 Seconds_Behind_Master:
0 #主从复制的时间差 Master_Server_Id: 1

 级联复制

1)主节点

[root@master ~]# vim /etc/my.cnf
[mysqld]
log_bin
binlog_format=ROW
server_id=1
[root@master ~]# systemctl restart mariadb
MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO testuser@\'192.168.130.%\' IDENTIFIED BY \'centos\';
MariaDB [(none)]> SHOW MASTER LOGS;

+--------------------+-----------+
| Log_name | File_size |
+--------------------+-----------+
| mariadb-bin.000001 | 19578756 |
| mariadb-bin.000002 | 401 |
+--------------------+-----------+
2 rows in set (0.00 sec)

2)从节点

[root@slave1 ~]# vim /etc/my.cnf
[mysqld]
log_bin  #注意,级联架构中中继从节点一定得开二进制日志功能
binlog_format=ROW
read_only=ON
server_id=2
log_slave_updates  #这项为关键,作用是将从服务的数据改变记录到二进制日志文件中
relay_log=relay-log
relay_log_index=relay-log.index
[root@slave1 ~]# systemctl start mariadb
MariaDB [(none)]> CHANGE MASTER TO
    -> MASTER_HOST=\'192.168.130.10\',
    -> MASTER_USER=\'testuser\',
    -> MASTER_PASSWORD=\'ccentos\',
    -> MASTER_PORT=3306,
    -> MASTER_LOG_FILE=\'mariadb-bin.000002\',
    -> MASTER_LOG_POS=401,
    -> MASTER_CONNECT_RETRY=10;
MariaDB [(none)]> START SLAVE;
MariaDB [(none)]> show master logs;
+--------------------+-----------+
| Log_name | File_size |
+--------------------+-----------+
| mariadb-bin.000001 | 19578633 |
| mariadb-bin.000002 | 10389327 |
| mariadb-bin.000003 | 1792 |
| mariadb-bin.000004 | 264 |
| mariadb-bin.000005 | 245 |
+--------------------+-----------+
5 rows in set (0.00 sec)

MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO testuser@\'192.168.0.%\' IDENTIFIED BY \'centos\';

3)从节点的从节点

[root@slave2 ~]# vim /etc/my.cnf
[mysqld]
read_only=ON
server_id=3
relay_log=relay-log
relay_log_index=relay-log.index
[root@slave2 ~]# systemctl start mariadb
MariaDB [(none)]> CHANGE MASTER TO
    -> MASTER_HOST=\'192.168.130.8\',
    -> MASTER_USER=\'testuser\',
    -> MASTER_PASSWORD=\'centos\',
    -> MASTER_PORT=3306,
    -> MASTER_LOG_FILE=\'mariadb-bin.000005\',
    -> MASTER_LOG_POS=245,
    -> MASTER_CONNECT_RETRY=10;
MariaDB [(none)]> START SLAVE;

4)测试

在主节点上生成一些数据:
MariaDB [(none)]> CREATE DATABASE testdb;
MariaDB [(none)]> use testdb
MariaDB [testdb]> create table testlog (id int auto_increment primary key,name char(20),age int default 20);
MariaDB [testdb]> delimiter $$
MariaDB [testdb]> create procedure pro_testlog()
    -> begin
    -> declare i int;
    -> set i = 1;
    -> while i < 100000
    -> do insert into testlog(name,age) values (concat(\'testuser\',i),i);
    -> set i = i +1; 
    -> end while;
    -> end$$
MariaDB [testdb]> delimiter ;
MariaDB [testdb]> START TRANSACTION;
MariaDB [testdb]> CALL pro_testlog;
MariaDB [testdb]> COMMIT;
在从节点上查看同步情况:
MariaDB [(none)]> SELECT COUNT(*) FROM testdb.testlog;
+----------+
| COUNT(*) |
+----------+
|    99999 |  #同步成功
+----------+
MariaDB [(none)]> SHOW SLAVE STATUS\\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.130.10
Master_User: testuser
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: mariadb-bin.000002
Read_Master_Log_Pos: 401
Relay_Log_File: relay-log.000004
Relay_Log_Pos: 531
Relay_Master_Log_File: mariadb-bin.000002
Slave_IO_Running: Yes #IO线程已启动
Slave_SQL_Running: Yes #SQL线程已启动
Seconds_Behind_Master: 0 #主从复制的时间差
Master_Server_Id: 1
在从节点的从节点上查看同步情况:
MariaDB [(none)]> SELECT COUNT(*) FROM testdb.testlog;
+----------+
| COUNT(*) |
+----------+
|    99999 |  #同步成功
+----------+
MariaDB [(none)]> SHOW SLAVE STATUS\\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.130.8
Master_User: testuser
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: mariadb-bin.000005
Read_Master_Log_Pos: 401
Relay_Log_File: relay-log.000002
Relay_Log_Pos: 687
Relay_Master_Log_File: mariadb-bin.000005
Slave_IO_Running: Yes #IO线程已启动
Slave_SQL_Running: Yes #SQL线程已启动
Seconds_Behind_Master: 0 #主从复制的时间差
Master_Server_Id: 1

主主复制架构

容易产生的问题:数据不一致,因此慎用;考虑要点:自动增长id
配置一个节点使用奇数id
auto_increment_offset=1 开始点
auto_increment_increment=2 增长幅度
另一个节点使用偶数id
auto_increment_offset=2
auto_increment_increment=2

半同步复制的实现

默认情况下,MySQL的复制功能是异步的,异步复制可以提供最佳的性能,主库把binlog日志发送给从库即结束,并不验证从库是否接收完毕。这意味着当主服务器或从服务器端发生故障时,有可能从服务器没有接收到主服务器发送过来的binlog日志,这就会造成主服务器和从服务器的数据不一致,甚至在恢复时造成数据的丢失;半同步复制的机制是只有当主节点和从节点同步完成,仅有一台同步完成即可,返回写入完成,这样的机制保证了数据的安全性。

1)主节点

[root@master ~]# vim /etc/my.cnf
[mysqld]
log_bin
binlog_format=ROW
log-basename=master
server_id=1
relay_log=relay-log
relay_log_index=relay-log.index
[root@master ~]# systemctl restart mariadb
MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO testuser@\'192.168.0.%\' IDENTIFIED BY \'centos\';
MariaDB [(none)]> SHOW MASTER LOGS;
+--------------------+-----------+
| Log_name | File_size |
+--------------------+-----------+
| mariadb-bin.000001 | 19578756 |
| mariadb-bin.000002 | 586 |
| mariadb-bin.000003 | 401 |
+--------------------+-----------+
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_master SONAME \'semisync_master.so\';  #安装模块
MariaDB [(none)]> SET GLOBAL rpl_semi_sync_master_enabled=1;  #开启半同步功能
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE \'%semi%\';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled       | ON    |  #已开启
| rpl_semi_sync_master_timeout       | 10000 |
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    |
+------------------------------------+-------+
MariaDB [(none)]> SHOW GLOBAL STATUS LIKE \'%semi%\';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+

2)从节点1

[root@slave1 ~]# vim /etc/my.cnf
[mysqld]
read_only=ON
log_bin
binlog_format=ROW
log-basename=slave
server_id=2
relay_log=relay-log
relay_log_index=relay-log.index
[root@slave1 ~]# systemctl restart mariadb
MariaDB [(none)]> CHANGE MASTER TO 
    -> MASTER_HOST=\'192.168.130.10\',
    -> MASTER_USER=\'testuser\',
    -> MASTER_PASSWORD=\'centos\',
    -> MASTER_PORT=3306,
    -> MASTER_LOG_FILE=\'master-bin.000003\',
    -> MASTER_LOG_POS=401,
    -> MASTER_CONNECT_RETRY=10;
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_slave SONAME \'semisync_slave.so\'; #安装模块
MariaDB [(none)]> SET GLOBAL rpl_semi_sync_slave_enabled=1; #开启半同步功能
MariaDB [(none)]> START SLAVE;
MariaDB [(none)]> SHOW MASTER LOGS;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| slave-bin.000001 | 245 |
+------------------+-----------+
1 row in set (0.00 sec)

MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO repluser@\'192.168.0.%\' IDENTIFIED BY \'replpass\';

3)从节点2

[root@slave2 ~]# vim /etc/my.cnf
[mysqld]
read_only=ON
server_id=3
relay_log=relay-log
relay_log_index=relay-log.index
[root@slave2 ~]# systemctl restart mariadb
MariaDB [(none)]> CHANGE MASTER TO
    -> MASTER_HOST=\'192.168.130.10\',
    -> MASTER_USER=\'testuser\',
    -> MASTER_PASSWORD=\'centos\',
    -> MASTER_PORT=3306,
    -> MASTER_LOG_FILE=\'slave-bin.000001\',
    -> MASTER_LOG_POS=245,
    -> MASTER_CONNECT_RETRY=10;
MariaDB [(none)]> START SLAVE;
当然,从服务器还可以有很多,此处到此为止。再按上面的测试一下就OK!

复制过滤器

复制过滤器表示可以指定只复制指定的表或者只复制指定的库,其他的表和库都不进行复制,两种方法可以实现:

  主服务器实现:主服务器指定只有指定的表或者库的修改信息才传递到从服务器的中继日志,但是主服务器出现问题之后会丢失未复制表和库的数据;不建议使用 (限定的二进制文件不会同步过来;这样做会使二进制数据造成丢失)

  从服务器实现:所有二进制日志都传到从服务器的中继日志,但是sql_thread只执行指定表和库的修改语句,当主服务器出现故障,则不会丢失数据,所有建议采用从服务器的复制过滤;(将所有的二进制日志文件都复制过来,但在同步到自己的数据库时,会选择不同步限制条件的内容)

从服务器配置:
SET GLOBAL replicate_do_db=库名 #指定只复制指定的库(相当于库的白名单)

SET GLOBAL Replicate_Ignore_DB=库名 #指定不复制指定的库(相当于库的黑名单)

SET GLOBAL Replicate_Do_Table=表名 #指定只复制指定表(相当于表的白名单)

SET GLOBAL Replicate_Ignore_Table=表名 #指定不复制指定表(相当于表的黑名单)

当指定了复制过滤器后,通过SHOW SLAVE STATUS;命令可以查看到指定的库和表

建议此配置写入配置文件永久生效。

加密复制

在默认的主从复制过程或远程连接到MySQL/MariaDB所有的链接通信中的数据都是明文的,外网里访问数据或则复制,存在安全隐患。通过SSL/TLS加密的方式进行复制的方法,来进一步提高数据的安全性

主服务器开启SSL:[mysqld] 加一行ssl
主服务器配置证书和私钥;并且创建一个要求必须使用SSL连接的复制账号
从服务器使用CHANGER MASTER TO 命令时指明ssl相关选项
参看:https://mariadb.com/kb/en/library/replication-with-secureconnections/
MariaDB [(none)]> SHOW VARIABLES LIKE \'%ssl%\';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_openssl  | DISABLED |
| have_ssl      | DISABLED |
| ssl_ca        |          |
| ssl_capath    |          |
| ssl_cert      |          |
| ssl_cipher    |          |
| ssl_key       |          |
+---------------+----------+

特别提示:在配置之前先检查mysql服务是否支持ssl功能,如果have_ssl的值为\'DISABLED\'则支持;如果为\'NO\'则不支持,需要再重新编译安装或者安装具有ssl功能的版本

1)CA

[root@CA ~]# mkdir /etc/my.cnf.d/ssl/
[root@CA ~]# cd /etc/my.cnf.d/ssl/
[root@CA ssl]# openssl genrsa 2048 > cakey.pem
[root@CA ssl]# openssl req -new -x509 -key cakey.pem -out cacert.pem -days 3650 #自签证书
    Country Name (2 letter code) [XX]:CN
    State or Province Name (full name) []:beijing
    Locality Name (eg, city) [Default City]:beijing
    Organization Name (eg, company) [Default Company Ltd]:testmysqlca 
    Organizational Unit Name (eg, section) []:opt
    Common Name (eg, your name or your server\'s hostname) []:ca.testmysqlca.com

[root@CA ssl]# openssl req -newkey rsa:2048 -days 365 -nodes -keyout master.key > master.csr
    Country Name (2 letter code) [XX]:CN
    State or Province Name (full name) []:beijing
    Locality Name (eg, city) [Default City]:beijing
    Organization Name (eg, company) [Default Company Ltd]:testmysqlca
    Organizational Unit Name (eg, section) []:opt
    Common Name (eg, your name or your server\'s hostname) []:master.testmysqlca.com
[root@CA ssl]# openssl x509 -req -in master.csr -CA cacert.pem -CAkey cakey.pem -set_serial 01 > master.crt #签署master证书

[root@CA ssl]# openssl req -newkey rsa:2048 -days 365 -nodes -keyout slave.key > slave.csr
    Country Name (2 letter code) [XX]:CN
    State or Province Name (full name) []:beijing
    Locality Name (eg, city) [Default City]:beijing
    Organization Name (eg, company) [Default Company Ltd]:testmysqlca 
    Organizational Unit Name (eg, section) []:opt
    Common Name (eg, your name or your server\'s hostname) []:slave.testmysqlca.com
[root@CA ssl]# openssl x509 -req -in slave.csr -CA cacert.pem -CAkey cakey.pem -set_serial 02 > slave.crt #签署slave证书

[root@CA ssl]# openssl req -newkey rsa:2048 -days 365 -nodes -keyout slave2.key > slave2.csr
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:testmysqlca
Organizational Unit Name (eg, section) []:opt
Common Name (eg, your name or your server\'s hostname) []:slave2.testmysqlca.com
[root@CA ssl]# openssl x509 -req -in slave2.csr -CA cacert.pem -CAkey cakey.pem -set_serial 03 > slave2.crt #签署slave2证书

[root@CA ssl]# openssl verify -CAfile cacert.pem master.crt slave.crt slave2.crt #检查证书是否可用
master.crt: OK
slave.crt: OK
slave2.crt: OK
先在各个节点上创建/etc/my.cnf.d/ssl/文件夹,将各自的证书,CA的证书和各自的秘钥文件复制过去
[root@CA ssl]# scp cacert.pem master.crt master.key root@192.168.0.7:/etc/my.cnf.d/ssl/
[root@CA ssl]# scp cacert.pem slave.crt slave.key root@192.168.0.8:/etc/my.cnf.d/ssl/ 
[root@CA ssl]# scp cacert.pem slave2.crt slave2.key root@192.168.0.9:/etc/my.cnf.d/ssl/

2)master

[root@master ~]# mkdir /etc/my.cnf.d/ssl/
[root@master ~]# vim /etc/my.cnf
[mysqld]
log_bin
binlog_format=ROW
log-basename=master
server_id=1
ssl #开启ssl功能
ssl-ca=/etc/my.cnf.d/ssl/cacert.pem #指定CA证书的路径
ssl-cert=/etc/my.cnf.d/ssl/master.crt #指定自己的证书的路径
ssl-key=/etc/my.cnf.d/ssl/master.key #指定自己的秘钥文件路径
[root@master ~]# systemctl restart mariadb
MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO repluser@\'192.168.0.%\' IDENTIFIED BY \'replpass\' REQUIRE SSL; #授权用户并且强制迫使用户开启ssl登录
MariaDB [(none)]> SHOW MASTER LOGS;
+-------------------+-----------+
| Log_name          | File_size |
+-------------------+-----------+
| master-bin.000001 |     26753 |
| master-bin.000002 |    921736 |
| master-bin.000003 |       413 |
+-------------------+-----------+

3)slave1

[root@slave1 ~]# mkdir /etc/my.cnf.d/ssl/
[root@slave1 ~]# mysql -urepluser -preplpass -h192.168.0.7 --ssl-ca=/etc/my.cnf.d/ssl/cacert.pem --ssl-cert=/etc/my.cnf.d/ssl/slave.crt --ssl-key=/etc/my.cnf.d/ssl/slave.key
[root@slave1 ~]# vim /etc/my.cnf
[mysqld]
read_only=ON
server_id=2
relay_log=relay-log
relay_log_index=relay-log.index
ssl
ssl-ca=/etc/my.cnf.d/ssl/cacert.pem
ssl-cert=/etc/my.cnf.d/ssl/slave.crt
ssl-key=/etc/my.cnf.d/ssl/slave.key
[root@slave1 ~]# systemctl restart mariadb
MariaDB [(none)]> CHANGE MASTER TO
    -> MASTER_HOST=\'192.168.0.7\',
    -> MASTER_USER=\'repluser\',
    -> MASTER_PASSWORD=\'replpass\',
    -> MASTER_PORT=3306,
    -> MASTER_LOG_FILE=\'master-bin.000003\',
    -> MASTER_LOG_POS=413,
    -> MASTER_CONNECT_RETRY=10,
    -> MASTER_SSL=1;  #注意,需要指明开启ssl链接
MariaDB [(none)]> START SLAVE;

4)slave2

[root@slave2 ~]# mkdir /etc/my.cnf.d/ssl/
[root@slave2 ~]# mysql -urepluser -preplpass -h192.168.0.7 --ssl-ca=/etc/my.cnf.d/ssl/cacert.pem --ssl-cert=/etc/my.cnf.d/ssl/slave2.crt --ssl-key=/etc/my.cnf.d/ssl/slave2.key
[root@slave2 ~]# vim /etc/my.cnf
[mysqld]
read_only=ON
server_id=3
relay_log=relay-log
relay_log_index=relay-log.index
ssl
ssl-ca=/etc/my.cnf.d/ssl/cacert.pem
ssl-cert=/etc/my.cnf.d/ssl/slave2.crt
ssl-key=/etc/my.cnf.d/ssl/slave2.key
[root@slave2 ~]# systemctl restart mariadb
MariaDB [(none)]> CHANGE MASTER TO
    -> MASTER_HOST=\'192.168.0.7\',
    -> MASTER_USER=\'repluser\',
    -> MASTER_PASSWORD=\'replpass\',
    -> MASTER_PORT=3306,
    -> MASTER_LOG_FILE=\'master-bin.000003\',
    -> MASTER_LOG_POS=413,
    -> MASTER_CONNECT_RETRY=10,
    -> MASTER_SSL=1;
MariaDB [(none)]> START SLAVE;

MySQL复制的相关指令和变量总结

选项:

log_bin 启用二进制日志,在主节点或级联复制中间的从节点必须要开启
binlog_format=ROW 二进制日志记录方式为基于行的方式记录,强烈建议开启
log-basename=master | slave ... 二进制日志的前缀名,不是必须向,但建议标识
server_id = # 服务器ID,各个节点的ID必须唯一
relay_log = relay-log 开启中继日志,并以relay-log为文件名开头,从节点开启
relay_log_index = relay-log.index 中继日志索引文件
log_slave_updates 作用是SQL线程重读中继日志时将改变数据的操作记录为二进制日志,在级联复制中使用
ssl 开启ssl功能
ssl-ca=/etc/my.cnf.d/ssl/cacert.pem
ssl-cert=/etc/my.cnf.d/ssl/master.crt
ssl-key=/etc/my.cnf.d/ssl/master.key
sync_binlog=1 每次写后立即同步二进制日志到磁盘
innodb_flush_log_at_trx_commit=1 每次事务提交立即同步日志写磁盘
sync_master_info=# #次事件后master.info同步到磁盘
skip_slave_start=ON 不自动启动slave
sync_relay_log=# #次写后同步relay log到磁盘
sync_relay_log_info=# #次事务后同步relay-log.info到磁盘
auto_increment_offset=1 自动增长开始点,在主主复制中使用
auto_increment_increment=2 增长幅度

变量:

replicate_do_db= 指定复制库的白名单
replicate_ignore_db= 指定复制库黑名单
replicate_do_table= 指定复制表的白名单
replicate_ignore_table= 指定复制表的黑名单
replicate_wild_do_table= foo%.bar% 支持通配符
replicate_wild_ignore_table= 指定复制的表,黑名单

rpl_semi_sync_slave_enabled=1 开启半同步复制,需要安装模块

指令:

START SLAVE; 启动主从复制
STOP SLAVE; 停止复制
SHOW SLAVE STATUS; 查看复制状态
Seconds_Behind_Master: 0 从服务器是否落后于主服务
RESET SLAVE ALL; 重置从服务器的配置
MASTER_SSL=1, 配合 CHANGE MASTER TO 使用,开启ssl加密复制
MASTER_SSL_CA = \'/etc/my.cnf.d/ssl/cacert.pem\',
MASTER_SSL_CERT = \'/etc/my.cnf.d/ssl/slave.crt\',
MASTER_SSL_KEY = \'/etc/my.cnf.d/ssl/slave.key\';
PURGE { BINARY | MASTER } LOGS { TO \'log_name\' | BEFORE datetime_expr } 删除二进制日志,谨慎操作
SHOW MASTER STATUS 查看二进制日志状态
SHOW BINLOG EVENTS 查看二进制日志
SHOW BINARY LOGS 查看二进制日志
SHOW PROCESSLIST 查看进程

MHA

对主节点进行监控,可实现自动故障转移至其它从节点;通过提升某一从节点为新的主节点,基于主从复制实现,还需要客户端配合实现,目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库。

工作原理

从宕机崩溃的master保存二进制日志事件(binlog events)
识别含有最新更新的slave 
应用差异的中继日志(relay log)到其他的slave 应用从master保存的二进制日志事件(binlog events) 提升一个slave为新的master 使其他的slave连接新的master进行复制

Manager工具包主要包括以下几个工具:

masterha_check_ssh 检查MHA的SSH配置状况
masterha_check_repl 检查MySQL复制状况
masterha_manger 启动MHA
masterha_check_status 检测当前MHA运行状态
masterha_master_monitor 检测master是否宕机
masterha_master_switch 故障转移(自动或手动)
masterha_conf_host 添加或删除配置的server信息

MHA软件由两部分组成,Manager工具包和Node工具包

Node工具包:这些工具通常由MHA Manager的脚本触发,无需人为操作)主 要包括以下几个工具:

save_binary_logs 保存和复制master的二进制日志

apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用 于其他的slave

purge_relay_logs 清除中继日志(不会阻塞SQL线程)

注意:为了尽可能的减少主库硬件损坏宕机造成的数据丢失,因此在配置MHA 的同时建议配置成MySQL 5.5的半同步复制

实现主从高可用MHA (在主服务器宕机时,自动将从服务器切换成主服务器来使用)

此功能只是一次性的,切换之后,功能就停用了,如果想启用需要再次开启此功能。

结构拓扑图:四台主机;manager,master,slave1,slave2 (管理者,主服务器,两个从服务器)

具体实验步骤:

1). 准备

selinux ,iptables ,time  (此实验各台服务器的时间要保持一致)

在vim /etc/ntp.conf  添加server 172.20.0.1   iburst

systemctl  start nptd

2) . 实现主从服务器的搭建

~]#vim /etc/my.cnf
[mysqld]
server_id=1
log_bin
skip_name_resolve  #跳过名字解析
~]#systemctl start mariadb #重启服务
mysql > grant replication slave on *.* to lv@’192.168.60.%’ identified by ‘centos’;  #授权用户账号
mysql > show master logs;  #查看此时的二进制日志状态为后面从服务器同步时使用

3 ).在slave1服务器上

~]#vim /etc/my.cnf
[mysqld]
server_id=2
log_bin
read_only=1
relay_log_purge=0
skip_name_resolve=1
~]#systemctl start mariadb  #重启服务
mysql > CHANGE MASTER TO MASTER_HOST=’192.168.60.20′, MASTER_USER=’lv’, MASTER_PASSWORD=’centos’, MASTER_LOG_FILE=’mariadb-bin.000001′, MASTER_LOG_POS=39

以上是关于mysql —复制的主要内容,如果未能解决你的问题,请参考以下文章

什么是在 C++ 中获取总内核数量的跨平台代码片段? [复制]

Android:使用支持片段管理器时复制片段

VsCode 代码片段-提升研发效率

为啥这个 CSS 片段可以画一个三角形? [复制]

mysql 强大的trim() 函数

从图库中获取图像以在片段中的图像视图中设置? [复制]