实验环境:

系统:CentOS Linux release 7.4.1708 (Core)

mariadb:mariadb-server-5.5.56-2.el7.x86_64

node1:172.18.0.7

node2:172.18.0.17

节点主机时间要同步,清空防火墙策略,关闭SELinux

一:实验:实现MySQL主从复制

1.首先配置主节点:

安装数据库

[root@node1 ~]# yum install mairadb-server  

编辑配置文件

[root@node1 ~]# vim /etc/my.cnf

设置server id
server-id=1 启用二进制日志
log-bin=/data/mysql/logs/mysql-bin 跳过名称解析
skip_name_resolve=ON

新建日志存放目录

[root@node1 ~]# mkdir -p  /data/mysql/logs

修改日志属主属组为mysql

[root@node1 ~]#  chown -R mysql.mysql /data/mysql/logs

启动Mariadb数据库

[root@node1 ~]# systemctl start mariadb

查看监听端口

[root@node1 ~]# ss -ntl

LISTEN      050*:3306*:*users:(("mysqld",pid=28046,fd=15))

2.配置从节点:

[root@node2 ~]# yum install mariadb-server
[root@node2 ~]#vim /etc/my.cnf
server-id=2 #确保从节点与主节点server id不同
启用中继日志
relay-log=/data/mysql/logs/relay-bin
skip_name_resolve=ON
read_only=ON #为了防止从节点写入数据导致和主节点数据不一致设置为只读
[root@node2 ~]# mkdir -p /data/mysql/logs/relay-bin
[root@node2 ~]# chown -R mysql.mysql /data/mysql/logs/
[root@node2 ~]# systemctl start mariadb
[root@node2 ~]# mysql

 

3.测试:

node1主服务器:

[root@node1 ~]# mysql

MariaDB [(none)]> SHOW BINARY LOGS;

+------------------+-----------+

| Log_name         | File_size |

+------------------+-----------+

| mysql-bin.000001 |       689 |

| mysql-bin.000002 |       746 |

+------------------+-----------+

2 rows in set (0.00 sec)

MariaDB [(none)]> SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+------------------+----------+--------------+------------------+

| mysql-bin.000002 |      746 |              |                  |

+------------------+----------+--------------+------------------+

1 row in set (0.00 sec)

MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'server_id';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| server_id     | 1|

+---------------+-------+

1 row in set (0.00 sec)

  

查看node2从服务器

[root@node2 ~]# mysql

MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'server_id';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| server_id     | 2|

+---------------+-------+

  

4.主节点对用户授权:

在主服务器上授权从服务器登录用户

[root@node1 ~]# mysql

MariaDB [(none)]> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO  zangfans@'172.18.0.%' IDENTIFIED BY 'andme1024';

把内存的数据同步到磁盘上

MariaDB [(none)]> FLUSH PRIVILEGES; 

查看授权信息

MariaDB [(none)]> USE mysql;

MariaDB [mysql]> select user,host from user;

+----------+---------------+

| user     | host          |

+----------+---------------+

| root     | 127.0.0.1     |

| zangfans | 172.18.0.%    |

| root     | ::1           |

|          | localhost     |

| root     | localhost     |

|          | node1         |

| root     | node1         |

+----------+---------------+

  

5.从服务器切换至主master

注:使用命令之前可以查看帮助信息

MariaDB [(none)]> HELP CHANGE MASTER TO

切换master

MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='172.18.0.7',MASTER_PORT=3306,MASTER_USER='zangfans',MASTER_PASSWORD='andme1024',MASTER_LOG_FILE='mysql-bin.0000001',MASTER_LOG_POS=746;

注:如果端口是默认端口3306可以不指定

查看而二进制日志信息

MariaDB [mysql]> show binlog events;

----------------------

踩到的坑

错误解决:

MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='172.18.0.7',MASTER_PORT=3306,MASTER_USER='zangfans',MASTER_PASSWORD='centos',MASTER_LOG_FILE='mysql-bin.000004',MASTER_LOG_POS=461;

