(一)主从复制的架构图
1.在主数据库上,每执行一个有可能引起数据库发生改变的的语句,都会记录到二进制日志文件中,并把它们保存为事件。
2.每保存一个事件,我们就通过mysql的服务器3306端口发送给另外一台服务器
3.另外一台服务器把这个事件接收下来,接收的时候先保存到本地的中继日志里面
4.然后,mysql从中继日志文件里读一个事件,然后保存到数据文件
(二)一主多从 半同步架构图
1.Master和Slave-1在同一个机房
2.Slave-2和Slave-3在其它机房
3.半同步指的是Master只保证Slave-1同步完成,Slave-2和Slave-3就不管了,异步完成,只要Slave-1返回信息确认成功了,就可以了
一:Master配置
二:Slave配置
三:错误
四:验证是否主从复制
五:半同步复制
六:基于SSL的复制
七:skip-slave-start参数
八:复制过滤
1.1修改/etc/my.cnf
log_bin=/MySQL_BIN_LOG/master-bin log_bin_index=/MySQL_BIN_LOG/maste-bin.index binlog_format=mixed server-id= 1 innodb_file_per_table=1
1.2创建具有复制权限的用户
GRANTR EPLICATION SLAVE ON *.* TO 'repluser'@'192.168.1.112' IDENTIFIEDBY 'replpass';
2.1修改/etc/my.cnf
2.1.1添加配置(中继日志)
relay_log=/MySQL_BIN_LOG/relay-log relay_log_index=/MySQL_BIN_LOG/relay-log.index server-id= 2
2.1.2关闭二进制日志
#log_bin=/MySQL_BIN_LOG/mysql-bin
2.2连接到主服务器执行复制,并指定相关条件
2.2.1查看主服务器使用的是哪个二进制日志和事件位置
2.2.2执行连接到主服务器,并指定从什么地方复制
mysql>CHANGE MASTER TO MASTER_HOST='192.168.1.111', MASTER_USER='repluser', MASTER_PASSWORD='replpass', MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=342;
2.2.3查看从服务器状态
mysql>SHOW SLAVE STATUS \G
2.3启动从服务器
mysql >START SLAVE; 等价于 mysql >START SLAVE IO_Thread; mysql >START SLAVE SQL_Thread;
2.4再次查看从服务器状态
3.分析以及解决错误
3.1重新到Master服务器修改密码,并执行FLUSH PRIVILEGES;并在Slave重启从服务器STOP SLAVE; START SLAVE;发现问题并没有解决,说明不是密码错误原因导致的
3.2查看selinux的状态,如果是enabled,则执行setenforce 0临时关闭,永久关闭需要编辑/etc/sysconfig/selinux文件进行修改
# /usr/sbin/sestatus -v
3.3在Slave服务器上使用repluser连接主服务器看是否能连接上
确定问题是repluser不能由从服务器连接到主服务器,于是想到是否是防火墙没有打开3306端口的原因,于是关闭防火墙service iptables stop临时关闭,(chkconfig iptables off永久关闭),再次在Slave登录,可以登录了,再次重启从服务器,发现问题解决
4.1在Master上创建caoytDB数据库
CREATE DATABASEcaoytDB;
4.2查看Slave的POSITION是否改变
4.3查看Slave上的数据库
4.4把从服务器设置为只读,但对于SUPER权限用户不生效
mysql>SET GLOBAL read_only=1;
4.5在主服务器上某一个事物已经提交了,事务提交以后,相关的二进制日志事件应该写到二进制日志文件中,但是二进制日志有缓存区,那也就意味着,事务提交以后,可能有些事件依然在缓冲区里,还没有写到二进制日志里面去,万一这个时候,主服务器奔溃了,从服务器上,就不能得到相关的事件,也就意味着跟这个事务相关的某些操作还没有复制过来,因为它没有保存到二进制日志当中,二进制没有,那么中继日志就没有,中继日志没有,那么这个事件就不能完整的执行,所以需要在主服务器上设置只要事务提交,就必须立即写到二进制日志当中,不要在缓冲区做任何停留,这样就降低了主从不一致的可能性
sync_binlog=1
5.1要实现半同步需要在Master和Slave各自安装一个插件,这个插件是由Google提供的,在数据库的安装目录的lib/plugin/目录下
5.2 Master上安装rpl_semi_sync_master
mysql>INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
mysql>SET GLOBAL rpl_semi_sync_master_enabled=1;
5.3 Slave安装rpl_semi_sync_slave
mysql>INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql>SET GLOBAL rpl_semi_sync_slave_enabled=1;
5.4 查看Master服务器的状态
mysql> SHOW GLOBAL STATUS LIKE 'rpl%';
5.5当Rpl_semi_sync_master_clients为0的时候,需要重启Slave的IO_THREAD;
mysql> STOPSLAVE IO_THREAD;
mysql> STARTSLAVE IO_THREAD;
6.1启动Master/Slave的SSL功能
在【mysqld】节点下添加ssl
6.2将Master服务器自己做成CA服务器
# cd /etc/pki/CA/ # (umask 077;openssl genrsa -out private/cakey.pem 2048)
openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650
# touch index.txt # echo 01 > serial
6.3为Master创建证书申请并由CA服务器签发证书
# mkdir /usr/local/mysql/ssl # cd /usr/local/mysql/ssl/ # (umask 077;openssl genrsa -out master.key 2048)
# openssl req -new -key master.key -out master.csr -days 3650
# openssl ca -in master.csr -out master.crt -days 3650
说明:图片中标记的地方说要小写,其实大小写都行
6.4为Slave服务器创建证书申请
# mkdir /usr/local/mysql/ssl # cd /usr/local/mysql/ssl # (umask 077;openssl genrsa -out slave.key 2048)
# openssl req -new -key slave.key -out slave.csr -days 3650
6.5为Slave服务器签署证书
【Slave】
# scp slave.csr root@'Master IP':/tmp/
【Master】
# openssl ca -in /tmp/slave.csr -out /tmp/slave.crt -days 3650 # scp /tmp/slave.crt root@'Slave IP':/usr/local/mysql/ssl/
6.6将CA证书拷贝到Slave服务器并为Master拷贝一份
# scp /etc/pki/CA/cacert.pem root@'Slave IP':/usr/local/mysql/ssl/ # cp /etc/pki/CA/cacert.pem /usr/local/mysql/ssl/
6.7修改Master与Slave服务器证书属主、属组为"mysql"用户
# chown -R mysql.mysql /usr/local/mysql/ssl
【Master】
【Slave】
6.8在Master与Slave服务器修改主配置文件开启SSL加密功能
【Master】
ssl #开启SSL功能 ssl_ca = /usr/local/mysql/ssl/cacert.pem #指定CA文件位置 ssl_cert = /usr/local/mysql/ssl/master.crt #指定证书文件位置 ssl_key = /usr/local/mysql/ssl/master.key #指定密钥所在位置
【Slave】
ssl_ca = /usr/local/mysql/ssl/cacert.pem ssl_cert = /usr/local/mysql/ssl/slave.crt ssl_key = /usr/local/mysql/ssl/slave.key
6.9在Master服务器查看SSL加密是否开启;然后创建授权一个基于密钥认证的用户
mysql>GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'192.168.1.112' IDENTIFIED BY'replpass' REQUIRE SSL;
6.10测试使用加密用户指定密钥连接Master服务器
# mysql -urepluser -preplpass -h 192.168.1.111 --ssl-ca=/usr/local/mysql/ssl/cacert.pem --ssl-cert=/usr/local/mysql/ssl/slave.crt --ssl-key=/usr/local/mysql/ssl/slave.key
6.11连接Master服务器
CHANGE MASTER TO MASTER_HOST='192.168.1.111', MASTER_USER='repluser', MASTER_PASSWORD='replpass', MASTER_LOG_FILE='master-bin.000006', MASTER_LOG_POS=107, MASTER_SSL=1, MASTER_SSL_CA='/usr/local/mysql/ssl/cacert.pem', MASTER_SSL_CERT='/usr/local/mysql/ssl/slave.crt', MASTER_SSL_KEY='/usr/local/mysql/ssl/slave.key';
7.从服务器启动起来以后会自动的启动从服务器线程连接到主服务器,万一从服务器奔溃了,下次一启动,它就会自动连接主服务器去复制数据,而有些数据是希望在从服务器上是想跳过去的,因为在主服务器上出现了误操作,比如DROP TABLE,所以不应该让从服务器一启动就去连接主服务器开始复制数据
skip-slave-start
8.1在Master端和Slave分别提供了两类服务器变量用于定义实现复制过滤功能
8.2【Master】
binlog-do-db= #白名单,仅将指定数据库的相关修改操作记录二进制日志 binlog-ignore-db= #黑名单,忽略哪些
虽然有这样的定义,但是不建议在Master端使用,这样会导致Master和Slave两端的二进制日志不一致
8.3【Slave】
replicate-do-db= #白名单,只复制那个数据库的事件 replicate-ignore-db= #黑名单,忽略哪些数据库的事件 replicate-do-table= #仅复制哪些表 replicate-do-table= #忽略哪些表 %和_ (百分号和下划线) replicate-wild-do-table= #通配符的方式定义哪些表复制 replicate-wild-ignore-table= #通配符的方式定义哪些表不复制