mysql's replication
Mysql的 Replication 是一个异步的复制过程,从一个 Mysql Master复制到另一个 Mysql Slave。在 Master 与 Slave 之间的实现整个复制过程主要由三个线程来完成,其中两个线程( thread )( SQL_Thread和IO_Thread )在 Slave 端,另外一个线程(IO_Tread )在 Master 端。
要实现 MySQL 的 Replication ,首先必须打开 Master 端的Binary Log(mysql-bin.xxxxxx)功能,否则无法实现。因为整个复制过程实际上就是Slave从Master端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。打开 MySQL 的 Binary Log 可以通过在启动 MySQL Server 的过程中使用“―log-bin”参数选项,或者在 my.cnf 配置文件中的 mysqld 参数组([mysqld]标识后的参数部分)增加“log-bin”参数项。
MySQL 复制的基本过程如下:
1.
Slave 上面的IO线程连接上 Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
2.
Master 接收到来自 Slave 的 IO 线程的请求后,通过负责复制的 IO 线程根据请求信息读取指定日志指定位置之后的日志信息,返回给 Slave 端的 IO 线程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息在 Master 端的 Binary Log 文件的名称以及在 Binary Log 中的位置;
3.
Slave 的 IO 线程接收到信息后,将接收到的日志内容依次写入到 Slave 端的Relay Log文件(mysql-relay-bin.xxxxxx)的最末端,并将读取到的Master端的bin-log的文件名和位置记录到master- info文件中,以便在下一次读取的时候能够清楚的高速Master“我需要从某个bin-log的哪个位置开始往后的日志内容,请发给我”
4.
Slave 的 SQL 线程检测到 Relay Log 中新增加了内容后,会马上解析该 Log 文件中的内容成为在 Master 端真实执行时候的那些可执行的 Query 语句,并在自身执行这些Query。这样,实际上就是在 Master 端和 Slave 端执行了同样的 Query,所以两端的数据是完全一样的。
实验过程
虚拟机版本 |
Rhel6.4 |
32位 |
MySQL版本 |
mysql-5.6.10 |
linux-glibc2.5-i686.tar.gz |
MySQL-5.6主从复制
两个HA节点:
MASTER |
SLAVE |
HA1:172.16.111.12 |
HA2:172.16.111.13 |
node1.doubao.com |
node2.doubao.com |
(基本是相同的设置,做node1的演示)
关掉selinux
# setenforce 0
或者
# vim /etc/selinux/config
##修改
SELINUX=permissive
配置主机名,保持主机名一致
# hostname node1.doubao.com
# vim /etc/sysconfig/network
##修改如下:
HOSTNAME=node1.doubao.com #当然HA2上要改为node2
:wq #保存退出
主机名称解析:
# vim /etc/hosts
##添加如下内容
172.16.111.6node1.doubao.com node1
172.16.111.7node2.doubao.com node2
双机互信:
#ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' 生成密钥
#ssh-copy-id -i .ssh/id_rsa.pub root@node2 ##将公钥文件发送到HA2上边
时间同步:
# hwclock �Cs #由于笔者的实验环境特殊,暂用此方法,也可以使用ntpdate的方法进行更新
配置好yum
http://407711169.blog.51cto.com/6616996/1179601 ## 此处前边是一个配置yum的例子
# mkdir /mydata/data -pv # groupadd -r -g 3306 mysql # useradd -r -g 3306 mysql # chown -R mysql.mysql /mydata/data/ # tar xf mysql-5.6.10-linux-glibc2.5-i686.tar.gz -C /usr/local # ln -sv mysql-5.6.10-linux-glibc2.5-i686 mysql # chown -R root.mysql ./* # scripts/mysql_install_db --user=mysql --datadir=/mydata/data # cp support-files/mysql.server /etc/rc.d/init.d/mysqld
然后这个时候现在主节点(node1 | MASTER)上执行
# vim my.cnf#注意这个my.cnf在/usr/local/mysql下 #添加如下内容 datadir = /mydata/data innodb_file_per_table = ON server-id = 1 socket =/tmp/mysql.sock :wq
保存退出后,将mysql的快捷路径输出下,便于以后打开mysql
# vim /etc/profile.d/mysql.sh ##添加如下内容 export PATH=$PATH:/usr/local/mysql/bin ##完成后退出,执行下此脚本。 # . /etc/profile.d/mysql.sh
然后命令提示符下打开mysql测试下链接
为从服务器添加用户及复制权限:
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'172.16.%.%' IDENTIFIED BY 'replpass'; Query OK, 0 rows affected (0.00 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)
从服务器配置
# vim my.cnf
##添加如下内容
datadir = /mydata/data server-id = 11 socket = /tmp/mysql.sock relay-log = relay-log relay-log-index =relay-log.index
保存退出
保存退出后,将mysql的快捷路径输出下,便于以后打开mysql
# vim /etc/profile.d/mysql.sh ##添加如下内容 export PATH=$PATH:/usr/local/mysql/bin ##完成后退出,执行下此脚本。 # . /etc/profile.d/mysql.sh
主上观看
从上
在主上创建个数据库测试下。
到从上,刚开始是同步不了的,因为IO和SQL的THREAD还没开启,
这样,主从的模型就完成了。
------------------------完成
(主上创建数据库,从上观看)
为了让从mysql只做读操作,
首先观察从中的mysql的read-only变量,为OFF,为了使其永久生效需要编辑其配置文件:
退出后重启下Mysql服务。然后在进去到mysql中查看其,已经打开(为on)。然后在Mysql中进行下创建数据库的操作(即写操作),就能发现其已经不能执行
MySQL-5.6半同步复制
PS:这里沿用上边的实验数据,从而进行进一步的修改
设置半同步步骤:
在Master和Slave的mysql命令行运行如下代码: 在Master和Slave的my.cnf中编辑: # On Master [mysqld] rpl_semi_sync_master_enabled=1##永久生效 rpl_semi_sync_master_timeout=1000 # 1 second # On Slave [mysqld] rpl_semi_sync_slave_enabled=1
然后重启Mysql
主服务器
从服务器
重启下IO线程才能正式启动
主上看
# 也可通过设置全局变量的方式来设置,如下: set global rpl_semi_sync_master_enabled=1 # 取消加载插件 mysql> UNINSTALL PLUGIN rpl_semi_sync_master; ============================================== # 查看从服务器上的semi_sync是否开启: mysql> SHOW GLOBAL STATUS LIKE 'rpl_semi%'; # 查看主服务器上的semi_sync是否开启,注意clients 变为1 ,证明主从半同步复制连接成功: mysql> SHOW GLOBAL STATUS LIKE 'rpl_semi%';
这样一个半同步复制的mysql服务器就已经搭建好了,大家可以进行实验测试。
MySQL-5.6-GTID多线程复制
主服务中编辑my.cnf文件添加如下内容
datadir = /mydata/data innodb_file_per_table = ON server-id = 1 socket=/tmp/mysql.sock log-bin = master-bin binlog-format=ROW log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=TABLE relay-log-info-repository=TABLE sync-master-info=1 slave-parallel-workers=2 binlog-checksum=CRC32 master-verify-checksum=1 slave-sql-verify-cheksum=1 binlog-rows-query-log_events=1 repo-port=3306 port=3306 report-host=172.16.111.12
# service mysqld restart
从服务器中编辑my.cnf文件添加内容:
datadir = /mydata/data server-id = 11 socket=/tmp/mysql.sock log-bin = master-bin binlog-format=ROW log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=TABLE relay-log-info-repository=TABLE sync-master-info=1 slave-parallel-workers=2 binlog-checksum=CRC32 master-verify-checksum=1 slave-sql-verify-cheksum=1 binlog-rows-query-log_events=1 repo-port=3306 port=3306 report-host=172.16.111.13
重启服务
主上边
然后主上mysql命令中设置
这个时候,GTID多线程复制已经创建好了。当然一台从服务器很难看出来其效果。这里不做具体演示,大家可以自行几个同学一起做下此个实验。
MySQL-5.6-SSL主从复制
PS:主从复制的过程仿照上边来进行,ok后仿照下面来执行SSL的配置
如果是编译安装MySQL,需要加上 --with-openssl 和 --with-vio的安装(这里不做具体演示)
1、自建SSL认证文件
# cd /data/ssl ##创建、签署CA过程 # openssl genrsa 2048 > ca-key.pem#生成密钥 # openssl req -new -x509 -nodes -days 3600 -key ca-key.pem -out ca-cert.pem # openssl req -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem -out server-req.pem # openssl rsa -in server-key.pem -out server-key.pem # openssl x509 -req -in server-req.pem -days 3600 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server- cert.pem # openssl req -newkey rsa:2048 -days 3600 -nodes -keyout client-key.pem -out client-req.pem # openssl rsa -in client-key.pem -out client-key.pem # openssl x509 -req -in client-req.pem -days 3600 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client- cert.pem
最后验证下是否正确,如下则是正确的:
# openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem server-cert.pem: OK client-cert.pem: OK
2、主从数据库配置调整:
编辑主服务器配置/etc/my.cnf 的 [mysqld] 下,加上如下几行,并重启数据库:
ssl ssl-ca = /data/ssl/ca-cert.pem ssl-cert = /data/ssl/server-cert.pem ssl-key = /data/ssl/server-key.pem
复制生成的认证文件到从库服务器/data/ssl下
编辑从库数据库配置/etc/my.cnf 的 [mysqld] 下,加上如下几行,并重启数据库:
ssl ssl-ca = /data/ssl/ca-cert.pem ssl-cert = /data/ssl/client-cert.pem ssl-key = /data/ssl/client-key.pem
登陆到主从数据库上,
mysql> show variables like '%ssl%'; +--------------------+------------------------------------------+ | Variable_name | Value| +--------------------+------------------------------------------+ | have_openssl| YES| | have_ssl| YES| | ssl_ca| /data/newscrets/ca-cert.pem| | ssl_capath|| | ssl_cert| /data/newscrets/server-cert.pem | | ssl_cipher|| | ssl_key| /data/newscrets/server-key.pem| +-------------------+--------------------------------------------+ 7 rows in set (0.00 sec)
看到YES就是成功了,如果看到的是NO或者DISABLE,那么看下验证文件的目录权限和文件权限。确保mysql用户可以读取即可。
3、主从同步
在主库上创建同步帐号:
mysql> GRANT FILE,SELECT,REPLICATION SLAVEON *.* TO 'repluser'@'192.168.1.241' IDENTIFIED BY 'replpass' REQUIRE SSL;
在从库上测试下是否可以成功登陆:
mysql -h192.168.1.154 -urepluser -preplpass -S /tmp/mysql.sock --ssl-ca=/data/ssl/ca-cert.pem --ssl- cert=/data/ssl/client-cert.pem --ssl-key=/data/ssl/client-key.pem
如果没有问题,登陆从库mysql,change master到主库
mysql> change master to master_host='172.16.111.12', master_port=3306, master_user='repluser', master_password='replpass', master_log_file='mysql-bin.000001', master_log_pos=348221, master_ssl=1, #是说开启SSL认证的意思。 master_ssl_ca='/data/ssl/ca-cert.pem', master_ssl_cert='/data/ssl/client-cert.pem', master_ssl_key='/data/ssl/client-key.pem';
这样,基于SSL的主从复制模型就搭建成功了。大家可以进行测试。
基于SSL认证这些内容,个人参考了一些资料。大家觉得不对的地方欢迎指出。