inux12 -MYSQL数据库 -->12mysql主从

Posted FikL-09-19

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了inux12 -MYSQL数据库 -->12mysql主从相关的知识,希望对你有一定的参考价值。

mysql的主从复制

一.mysql主从复制

1.主从复制主库的操作

1.主库要开启二进制日志
2.主库的server_id和从库不同
3.主库要有提供从库连接的用户
4.主库确定binlog名称和位置点
5.获取其他主库信息:ip,port,user,password

2.主从复制从库的操作

1.从库需要配置与主库不同的server_id
2.同步主库的所有数据
3.从库填写主库信息进行同步(change master to)
4.从库开启IO线程和SQL线程

3.主从复制原理

1)文字描述

1.主库配置server_id和binlog
2.主库授权用户
3.主库查看binlog名字及位置点
4.通过change master to语句告诉从库主库的ip,port,user,password,file,pos
5.从库开启IO线程和SQL线程(start slave;)
6.从库通过IO线程和change master to获取的信息连接主库
7.从库连接主库后,会去询问主库的dump线程,是否有比change master to时更新的binlog文件和位置点
8.主库接收到从库请求后,比较一下binlog信息,如果有就将最新数据通过dump线程给从库IO线程(使用ACK)
9.从库通过IO线程接收到主库发来的binlog事件,存储到TCP/IP缓存中(使用ACK)
10.从库IO线程也会返回ACK更新master.info文件里面的binlog文件名和位置点(使用ACK)
11.TCP/IP缓存中的内容会存到relay-log中
12.SQL线程会读取relay-log.info,获取上一次执行到的位置点,与中继日志对比,执行最新的relay-log日志
13.SQL线程执行完relay-log最新的数据后,更新relay-log.info,记录本次更新到的位置点

4.主从涉及到的文件

1)主库

1.主库binlog:记录主库发生过的修改事件
2.dump线程:对比binlog是否更新,并且将新数据的二进制日志传送给从库

2)从库

1.IO线程:连接主库,接收主库发来的新数据的binlog日志
2.SQL线程:执行主库传过来的新数据的binlog日志
3.relay-log(中继日志):存储所有主库传过来的binlog事件
4.master.info:记录上次请求到的主库binlog名字和位置点
5.relay-log.info:记录上一次执行relay-log到的位置,下次从记录的位置开始向下继续执行

二、主从复制搭建实战

1.主库操作:

给主库个密码 mysqladmin -uroot password '123'

1)配置主库配置文件

#编辑mysql配置文件
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
server_id=1
#开启binlog日志
log_bin=mysql-bin

2)创建主从复制用户

#登录数据库
[root@db01 ~]# mysql -uroot -p123
#创建rep用户作为从库连接用的用户
mysql> grant replication slave on *.* to rep@'10.0.0.%' identified by 'oldboy123';
	这里必须 *.* 不能指定库授权,因为 replication slave 是全局的

3)查看主库binlog信息

mysql> show master status;

2. 从库操作:

1)修改配置文件

[root@db02 ~]# vim /etc/my.cnf
[mysqld]
#主库server-id为1,从库不等于1
server_id=2

#重启数据库
[root@db02 ~]# /etc/init.d/mysqld restart

2)配置主从同步

#登陆数据库
[root@db02 ~]# mysql -uroot -poldboy123

#执行change master to 语句
mysql> change master to
-> master_host='10.0.0.51',
-> master_user='rep',
-> master_password='123',
-> master_log_file='mysql-bin.000001',
-> master_log_pos=1357;

#开启IO和SQL线程
start slave;

3.添加数据库主从(数据库运行中做主从)

1.准备纯净的从库环境
2.主库全备数据
	#如果不打点备份
	mysqldump -uroot -p123 -A -R --triggers > /backup/full.sql
	#打点备份
	mysqldump -uroot -p123 -A -R --triggers --master-data=2 –single-transaction > /backup/full.sql
3.将热备数据传达从库
	scp /backup/full.sql 172.16.1.52:/tmp
4.模拟主库运行,有数据写入
	insert into .....
5.导入全备数据
	#导入不打点的数据的话,接下来主从,位置点只能去主库查看 show master status; 这个是不准确的
	#如果导入的是打点的数据,那么接下来主从的同步位置点可以从全被sql里面找到,是准确的
6.查看sql文件中的位置点(如果是打点备份的话)
	[root@db02 scripts]# head -50 /tmp/dadian.sql|grep 'MASTER_LOG_POS'
	-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=1544;