ERROR 1198 (HY000): This operation cannot be performed with a running slave; run STOP SLAVE first

如果change master错误需要

MariaDB [(none)]> STOP SLAVE;

MariaDB [(none)]> RESET SLAVE;

-------------------

启动从服务器也可以指定的线程

MariaDB [(none)]> STRAT SLAVE;

查看运行状态

错误语法:

MariaDB [(none)]> SHOW SLAVE STATUS\G; 

正确语法:

MariaDB [(none)]> SHOW SLAVE STATUS\G

测试:

在主服务器创建数据库

MariaDB [mysql]> CREATE DATABASE mydb;

Query OK, 1 row affected (0.00 sec)

在从服务器上可以看到服务器

MariaDB [(none)]> SHOW DATABASES;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mydb               |

| mysql              |

| performance_schema |

| test               |

+--------------------+

5 rows in set (0.00 sec)

MySQL主从复制搭建起来是非常简单的但是在今后进行维护起来是非常让人头疼的事情,这是因为Mysl主从复制线程是异步的,异步导致从节点落后于主节点,会导致数据不一致。

落后的原因有多种:

对于主节点在事务隔离级别不是非常高的级别下,如read comititted repeatable read 多个事务是可以同时提交、同时执行,事务执行过程当中是并行的,写语句能够被串行写入到日志文件中的是分为多个步骤依次进行的但从节点在复制时依次只能获取一个事件,此事件依次保存在中继日志中, 带来的结果就是从节点必然是落后于主节点。

由于不同步也可能导致从节点执行事务的顺序是不一致的,带来主从数据不一致,此结果在Mysql上是一种非常常见的现象,只要在mysql中使用主从复制基本都会面对的问题。

通过手动去查找不一致的数据集,然后对错误数据进行修改是非常麻烦的事情,有可能在出现的错误人工排查不出来的可能性。percona提过了比对主从节点数据不一致的工具,不一致会启动不阻塞主节点业务场景当中,通常会重新启动在进行二者数据同步的过程。这种代价会影响服务器的性能但是对于重新复制来讲代价要小很多。

二:实验:实现MySQL主主复制

解决主节点单点

由于在实验环境可以对生成数据文件删除,真实生产环境建议还是移动到一个空间,不到万不得已不要删除

[root@node1 logs]# rm -rf /var/lib/mysql/* /data/mysql/logs/*

[root@node2 ~]# rm /var/lib/mysql/* /data/mysql/logs/* -rf

  

node1节点:

[root@node1 ~]# mkdir -p /data/mysql/logs/

[root@node1 ~]# chown -R  mysql.mysql /data/mysql/logs

[root@node1 ~]# vim /etc/my.cnf

server-id=1

log_bin=/data/mysql/logs/mysql-bin

relay_log=/data/mysql/logs/relay-log

skip_name_resolve=ON

node2节点:

[root@node2 ~]# mkdir -p /data/mysql/logs/

[root@node2 ~]# chown -R  mysql.mysql /data/mysql/logs

[root@node2 ~]# vim /etc/my.cnf

server-id=2

log_bin=/data/mysql/logs/mysql-bin

relay-log=/data/mysql/logs/relay-log

skip_name_resolve=ON  

注:主主都得开启二进制日志和中继日志

启动主从节点mariadb服务

[root@node1 ~]# systemctl start mariadb
[root@node2 ~]# systemctl start mariadb

此时可以查看到生成的日志信息

[root@node2 ~]# ls /data/mysql/logs

mysql-bin.000001  mysql-bin.000002  mysql-bin.000003  mysql-bin.index

授权命令grant也是写操作,如果在另一台主机上开启了mariadb那么就会造成从节点也会复制一份,也进行执行,如此往来就会造成死循环,所以必须进行对创建账号之后进行复制。但是仅仅只是账号的复制对于双方来说影响不大也可以不停止服务。

1.授权

node1,node2对账号进行授权

