MySQL-lesson08-主从复制基础

1、主从复制准备

1.1 前提

  1. 准备2个以上地mysql实例,一主一从。
  2. 每台实例server_id不同
  3. 主库方面创建专用地复制用户
  4. 主库必须开启二进制日志
  5. 从库需要初始化数据,保证和主库数据在一个时间点上一致

1.2 准备

  1. 3307配置文件添加binlog配置
    vim /data/3307/my.cnf
    log_bin=/data/3307/data/mysql-bin
    binlog_format=row

  2. 启动多实例
    /application/mysql/bin/mysqld_safe --defaults-file=/data/3307/my.cnf &
    /application/mysql/bin/mysqld_safe --defaults-file=/data/3308/my.cnf &
    /application/mysql/bin/mysqld_safe --defaults-file=/data/3309/my.cnf &

  3. 验证
    netstat -lnp|grep 330

  4. 主库创建复制用户
    mysql -uroot -S /data/3307/mysql.sock
    grant replication slave on *.* to repl@'10.0.0.%' identified by '123';

  5. 全备主库数据,恢复到从库
    mysqldump -S /data/3307/mysql.sock -A -R --triggers --master-data=2 --single-transaction >/tmp/full.sql

  6. 查看binlog文件和位置点
    vim /tmp/full.sql
    -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=325;

  7. 全备导入从库
    mysql -uroot -S /data/3308/mysql.sock
    set sql_log_bin=0;
    source /tmp/full.sql

  8. 开启主从复制
    mysql -uroot -S /data/3308/mysql.sock

CHANGE MASTER TO
MASTER_HOST='10.0.0.51', ---->主库IP
MASTER_USER='repl', ---->主库复制用户
MASTER_PASSWORD='123', ---->主库复制用户密码
MASTER_PORT=3307, ----->主库端口
MASTER_LOG_FILE='master2-bin.000001', ----->需要复制的二进制日志名
MASTER_LOG_POS=325, ---->需要复制的二进制日志复制起点
MASTER_CONNECT_RETRY=10; ---->重连重试次数

启动复制线程
start slave;

查看主从状态
show slave status\G
slave_IO_Running:yes
slave_SQL_Running:yes

2、主从复制介绍

2.1 什么是主从复制?

基于主库二进制日志实时恢复到从库

2.2 主从复制存在的原因

  1. 辅助备份:解决物理损坏
  2. 演变高可用架构:在主库发生故障时,自动进行故障转移,对应用透明

2.3 主从复制原理

  • 主从复制前提
  1. 多台节点
  2. server_id要不同
  3. 主库开启binlog
  4. 主库提供专门的复制用户
  5. 主库备份导入从库,跟上主库的数据位置
  6. 通知从库:复制用户、密码、IP、port、复制文件和起点
  7. 开启复制
  • 文件
  1. Master:
    binlog:记录主库的数据变化
  2. Slave:
    relaylog:中继日志,存储从主库请求过来的二进制日志的存储位置
    master.info:存储用户,密码,IP,port,记录上次请求过的binlog位置
    relay-log.info:记录了上次SQL线程执行过的relaylog的位置点
  • 线程:
  1. Master:
    dump线程:主库发送二进制日志给从库的线程
  2. Slave:
    IO线程:请求binlog,并接收binlog的线程
    SQL线程:执行relaylog日志的线程

主从复制原理

image.png

  1. 从库IO线程,查看master.info信息,获取IP,port,user,password,file,position位置点
  2. 通过IP,port,user,password,连接到主库
  3. 拿着 file(mysql-bin.000003),pos(120),请求主库
  4. 主库判断如果有新的binlog(mysql-bin.000003,800),通过Dump线程从3号文件的120开始发送二进制日志事件
  5. 从库IO线程,接收binlog日志
  6. 接收到的binlog日志存到TCP/IP缓存
  7. IO线程回复一个ACK确认给dump线程,主库收到后,主库此次复制工作就完成了
  8. IO线程通知更新master.info文件,file,position被更新为最新请求的值
  9. 同时TCP/IP的缓存数据,写入relay-log中
  10. SQL线程,读取relay-log.info,获取到上次已经执行过的位置信息
  11. SQL执行最新的relay-log日志内容,数据重做
  12. 再次更新relay-log.info
  13. 已经复制过的relay-log,会被自动清理

简单来说就是三个步骤:
1、master将改变记录到二进制日志(binary log),这些记录过程叫做二进制日志事件(binary log events);
2、slave将master 的binary log events 拷贝到它的中继日志( relay log);
3、slave重做中继日志中的事件,将改变应用到自己的数据库中。mysql复制是异步的且串行化的