7.从库配置主从
	mysql> change master to
	-> master_host='10.0.0.51',
	-> master_user='rep',
	-> master_password='123',
	-> master_log_file='mysql-bin.000001',
	-> master_log_pos=1357;
8.开启SQL线程和IO线程
	start slaves;
9.查看主从状态
	show slave status;

4.验证多个从库server_id相同,主从是否有问题

1.配置第二个从库
	[root@db01 ~]# vim /etc/my.cnf
	[mysqld]
	server_id=2
2.启动数据库
	systemctl start mysql
3.将主库的全备发送到从库
	scp /tmp/full.sql root@172.16.1.51:/tmp	
4.在从库执行sql文件
	mysql < /tmp/full.sql
5.查看sql文件中的位置点
	[root@db02 scripts]# head -50 /tmp/dadian.sql|grep 'MASTER_LOG_POS'
	-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=1544;
6.在从库上执行change master
	change master to
	master_host='172.16.1.50',
	master_user='rep',
	master_password='123',
	master_log_file='mysql-bin.000001',
	master_log_pos=2100;
7.开启SQL线程和IO线程
	start slave;
8.查看主从复制的状态
	show slave status\\G

三、主从复制基本故障处理

#清空主从配置
	reset slave all;

1.IO线程问题

1.检测网络:
	[root@db01 ~]# ping 172.16.1.51

2.检测端口:
	[root@db01 ~]# telnet 172.16.1.51 3307
	#阿里云机器有的禁ping
	[root@db01 ~]# tcping 172.16.1.51 3306

3.检测账号,密码:
	#根据授权命令
	grant replication slave on *.* to rep@'172.16.1.5%' identified by '123';
	#连接测试
	mysql -urep -p123 -h127.0.0.1 -P 3307

4.查看binlog是否存在
	show master status;

5.反向解析
	#没有跳过反向解析
	ERROR 1045 (28000): Access denied for user 'root'@'db01' (using password: YES)
	#配置
	skip_name_resolve

2.SQL线程问题

1.主库有的数据,从库没有
	主库:a库
	从库:没有a库
2.从库有的数据,主库没有
	从库:a库
	主库:要创建a库
3.主库与从库数据库结构有差别

#处理方法一:
	#临时停止同步
	mysql> stop slave;
	#将同步指针向下移动一个(可重复操作)解决不了根本问题
	mysql> set sql_slave_skip_counter=1;
	#开启同步
	mysql> start slave;
	
#处理方法二:
	#编辑配置文件
	[root@db01 ~]# vim /etc/my.cnf
	#在[mysqld]标签下添加以下参数
	slave-skip-errors=1032,1062,1007
	
#处理方法三:
	1.要求,主从复制之前,主库和从库的数据保证一致.
	2.在从库上设置  只读:set read-only=1;
	(做读写分离时使用,但是做MHA会出现提升为主库时,主库只读,后面会讲专门做读写分离的Atlas)

3.当数据库主库与从库的uuid相同时

#做主从会报错

#解决方法:
	1.删除UUID文件,重启数据库
	2.修改UUID

四、延时从库

我们说用延时从库可以做备份,主库执行删除的时候,从库还没有删除,可以把表数据拿出来恢复回去
企业中一般会延时3-6小时

1.延时从库配置方法

1)已经有主从的情况下

1.停止主从
	mysql> stop slave;
2.设置延时为180秒
	mysql> CHANGE MASTER TO MASTER_DELAY = 180;
3.开启主从
	mysql> start slave;
4.查看状态
	mysql> show slave status \\G
	SQL_Delay: 180
5.主库创建数据,会看到从库值变化,创建的库没有创建
	SQL_Remaining_Delay: 170

2)没有主从复制的情况下

1.修改主库,从库配置文件
	server_id
	开启binlog

2.保证从库和主库的数据一致

3.执行change语句
	change master to
	master_host='172.16.1.50',
	master_user='rep',
	master_password='123',
	master_log_file='mysql-bin.000001',
	master_log_pos=2752,
	master_delay=180;

3)延时从库停止方法

1.停止主从
mysql> stop slave;

2.设置延时为0
mysql> CHANGE MASTER TO MASTER_DELAY = 0;

3.开启主从
mysql> start slave;

#注:做延时从库只是为了备份,不提供服务

2.思考:延时到底是在哪里延时的

思考:IO线程还是SQL线程做的手脚?

#去主库创建一个库
	create database ttt;
#查看从库的relaylog看看有没有内容
	mysqlbinlog --base64-output=decode-rows -vvv db03-relay-bin.000002