MariaDB [(none)]> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO zangfans@'172.18.0.%' IDENTIFIED BY 'andme1024';

注:授权账号密码不要过于简单,我在使用centos密码对change mster始终出现了失败

2.同步数据

node1,node2节点数据从内存同步到磁盘中

MariaDB [(none)]> FLUSH PRIVILEGES;

node1,node2各自都要查看二进制未见处于哪个文件并获得它的位置

MariaDB [(none)]> SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+------------------+----------+--------------+------------------+

| mysql-bin.000003 |      492 |              |                  |

+------------------+----------+--------------+------------------+

1 row in set (0.00 sec)

3.切换主master

node1,node2各自进行change master

node1节点

MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='172.18.0.17',MASTER_USER='zangfans',MASTER_PASSWORD='andme1024',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=492;

注:master的ip是主节点的ip

node2节点

MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='172.18.0.7',MASTER_USER='zangfans',MASTER_PASSWORD='andme1024',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=492; 

4.查看状态

node1节点状态:

MariaDB [(none)]> SHOW SLAVE STATUS\G

*************************** 1. row ***************************

               Slave_IO_State:

                  Master_Host: 172.18.0.17

                  Master_User: zangfans

                  Master_Port: 3306

 Master_Log_File: mysql-bin.000003

 Read_Master_Log_Pos: 492

  Relay_Log_File: relay-log.000001

  Relay_Log_Pos: 4

  

此时IO线程和SQL线程是没有启动

Slave_IO_Running: No

Slave_SQL_Running: No

node2节点状态:

MariaDB [(none)]> show slave status\G

*************************** 1. row ***************************

               Slave_IO_State:

                  Master_Host: 172.18.0.7

                  Master_User: zangfans

                  Master_Port: 3306

IO_THREAD:从节点向主节点复制事件

SEL_THREAD:在本地重放中继日志事件

5.启动IO线程

node1,node2启动IO线程

MariaDB [(none)]> START SLAVE IO_THREAD;

MariaDB [(none)]> show salve status\G

Slave_IO_Running: Yes

在启动SQL线程之前查看一下Mysql错误日志信息

错误日志不光记录了服务器运行过程中的错误信息,服务停止过程中的信息诊断信息,还有可能记录复制线程启动信息。

6.查看错误日志,查看是否启动信息

[root@node2 ~]# cd /var/log/mariadb/

[root@node2 mariadb]# tail mariadb.log

180605 15:22:14 [Warning] 'user' entry '@node2' ignored in --skip-name-resolve mode.

180605 15:22:14 [Warning] 'proxies_priv' entry '@ root@node2' ignored in --skip-name-resolve mode.

180605 15:22:14 [Note] Event Scheduler: Loaded 0 events

180605 15:22:14 [Note] /usr/libexec/mysqld: ready for connections.

Version: '5.5.56-MariaDB'  socket: '/var/lib/mysql/mysql.sock'  port: 3306  MariaDB Server

180605 15:23:45 [Warning] 'user' entry 'root@node2' ignored in --skip-name-resolve mode.

180605 15:23:45 [Warning] 'user' entry '@node2' ignored in --skip-name-resolve mode.

180605 15:23:45 [Warning] 'proxies_priv' entry '@ root@node2' ignored in --skip-name-resolve mode.

180605 15:25:29 [Note] 'CHANGE MASTER TO executed'. Previous state master_host='', master_port='3306', master_log_file='', master_log_pos='4'. New state master_host='172.18.0.7', master_port='3306', master_log_file='mysql-bin.000003', master_log_pos='491'.

180605 15:26:30 [Note] Slave I/O thread: connected to master 'alex@172.18.0.7:3306',replication started in log 'mysql-bin.000003' at position 491

7.启动SQL线程

node1,node2同时启动SQL线程

MariaDB [(none)]> START SLAVE SQL_THREAD;

MariaDB [(none)]> show slave status\G

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

[root@node2 mariadb]# tail mariadb.log

