218.4.3-4.4 15周2,3次课
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了218.4.3-4.4 15周2,3次课相关的知识,希望对你有一定的参考价值。
十五周二,三次课 mysql扩展知识
MySQL主从复制原理
MYSQL的主从复制是一个异步的复制过程,数据将从一个MySQL数据库(Master)复制到另一个MySQL数据库(Slave), 在Master与Slave 之间实现整个主从复制的过程是由三个线程参与完成的。其中有两个线程 (SQL线程和I/O线程) 在Slave端 , 另外一个线程 ( I/O线程) 在 Master端.
要实现MySQL的主从复制,首先必须打开Master端的binlog记录功能, 否则就无法实现。 因为整个复制过程实际上就是Slave从Master端获取binlog日志,然后再在 Slave上以相同顺序执行获取的binlog日志中所记录的各种SQL操作。
要打开MySQL的binlog记录功能,可通过在MYSQL的配置文件my.cnf中的 mysqld模块([mysqld]标识后的参数部分)增加"log-bin"参数选项来实现,具体信息如下。
[mysqld]
Log-bin=/data/mysql/mysql-bin
提示:有些读者因把log-bin放在了配置文件结尾,而不是[mysqld]标识后,从而导致配置复制不成功。
下面简单描述MySQL Replication的复制原理过程。
1) 在Slave服务器上执行start slave命令开启主从复制开关,开始进行主从复制
2) 此时,Slave服务器的I/O线程会通过在Master上已经授权的复制用户权限请求连接Master服务器,并请求从指定binlog日志文件的指定位置(日志文件名和位置就是在配置主从复制服务时执行change master命令指定的)之后开始发送binlog日志内容
3) Master服务器接收到来自Slave服务器的I/O线程的请求后,其上负责复制的I/O线程会根据Slave服务器的I/O线程请求的信息分批读取指定binlog日志文件指定位置之后的binlog日志信息,然后返回给Slave端的I/O线程。返回的信息中除了binlog日志内容外,还有在Master服务器端记录的新的binlog文件名称,以及在新的binlog中的下一个指定更新位置。
4) 当Slave服务器的I/O线程获取到Master服务器上I/O线程发送的日志内容、日志文件及位置点后,会将binlog日志内容依次写到Slave端自身的Relay Log(即中继日志)文件(MySQL-relay-bin.xxxxxx)的最末端,并将新的binlog文件名和位置记录到 master-info文件中,以便下一次读取Master端新binlog日志时能够告诉Master服务器从新binlog日志的指定文件及位置开始请求新的binlog日志内容。
5) Slave服务器端的SQL线程会实时检测本地Relay Log中I/O线程新增加的日志内容,然后及时地把Relay Log文件中的内容解析成SQL语句,并在自身Slave服务器上按解析SQL语句的位置顺序执行应用这些SQL语句,并在relay-log.info中记录当前应用中继日志的文件名及位置点.
经过了上面的过程,就可以确保在Master端和Slave端执行了同样的SQL语句。当复制状态正常时,Master端和Slave端的数据是完全一样的。当然,MySQL的复制机制也有一些特殊情况 ,不过在大多数情况下,大家不用担心。
针对MYSQL主从复制原理的重点进行小结:
主从复制是异步的逻辑的SQL语句级的复制。
复制时,主库有一个I/O线程,从库有两个线程,即I/O 和SQL线程。
实现主从复制的必要条件是主库要开启记录binlog功能。
作为复制的所有MYSQL节点的server-id都不能相同。
binlog文件只记录对数据库有更改的SQL语句(来自主数据库内容的变更),不记录任何查询(如select、show)语句。
mysql主从数据库不同步的2种解决方法
Mysql的主从数据库没有同步
先上Master库:
mysql>show processlist; 查看下进程是否Sleep太多。发现很正常。
show master status; 也正常。
mysql> show master status;
+-------------------+----------+--------------+-------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+-------------------------------+
| mysqld-bin.000001 | 3260 | | mysql,test,information_schema |
+-------------------+----------+--------------+-------------------------------+
1 row in set (0.00 sec)
再到Slave上查看
mysql> show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: No
可见是Slave不同步
下面介绍两种解决方法:
方法一:忽略错误后,继续同步
该方法适用于主从库数据相差不大,或者要求数据可以不完全统一的情况,数据要求不严格的情况
解决:
stop slave;
#表示跳过一步错误,后面的数字可变
set global sql_slave_skip_counter =1;
start slave;
之后再用mysql> show slave status\G 查看:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
ok,现在主从同步状态正常了。。。
方式二:重新做主从,完全同步
该方法适用于主从库数据相差较大,或者要求数据完全统一的情况
解决步骤如下:
1.先进入主库,进行锁表,防止数据写入
使用命令:
mysql> flush tables with read lock;
注意:该处是锁定为只读状态,语句不区分大小写
2.进行数据备份
#把数据备份到mysql.bak.sql文件
[[email protected] mysql]#mysqldump -uroot -p -hlocalhost > mysql.bak.sql
这里注意一点:数据库备份一定要定期进行,可以用shell脚本或者python脚本,都比较方便,确保数据万无一失
3.查看master 状态
mysql> show master status;
+-------------------+----------+--------------+-------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+-------------------------------+
| mysqld-bin.000001 | 3260 | | mysql,test,information_schema |
+-------------------+----------+--------------+-------------------------------+
1 row in set (0.00 sec)
4.把mysql备份文件传到从库机器,进行数据恢复
#使用scp命令
[[email protected] mysql]# scp mysql.bak.sql [email protected]:/tmp/
5.停止从库的状态
mysql> stop slave;
6.然后到从库执行mysql命令,导入数据备份
mysql> source /tmp/mysql.bak.sql
7.设置从库同步,注意该处的同步点,就是主库show master status信息里的| File| Position两项
change master to master_host = '192.168.128.100', master_user = 'rsync', master_port=3306, master_password='', master_log_file = 'mysqld-bin.000001', master_log_pos=3260;
8.重新开启从同步
mysql> stop slave;
9.查看同步状态
mysql> show slave status\G 查看:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
好了,同步完成啦。
mysql一主多从同步配置
一主多从,其实和一主一从是一样的原理
一、环境
Master:192.168.1.100
slave1:192.168.1.110
slave2:192.168.1.111
master和 slave上的相关配置
master 上编辑my.cnf文件
在[mysqld]下添加如下字段:
server-id = 100
log-bin=mysql-bin
binlog-do-db=YYY //需要同步的数据库
binlog-ignore-db=mysql //被忽略的数据库
binlog-ignore-db=information-schema //被忽略的数据库
在master上为slave添加一个同步账号
grant replication slave on *.* to 'repl'@192.168.1.110 identified by '123456'; //在slave1上登陆成功
grant replication slave on *.* to 'repl'@192.168.37.111 identified by 'password'; //在slave2上登陆成功
保存后,重启master的mysql服务:
service mysql restart;
用show master status命令查看日志情况
修改slave1上的配置文件my.cnf
在[mysqld]下添加如下字段:
server-id = 110
保存后,重启slave1的mysql服务
先关闭主从同步:stop slave;
实现主从同步:
change master to master_host='192.168.1.100', master_user='repl', master_password='123456', master_log_file=' mysql-bin.000001', master_log_pos=320;
打开同步:start slave;
判断主从是否配置成功:show slave status\G(最后可以不用分号,\G本身就是结束符)
确认以下两项参数都为Yes
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
修改slave2上的配置文件my.cnf
在[mysqld]下添加如下字段:
server-id = 111
其他操作和slave1上相同
MySQL双主(主主)架构方案
MySQL双主(主主)架构方案思路是:
1.两台mysql都可读写,互为主备,默认只使用一台(masterA)负责数据的写入,另一台(masterB)备用;
2.masterA是masterB的主库,masterB又是masterA的主库,它们互为主从;
3.两台主库之间做高可用,可以采用keepalived等方案(使用VIP对外提供服务);
4.所有提供服务的从服务器与masterB进行主从同步(双主多从);
5.建议采用高可用策略的时候,masterA或masterB均不因宕机恢复后而抢占VIP(非抢占模式);
这样做可以在一定程度上保证主库的高可用,在一台主库down掉之后,可以在极短的时间内切换到另一台主库上(尽可能减少主库宕机对业务造成的影响),减少了主从同步给线上主库带来的压力;
但是也有几个不足的地方:
1.masterB可能会一直处于空闲状态(可以用它当从库,负责部分查询);
2.主库后面提供服务的从库要等masterB先同步完了数据后才能去masterB上去同步数据,这样可能会造成一定程度的同步延时;
架构的简易图如下:
主主环境:
1. 2台:masterA(192.168.1.100,masterB(192.168.1.101)CentOS 7.4
2.Mysql5.6版本
添加masterA配置文件/etc/my.cnf
[mysqld]
server-id = 100
log-slave-updates = true #将复制事件写入binlog,一台服务器既做主库又做从库此选项必须要开启
#masterA自增长ID
auto_increment_offset = 1
auto_increment_increment = 2 #奇数ID
添加masterB配置文件/etc/my.cnf
[mysqld]
server-id = 101
log-slave-updates = true #将复制事件写入binlog,一台服务器既做主库又做从库此选项必须要开启
#masterB自增加ID
auto_increment_offset = 2
auto_increment_increment = 2 #偶数ID
添加主从同步账户
masterA上:
mysql> grant replication slave on *.* to 'repl'@'192.168.1.101' identified by '123456';
mysql> flush privileges;
masterB上:
mysql> grant replication slave on *.* to 'repl'@'192.168.1.100' identified by '123456';
mysql> flush privileges;
查看主库的状态
masterA上:
mysql> show master status;
File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 120 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
masterB上
mysql> show master status;
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 437 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
配置同步信息:
masterA上:
mysql>change master to
master_host='192.168.10.12',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=437;
mysql> start slave;
mysql> show slave status\G;
显示有如下状态则正常:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
masterB上:
#本人是测试环境,可以保证没数据写入,否则需要的步骤是:先masterA锁表-->masterA备份数据-->masterA解锁表 -->masterB导入数据-->masterB设置主从-->查看主从
mysql> change master to
master_host='192.168.1.100',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=120;
mysql>start slave;
mysql> show slave status\G;
显示有如下状态则正常:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
开启MySQL5.6的GTID功能
masterA和masterB分别执行如下命令:
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> change master to MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
以上是关于218.4.3-4.4 15周2,3次课的主要内容,如果未能解决你的问题,请参考以下文章