总结:
	延时从库是在SQL线程做的手脚,IO线程已经把数据放到relay-log里了.
	SQL线程在执行的时候,会延迟你设定的时间长度.

3.使用延时从库恢复数据

1)场景

总数据量级500G,正常备份去恢复需要1.5-2小时
1)配置延时3600秒
mysql> CHANGE MASTER TO MASTER_DELAY = 3600;

2)主库
drop database db;

3)怎么利用延时从库,恢复数据?

2)环境准备

1.进行每日的全备
	mysqldump -uroot -p123 -A -R --triggers --master-data=2 –single-transaction > /backup/full.sql
2.调整延时从库延时时间为10分钟
	stop slave;
	CHANGE MASTER TO MASTER_DELAY = 600;
	start slave;
3.主库写入新数据
	create database yanshi;
	use yanshi;
	create table yanshi(id int);
	insert into yanshi values(1),(2),(3),(4);
	
	create database yanshi2;
	use yanshi2;
	create table yanshi2(id int);
	insert into yanshi2 values(1),(2),(3),(4);

3)模拟删除数据

1.删除一个库,可以是之前的,也可以是刚创建的
	#因为刚我们看了,只要我执行了,从库已经写到了relay-log,跟我数据库里的数据关系不大
	drop database world;

4)使用延时从库恢复数据

1.停止从库sql线程
	stop slave sql_thread;
2.查看状态
	show slave status;
3.备份从库数据
	mysqldump -uroot -p123 -B world > /backup/congku.sql
4.截取一下relay-log
	1)确认起点
		[root@db02 data]# cat relay-log.info
		./db02-relay-bin.000005
		283
	2)确认终点
		[root@db02 data]# mysqlbinlog --base64-output=decode-rows -vvv db02-relay-bin.000005
		drop语句之前
	3)截取数据
		[root@db02 data]# mysqlbinlog --start-position=283 --stop-position=1112 db02-relay-bin.000005 > /tmp/yanshi.sql
5.将从库全备的数据与relaylog截取数据拷贝到主库
	scp /tmp/yanshi.sql 172.16.1.51:/tmp/
	scp /backup/congku.sql 172.16.1.51:/tmp/
6.将数据导入主库
	#导入前不要停掉binlog
	mysql < /tmp/yanshi.sql
	mysql < /tmp/congku.sql
7.开启从库的sql线程
	start slave sql_thread;

#主库那边执行到删除的时候没关系,因为还有创建的部分,他会再次把数据创建回来

五、半同步复制

mysql主从本身是异步复制
IO线程将数据写入TCP/IP以后就不管了,当TCP缓存返回ACK的时候,IO线程会继续去主库拿数据

从MYSQL5.5开始,支持半自动复制。之前版本的MySQL Replication都是异步(asynchronous)的,主库在执行完一些事务后,是不会管备库的进度的。如果备库不幸落后,而更不幸的是主库此时又出现Crash(例如宕机),这时备库中的数据就是不完整的。简而言之,在主库发生故障的时候,我们无法使用备库来继续提供数据一致的服务了。

半同步复制(Semi synchronous Replication)则一定程度上保证提交的事务已经传给了至少一个备库。
出发点是保证主从数据一致性问题,安全的考虑。

半同步复制是IO线程拿完数据,会等待SQL线程执行完以后再去拿数据,而且还会影响主库性能,他会阻塞主库数据的写入,如果SQL要执行十分钟,那么IO线程就一直等待,并且不让主库写入数据

半同步,是在IO线程上做的手脚,数据写入到TCP/IP缓存中,不返回ACK,直到SQL线程执行完之后,才返回ACK
ACK是一个确认字符

半同步其实是mysql自带的一个和插件(很少有人用)
1.效率低
2.影响主库的性能
3.设置一个超时时间:过了这个超时时间,会恢复到异步复制

5.5 出现概念,但是不建议使用,性能太差
5.6 出现group commit 组提交功能,来提升开启半同步复制的性能
5.7 更加完善了,在group commit基础上出现了MGR
5.7 的增强半同步复制的新特性:after commit; after sync;

1.半同步复制开启方法

1)主库

#登录数据库
[root@db01 ~]# mysql -uroot -p123
#查看是否有动态支持
mysql> show global variables like 'have_dynamic_loading';
#安装自带插件(.so结尾的文件在 /usr/local/mysql/lib/plugin/ 下面)
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME'semisync_master.so';
#启动插件
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
#设置超时
mysql> SET GLOBAL rpl_semi_sync_master_timeout = 1000;