180605 15:26:30 [Note] Slave I/O thread: connected to master 'alex@172.18.0.7:3306',replication started in log 'mysql-bin.000003' at position 491

180605 15:30:44 [Note] Slave SQL thread initialized, starting replication in log 'mysql-bin.000003' at position 491, relay log '/data/mysql/logs/relay-log.000001' position: 4

  

验证:

从主节点创建一个表,其实主节点起始位置和从节点起始位置都将发生改变

MySQL:优化配置

存在自动增长id的表,为了使得id不相冲突,需要定义其自动增长方式;

node1节点:

[root@node1 ~]# vim /etc/my.cnf

auto_increment_offset=1

auto_increment_increment=2

node2节点:

[root@node2 ~]# vim /etc/my.cnf

auto_increment_offset=2  #

auto_increment_increment=2

下次启动知道复制的位置cat /var/lib/mysql/master.info,此文件的记录也会存放在内存缓存区当中

三:实验:实现MySQL半同步复制

环境配置主从架构

使用2个节点一个做主节点,一个做同步复制

node1节点:

[root@node1 ~]# vim /etc/my.cnf

server-id=1

log_bin=/data/mysql/logs/mysql-bin

skip_name_resolve=ON

新建日志存放目录

[root@node1 ~]# mkdir -p  /data/mysql/logs

修改日志所属所组为mysql

[root@node1 ~]#  chown -R mysql.mysql /data/mysql/logs

启动Mariadb数据库

[root@node1 ~]# systemctl start mariadb

  

node2节点:

[root@node2 ~]# vim /etc/my.cnf

server-id=2

relay_log=/data/mysql/logs/relay-log

skip_name_resolve=ON

read_only=ON  #只读
[root@node2 ~]# mkdir -p /data/mysql/logs/relay-bin [root@node2 ~]# chown -R mysql.mysql /data/mysql/logs/ [root@node2 ~]# systemctl start mariadb

node1节点授权

MariaDB [mydb]>  GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO alex@'172.18.0.%' IDENTIFIED BY 'andme1024';

MariaDB [mydb]> FLUSH PRIVILEGES;

Query OK, 0 rows affected (0.00 sec)

  

查看Master状态

MariaDB [(none)]> show master status;

+------------------+----------+--------------+------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+------------------+----------+--------------+------------------+

| mysql-bin.000003 |      245 |              |                  |

+------------------+----------+--------------+------------------+

node2节点changer master

MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='172.18.0.7',MASTER_PORT=3306,MASTER_USER='alex',MASTER_PASSWORD='andme1024',MASTER_LOG_FILE='mysql-bin.0000003',MASTER_LOG_POS=245;

测试:主节点创建数据库和表,在从节点查看

此时复制方式是异步,改成半同步复制,可以在后面更改IO线程

主从节点默认是没有安装插件

semisync_master.so  #主节点插件

semisync_slave.so

查看已安装的插件

MariaDB [db1]> SHOW PLUGINS;

查看插件放于的位置

/usr/lib64/mysql/plugin/

1.启用插件

主节点启用master插件

MariaDB [db1]> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

从节点启用slave插件

MariaDB [db1]> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

2.设置半同步启用

ON:启用

OFF:关闭

同时也可以使用0代替ON,1代替OFF

主节点:

MariaDB [db1]> SET GLOBAL rpl_semi_sync_master_enabled=ON;

从节点:

MariaDB [db1]> SET GLOBAL rpl_semi_sync_slave_enabled=ON;

3.查看状态的方式

MariaDB [db1]> SHOW GLOBAL STATUS LIKE 'rpl%';

MariaDB [db1]> SHOW GLOBAL VARIABLES LIKE 'rpl%';

+------------------------------------+-------+

| Variable_name                      | Value |

+------------------------------------+-------+

| rpl_semi_sync_master_enabled       | OFF|1为开启,表示在master上已经开启了半同步复制模式;

