09 :mysql 主从复制
主从复制简介
1、能做什么?
1、预防数据库的物理损坏故障
2、实时备份二进制日志,辅助备份
3、高可用架构和高性能架构
2、基于什么来做的? 二进制日志
3、二进制日志在哪?如何设置位置和命名?
log_bin=/data/mysql/mysql-bin
4、二进制日志记录什么?
events形式记录
DDL DCL 使用语句记录模式
DML 已提交的事务,row方式记录
5、二进制日志格式是怎样的?
binlog_format=row
6、二进制日志如何滚动?
flush logs
7、二进制日志用来干嘛?
可以做即时点恢复
主从复制的必要条件
8、二进制日志的操作命令?
show master status;
show binary logs;
show binlog events in "mysql-bin.000001";
其它一些 参数:
mysqlbinlog --base64-output=decode-rows -vvv --start-position --stop-position -d
------------------------
主从复制原理
1、主从复制构建前提
(1)至少两个mysql实例
(2)主库要开启二进制日志
(3)主库要提供一个专门用作复制用户
(4)从库需要“补课”,通过备份工具实现从库追上主库的数据状态,从这一刻开始由主从复制自动进行实现
(5)从库需要我们告诉它,从“什么时候”开始自动复制(二进制日志文件号+position)
(6)从库还需要我们告诉他,主库IP、port、user、password
2、工作原理(classic replication)
(1)主从复制构建过程中,已经告诉从库关于主库的一些信息,主从复制的起始位置
change master to (IP、prot、user、password、二进制日志文件名、位置号)
从库会自动存放在master.info中。
(2)从IO线程,读取master.info信息,连接到master,问master,有没有比master.info中记录的还要新的(7号文件,340号).
(3)master说:你等一下,我看一下(show master status,7号文件,1040),你要不要。
(4)slave说:我要啊,你给我吧
(5)master,通过dump Thread截取binlog当中新的事件,传送给Slave IO线程。
(6)Slave,io线程接收到主库发过来的新的二进制日志,存储到TCP/IP缓存,立即返回ACK给主库。
(7)将TCP/IP 缓存中数据,最终会被写入到relaylog中,并且更新master.info,将位置号更新到最后一次获取位置(1040)
(8)SQL Thread 读取relay-log.info,找到上次运行过的relaylog的位置点,向后接着运行。
(9)运行完成后,会再次更新relay-log.info信息,以运行过的relay-log会被自动清理。
一次主从复制就完成了。
-------------------------------------------------------------------------------
主从复制搭建过程(Classic Replication 传统的主从复制)
1、准备两个以上的MySQL实例(这里用的多实例)
(1)准备多实例
清除之前多实例的数据
rm -rf /data/3307/data/*
rm -rf /data/3307/mysql*
rm -rf /data/3308/data/*
rm -rf /data/3308/mysql*
rm -rf /data/3309/data/*
rm -rf /data/3309/mysql*
(2)重新初始化数据
mv /etc/my.cnf /etc/my.cnf.bak
初始化数据:
/application/mysql/scripts/mysql_install_db --user=mysql --basedir=/application/mysql --datadir=/data/3307/data/
/application/mysql/scripts/mysql_install_db --user=mysql --basedir=/application/mysql --datadir=/data/3308/data/
/application/mysql/scripts/mysql_install_db --user=mysql --basedir=/application/mysql --datadir=/data/3309/data/
修改目录权限
[root@db01 3307]# touch /data/330{7..9}/mysql.log
[root@db01 3307]# chown -R mysql.mysql /data/330*
启动多实例
mysqld_safe --defaults-file=/data/3307/my.cnf &
mysqld_safe --defaults-file=/data/3308/my.cnf &
mysqld_safe --defaults-file=/data/3309/my.cnf &
[root@db01 3307]# netstat -lnp|grep 330
2、全备主库数据
规划:
3307:master
3308:slave
3307全备:
mysqldump -S /data/3307/mysql.sock -A -R --triggers --master-data=2 --single-transaction >/backup/full3307.sql
3、主库创建复制用户
mysql -S /data/3307/mysql.sock
grant replication slave on *.* to repl@'10.0.0.%' identified by '123';
4、从库恢复数据
mysql -S /data/3308/mysql.sock
set sql_log_bin=0;
source /backup/full3307.sql;
set sql_log_bin=1;
5、从库开启主从复制
(1)找到复制起点
/backup/full3307.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=120;
(2)开始自己复制
mysql -S /data/3308/mysql.sock
help change master to
CHANGE MASTER TO
MASTER_HOST='10.0.0.181',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3307,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=120,
MASTER_CONNECT_RETRY=10;
以上信息会被存储到master.info信息中
[root@mysql181 data]# ls
auto.cnf mysql performance_schema test xxxxxxxxxx
ibdata1 mysql181.pid relay-log.info XUJIN xxxxxxxxxxsadsadsad
ib_logfile0 mysql181-relay-bin.000004 shiwutest xujintest
ib_logfile1 mysql181-relay-bin.000005 shiwutest12222 xujintest111
master.info mysql181-relay-bin.index shiwutestasdsad xujintest111sadsad
[root@mysql181 data]# cat master.info
23
mysql-bin.000003
621
192.168.6.181
repl
123
3306
10
0
...... ........
[root@mysql181 data]#
开启从库复制线程:
start slave ;
排错思路:
show slave status\G
Last_IO_Error: error connecting to master 'repl@10.0.0.181:3307' - retry-time: 10 retries: 6
报错了:
排查过程:
1、验证用户可用性
mysql -urepl -p123 -h 10.0.0.51 -P3307
Warning: Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'repl'@'db01' (using password: YES)
说明mysql做了自动别名解析。需要在mysql配置文件中加入以下一行:
vim /data/3307/my.cnf
skip_name_resolve
vim /data/3308/my.cnf
skip_name_resolve
vim /data/3309/my.cnf
skip_name_resolve
重启数据库节点
mysqladmin -S /data/3307/mysql.sock shutdown
mysqladmin -S /data/3308/mysql.sock shutdown
mysqladmin -S /data/3309/mysql.sock shutdown
mysqld_safe --defaults-file=/data/3307/my.cnf &
mysqld_safe --defaults-file=/data/3308/my.cnf &
mysqld_safe --defaults-file=/data/3309/my.cnf &
----
处理完成后,检查3308主从状态
mysql -S /data/3308/mysql.sock
出现两个yes,就说明主从复制成功了:
show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
------------------------------
主从复制故障:
1、判断故障的第一标准
两个线程是否为yes,不是yes,肯定是有问题的,如果都是yes也不一定完全没问题的。
show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
2、分析故障原因
IO线程故障:
IO线程负责什么?
(1)读取master.info信息
(2)连接主库
(3)请求的二进制日志
故障原因
(1)ip port user password 错误或不正常,解析错误,主库没有用户,网络,防火墙
(2)请求的二进制日志不存在,或信息错误
出现以上解决方案:
1、用户名密码错误,,ip port
stop slave; ----停止从库线程
reset slave all; ----清除从库复制信息
重新change master to
重新开启主从复制线程
start slave;
2、主库二进制日志故障
stop slave; ----停止从库线程
reset slave all; ----清除从库复制信息
将数据重新备份恢复到从库
重新change master to
重新开启主从复制线程
start slave;
SQL线程故障:
最核心的功能是执行relay-log中的SQL语句
研究SQL线程故障,说白了就是研究SQL语句为什么执行失败。
为什么主库执行成功,从库为啥执行不成功?
主库:
drop database oldboy; create database oldboy; update delete insert
从库:
未执行成功
原因是什么?
(1)因为没做初始化从库,初始化有问题(备份主库,恢复从库没有做好)
(2)从库被写入增删改查了。破坏了和主库的一致性
有风险的处理方法:
跳过错误操作:
stop slave;
set global sql_slave_skip_counter = 1 ;
start slave;
靠谱的方法:
重新搭建主从。
从根上解决问题:
从库只读。
命令行设置:
set global read_only=1;
配置文件设置:
read_only=1
注意:read_only参数对root权限的账号不起作用。