MySql主从同步

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySql主从同步相关的知识,希望对你有一定的参考价值。

    在谈到mysql主从同步前,我们先来了解下普通文件的数据同步。


          普通文件的数据同步

 1.NFS网络文件共享可以同步存储数据

 2.samba共享--windows平台

 3.定时任务或守护进程结合rsync,scp

 4.inotify+rsync实时同步

 5.ftp数据同步

 6.svn

 ......

                mysql同步

      mysql有其自带的同步功能,mysql同步不是磁盘上文件直接同步。

 mysql支持单向、双向、链式级联、事实、异步复制。在复制过程中,一台服务器充当主服务器Master,而一个或者多个其他服务器充当为从服务器Slave。

复制可以是单向:M==>S,也可以是双向;M<==>M,当然也可以多从多M环状同步等。

 如果设置了链式级联复制,那么,从服务器本身除了充当从服务器外,也会同时充当其下面从服务器的主服务器

 链式级联复制:A-->B-->C-->D的复制形式

 在当前的生产工作中,大多数应用的mysql主从同步都是异步的复制方式,即不是严格实时的数据同步。

 生产环境授权

 主库用户:grant select, insert, update,delete on 'xx'.* to '用户'@'网段' identified by '用户密码';

 从库:grant select on 'xx'.* to '用户'@'网段' identified by '用户密码';

 可以结合read-only参数共同做

 如何实现上述授权方案,最简单的办法是在主库配置binlog-ignore-db=mysql

 当配置好主从同步后,所有数据库内容更新必须在主服务器上进行,避免用户对主服务器的数据库内容的更新与对从服务器上数据更新不一致而导致冲突

 如何确保用户在主服务器上更新呢?

   1.防止从库写数据方法

       采取忽略授权表方式的同步,然后对从服务器上的用户仅授权select读权限。不同步mysql库

  

   2.防止从库写数据方法

     除了select授权外,在slave服务器启动选项增加参数或者在my.cnf配置文件中加read-only保证从库只读,两者同时操作效果更佳

应用场景

1.主从服务器互为备份


2.主从服务器读写分离分担网站压力


3.根据服务器拆分业务独立分担压力

在企业生产环境中,通常采取读写分离策略,即主库负责写操作,从库负责读操作。一般从库有多台,主库可以采用高可用手段实现故障自动切换,如采用heartbeat+drbd。如果网站读的压力比较大,还可以利用负载均衡,分担从库服务器读的压力。

         mysql读写分离方法

1.通过程序实现读写分离(性能、效率最佳),如php,java程序

2.通过软件实现,如mysql-proxy amoeba等一些代理软件也可以实现读写分离,但最常用最好用的还是程序实现读写分离。

   

     mysql主从复制原理

mysql主从复制是一个异步的复制过程(一般情况下感觉是实时同步),数据从master复制到slave。这个过程是由三个线程参与完成的,两个线程(SQL线程和IO线程)在slave端,另一个线程(IO线程)在master端。slave端的IO线程负责与master端的线程打交道

 要实现mysql的主从复制,首先必须打开master端的Binlog(mysql-bin.xxx)功能,否则无法实现主从复制。因为整个复制过程实际上是slave从master端获取binlog日志,然后在slave自身上以相同顺序执行获取的binlog日志中记录的操作。

技术分享图片

 当用户写入数据到主库中,主库将这些sql语句(数据库的更改语句)放到binlog中,从库开启复制后通过IO线程和主库IO线程打交道,提供用户名密码,log文件及位置信息给主库,主库验证通过后读取binlog信息(根据从库IO县线程需求)返回给从库IO,位置信息保存在master-info中,sql放到relay-log(中继日志)中,从库通过sql线程按照顺序执行sql,从库IO线程继续读取 master-info信息,然后与主库IO交互。

          mysql主从复制实践

1.定义服务器角色

 主库(mysql master):ip 192.168.132.10 端口:3306

