主从复制(过程)原理:
1)从库执行change master to 命令(主库的连接信息+复制的七点)
2)从库会将以上信息,记录到master.info文件中
3)从库开启start slave命令,立即开启io_thread和sql_thread
4))从库io_thread读取master.info文件中的信息,获取到IP,port,user,passwd以及binlog的位置信息
5)从库io_thread请求连接主库,主库专门提供一个dump_thread,负责io交互
6)从库io_thread根据binlog的位置信息(mysql-binlog.xxxx,4444)请求新的binlog
7)主库通过dump_thread将最新的binlog通过网络发送给从库的io_thread
8)io_thread接收到的新binlog日志,存储到tcp、ip缓存立即返回ack给主库,并更新master.info
9)sql_thread读取realy.info中的信息,获取到上次已经应用过的relaylog的位置信息
10)sql_thread读取realy.info中的信息,获取到上次已经使用过的relaylog位置信息
11)sql_thread会按照上次位置点回放最新的realylog,再次更新relay.info信息
补充说明:
一旦主从复制构建成功,主库中发生了新的变化,都会通过dump_thread发送信号到从库的io_thread,增强主从复制的实时性
主从配置
#传统模式
sed -i ‘/^SELINUX=/cSELINUX=disabled’ /etc/selinux/config
groupadd mysql
useradd -r -g mysql -s /bin/false mysql
mkdir -p /data/mysql/data
mkdir -p /data/mysql/logs
mkdir -p /data/mysql/tmp
chown -R mysql:mysql /usr/local/mysql
chown -R mysql:mysql /data/mysql/
#配置文件
master ~ /etc/my.cnf
[mysqld]
port = 3306
datadir = /data/mysql/data
tmpdir = /data/mysql/tmp
log_error = /data/mysql/data/error.log
pid_file = /data/mysql/mysql.pid
log_bin = /data/mysql/logs/logbin
log_bin_index = /data/mysql/logs/logbin.index
socket = /tmp/mysql.sock
innodb_buffer_pool_size = 1G
wait_timeout=28800
interactive_timeout=28800
max_connections = 2000
expire_logs_days = 5
log_slave_updates=1
character_set_server=utf8mb4
server-id=10
slave1 ~ /etc/my.cnf
[mysqld]
port = 3306
datadir = /data/mysql/data
tmpdir = /data/mysql/tmp
log_error = /data/mysql/data/error.log
pid_file = /data/mysql/mysql.pid
log_bin = /data/mysql/logs/logbin
log_bin_index = /data/mysql/logs/logbin.index
socket = /tmp/mysql.sock
innodb_buffer_pool_size = 1G
wait_timeout=28800
interactive_timeout=28800
max_connections = 2000
expire_logs_days = 5
log_slave_updates=1
character_set_server=utf8mb4
server-id=20
slave2 ~ /etc/my.cnf
[mysqld]
port = 3306
datadir = /data/mysql/data
tmpdir = /data/mysql/tmp
log_error = /data/mysql/data/error.log
pid_file = /data/mysql/mysql.pid
log_bin = /data/mysql/logs/logbin
log_bin_index = /data/mysql/logs/logbin.index
socket = /tmp/mysql.sock
innodb_buffer_pool_size = 1G
wait_timeout=28800
interactive_timeout=28800
max_connections = 2000
expire_logs_days = 5
log_slave_updates=1
character_set_server=utf8mb4
server-id=30
初始化
cd /usr/local/mysql
./bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/data
#设置MYSQL系统服务
chmod +x /etc/init.d/mysqld
chkconfig --add mysqld
启动MYSQLD
service mysqld restart
检查 MySQL 服务是否启动成功
netstat -ntlp | grep 3306
if [ $? -ne 0 ];then
echo ‘MySQL Boot failure!!!’
exit
else
echo ‘====================================’
echo ‘start MySQL successfully!’
fi
将 MYSQL 的 BIN ⽬录加⼊ PATH 环境变量
cat >> /etc/profile << EOF
export PATH=$PATH:/usr/local/mysql/bin
EOF
source /etc/profile
主从搭建
mysql> create user ‘slave’@‘%’ identified by ‘123’;
mysql> grant replication slave on . to ‘slave’@‘%’;
mysql> flush privileges;
mysql> change master to master_host=‘172.72.6.2’,master_user=‘slave’, master_password=‘123’, master_port=3306, master_log_file='logbin.000003’, master_log_pos=1002;
innobackupex --socket=/tmp/8375.sock /data/dbbak
innobackupex --socket=/tmp/8375.sock --apply-log /data/dbbak/2018-12-25_11-10-42/
参数介绍:
1)连接信息
master_log_file master正在写的二进制文件名
master_log_pos master正在写的二进制位置
从库relay应用信息(relay.info):
排错
io connecting:一般因网络问题导致,关闭防火墙后变成io:no
查看告警日志,定位故障
修改server_id,重启数据库及slave线程
随便修改uuid
当网络环境没问题,发生此问题为从库io线程的sn和主库的sn没对应上所导致的
最后发现确实是sn没对上导致,但是是因为change语句中冒号出错导致
#参数解析
从库线程运行状态(排错用)
Slave_IO_Running: Yes io线程状态
Slave_SQL_Running: Yes sql线程状态
Last_IO_Errno: 0 io错误数
Last_IO_Error: 显示io报错内容
Last_SQL_Errno: 0 sql线程报错次数
Last_SQL_Error: sql线程错误内容
Last_IO_Error_Timestamp: 上次io线程出错时间
Last_SQL_Error_Timestamp: 上次sql线程出错时间
过滤复制有信息
Replicate_Do_DB: 指定要复制的DB
Replicate_Ignore_DB: 指定不复制的DB
Replicate_Do_Table: 指定复制表
Replicate_Ignore_Table: 指定不复制的表
Skip_Counter: 0 跳过的事务数
Seconds_Behind_Master: 0 主从延时时间,单位s
延时从库
SQL_Delay: 0 从库上指定的sql延时执行时间
SQL_Remaining_Delay: NULL
Gtid复制状态信息
Retrieved_Gtid_Set: 从库接收到的事务
Executed_Gtid_Set: 从库已执行的事务
Auto_Position: 0 是否打开gtid
故障分析
从库:
1)Io 线程故障 连接主库:connecting
网络连接信息变更,防火墙,连接数方面排查
2)请求binlog 没开/binlog损坏,不存在
主库reset master处理
从库:stop slave
CHANGE MASTER TO MASTER_HOST=‘172.72.6.2’,MASTER_USER=‘slave’, MASTER_PASSWORD=‘123’,MASTER_LOG_FILE=‘logbin.000003’, master_log_pos=1002;
3)sql线程故障
Relay-log损坏/约束冲突
暴力解决:
Stop slave/set global sql_slave_counter=1;跳过这个事务/start slave
方法二:
/etc/my.cnf
Slave-skip-errors = 1032,1062,1007
1007:对象已存在
1032:无法执行dml
1062:主键冲突,约束冲突
注意:以上操作均有风险,可造成数据不一致、最稳妥的方法是重构主从
故障避免
1)从库只读:read_only
2) 使用读写分离中间件:atlas,mycat,proxysql