| rpl_semi_sync_master_timeout       | 10000 |表示如果主库在某次事务中的等待时间超过10000毫秒,则降级为异步复制模式,不在等待slave从库。如果主库再次探测到slave从恢复了,则会自动切换回半同步复制模式;

| rpl_semi_sync_master_trace_level   | 32|指用于开启半同步复制模式时的调试级别,默认为32。

| rpl_semi_sync_master_wait_no_slave | ON    |表示是否允许master每个事务提交后都要等待slave的接收确认信号。默认为ON,即每一个事务都会等待。如果为OFF,则slave追赶上之后,也不会开启半同步复制模式,需要手工开启;

4.关闭异步线程,开启同步线程

MariaDB [db1]> SHOW GLOBAL VARIABLES LIKE 'rpl%';

+---------------------------------+-------+

| Variable_name                   | Value |

+---------------------------------+-------+

| rpl_recovery_rank               | 0     |

| rpl_semi_sync_slave_enabled     | ON    |

| rpl_semi_sync_slave_trace_level | 32    |

+---------------------------------+-------+

  

此时发现IO线程和SQL线程都启用了,是以异步方式连接过来

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

关闭异步线程

MariaDB [db1]> STOP SLAVE IO_THREAD;

MariaDB [db1]> STOP SLAVE SQL_THREAD;

开启同步IO线程

MariaDB [db1]> START SLAVE IO_THREAD;

测试:

MariaDB [db1]> SHOW GLOBAL STATUS LIKE 'rpl%';                                

+--------------------------------------------+-------------+

| Variable_name                              | Value       |

+--------------------------------------------+-------------+

| Rpl_semi_sync_master_clients| 1           |

此时在node1主节点上可以看到有了连接客户端

在node1节点创建一个表

MariaDB [db1]> INSERT INTO tb1 VALUES (3,'peter'); 

查看状态信息

MariaDB [db1]> SHOW GLOBAL STATUS LIKE 'rpl%';   

+--------------------------------------------+-------------+

| Variable_name                              | Value       |

+--------------------------------------------+-------------+

| Rpl_semi_sync_master_clients| 1           |

| Rpl_semi_sync_master_net_avg_wait_time     | 682         |  #等待平均时长

| Rpl_semi_sync_master_net_wait_time         | 682  #等待时长

注:找一个离主机最近的,最好为同一个机架上的机器,将来提升一个新的主节点时此节点将是优选

缺陷:主节点带宽被降低了

MySQL主从复制,主主复制,半同步复制的更多相关文章

  1. MySQL 5.7 基于GTID主从复制+并行复制+半同步复制

    环境准备 IP HOSTNAME SERVICE SYSTEM 192.168.131.129 mysql-master1 mysql CentOS7.6 192.168.131.130 mysql- ...

  2. Centos7.5部署MySQL5.7基于GTID主从复制+并行复制+半同步复制+读写分离(ProxySQL) 环境- 运维笔记 (完整版)

    之前已经详细介绍了Mysql基于GTID主从复制的概念,原理和配置,下面整体记录下MySQL5.7基于GTID主从复制+并行复制+增强半同步复制+读写分离环境的实现过程,以便加深对mysql新特性GT ...

  3. MySQL5.7延迟复制半同步复制

    MySQL5.7延迟复制半同步复制 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.延迟复制 1>.什么是延迟复制 延迟复制是指定从库对主库的延迟至少是指定的这个间隔时间 ...

  4. 【3.1】【mysql基本实验】mysql复制(主从复制/异步复制/半同步复制,一主一从)

    关键词:mysql复制(异步复制),mysql异步复制 核心原理: mysql 复制流程原理 一个事务在 mysql异步复制中的流程与生命周期 一个事务,在传统半同步的复制流程 #mysql主从基本实 ...

  5. 【可靠性】Mysql 5.7 降低了半同步复制-数据丢失的风险

    如果你的生产线开启了半同步复制,那么对数据的一致性会要求较高,但在MySQL5.5/5.6里,会存在数据不一致的风险.有这么一个场景,客户端提交了一个事务,master把binlog发送给slave, ...

  6. mysql关于“异步复制”“同步复制”“半同步复制”“无损复制”的概念与区别

    异步复制:主把事务写到binlog日志并不管从是否接收或者什么时候接收,commit之后,不会与从发生ack之类的交互. 同步复制:当主提交一个事务,在主向前端返回一个commit成功的指令前,必须保 ...

  7. MySQL 半同步复制+MMM架构

    200 ? "200px" : this.width)!important;} --> 介绍 上篇文章介绍了MMM架构的实现方法,但是上篇文章的MMM方案的复制是异步复制,异 ...

  8. 安装MySQL半同步复制

    一.简介 从MySQL5.5开始,MySQL以插件的形式支持半同步复制.如何理解半同步呢?首先我们来看看异步,全同步的概念 异步复制(Asynchronous replication) MySQL默认 ...

  9. MySQL半同步复制搭建

    默认情况下,MySQL 5.5/5.6/5.7和MariaDB 10.0/10.1的复制是异步的,异步复制可以提供最佳性能,主库把binlog日志发送给从库,这一动作就结束了,并不会验证从库是否接收完 ...

  10. 深入MySQL复制(三):半同步复制

    1.半同步复制 半同步复制官方手册:https://dev.mysql.com/doc/refman/5.7/en/replication-semisync.html 默认情况下,MySQL的复制是异 ...

