zoukankan      html  css  js  c++  java
  • 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 statusG
    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 statusG

    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes

    ------------------------------
    主从复制故障:

    1、判断故障的第一标准

    两个线程是否为yes,不是yes,肯定是有问题的,如果都是yes也不一定完全没问题的。
    show slave statusG
    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权限的账号不起作用。

  • 相关阅读:
    一步步用新浪SAE免费教大家搭建个人博客(wordpress 3.0.4 for SAE )
    欢迎大家来访西北狼网络乌托邦
    教大家如何让新浪SAE上安装wordpress实现伪静态
    CSDN 600万用户数据信息泄露并道歉
    推荐5款好用的屏幕录像软件
    IPv6无法解决全部安全问题
    详解STP以及工作过程
    如何在WordPress中实现彩色标签云
    EIGRP和RIP的一个综合性很强的实验(变态实验之一)
    查看系统等待的sql
  • 原文地址:https://www.cnblogs.com/jim-xu/p/11644832.html
Copyright © 2011-2022 走看看