一、MySQL主从复制的原理
1、mysql的复制过程:每执行一个写操作,它都会往自己的数据库中存一份,与此同时这个写操作也会存储在二进制日志文件中一份,并且把它们保存为事件,所以在这个数据库上,前端数据每执行一个写操作或者有可能引起修改的操作,都会保存一个事件,我们就把这个事件通过mysql服务器3306端口发送给另外一台服务器,另外一台服务器把这个事件接收下来,接受下来以后先保存在本地的日志文件中,而后从这个日志文件中一次读一个事件并且在本地执行一下,然后保存在数据库里面,这个过程就叫mysql的复制。如下图所示:
2、在这样一个模型当中,我们把允许来自外部操作记录下来记录到数据库中,并保存至二进制文件中的这台服务器叫做复制架构中主服务器(master)。主服务器中的日志文件叫二进制日志。
3、slave:从服务器中的日志文件是从主服务器中复制过来的,叫做中继日志,主要目的是复制下来,再在本地用一遍,相当于产生一个接力的过程。
4、主服务器允许并行执行,主服务器上若有多个CPU,它允许多个服务器并行执行。但是我们写到二进制文件中,只能一条一条的写,从服务器只能一条一条的执行。从服务器默认情况下也只能是一个进程,读一条执行一个,所以从服务器慢于主服务器。
二、MySQL主从复制实现的过程
1、主服务器的配置过程
1)添加系统用户并修改权限
2)下载mysql软件包解压后并创建链接
[root@node1 ~]# lftp 172.16.0.1/pub/Sources/mysql-5.5/ 下载mysql-5.5包
cd ok, cwd=/pub/Sources/mysql-5.5
lftp 172.16.0.1:/pub/Sources/mysql-5.5> ls
...
lftp 172.16.0.1:/pub/Sources/mysql-5.5> get mysql-5.5.28-linux2.6-i686.tar.gz
179907710 bytes transferred in 25 seconds (6.89M/s)
lftp 172.16.0.1:/pub/Sources/mysql-5.5> bye
3)初始化数据库并复制文件
4)修改配置文件并复制到从服务器
[root@node1 mysql]# vim /etc/my.cnf 修改配置文件内容如下:
[root@node1 ~]# scp /etc/my.cnf node2:/etc/ 把配置文件复制到从服务器
my.cnf 100% 4746
5)启动mysql,测试能否连接到mysql
[root@node1 mysql]# vim /etc/profile.d/mysql.sh 为了以下命令用起来方便,编辑配置文件
[root@node1 mysql]# . /etc/profile.d/mysql.sh 执行一下脚本
6)复制mysql软件包到从服务器,然后连接到mysql创建用户
2、配置从服务器
1)创建用户修改权限并解压软件包连接到数据库
[root@node2 ~]# mkdir -pv /mydata/data
mkdir: created directory `/mydata'
mkdir: created directory `/mydata/data'
[root@node2 ~]# useradd -r mysql
[root@node2 ~]# chown -R mysql.mysql /mydata/data/
[root@node2 ~]# tar xf mysql-5.5.28-linux2.6-i686.tar.gz -C /usr/local/
[root@node2 ~]# cd /usr/local/
[root@node2 local]# ls
bin etc games include lib libexec mysql-5.5.28-linux2.6-i686 sbin share src
[root@node2 local]# ln -sv mysql-5.5.28-linux2.6-i686 mysql
create symbolic link `mysql' to `mysql-5.5.28-linux2.6-i686'
[root@node2 local]# cd mysql
[root@node2 mysql]# chown -R root.mysql 改变属主属组
[root@node2 mysql]# ll
[root@node2 mysql]# scripts/mysql_install_db --user=mysql --datadir=/mydata/data/ 初始化数据库
2)复制脚本内容并修改所需配置文件
[root@node2 mysql]# vim /etc/my.cnf 修改配置文件内容如下:
3)启动mysql
[root@node2 mysql]# service mysqld start
Starting MySQL.... [ OK ]
[root@node2 mysql]# vim /etc/profile.d/mysql.sh 编辑配置文件的内容如下:
[root@node2 mysql]# . !$ 读一下上面的脚本
. /etc/profile.d/mysql.sh
4)在主节点上即HA1上查看从哪个节点开始复制
[root@node1 ~]# mysql
5)修改主服务器的一些属性
6)查看从服务器启动前后的状态
mysql> start slave; 启动从服务器
Query OK, 0 rows affected (0.00 sec)
到这里主从复制架构依然完成。
3、主服务器上创建数据,从服务器上是否会出现
1)在主服务器连接到数据库并创建数据库
2)查看从服务器的状态,并查看数据库
4)让从服务器变成只读的
[root@node2 mysql]# vim /etc/my.cnf 修改配置文件,让read_only = ON永久有效
5)重启服务器,查看read_only是否启动
(read-only = YES 对具有SUPER权限的用户不生效)
mysql> show slave status\G 查看复制线程能否自动运行
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.66.6
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000001
Read_Master_Log_Pos: 430
Relay_Log_File: relay-log.000004
Relay_Log_Pos: 254
Relay_Master_Log_File: master-bin.000001
Slave_IO_Running: Yes 当使用change master to之后
Slave_SQL_Running: Yes 就算重启服务器复制线程也会自动启动
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 430
Relay_Log_Space: 404
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
1 row in set (0.00 sec)
6)查看/mydata/data/下的文件
[root@node2 mysql]# cd /mydata/data/ 切换到/mydata/data目录下
[root@node2 data]# ls 查看文件
ibdata1 master-bin.000001 master-bin.index node2.magedu.com.pid relay-log.index
ib_logfile0 master-bin.000002 master.info performance_schema relay-log.info
ib_logfile1 master-bin.000003 mysql relay-log.000003 test
magedudb master-bin.000004 node2.magedu.com.err relay-log.000004
[root@node2 data]# file master.info 查看master.info
master.info: ASCII text 纯ASCII码的文件
[root@node2 data]# file relay-log.info
relay-log.info: ASCII text 纯ASCII码的文件
[root@node2 data]# cat relay-log.info 查看一下relay-log.info里面的内容
./relay-log.000004 当前使用的relay-log文件事件位置
254
master-bin.000001 正在读取的主服务器上的二进制文件事件位置
430
【read-only = YES 只读,在从服务器上,但对具有SUPER权限的用户不生效;所以管理员照样能写;
sync-binlog = ON 在主服务器上设定,用于事务安全; 】
7、有没有这样一个问题呢?在主服务器上某个事物已经提交了,而有些事务仍然在缓冲区内,万一这个时候主服务器崩溃了,从服务器上能否得到复件?如何降低主从不一致的可能性呢?应该配置主服务器同步二进制日志。
配置主服务器同步二进制日志
mysql> show global variables like '%log%'; 查看跟日志相关的内容
8、我们的从服务器启动起来后会自动连接主服务器,如果主服务器崩溃了,从服务器启动后还会自动连接到主服务器复制二进制日志,一般来讲不应该让从服务器从复制线程自动启动,怎么让从服务器不会自动启动?
1)首先连接到mysql查看从服务器相关的内容
mysql>show global variables like '%slave%';
2)如果想彻底的重新定义mysql从服务器的话,执行mysql服务器线程了可以手动停掉;具体过程如下:
mysql> stop slave IO_THREAD; 停掉线程服务
mysql> show slave status/G 查看状态
补充:也可以一个一个的停掉线程服务
mysql> start slave IO_THREAD;
mysql> show slave status/G
mysql> start slave SQL_THREAD;
mysql> show slave status/G
mysql> \q
所有跟从服务器相关的内容都会保存在数据库服务的错误日志当中
[root@node2 mysql]# tail /mydata/data/node2.magedu.com.err
三、如何实现mysql的半同步复制
1、在主服务器和从服务器上各自安装一个插件,这个插件是google提供的。
[root@node2 data]# cd /usr/local/mysql 切换到mysql路径下
[root@node2 mysql]# ls
[root@node2 mysql]# cd lib/plugin
(semisync_master.so是半同步的主服务器上安装的插件,semisync_slave.so是半同步的从服务器上安装的插件)
1)主服务器上的配置:
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; 装载模块
rpl_semi_sync_master是模块(插件)名称、semisync_master.so是模块文件名
mysql> show global variables like '%rpl%';
2)从服务器上的配置:
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; 装载模块
mysql> show variables like 'rpl%'; 查看rpl开头的
2、启用rpl_semi_sync_master_enabled模块
1)主服务器上:
mysql> set global rpl_semi_sync_master_enabled=1; 启用rpl_semi_sync_master_enabled
mysql> show global varitables like '%rpl%'; rpl_semi_sync_master_enabled 显示为ON了
2)从服务器上:
mysql> set global rpl_semi_sync_master_enabled=1; 启用rpl_semi_sync_master_enabled
mysql> show global varitables like '%rpl%'; rpl_semi_sync_master_enabled 显示为ON了
mysql> show global status like 'rpl%'; 查看全局状态变量
mysql> stop slave IO_THREAD; 停掉IO线程
mysql> start slave IO_THREAD; 启用IO线程
mysql> show global status like 'rpl%';
到此,半同步复制就结束了。