MySQL主从同步(复制),实现读写分离

版权声明:有疑问可加微信15216874307 https://blog.csdn.net/Doudou_Mylove/article/details/82428794

应用场景和意义
大量的并发访问和操作,除了在网站实现分布式负载均衡还远远不够。

MySQL主从可以实时备份,保证数据安全性,提升访问速度和易于维护管理。
可以应用在读写分离的场景中,用以降低单台MySQL服务器的I/O
可以实现MySQL服务的HA集群(高可用)

同步原理:
slave启动复制开关,通过master授权的用户去连接master并请求binlog日志文件的指定位置,master上数据更新时会记录一个bin-log并通过IO线程传给slave,slave把该bin-log依次记录在自己的relay-log(中继日志)并实时检测依次执行relay-log中同步过来的bin-log执行过的sql语句进行同样的操作动作 。

环境
master:115.159.42.246(centos6)mysql5.5
slave:123.206.207.197(centos7)mysql5.5
slave:49.51.9.203 (centos7) mysql5.5

master配置
1、授权同步复制帐号
mysql>grant replication slave  on *.* to 'repuser'@'123.206.207.197' identified by '123456';
mysql>grant replication slave  on *.* to 'repuser'@'49.51.9.203' identified by '123456';
mysql>flush privileges;
mysql>select user,host from mysql.user;              //MySQL查看用户
#有时候会要求用内网ip较快,这里slave用户必须有REPLICATION SLAVE权限.


2、拷贝数据
flush tables with read lock;                     #数据库只读锁定命令,防止导出数据库的时候有数据写入
flush table with read lock;                                    #5.1和5.5不同版本的用法
mysqldump -uroot -p -A -B --events --skip-lock-tables  performance_schema> /tmp/rep.sql     #导出数据  
#导出数据,在mysql5.5中,增加了performance_schema,--skip-lock-tables可防止报错
#拷贝之前必须关停Master服务器,禁止在Master和slave服务器中进行写操作,使得两数据库中的数据一定要相同!

3、数据上传到slave
scp /tmp/rep.sql root@slave-ip:/home
unlock tables;                           #解除锁定
到这里主库就可以提供服务了。


4、master配置文件修改
vi /etc/my.cnf
[mysqld]             
server-id=1                     #设置服务器id,数字自己定义
log-bin=mysql-bin             #启动MySQ二进制日志系统,默认是打开的
#binlog-do-db=db1          #需要同步的数据库名,多个数据库可重复此参数每个数据库一行,如果同步全部这一步和下一步就省略
#binlog-ignore-db=mysql       #不同步mysql系统数据库
#default-character-set=utf8    #增加字符集(有时候不用加,默认就是)
:wq! 

5、service mysqld  restart                                   #重启MySQL
mysql> show variables like 'server_id';                 #查看server-id的值是否为1
+---------------+-------+

扫描二维码关注公众号,回复: 3159838 查看本文章

| Variable_name | Value |

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

| server_id     | 1     |

+---------------+-------+
1 row in set (0.00 sec)

show master status;          #查看主服务器,出现以下类似信息
mysql> show master status;
+------------------+----------+--------------+------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

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

| mysql-bin.000011 |      107 | osyunweidb   | mysql            |

+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

注意:这里记住File的值:mysql-bin.000011 和 Position的值:107,后面会用到。


slave操作

mysql -uroot -p  </home/rep.sql                 #导入备份文件到数据库
mysql -u repuser -h master-ip -p                  #测试在从服务器上登录到主服务器
提示:初次创建数据库要提前调整好统一的字符集。

slave1修改配置文件
vi /etc/my.cnf
[mysqld]           
server-id=2                   #设置服务器id,值要比master的数字大,表示为从数据库
log-bin=mysql-bin              #启动MySQ二进制日志
:wq!                                       #保存退出