2.4 主从复制监控

  1. 主库:
    show master status; //主库和从库的文件和位置信息应该是一致
    show processlist;

  2. 从库:

show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 10.0.0.51
                  Master_User: repl
                  Master_Port: 3307
                Connect_Retry: 10
              Master_Log_File: master-bin.000004      //主库的binlog日志文件
          Read_Master_Log_Pos: 918                      //binlog日志文件位置点
               Relay_Log_File: db01-relay-bin.000001       //relay log 文件
                Relay_Log_Pos: 4                                      //relay  log 位置点
        Relay_Master_Log_File: master-bin.000004      //relaylog 日志文件对应的主库的binlog文件名
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

  1. 启动关闭线程
    stop slave;
    start slave;
    stop slave io_thread; //单独关闭IO线程
    stop slave sql_thread; //单独关闭sql线程

  2. 监控线程具体报错信息

                Last_IO_Errno: 1236
                Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'
               Last_SQL_Errno: 0
               Last_SQL_Error: 

2.5 主从复制故障

  1. IO线程故障
  • 连接master故障
    user,password,IP,port,网络不通,防火墙,master没启动,master连接数到达上限,反向解析(skip-name-resolve)
# 用户密码错误,尝试登录主库
mysql -urepl -p123 -h 10.0.0.51 -P3307

# 解决方法:
show slave status\G   //查看故障点的binlog位置
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 918 

# 停止复制
stop slave;         
reset slave all;    //清除之前的复制

# 修改信息重新复制
CHANGE MASTER TO
MASTER_HOST='10.0.0.51', 
MASTER_USER='repl',   
MASTER_PASSWORD='123', 
MASTER_PORT=3307, 
MASTER_LOG_FILE='mysql-bin.000004',
MASTER_LOG_POS=918,      //从故障时间点的位置开始复制主库
MASTER_CONNECT_RETRY=10;

start slave;
show slave status\G
  • 接收binlog故障
    binlog日志文件找不到、损坏、与主库断节
                Last_IO_Errno: 1236
                Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'
               Last_SQL_Errno: 0
               Last_SQL_Error: 

reset master //二进制日志从头开始。禁用

解决方法:

# 从库停库
stop slave;
reset slave all;

# 使用备份恢复,重新初始化数据;如果主库数据没有变化,则不用
set sql_log_bin=0;
source /tmp/full.sql

# 重新复制
CHANGE MASTER TO
MASTER_HOST='10.0.0.51', 
MASTER_USER='repl',   
MASTER_PASSWORD='123', 
MASTER_PORT=3307, 
MASTER_LOG_FILE='mysql-bin.000001',    //从头开始复制
MASTER_LOG_POS=120,
MASTER_CONNECT_RETRY=10; 

start slave;
  1. SQL线程故障
    (1)读写relay log.info
    (2)relay log 损坏,断节,找不到
    (3)接收到的SQL无法执行;根本原因是从库有写入操作,从库所有的数据都应该来自于主库。

解决方法:
1、写入操作撤回
2、跳过错误的方法是有风险的,最安全的方法重新构建主从。
3、彻底解决方法是将从库设置为只读库

从库设置只读权限

# 会话级别设置:
set global read_only=1;

# 永久设置:
vim /etc/my.cnf
[mysqld]
read_only=1

# 以上两条只对普通用户生效

# 设置管理员只读权限
vim /etc/my.cnf
[mysqld]
innodb_read_only=1
会话级别无法设置,只能重启生效
  1. 主从复制延时过高

定义:主库做了一个操作,从库很久都没有追上

  • 原因1 主库写binlog不及时

解决方法:控制binlog从内存写入到磁盘的控制参数:

  1. 每次事务提交会立即刷新binlog到磁盘(双一标准的其中一个)
    sync_binlog=1

  2. 每次事务提交不立即写入磁盘,靠操作系统判断什么时候写入
    sync_binlog=0

  • 原因2 dump线程压力大

  • 原因3 IO线程阻塞
    大事务------->拆成多个小事务
    事务量大------->group commit,5.6以后的参数,可以同时提交

  • 原因4 SQL线程慢

  1. 默认只有一个SQL线程,从库中的事务都是一个一个来执行的
  2. 如果主库的并发事务数很多,大事务,都会造成从库延时
    5.6 多线程复制(多SQL线程),有局限性,针对不同库的事务进行并发;
    大事务只能在主库拆成小事务。
  • 查看从库延时时间
    show slave status\G
    Seconds_Behind_Master:8888
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,639评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,277评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,221评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,474评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,570评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,816评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,957评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,718评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,176评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,511评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,646评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,322评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,934评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,755评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,987评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,358评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,514评论 2 348

推荐阅读更多精彩内容