随机推荐

  1. war 和 war exploded

    IDEA 开发项目时,部署 tomcat 的 Deployment 选项出现: war 模式 可以称之为发布模式.先将 WEB 工程打成 war 包,然后再将其上传到服务器进行发布. war expl ...

  2. Dockerfile极简入门与实践

    前文中,罗列了docker使用中用到的基本命令 此文,将会对怎样使用Dockerfile去创建一个镜像做简单的介绍 Dockerfile命令 要开始编写Dockerfile,首先要对相关的命令有个清晰 ...

  3. POJ 1163 数字三角形

    Portal:http://poj.org/problem?id=1163 DP经典题,IOI94考题,在各大OJ上都有 #include<iostream> #include<al ...

  4. 性能测试环境搭建:XAMPP1.8+PHPwind9.0安装教程

    1.安装准备 1.1软件版本 XAMPP的版本:XAMPP 1.8.2 phpwind的版本:PHPWind 9.0   1.2.安装环境 我的环境:win10 其实安装环境影响不大,win7,win ...

  5. java应用诊断和在线debug利器bistoury介绍与在K8S环境使用

    Bistoury介绍 Bistoury 是去哪儿网开源的一个对应用透明,无侵入的java应用诊断工具,用于提升开发人员的诊断效率和能力,可以让开发人员无需登录机器或修改系统,就可以从日志.内存.线程. ...

  6. 并发——抽象队列同步器AQS的实现原理

    一.前言   这段时间在研究Java并发相关的内容,一段时间下来算是小有收获了.ReentrantLock是Java并发中的重要部分,所以也是我的首要研究对象,在学习它的过程中,我发现它是基于抽象队列 ...

  7. 001_Three.js中的跨域问题

    001_Three.js中的跨域问题 [情景描述]: 在初始化模型,引入字体和纹理皮肤图片的时候,由于跨域问题,出现了以下提示: Access to image at 'file:///F:/User ...

  8. ELK数据批量导入

                                                                            数据批量导入 • 使用 _bulk 批量导入数据 – 批 ...

  9. Android视频悬浮窗口实现

    前言 本文例子实现了点击显示悬浮窗口,同时窗口可播放视频,拖动位置,点击关闭及返回APP页面,通过例子来讲述悬浮窗口实现原理及细节处理,效果图如下所示: 原理 WindowManager对View视图 ...

  10. 【Mongodb】视图 && 索引

    准备工作 准备2个集合的数据,后面视图和索引都会用到1个订单集合,一个收款信息集合 var orders = new Array(); var shipping = new Array(); var ...