slave2修改配置文件
vi /etc/my.cnf
[mysqld]           
server-id=3                   #设置服务器id,值要比master的数字大,且不能和别的slave值相同
log-bin=mysql-bin              #启动MySQ二进制日志
:wq!                                       #保存退出

service mysqld restart                #重启MySQL
mysql> show variables like 'server_id';           #查看server-id的值是否与配置文件一致


slave stop;                                                              #停止slave同步进程
change master to master_host='123.206.207.197',master_user='rep',master_password='123456',master_port=3306,master_log_file='mysql-bin.000005' ,master_log_pos=320;                                     #执行同步命令    

mysql> slave start;                       #开启slave同步进程

mysql> show slave status\G                #查看slave同步信息   

注意查看:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
以上这两个参数的值为Yes,即说明配置成功!

至此,Linux下MySQL数据库主从同步配置完成!


流程总结:
master
vi /etc/my.cnf   
server-id=1          
log-bin=mysql-bin
service mysqld restart
1、授权复制帐号
grant replication slave  on *.* to 'repuser'@'123.206.207.197' identified by '123456';
2、flush tables with read lock;            #数据库只读
3、mysqldump -uroot -p -A -B --events  --skip-lock-tables  performance_schema> /tmp/rep.sql
4、scp /tmp/rep.sql [email protected]:/home
5、unlock tables;  
到这里主库就可以提供服务了。

slave
vi /etc/my.cnf   
server-id=2           
log-bin=mysql-bin
service mysqld restart
#执行同步命令    
change master to master_host='123.206.207.197',master_user='rep',master_password='123456',master_port=3306,master_log_file='mysql-bin.000005' ,master_log_pos=411;
slave start;

slave之间的设置唯一不同的就是server-id的值,其它操作一样

流程总结完毕.

复制故障实例
1、show master status \G如果没内容就是配置文件里的bin-log没开。
2、change master to命令执行时报错找不到bin-log文件可能是两边有空格。
3、由于切换binlog导致show master status 位置变化无影响。


读写分离

主从同步完成后,配置master写,slave读。个人认为master不需要再修改,只给予slave上操作的用户只读的权限即可.

slave上操作
slave修改配置文件
vim /etc/my.cnf
mysqld]
read-only = 1
重启数据库
service mysqld restart
先添加一个新普通用户,只给 select,update,insert,delete权限,这是核心所在:
mysql>grant select,update,insert,delete on *.* to lijunmin@localhost identified by '123456';    #这个用来自己测试
mysql>grant select,update,insert,delete on *.* to lijunmin@'%' identified by '123456';        #这个用于其它用户测试
然后在salve上用这个新用户登录MySQL
mysql -ulijunmin -p123456
进去后增删改随意执行一个动作
mysql> create database db2;
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
报错提示:--read-only表示只读.

测试成功.

master端
do:只记录
binlog-do-db = mysql(在主库上设置此项意为只记录mysql库的binlog)
binlog-do-db = performance_schema
binlog-do-db = information_schema

ignore:排除
binlog-ignore-db = mysql(在主库上设置此项意为不记录binlog,来达到从库不同步mysql库)
binlog-ignore-db = performance_schema
binlog-ignore-db = information_schema

slave端
do:只复制
replicate-do-db = mysql,test      #需要忽略的数据库,多个库用逗号分隔

ignore:只忽略
replicate-ignore-db = mysql,test    #需要忽略的数据库,多个库用逗号分隔


read_only=1只读模式,slave可以限定普通用户进行数据修改的操作,但不会限定具有super权限的用户的数据修改操作.

那么super用户怎么控制读写?

设置“read_only=1”和“flush tables with read lock;”两条命令,就可以确保数据库处于只读模式,不会发生任何数据改变。

#但同时由于加表锁的命令对数据库表限定非常严格,如果在slave从库上执行这个命令后,slave库可以从master读取binlog日志,但不能够应用日志,slave库不能发生数据改变,当然也不能够实现主从同步了,这时如果使用 “unlock tables;”解除全局的表读锁,slave就会自动应用从master读取到的binlog日志,继续保证主从库数据库一致同步。
 