#修改配置文件
[root@db01 ~]# vim /etc/my.cnf
#在[mysqld]标签下添加如下内容(不用重启库)
[mysqld]
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000

#查看半同步状态是否开启
mysql> show variables like'rpl%';
mysql> show global status like 'rpl_semi%';

2)从库

#登录数据库
[root@mysql-db02 ~]# mysql -uroot -poldboy123
#先检查从库状态
show slave status\\G
#安装slave半同步插件
mysql>  INSTALL PLUGIN rpl_semi_sync_slave SONAME'semisync_slave.so';
#启动插件
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
#重启io线程使其生效
mysql> stop slave io_thread;
mysql> start slave io_thread;
#编辑配置文件(不需要重启数据库)
[root@mysql-db02 ~]# vim /etc/my.cnf
#在[mysqld]标签下添加如下内容
[mysqld]
rpl_semi_sync_slave_enabled =1

3)测试半同步

六、过滤复制

我们在授权主从用户的时候必须使用
	mysql> grant replication slave on *.* to rep@'10.0.0.%' identified by 'oldboy123';
		这里必须 *.* 不能指定库授权,因为 replication slave 是全局的,不用则报错

企业里或许有只想同步某一个库的需求,可能是因为环境多为了节省资源
企业里很多环境
1.开发环境:开发开发完自己测试
2.测试环境:
	1)性能测试
	2)功能测试
4.预发布环境(beta,内测不删档)、灰度环境、沙盒环境
5.生产环境

除了生产和预发布其他的环境都是虚拟机测试用的

测试环境有很多游戏,我就想一个从库同步一种游戏,还有合服,建新服,其实就是一个库或者一个表而已
创建角色总是提示改昵称已被创建,就是因为姓名也是唯一键

1.确认三台机器主从状态

show slave status\\G

2.过滤复制两种方式

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      262 |  白名单   	  |       黑名单      |                   |
+------------------+----------+--------------+------------------+-------------------+


1)黑名单

不记录黑名单列出的库的二进制日志

#参数
--replicate-ignore-db
--replicate-ignore-table
--replicate-wild-ignore-table

2)白名单

只执行白名单中列出的库或者表的中继日志

#参数:
--replicate-do-db=test
--replicate-do-table=test.t1
--replicate-wild-do-table=test.t2

3.配置过滤复制

1)主库创建两个库

create database wzry;
create database yxlm;

2)从库1配置

[root@db02 ~]# vim /etc/my.cnf
[mysqld]
replicate-do-db=wzry

[root@db02 ~]# systemctl restart mysql

#查看主从状态
show slave status;

3)从库2配置

[root@db03 ~]# vim /etc/my.cnf
[mysqld]
replicate-do-db=yxlm

[root@db03 ~]# systemctl restart mysql

#查看主从状态
show slave status;

4)主库创建表测试

use wzry;
create table dianxin1;

use yxlm;
create table wangtong1;

5)从库查看表

#登陆两台数据库查看表是否存在

4.尝试把白名单配置到主库

[root@db01 ~]# vim /etc/my.cnf
[mysqld]
replicate-do-db=yxlm

[root@db01 ~]# systemctl restart mysql

#测试同步

5.过滤复制总结:

#我们可以查看一下中继日志,其实数据都拿过来了,只不过他是读取配置文件过滤去执行sql的


在主库上设置白名单:只记录白名单设置的库或者表,相关的SQL语句到binlog中
在主库上设置黑名单:不记录黑名单设置的库或者表,相关的SQL语句到binlog中

在从库上设置白名单:IO线程会拿所有的binlog,但是SQL线程只执行白名单设置的库或者表相关的SQL语句
在从库上设置黑名单:IO线程会拿所有的binlog,但是SQL线程不执行黑名单设置的库或者表相关的SQL语句

#从库白名单,只同步某个库
replicate-do-db=test
#从库白名单,只同步某个库中的某个表
replicate-do-table=test.t1
replicate-do-table=test.c2
replicate-do-table=test.b3
replicate-do-table=test.a4
#从库白名单,只同步某个库中的以t开头的所有表
replicate-wild-do-table=test.t*

以上是关于inux12 -MYSQL数据库 -->12mysql主从的主要内容,如果未能解决你的问题,请参考以下文章

inux .gz文件 解压缩命令

inux软件安装管理之——dpkg与apt-*详解

inux 内存监控分析

如何为inux系统删除文件自动重启服务

inux-安装oracle 11g

我的inux   编译 java