使用MySQL主从复制技术实现数据库热备
1 MySQL Replication
2 部署MySQL主从同步
3 部署MySQL主主双向主从复制node
MySQL Replication
什么是MySQL Replication
Replication能够实现将数据从一台数据库服务器(master)复制到一台或多台数据库服务器(slave)
默认状况下属于异步复制,无需维持长链接
经过配置,能够复制全部的库或者几个库,甚至库中的一些表
是MySQL内建的,自己自带的
Replication的原理
简单的说就是master将数据库的改变写入二进制日志,slave同步这些二进制日志,并根据这些二进制日志进行数据操做
DML:SQL操做语句,update, ×××ert,delete
Relay log :中继日志
Replication的做用
Fail Over 故障切换
Backup Server 备份服务,没法对SQL语句执行产生的故障恢复,有限的备份
High Performance 高性能,能够多台slave,实现读写分离
Replication工做原理
总体上来讲,复制有3个步骤:
master将改变记录到二进制日志(binary log)中(这些记录叫作二进制日志事件,binary log events)
slave将master的binary log events拷贝到它的中继日志(relay log)
slave重作中继日志中的事件,修改salve上的数据。mysql
MySQL主从复制中:
第一步:master记录二进制日志。在每一个事务更新数据完成以前,master在二进制日志记录这些改变。MySQL将事务写入二进制日志,即便事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务。
第二步:slave将master的binary log拷贝到它本身的中继日志。首先,slave开始一个工做线程—I/O线程。I/O线程在master上打开一个普通的链接,而后开始binlog dump process。Binlog dump process从master的二进制日志中读取事件,若是已经执行完master产生的全部文件,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志。
第三步:SQL slave thread(SQL从线程)处理该过程的最后一步。SQL线程从中继日志读取事件,并从新执行其中的事件而更新slave的数据,使其与master中的数据一致。sql
Replication常见方案
One master and Muti salve 一主多备数据库
通常用来作读写分离的,master写,其余slave读,这种架构最大问题I/O压力集中
在Master上<多台同步影响IO>vim
2.M-S-S安全
使用一台slave做为中继,分担Master的压力,slave中继须要开启bin-log,并配置log-slave-updates
Slave中继可以使用Black-hole存储引擎,不会把数据存储到磁盘,只记录二进制日志服务器
M-M 双主互备 (互为主从)
不少人误觉得这样能够作到MySQL负载均衡,实际没什么好处,每一个服务器须要作一样的同步更新,破坏了事物的隔离性和数据的一致性。架构
M-M-M
监控三台机器互相做对方的master并发
天生的缺陷:复制延迟,slave上同步要慢于master,若是大并发的状况那延迟更严重
mysql在5.6已经自身能够实现fail over故障切换
One slave Muti master 一从对多主
好处:节省成本,将多个master数据自动化整合
缺陷:对库和表数据的修改较多负载均衡
部署MySQL主从同步 <M-S>
环境准备:
模式:C/S
端口:3306
配置主数据库服务器node-1
安装MySQL 5.7版本
上传mysql-5.7.tar.gz到Linux主机上,并解压:
注:mysql-5.7.tar.gz 中包括了安装mysql5.7主要的软件包。 这样部署起来更方便
下载mysql 5.7 解压并安装
[root@node-1 ~]# wget https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar
[root@node-1 ~]# tar xvf mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar
mysql-community-embedded-devel-5.7.26-1.el7.x86_64.rpm
mysql-community-libs-5.7.26-1.el7.x86_64.rpm
mysql-community-embedded-5.7.26-1.el7.x86_64.rpm
mysql-community-test-5.7.26-1.el7.x86_64.rpm
mysql-community-embedded-compat-5.7.26-1.el7.x86_64.rpm
mysql-community-common-5.7.26-1.el7.x86_64.rpm
mysql-community-devel-5.7.26-1.el7.x86_64.rpm
mysql-community-client-5.7.26-1.el7.x86_64.rpm
mysql-community-server-5.7.26-1.el7.x86_64.rpm
mysql-community-libs-compat-5.7.26-1.el7.x86_64.rpm
[root@node-1 ~]# yum ×××tall ./mysql*.rpm
启动mysql 并生成临时密码
[root@node-1 ~]# systemctl start mysqld
在MySQL的配置文件/etc/my.cnf 中关闭密码强度审计插件,并重启MySQl服务。
[root@node-1 ~]# vim /etc/my.cnf
#修改MySQL的配置文件,在[myqld]标签处末行添加如下项
validate-password=OFF #不使用密码强度审计插件
重启mysqld
[root@node-1 ~]# systemctl restart mysqld
获取临时密码
[root@node-1 ~]# grep 'password' /var/log/mysqld.log
2019-06-11T03:30:58.381293Z 1 [Note] A temporary password is generated for root@localhost: Ulw=h.3N1r/T
使用临时密码登录mysql,注意临时密码须要引号
[root@node-1 ~]# mysql -u root -p"Ulw=h.3N1r/T"
修改root密码
mysql> set password for root@localhost = password('123456');
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
mysql> exit
Bye
建立须要同步的数据库:
[root@node-1 ~]# mysql -u root -p123456
mysql> create database HA;
Query OK, 1 row affected (0.01 sec)
mysql> use HA;
Database changed
mysql> create table T1(id int,name varchar(20));
Query OK, 0 rows affected (0.01 sec)
mysql> exit
Bye
[root@node-1 ~]# vim /etc/my.cnf
log-bin=mysql-bin-master #启用二进制日志
server-id=1 #本机数据库ID 标示
binlog-do-db=HA #能够被从服务器复制的库, 二进制须要同步的数据库名
binlog-ignore-db=mysql #不能够被从服务器复制的库
受权
[root@node-1 ~]# mysql -uroot -p123456
mysql> grant replication slave on . to slave@192.168.150.139 identified by "123456";
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
查看状态信息
+-------------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------------+----------+--------------+------------------+-------------------+
| mysql-bin-master.000001 | 604 | HA | mysql | |
+-------------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
查看二进制文件
mysql> show binlog events\G
复制前要保证同步的数据库一致
导出数据库文件
[root@node-1 ~]# mysqldump -uroot -p123456 HA >HA.sql
将数据导出传给从服务器
[root@node-1 ~]# scp HA.sql root@192.168.150.139:/root
配置从服务器node-2
下载数据库
[root@node2 ~]# wget https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar
解压mysql
[root@node2 ~]# tar xf mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar
[root@node2 ~]# yum ×××tall -y ./mysql*.rpm
mysql 启动会生成临时密码
[root@node2 ~]# systemctl start mysqld
在MySQL的配置文件/etc/my.cnf 中关闭密码强度审计插件,并重启MySQl服务
[root@node2 ~]# systemctl restart mysqld
获取临时密码
[root@node2 ~]# grep 'password' /var/log/mysqld.log
2019-06-13T02:38:35.490766Z 1 [Note] A temporary password is generated for root@localhost: ,%d&>aAaQ2!7
使用临时密码登录 记住mysql 是单引号双引号不识别
[root@node2 ~]# mysql -u root -p',%d&>aAaQ2!7'
修改root密码
mysql> set password for root@localhost = password('123456');
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> exit
Bye
如今登录node-1 服务器测试远程可否登录上数据库是否一致
[root@node-1 ~]# mysql -u root -p123456
mysql> show variables like '%version%';
测试连接主服务器是否成功
若是远程连接不上请开启服务器端口
开放端口
[root@node-1 ~]# firewall-cmd --zone=public --add-port=80/tcp --permanent
success
[root@node-1 ~]# firewall-cmd --zone=public --add-port=1000-2000/tcp --permanent
success
重载服务
[root@node-1 ~]# firewall-cmd --reload
success
查看端口
[root@node-1 ~]# firewall-cmd --zone=public --query-port=80/tcp
yes
开放相应服务器端口
[root@node-1 ~]# firewall-cmd --zone=public --add-port=3306/tcp --permanent
success
重载服务
[root@node-1 ~]# firewall-cmd --reload
success
测试远程数据库连接是否是正常
出现如下服务表示服务器正常连接
[root@node2 ~]# mysql -u slave -p123456 -h 192.168.150.138
mysql: [Warning] Using a password on the command line interface can be ×××ecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.26-log MySQL Community Server (GPL)
Copyright (c) 2000, 2019, 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> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.00 sec)
只有复制的权限, 是看不到其余库的。正常导入数据库,和主数据库服务器保持一致
mysql> exit
Bye
在node-2上建立相应数据库
[root@node2 ~]# mysql -uroot -p123456
mysql> create database HA;
Query OK, 1 row affected (0.00 sec)
mysql> exit
Bye
导入数据库
[root@node2 ~]# mysql -uroot -p123456 HA < HA.sql
如下提示是 不能再命令行下使用 提示不安全 其实已经导入数据库文件进去了
mysql: [Warning] Using a password on the command line interface can be ×××ecure.
修改从服务器配置文件
从服务器不必开启bin-log日志
中止mysql 服务
[root@node2 ~]# systemctl stop mysqld
[root@node2 ~]# vim /etc/my.cnf
server-id = 2 #从服务器ID号,不要和主ID相同 ,若是设置多个从服务器,每一个从服务器必须有一个惟一的server-id值,必须与主服务器的以及其它从服务器的不相同。能够认为server-id值相似于IP地址:这些ID值能惟一识别复制服务器群集中的每一个服务器实例。
启动mysql 服务
[root@node2 ~]# systemctl restart mysqld
[root@node2 ~]# mysql -u root -p123456
中止slave
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
写入主服务器
mysql> change master to master_host='192.168.150.138',master_user='slave',master_password='123456';
Query OK, 0 rows affected, 2 warnings (0.01 sec)
启动slave
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
查看状态
mysql> show slave status\G
Slave_IO_Running :一个负责与主机的IO通讯
Slave_SQL_Running:负责本身的slave mysql进程
两个为YES 就成功了!
再到主服务器查看状态
[root@node-1 ~]# mysql -uroot -p123456
mysql> show processlist \G
mysql> use HA;
这句话的是意思是
读取表信息以完成表和列名称
您能够关闭此功能以使用-A更快地启动
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
从数据库查看
mysql> ×××ert into T1 values (1,'man');
排错
若是遇到主从不一样步,看一下主从bin-log的位置,而后再同步。
mysql> show master status;
在主服务器上看二进制日志事件列表
先中止从服务器
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
change master to master_log_file='mysql-bin-master.000001',master_log_pos=1164;
Query OK, 0 rows affected (0.01 sec)
#根据上面主服务器的show master status的结果,进行从服务器的二进制数据库记录回归,达到同步的效果
从新启动slave同步服务
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G; #用show slave status\G;看一下从服务器的同步状况
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
若是都是yes,那表明已经在同步
重启从服务器,再查看状态:
stop slave; #中止从服务器
start slave; #开启从服务器
排错思路:
二进制日志没有开启
IPTABLES 没有放开端口
对应的主机 IP地址写错了
SQL线程出错主从服务器数据库结构不统一,出错后,数据少,能够手动解决建立插入,再更新slave状态。注:若是主上误删除了。那么从上也就误删除了。 #所以主上要按期作mysqldump备份