slave上操作
用root用户登录进行测试
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
mysql> create database db5;
ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

测试成功.

slave状态错误码解决:

方法一:(最好不用)
slave stop;
set global sql_slave_skip_counter = 1;
slave start;

方法二:(推荐)
跳过指定的错误号
从库my.cny配置文件添加
slave-skip-errors = 1008                 #可加多个用,(逗号)隔开

处理一则MySQL Slave环境出现ERROR 1201 (HY000): Could not initialize master info structure的案例

mysql> start slave;
ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository

在操作系统端查看master/slave的配置文件relay-log.info master.info,发现是两个0字节文件
会不会是这个原因呢,直接删除这两个文件,然后尝试重新执行change master:
rm -fr relay-log.info master.info
搞定。

mysql-bin和relay-bin 清除                 #主库应该没有relay-bin
master
mysql> reset master;
slave
mysql> reset slave;


延迟情况

从库同步延迟情况出现的依据
1、show slave status显示参数Seconds_Behind_Master不为0,这个数值可能会很大
2、show slave status显示参数Relay_Master_Log_File和Master_Log_File显示bin-log的编号相差很大,说明bin-log在从库上没有及时同步,所以近期执行的bin-log和当前IO线程所读的bin-log相差很大
3、mysql的从库数据目录下存在大量mysql-relay-log日志,该日志同步完成之后就会被系统自动删除,存在大量日志,说明主从同步延迟很厉害

MySQL数据库主从同步延迟原理
mysql主从同步原理:
master针对写操作,顺序写binlog,slave单线程去主库顺序读”写操作的binlog”,从库取到binlog在本地原样执行(随机写),来保证主从数据逻辑上一致。
mysql的主从复制都是单线程的操作,主库对所有DDL和DML产生binlog,binlog是顺序写,所以效率很高,slave的Slave_IO_Running线程到主库取日志,效率比较高,下一步,问题来了,slave的Slave_SQL_Running线程将主库的DDL和DML操作在slave实施。DML和DDL的IO操作是随即的,不是顺序的,成本高很多,还可能可slave上的其他查询产生lock争用,由于Slave_SQL_Running也是单线程的,所以一个DDL卡主了,需要执行10分钟,那么所有之后的DDL会等待这个DDL执行完才会继续执行,这就导致了延时。
有朋友会问:“主库上那个相同的DDL也需要执行10分,为什么slave会延时?”,答案是master可以并发,Slave_SQL_Running线程却不可以。

MySQL数据库主从同步延迟是怎么产生的?
当主库的TPS并发较高时,产生的DDL数量超过slave一个sql线程所能承受的范围,那么延时就产生了,当然还有就是可能与slave的大型query语句产生了锁等待。
首要原因:数据库在业务上读写压力太大,CPU计算负荷大,网卡负荷大,硬盘随机IO太高
次要原因:读写binlog带来的性能影响,网络传输延迟。

 MySQL数据库主从同步延迟解决方案。

架构方面
1.业务的持久化层的实现采用分库架构,mysql服务可平行扩展,分散压力。
2.单个库读写分离,一主多从,主写从读,分散压力。这样从库压力比主库高,保护主库。
3.服务的基础架构在业务和mysql之间加入memcache或者redis的cache层。降低mysql的读压力。
4.不同业务的mysql物理上放在不同机器,分散压力。
5.使用比主库更好的硬件设备作为slave

总结,mysql压力小,延迟自然会变小。

硬件方面

1.采用好服务器,比如4u比2u性能明显好,2u比1u性能明显好。
2.存储用ssd或者盘阵或者san,提升随机写的性能。
3.主从间保证处在同一个交换机下面,并且是万兆环境。

总结,硬件强劲,延迟自然会变小。一句话,缩小延迟的解决方案就是花钱和花时间。

猜你喜欢

转载自blog.csdn.net/Doudou_Mylove/article/details/82428794