从库(mysql slave): ip 192.168.132.20 端口: 3306


2.数据库环境准备

实践环境以两台虚拟机为实践对象,进行单向主从复制。

虚拟机均安装mysql 5.1.72版本且数据库已启动


3.主库上执行操作

设置server-id值并且开启binlog参数

vim /etc/my.cnf

开启log-bin

[mysqld]

server-id       = 1

 

# Uncomment the following if you want to log updates

log-bin=mysql-bin

由于虚拟机mysql安装路径为/usr/local/mysql,数据路径为/usr/local/mysql/data,即日志文件在该路径下。

server-id不能一样

提示:

1.    server-idlog-bin必须放在mysqld模块里

2.   server-id的值使用服务器ip地址的最后8位如10目的是避免不同机器或实例重复(不适合多实例)

3.   现在配置文件中查找相关参数,不存在时再添加,参数不要重复

4.   修改配置文件中需要重启数据库

检查是否生效:

[[email protected] data]# mysql -uroot -p'123456' -e "show variables like 'log_bin';"

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

| Variable_name | Value |

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

| log_bin       | ON    |

4.建立用于从库复制的账号

登陆主库mysql

grant replication slave on *.* to [email protected]'192.168.132.%' identified by 'rep99';

刷新权限flush privileges;

检查用户

select user,host from mysql.user;

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

| user | host          |

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

| root | %             |

| root | 127.0.0.1     |

| rep  | 192.168.132.% |

| root | localhost     |

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

4 rows in set (0.00 sec)

5.对数据库锁表只读(当前窗口不要关掉)

因为要备份数据库,锁表后能保证数据导出时一致

flush tables  with read lock;

当前状态,即当前binlog日志文件名和二进制binlog日志偏移量,后续从库同步时需要用到。

show master status;

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

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

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

| mysql-bin.000001 |     1336 |              |                  |

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

1 row in set (0.00 sec)

6.导出数据库备份

打开新的窗口,导出数据库数据,如果数据很大(100G+),并且允许停机,可以停库直接打包数据文件迁移

mysqldump  -uroot -p'123456' -A -B|gzip>/home/tuwei/new.sql.gz

-A表示备份所有库 -B表示增加use DBdrop等(导库时会直接覆盖原有的)

7.  解锁主库

解锁主库,恢复可写

 mysql> unlock table;

Query OK, 0 rows affected (0.00 sec)

8. 从库执行操作

设置server-id值并关闭binlog参数

这里将从库server-id值设为2log-bin注释掉,注意要在mysqld模块里设置

有两种情况需要打开binlog

1.    级联同步A->B->C中间的B就要开启

2.   从库做数据库备份,数据库备份需要全备及binlog

设置完后重启数据库

9.  导入数据库到从库

将主库上备份的数据库文件传送到从库上进行导入,可以利用scpsftp等命令进行传送。

解压数据库文件

gzip -d new.sql.gz

导入数据库

mysql -uroot -p'123456' <new.sql

10.   配置从库同步参数

可以不用登陆数据库里面进行操作,快速执行change master语句(适合脚本里操作)

cat |mysql -uroot -p'123456' <<EOF

> CHANGE MASTER TO

> MASTER_HOST='192.168.132.10',

> MASTER_PORT=3306,

> MASTER_USER='rep',

> MASTER_PASSWORD='rep99',

> MASTER_LOG_FILE='mysql-bin.000001',

> MASTER_LOG_POS=1336;

> EOF

 

11. 启动从库同步开关

slave start;

然后查看从库状态

show slave statusG;

查看关键的三点

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

Seconds_Behind_Master: 0

表示同步完成


以上是关于MySql主从同步的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL管理之主从同步管理

mysql1.6(主从同步,数据读写分离,mysql优化)

MySQL主从同步实验

MySQL的3节点主从同步复制方案

mysql主从同步

MySQL的3节点主从同步复制方案