红联Linux门户
Linux帮助

MySQL数据复制

发布时间:2016-08-29 14:57:11来源:linux网站作者:猫步旅人
MySQL支持两种数据复制的方式,基于行的复制和基于语句的复制。基于语句的复制也称为逻辑复制,在3.23版本中就存在,基于行的复制是在5.1版本中才被加进来的。这两种复制方式都是通过在主库上记录二进制日志,在备库重放日志的方式来实现异步的数据复制。
这种方式,会造成在同一时间点主库与备库数据可能不一致,并且无法保证主备之间的延迟。
 
数据复制的工作方式
在主库上把数据更改记录到二进制日志中(binary log),这些记录被称为二进制日志事件。
备库将主库上的日志复制到自己的中继日志(relay log)。
备库读取中继日志中的事件,将其重放到备库数据之中。
MySQL数据复制
主库记录二进制日志。在MySQL中首先需要打开二进制日志记录功能,通过在MySQL命令行中查看:
show variables like 'log%';
查看 log_bin 是 OFF 还是 ON ,即可知道是否打开。
在每次准备提交事务更新数据之前,主库将数据更新的事件记录到二进制日志当中,MySQL是按照事务提交的顺序而非每条语句执行的顺序来记录二进制日志的。
备库首先启动一个IO工作线程,与主库建立一个TCP/IP连接,然后在主库上启动一个特殊的二进制转储线程,读取主库上的二进制日志。备库将主库上的二进制日志复制到本地中继日志中。
备库上的SQL线程,从中继日志中读取时间并在备库上执行,从而实现备库数据的更新。
PS:在主库上并发运行的查询在备库上只能串行化执行,因为备库上只有一个SQL线程来重放中继日志中的事件,这也是很多工作负载的性能瓶颈所在。
 
MYSQL 的服务器复制配置 – 实验
在虚拟机中模拟实验。
操作系统:ubuntu-16.04-server-amd64.iso
安装好虚拟机之后,如果不想去创建本地软件仓库,直接使用ISO镜像也能很快的找到MySQL等一系列的安装包。具体操作方式如下:
1.在虚拟机设置中,将安装的镜像文件挂载
2.一般挂载后,对应的/dev/sr*下就会有一个对应的文件就是你所挂载的镜像
3.mount /dev/sr0 /media/cdrom,将镜像挂载到/media/cdrom中,进入该目录,所有的安装包都在pool文件夹中,找到对应的安装包,dpkg -i *即可,如果出现缺少依赖造成安装失败,找到依赖的安装包,安装好后再次安装MySQL即可。
主要分为以下几步:
1.在每台服务器上创建复制账户
2.配置主库和备库
3.通知备库连接到主库并从主库复制数据
 
创建复制账号
备库运行的I/O线程会建立一个到主库的TCP/IP连接,这意味着必须在主库创建一个用户,并赋予其合适的权限,备库I/O线程以该用户名连接到主库并读取二进制日志。
 GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.*
 to repl@'192.168.0.*' IDENTIFIED BY 'p4ssword';
主库和备库都创建该账户,该账户是一个特权账号,不能执行 select或者修改数据,但是能够从二进制日志中获取一些信息。
 
配置主库和备库
通过以上方法安装好MySQL之后,发现MySQL的配置文件在/etc/mysql/中,打开my.cnf如下所示:
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
包含另外两个吗,目录中的配置文件,在配置时,只需要在 /etc/mysql/mysql.conf.d/mysqld.cnf 配置即可,将log-bin 和 server_id 的配置注释去掉,修改成如下配置:
log_bin = mysql-bin
server_id = 10
此处我们使用10作为服务器ID,一般可以使用服务器IP地址的后8为作为服务器ID,但是前提是IP不能改变,且保证唯一。重启MySQL,使配置生效。
/etc/init.d/mysql restart
MySQL数据复制
在备库的配置文件中需要增加类似的配置
log-bin             = mysql-bin
server_id           = 2
relay_log           = /var/log/mysql/mysql-relay-bin
log_slave_updates   = 1
read_only           = 1
relay_log: 制定中继日志的位置和命名
log_slave_updates:允许备库将其重放的事件也记录到自身的二进制日志中
 
启动复制
这一步是告诉备库如何连接到主库并重放二进制日志。此处不要修改my.cnf配置文件,直接使用change master to语句,并且允许以后指定向别的主库时无须重启备库。
change master to master_host='主库的IP',
master_user='repl',
master_password='p4wword',
master_log_file='mysql-bin.000001',
master_log_pos=0;
master_log_pos为0,表示的是日志的开头,并不一定是日志的最开始的位置,可以通过在主库中使用show master status查看 position的位置。
在启动复制之前查看slave status
show slave status
Slave_IO_State:
Slave_IO_Running: No
Slave_SQL_Running: No
这三列显示当前备库复制尚未运行。现在启动复制
start slave;
再查看状态show slave status
Slave_IO_State: connecting to master
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
Last_IO_Errno: 2003
Last_IO_Error: error connecting to master ‘repl@192.168.192.131:3306’ -retry-time
上述表明备库在连接主库时发生异常,错误码为2003,这个问题一般主要有几种原因:
a. 网络不通(是否打开防火墙)
b. 复制的用户密码不对
c. 指定的 master_port 端口不对,不是默认的3306
d. master 上的 mysql-bin.XXXXXX 文件被误删或者不存在
e. 主库磁盘满了。
经过排查,发现主备机防火墙都关闭了,然后从备机上连接主机器的MySQL的时候,被拒绝了,ssh服务是能够跳转过去的,所以不是因为网络不通,是因为MySQL主库的设置问题,在配置文件中,bind_address这个配置参数配置的是 127.0.0.1,不允许其他机器访问MySQL数据库,将这个参数改成主机的IP地址即可。
PS:如果希望外部机器能够以 root 用户访问MySQL,需要设置权限。
grant all privileges on *.* to root@'%' identified by 'XXXXXX' with grant option;
也可以用这种方法建立新用户。
解决上述问题之后,先停止之前启动的复制进程,在启动复制
stop slave;
start slave;
查看状态如下
Slave_IO_State: Waiting for master to send event
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
说明已经成功启动复制。
在备库上查看进程列表
show processlist
MySQL数据复制
在备库上可以看到两个线程,一个是I/O线程,一个是SQL线程。
 
实验效果
在主库的userinfo数据库中user表中查询数据如下:
select * from user;
+----+------+---------------------+------+
| id | age  | birth               | name |
+----+------+---------------------+------+
|  1 |   23 | 1994-12-27 00:00:00 | Tom     |
+----+------+---------------------+------+
在丛库userinfo数据库中user表中查询数据
select * from user;
+----+------+---------------------+------+
| id | age  | birth               | name |
+----+------+---------------------+------+
|  1 |   23 | 1994-12-27 00:00:00 | Tom  |
+----+------+---------------------+------+
此时两个数据库中的数据时相同的,在主库中插入数据
insert into user(age, birth, name) values(25, '1991-01-01', 'Allice');
在丛库中查看
select * from user;
+----+------+---------------------+--------+
| id | age  | birth   | name   |
+----+------+---------------------+--------+
|  1 |   23 | 1994-12-27 00:00:00 | Tom|
|  2 |   25 | 1991-01-01 00:00:00 | Allice |
+----+------+---------------------+--------+
2 rows in set (0.00 sec)
数据复制成功。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/23713.html