zoukankan      html  css  js  c++  java
  • MySQL数据库企业级应用实践(主从复制)

    MySQL数据库企业级应用实践(主从复制)

    链接:https://pan.baidu.com/s/1ANGg3Kd_28BzQrA5ya17fQ
    提取码:ekpy
    复制这段内容后打开百度网盘手机App,操作更方便哦

    1.MySQL主从复制简介

    MySQL数据库的主从复制方案,与使用scp/rsync等命令进行的文件级别复制类似,都是数据的远程传输,只不过MySQL的主从复制是其自带的功能,无需借助第三方工具,而且,MySQL的主从复制并不是数据库磁盘上的文件直接拷贝,而是通过逻辑的binlog日志复制到要同步的服务器本地,然后由本地的线程读取日志里面的SQL语句,重新应用到MySQL数据库中。

    2.概述

    • MySQL数据库支持单向,双向,链式级联,环状等不同业务场景的复制。在复制过程中,一台服务器充当主服务器(Master),接收来自用户的内容更新,而一个或多个其他的服务器充当从服务器(Slave),接收来自主服务器binlog文件的日志内容,解析出SQL,重新更新到从服务器,使得主从服务器数据达到一致。
    • 如果设置了链式级联复制,那么,从服务器(Slave)本身除了充当从服务器外,也会同时充当其下面从服务器的主服务器。链式级联复制类似A-->B-->C的复制形式。

    下图为单向主从复制架构逻辑图,此架构只能在Master端进行数据写入

    image_1cl0j2dl916mj17l2181jefr1viqp.png-34.6kB

    image_1cl0j3e5t49e5jgi6p1runcmq29.png-68.6kB

    下图为双向主主复制逻辑架构图,此架构可以在Master1端或Master2端进行数据写入,或者两端同时写入数据(需要特殊设置)

    image_1cl0j5roq19om1kmbgphvob1sd32m.png-37.6kB

    下图为线性级联单向双主复制逻辑架构图,此架构只能在Master1端进行数据写入,工作场景中,Master1和master2作为主主互备,Slave1作为从库,中间的Master2需要做特殊的设置。

    image_1cl0j6viv19hv3q1fh91qtu1ej133.png-54.6kB

    下图为环状级联单向多主同步逻辑架构图,任意一个点都可以写入数据,此架构比较复杂,属于极端环境下的“成品”,一般场景慎用

    image_1cl0j815g1titvaj5eu10ic48q3g.png-69.9kB

    3.小结

    在当前的生产工作中,MySQL主从复制都是异步的复制方式,既不是严格实时的数据同步,但是正常情况下给用户的体验是真实的。

    4.MySQL主从复制的企业应用场景

    4.1从服务器作为主服务器的实时数据备份

    • 主从服务器架构的设置可以大大加强MySQL数据库架构的健壮性。例如:当主服务器出现问题时,我们可以人工或设置自动切换到从服务器继续提供服务,此时从服务器的数据与宕机时的主数据库几乎是一致的。
    • 这类似NFS存储数据通过inotify + rsync同步到备份的NFS服务器,只不过MySQL的复制方案是其自带的工具。
    • 利用MySQL的复制功能进行数据备份时,在硬件故障,软件故障的场景下,该数据备份是有效的,但对于人为地执行drop,delete等语句删除数据的情况,从库的备份功能就没用了,因为从服务器也会执行删除的语句。

    4.2主从服务器实现读写分离,从服务器实现负载均衡

    • 主从服务器架构可通过程序(PHP,java等)或代理软件(mysql-proxy,Amoeba)实现对用户(客户端)的请求读写分离,即让从服务器仅仅处理用户的select查询请求,降低用户查询响应时间,以及同时读写在主服务器上带来的访问压力。对于更新的数据(例如:update,insert,delete语句),则仍然交给主服务器处理,确保主服务器和从服务器保持实时同步。
    • 百度,淘宝,新浪等绝大多数的网站都是用户浏览页面多于用户发布内容,因此通过在从服务器上接收只读请求,就可以很好地减轻主库的读压力,且从服务器可以很容易地扩展为多台,使用LVS做负载均衡效果就非常棒了,这就是传说中的数据库读写分离架构。逻辑架构图如下所示:

    image_1cl0jv1tcjs81icq63rnih1cs93t.png-158.7kB

    4.3把多个从服务器根据业务重要性进行拆分访问

    可以把几个不同的从服务器,根据公司的业务进行拆分。例如:有为外部用户提供查询服务的从服务器,有内部DBA用来数据备份的从服务器,还有为公司内部人员提供访问的后台,脚本,日志分析及供开发人员查询使用的从服务器。这样的拆分除了减轻主服务器的压力外,还可以使数据库对外部用户浏览,内部用户业务处理及DBA人员的备份等互不影响。

    5.实现MySQL主从读写分离的方案

    5.1通过程序实现读写分离(性能和效率最佳,推荐)

    PHP和Java程序都可以通过设置多个连接文件轻松地实现对数据库的读写分离,即当语句关键字为select时,就去连接读库的连接文件,若为update,insert,delete时,则连接写库的连接文件。
    通过程序实现读写分离的缺点就是需要开发人员对程序进行改造,使其对下层不透明,但这种方式更容易开发和实现,适合互联网业务场景。

    根据业务重要性拆分从库方案

    image_1cl0ks6ci1otudn4b501uup1nvi1c.png-181.3kB

    5.2通过开源的软件实现读写分离

    MySQL-proxy,Amoeba等代理软件也可以实现读写分离功能,这些软件的稳定性和功能一般,不建议生产使用。绝大多数公司常用的还是在应用端发程序实现读写分离。

    5.3大型门户独立开发DAL层综合软件

    百度,阿里等大型门户都有开发牛人,会花大力气开发适合自己业务的读写分离,负载均衡,监控报警,自动扩容,自动收缩等一系列功能的DAL层软件。

    image_1cl0kuj5u1hp81o4b1unhfe21mj51p.png-121.4kB

    6.MySQL主从复制原理过程详细描述

    6.1简单描述MySQL Replication的复制原理过程

    • 在Slave服务器上执行start slave命令开启主从复制开关,开始进行主从复制
    • 此时,Slave服务器的I/O线程会通过在Master上已经授权的复制用户权限请求连接Master服务器,并请求从指定binlog日志文件的指定位置(日志文件名和位置就是在配置主从复制服务时执行change master命令指定的)之后开始发送binlog日志内容。
    • Master服务器接收到来自Slave服务器的I/O线程的请求后,其上负责复制的I/O线程会根据Slave服务器的I/O线程请求的信息分批读取指定binlog日志文件指定位置之后的binlog日志信息,然后返回给Slave端的I/O线程。返回的信息中除了binlog日志内容外,还有在Master服务器端记录的新的binlog文件名称,以及在新的binlog中的下一个指定更新位置。
    • 当Slave服务器的I/O线程获取到Master服务器上I/O线程发送的日志内容,日志文件及位置点后,会将binlog日志内容依次写到Slave端自身的Relay Log(即中继日志)文件(MySQL-relay-bin.xxxx)的最末端,并将新的binlog文件名和位置记录到master-info文件中,以便下一次读取Master端新binlog日志时能够告诉Master服务器从新binlog日志的指定文件及位置开始请求新的binlog日志内容。
    • Slave服务器端的SQL线程会实时检测本地Relay Log中I/O线程新增加的日志内容,然后及时地把Relay Log文件中的内容解析成SQL语句,并在自身Slave服务器上按解析SQL语句的位置顺序执行应用这些SQL语句,并在relay-log.info中记录当前应用中继日志的文件名及位置点。

    6.2MySQL Replication的复制原理逻辑图

    image_1cl0l79egkp41lug1u5cotk16hf2m.png-115.8kB

    6.3针对MySQL主从复制原理的重点进行小结

    • 主从复制是异步的逻辑的SQL语句级的复制
    • 复制时,主库有一个I/O线程,从库有两个线程,即I/O和SQL线程
    • 实现主从复制的必要条件是主库要开启记录binlog功能
    • 作为复制的所有MySQL节点的server-id都不能相同。
    • binlog文件只记录对数据库有更改的SQL语句(来自主数据库内容的变更),不记录任何查询(如select,show)语句。

    7.MySQL主从复制实践

    7.1主从复制数据库实战环境准备

    [root@yangwenbo /]# ss -antup | grep 330
    tcp    LISTEN     0      128            *:3307             *:*  users:(("mysqld",2576,11))
    tcp    LISTEN     0      128            *:3306             *:*  users:(("mysqld",4043,11))
    

    7.2修改主库的配置文件(3306为主,3307为从)

    [root@yangwenbo /]# vim /data/3306/my.cnf 
      4 [mysqld]             #下面两个参数必须放在[mysqld]模块下,否则会出错
     53 server-id = 1        #用于同步的每台机器或实例server-id都不能相同
     54 log-bin=mysql-bin    #binlog日志的位置
    [root@yangwenbo /]# vim /data/3307/my.cnf 
      4 [mysqld] 
     53 server-id = 5        #不能与主库相同(可以为任意数值)
    

    7.3重启主库MySQL服务

    [root@yangwenbo /]# /data/3306/mysql restart
    Restarting MySQL...
    Stoping MySQL...
    Starting MySQL....
    

    7.4登陆3306主库,检查参数的更改情况

    [root@yangwenbo /]# mysql -uroot -p971108 -S /data/3306/mysql.sock        #登陆3306实例
    Welcome to the MySQL monitor.  Commands end with ; or g.
    Your MySQL connection id is 1
    Server version: 5.5.22-log Source distribution
    
    Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    mysql> show variables like 'server_id';        #查看MySQL的系统变量(like类似于grep过滤)
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+                      #配置的server_id为1
    | server_id     | 1     |
    +---------------+-------+
    1 row in set (0.00 sec)
    
    mysql> show variables like 'log_bin';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+                      #binlog功能已开启
    | log_bin       | ON    |
    +---------------+-------+
    1 row in set (0.00 sec)
    
    
    [root@yangwenbo ~]# ls /data/3306/data         #这样,binlog功能就开启了
    ibdata1      ib_logfile1  mysql             mysql-bin.index     test
    ib_logfile0  ib_logfile2  mysql-bin.000001  performance_schema
    

    7.5登陆3306主库,建立用于主从复制的账号

    mysql> grant replication slave on *.* to 'yunjisuan'@'192.168.%' identified by '971108';
    
    Query OK, 0 rows affected (0.00 sec)
    
    #语句说明:
    1)replication slave为mysql同步的必须权限,此处不要授权all权限
    2)*.* 表示所有库所有表,也可以指定具体的库和表进行复制。例如yunjisuan.test中,yunjisuan为库名,test为表名
    3)'yunjisuan'@'192.168.0.%' yunjisuan为同步账号。192.168.%为授权主机网段,使用了%表示允许整个192.168.0.0网段可以用yunjisuan这个用户访问数据库
    4)identified by '971108';  971108为密码,实际环境下设置的复杂些为好
    

    7.6创建完账号并授权后,需要刷新权限,使授权的权限生效

    mysql> flush privileges;
    Query OK, 0 rows affected (0.00 sec)
    

    7.7检查主库创建的yunjisuan复制账号命令及结果

    mysql> select user,host from mysql.user;
    +-----------+-----------+
    | user      | host      |
    +-----------+-----------+
    | root      | 127.0.0.1 |
    | yunjisuan | 192.168.% |       #出现这行表示复制账号已经配置好了
    | root      | ::1       |
    |           | localhost |
    | root      | localhost |
    |           | yangwenbo |
    | root      | yangwenbo |
    +-----------+-----------+
    7 rows in set (0.00 sec)
    
    #说明:MySQL里的授权用户是以数据表格的形式存储在mysql这个库的user表里。
    
    mysql> show grants for yunjisuan@'192.168.%';
    +-----------------------------------------------------------------------------------------------+
    | Grants for yunjisuan@192.168.%                                                                |
    +-----------------------------------------------------------------------------------------------+
    | GRANT REPLICATION SLAVE ON *.* TO 'yunjisuan'@'192.168.%' IDENTIFIED BY PASSWORD '*2E086B4AB841306370F090F3973AC88BDAA569D3'                                                                   |
    +-----------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
    

    注意:设置主从复制之前要注意两台机器内容一致(可以通过备份的方式以及Rsync来实现)

    7.8登陆3307从库,配置复制参数

    mysql> CHANGE MASTER TO 
    MASTER_HOST='192.168.0.102',            #这里是主库的IP
    MASTER_PORT=3306,                       #这里是主库的端口,从库端口可以和主库不同
    MASTER_USER='yunjisuan';                #这里是主库上建立的用于复制的用户yunjisuan
    MASTER_PASSWORD='971108',               #这里是yunjisuan用户的密码
    MASTER_LOG_FILE='mysql-bin.000001',     #这里是show  master status时查看到的二进制日志文件名称
    MASTER_LOG_POS=962;                     #这里是show master status时查看到的二进制日志偏移量
    
    Query OK, 0 rows affected (0.02 sec)
    

    注意:上方的962是参照主库的位置

    mysql> show master status;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000001 |      962 |              |                  |
    +------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)
    

    7.9从库查看授权结果

    mysql> show slave statusG;
    *************************** 1. row ***************************
                   Slave_IO_State: 
                      Master_Host: 192.168.0.102
                      Master_User: yunjisuan
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000001
              Read_Master_Log_Pos: 962
                   Relay_Log_File: relay-bin.000001
                    Relay_Log_Pos: 4
            Relay_Master_Log_File: mysql-bin.000001
                 Slave_IO_Running: No
                Slave_SQL_Running: No
                 #中间省略。。。
                 Seconds_Behind_Master: 0
                 #以下省略。。。
    

    7.10从库激活主从复制

    mysql> start slave;
    Query OK, 0 rows affected (0.01 sec)
    

    7.11从库查看主从复制状态

    mysql> show slave statusG;
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.0.102
                      Master_User: yunjisuan
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000001
              Read_Master_Log_Pos: 962
                   Relay_Log_File: relay-bin.000002
                    Relay_Log_Pos: 253
            Relay_Master_Log_File: mysql-bin.000001
                 Slave_IO_Running: Yes        #只要这里两个是`Yes`,
                Slave_SQL_Running: Yes        就说明主从复制状态正常
                   #中间省略。。。
                Seconds_Behind_Master: 0      #0表示已经同步状态
                   #以下省略。。。
    

    7.12主从同步是否成功,最关键的为下面的3项状态参数:

    [root@yangwenbo ~]# mysql -uroot -p971108 -S /data/3307/mysql.sock -e "show slave statusG" | egrep "IO_Running|SQL_Running|Seconds_Behind_Master"
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
            Seconds_Behind_Master: 0
    
    • Slave_IO_Running:Yes,这个时I/O线程状态,I/O线程负责从从库到主库读取binlog日志,并写入从库的中继日志,状态为Yes表示I/O线程工作正常。
    • Slave_SQL_Running:Yes,这个是SQL线程状态,SQL线程负责读取中继日志(relay-log)中的数据并转换为SQL语句应用到从数据库中,状态为Yes表示I/O线程工作正常。
    • Seconds_Behind_Master:0,这个是复制过程中从库比主库延迟的秒数,这个参数极度重要,但我们可以更准确地判断主从延迟的方法为:在主库写时间戳,然后从库读取时间戳,和当前数据库时间进行比较,从而认定是否延迟。

    7.13检验主从复制是否成功

    7.13.1已知查看主库下信息如下

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    +--------------------+
    4 rows in set (0.00 sec)
    

    7.13.2已知查看从库下信息如下

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    +--------------------+
    4 rows in set (0.00 sec)
    

    从以上信息来看,主从数据一致

    7.13.3为检验成果,在主库上创建一个小库

    mysql> create database yangwenbo;
    Query OK, 1 row affected (0.08 sec)
    

    7.13.4检验当下主库内数据

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    | yangwenbo          |
    +--------------------+
    5 rows in set (0.00 sec)
    

    7.13.5检验当下从库内数据

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    | yangwenbo          |
    +--------------------+
    5 rows in set (0.00 sec)
    

    以上信息数据表明,主从复制成功

    7.14重置主从复制记录

    mysql> reset slave all;   #重置主从复制记录
    
    

    8. MySQL主从复制配置完整步骤小结

    • 准备两台数据库环境或单台多实例环境,确定能正常启动和登陆
    • 配置my.cnf文件:主库配置log-binserver-id参数;从库配置server-id,该值不能和主库及其他从库一样,一般不开启从库log-bin功能。注意,配置参数后要重启才能生效。
    • 登陆主库,增加从库连接主库同步的账户,例如:yunjisuan,并授权replication slave同步的权限。
    • 登陆主库,整库锁表flush table with read lock(窗口关闭后即失效,超时参数设置的时间到了,锁表也失效),然后show master status查看binlog的位置状态。
    • 新开窗口,在Linux命令行备份导出原有的数据库数据,并拷贝到从库所在的服务器目录。如果数据库数据量很大,并且允许停机,可以停机打包,而不用mysqldump
    • 导出主库数据后,执行unlock tables解锁主库。
    • 把主库导出的数据恢复到从库
    • 根据主库的show master status查看到的binlog的位置状态,在从库执行change master to....语句。
    • 从库开启复制开关,即执行start slave;
    • 从库show slave statusG,检查同步状态,并在主库进行更新测试。

    9.MySQL主从复制线程状态说明及用途

    9.1MySQL主从复制主库I/O线程状态说明

    9.1.1登陆主数据库查看MySQL线程的同步状态

    mysql> show processlistG;
    *************************** 1. row ***************************
         Id: 1
       User: yunjisuan
       Host: 192.168.0.102:33254
         db: NULL
    Command: Binlog Dump
       Time: 949
      State: Master has sent all binlog to slave; waiting for binlog to be updated
       Info: NULL
    *************************** 2. row ***************************
         Id: 2
       User: root
       Host: localhost
         db: NULL
    Command: Query
       Time: 0
      State: NULL
       Info: show processlist
    2 rows in set (0.00 sec)
    
    ERROR: 
    No query specified
    #提示:上述状态的意思是线程已经从binlog日志读取所有更新,并已经发送到了从数据库服务器。线程目前为空闲状态,等待由主服务器上二进制日志中的新事件更新。
    

    下图中列出了主服务器binlog Dump线程中State列的最常见状态。如果你没有在主服务器上看见任何binlog Dump线程,则说明复制没有运行,二进制binlog日志由各种事件组成,事件通常会为更新添加信息。
    image_1cl17k92artuuq0151u1i4b177g20.png-52.3kB

    9.1.2登陆从数据库查看MySQL线程工作状态

    从库有两个线程,即I/O和SQL线程。从库I/O线程的状态如下:

    mysql> show processlistG;
    *************************** 1. row ***************************
         Id: 1
       User: system user
       Host: 
         db: NULL
    Command: Connect
       Time: 1181
      State: Slave has read all relay log; waiting for the slave I/O thread to update it
       Info: NULL
    *************************** 2. row ***************************
         Id: 2
       User: system user
       Host: 
         db: NULL
    Command: Connect
       Time: 1211
      State: Waiting for master to send event
       Info: NULL
    *************************** 3. row ***************************
         Id: 3
       User: root
       Host: localhost
         db: NULL
    Command: Query
       Time: 0
      State: NULL
       Info: show processlist
    3 rows in set (0.00 sec)
    
    ERROR: 
    No query specified
    

    下图列出了从服务器的I/O线程的State列的最常见的状态。该状态也出现在Slave_IO_State列,由SHOW SLAVE STATUS显示。
    image_1cl18ncf619iquo910d18bl10ff2d.png-71.6kB

    下图列出了从服务器的SQL线程的State列的最常见状态
    image_1cl19dnmt144h241n7tq9mdg02q.png-49.7kB

    9.2查看MySQL线程同步状态的用途

    • 通过MySQL线程同步状态可以看到同步是否正常进行,故障的位置是什么,另外还可查看数据库同步是否完成,可用于主库宕机切换数据库或人工数据库主从切换迁移等。
    • 例如:主库宕机,要选择最快的从库将其提升为主库,就需要查看主从库的线程状态,如果主从复制在正常情况下进行角色切换,也需要查看主从库的线程状态,根据复制状态确定更新是否完成。

    10.模拟MySQL从库停止复制故障案例(先在从库创建一个库,然后去主库创建同名的库来模拟数据冲突)

    10.1已知主库内信息数据

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    +--------------------+
    4 rows in set (0.00 sec)
    

    10.2已知从库内信息数据

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    | yangwenbo          |
    +--------------------+
    5 rows in set (0.00 sec)
    

    已知从库比主库多了个小库yangwenbo

    10.3这时主库创建小库yangwenbo

    mysql> create database yangwenbo;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    | yangwenbo          |
    +--------------------+
    5 rows in set (0.01 sec)
    

    10.4这时查看从库信息数据无任何变化

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    | yangwenbo          |
    +--------------------+
    5 rows in set (0.00 sec)
    

    10.5从库查看主从复制状态

    mysql> show slave statusG;
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.0.102
                      Master_User: yunjisuan
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000004
              Read_Master_Log_Pos: 291
                   Relay_Log_File: relay-bin.000011
                    Relay_Log_Pos: 301
            Relay_Master_Log_File: mysql-bin.000004
                 Slave_IO_Running: Yes
                Slave_SQL_Running: No
                  Replicate_Do_DB: 
              Replicate_Ignore_DB: mysql
               Replicate_Do_Table: 
           Replicate_Ignore_Table: 
          Replicate_Wild_Do_Table: 
      Replicate_Wild_Ignore_Table: 
                       Last_Errno: 1007
                       Last_Error: Error 'Can't create database 'yangwenbo'; database exists' on query. Default database: 'yangwenbo'. Query: 'create database yangwenbo'
                     Skip_Counter: 0
              Exec_Master_Log_Pos: 198
                  Relay_Log_Space: 690
                  Until_Condition: None
                   Until_Log_File: 
                    Until_Log_Pos: 0
               Master_SSL_Allowed: No
               Master_SSL_CA_File: 
               Master_SSL_CA_Path: 
                  Master_SSL_Cert: 
                Master_SSL_Cipher: 
                   Master_SSL_Key: 
            Seconds_Behind_Master: NULL
    Master_SSL_Verify_Server_Cert: No
                    Last_IO_Errno: 0
                    Last_IO_Error: 
                   Last_SQL_Errno: 1007
                   Last_SQL_Error: Error 'Can't create database 'yangwenbo'; database exists' on query. Default database: 'yangwenbo'. Query: 'create database yangwenbo'
      Replicate_Ignore_Server_Ids: 
                 Master_Server_Id: 1
    1 row in set (0.00 sec)
    
    ERROR: 
    No query specified
    

    10.6对于该冲突,解决办法如下

    方法一:
    (1)直接将从库的yangwenbo小库删掉(当然如果里面有重要数据,可以先进行备份,找时间再恢复)

    mysql> stop slave;                    #首先要停库;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> drop database yangwenbo;       #再者删掉这个小库
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> start slave;                   #开启库
    Query OK, 0 rows affected (0.01 sec)
    

    (2)查看从库主从复制状态

    mysql> show slave statusG;
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.0.102
                      Master_User: yunjisuan
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000004
              Read_Master_Log_Pos: 291
                   Relay_Log_File: relay-bin.000012
                    Relay_Log_Pos: 253
            Relay_Master_Log_File: mysql-bin.000004
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                 #中间省略。。。
                 Seconds_Behind_Master: 0    #0表示已经同步状态
                 #以下省略。。。
    

    提示:

    set global sql_slave_skip_counter=n;   #n取值>0,忽略执行N个更新。
    

    (3)查看主库内信息数据

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    | yangwenbo          |
    +--------------------+
    5 rows in set (0.00 sec)
    

    (4)查看主库内信息数据

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    | yangwenbo          |
    +--------------------+
    5 rows in set (0.00 sec)
    

    主从信息数据已恢复已知,证明已成功

    方法二:
    (1)关闭从同步,调动sql_slave指针

    mysql> stop slave;                               #首先要停库;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> set global sql_slave_skip_counter=1;      #将sql线程同步指针向下移动一个,如果多次不同步,可以重复操作
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> start slave;                              #开启库
    Query OK, 0 rows affected (0.00 sec)
    

    (2)查看从库主从复制状态

    mysql> show slave statusG;
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.0.102
                      Master_User: yunjisuan
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000004
              Read_Master_Log_Pos: 291
                   Relay_Log_File: relay-bin.000012
                    Relay_Log_Pos: 253
            Relay_Master_Log_File: mysql-bin.000004
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                 #中间省略。。。
                 Seconds_Behind_Master: 0    #0表示已经同步状态
                 #以下省略。。。
    

    提示:

    set global sql_slave_skip_counter=n;   #n取值>0,忽略执行N个更新。
    

    (3)查看主库内信息数据

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    | yangwenbo          |
    +--------------------+
    5 rows in set (0.00 sec)
    

    (4)查看主库内信息数据

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    | yangwenbo          |
    +--------------------+
    5 rows in set (0.00 sec)
    

    主从信息数据已恢复已知,证明已成功

    10.7其他可能引起复制故障的原因:

    • MySQL自身的原因及人为重复插入数据。
    • 不同的数据库版本会引起不同步,低版本到高版本可以,但是高版本不能往低版本同步。
    • MySQL的运行错误或程序bug
    • binlog记录模式,例如:row level模式就比默认的语句模式要好。

    11.让MySQL从库记录binlog日志的方法

    • 从库需要记录binlog的应用场景:当前的从库还要作为其他从库的主库,例如级联复制或双主互为主从场景的情况下。下面介绍从库记录binlog日志的方法。
    • 在从库的my.cnf中加入如下参数,然后重启服务生效即可。
     54 
     55 log-slave=updates     #必须要有这个参数
     56 log-bin = /data/3307/mysql-bin
     57 expire_logs_days = 7  #相当于find /data/3307/ -type f -name "mysql-bin.000*" -mtime +7 | xargs rm -f
     58 
    
    [root@yangwenbo ~]# /data/3307/mysql restart
    Restarting MySQL...
    Stoping MySQL...
    Starting MySQL....
    

    12. MySQL主从复制集群架构的数据备份策略

    • 有主从复制了,还需要做定时全量加增量备份么?答案是肯定的!
      因为,如果主库有语句级误操作(例如:drop database yunjisuan;),从库也会执行drop database yunjisuan;,这样MySQL主从库就都删除了该数据。
    • 把从库作为数据库备份服务器时,备份策略如下:高并发业务场景备份时,可以选择在一台从库上备份(Slave5),把从库作为数据库备份服务器时需要在从库开启binlog功能,其逻辑图如下所示

    image_1cl1dsu4f1hr0l9913o1knt7iu37.png-153.3kB

    步骤如下:

    • 选择一个不对外提供服务的从库,这样可以确保和主库更新最接近,专门用于做数据备份。
    • 开启从库的binlog功能

    备份时可以选择只停止SQL线程,停止应用SQL语句到数据库,I/O线程保留工作状态,执行命令为stop slave sql_thread;,备份方式可以采取mysqldump逻辑备份或直接物理备份,例如:使用cp,tar(针对/data目录)工具或xtrabackup(第三方的物理备份软件)进行备份,则逻辑备份和物理备份的选择,一般是根据总的备份数据量的多少进行选择的,数据量低于30G,建议选择mysqldump逻辑备份方法,安全稳定,最后把全备和binlog数据发送到备份服务器上留存。

    13.MySQL主从复制延迟问题的原因及解决方案

    13.1主库的从库太多,导致复制延迟

    从库数量以3~5个为宜,要复制的从节点数量过多,会导致复制延迟。

    13.2从库硬件比主库差,导致复制延迟。

    查看Master和Slave的系统配置,可能会因为机器配置不当,包括磁盘I/O,CPU,内存等各方面因素造成复制的延迟。这一般发生在高并发大数据量写入场景中。

    13.3慢SQL语句太多

    假如一条SQL语句执行时间是20秒,那么从执行完毕到从库上能查到数据至少需要20秒,这样就延迟20秒了。
    一般要把SQL语句的优化作为常规工作,不断的进行监控和优化,如果单个SQL的写入时间长,可以修改后分多次写入。通过查看慢查询日志或show full processlist命令,找出执行时间长的查询语句或大的事务。

    13.4主从复制的设计问题

    例如,主从复制单线程,如果主库写并发太大,来不及传送到从库,就会导致延迟。
    更高版本的MySQL可以支持多线程复制,门户网站则会自己开发多线程同步功能。

    13.5主从库之间的网络延迟

    主从库的网卡,网线,连接的交换机等网络设备都可能成为复制的瓶颈,导致复制延迟,另外,跨公网主从复制很容易导致主从复制延迟。

    13.6主库读写压力大,导致复制延迟。

    主库硬件要搞好一点,架构的前端要加buffer及缓存层。

    14.通过read-only参数让从库只读访问

    read-only参数选项可以让从服务器只允许来自从服务器线程或具有SUPER权限的数据库用户进行更新,确保从服务器不接受来自用户端的非法用户更新。

    14.1read-only参数允许数据库更新的条件为:

    • 具有SUPER权限的用户可以更新,不受read-only参数影响,例如:管理员root。
    • 来自从服务器线程可以更新,不受read-only参数影响,例如:前文的yunjisuan用户。
    • 再生产环境中,可以在从库Slave中使用read-only参数,确保从库数据不被非法更新。

    14.2read-only参数的配置方法如下:

    方法一:直接带 --read-only参数启动或重启数据库,

    使用killall mysqld
    mysqladmin -uroot -p123123 -S /data/3307/mysql.sock shutdown mysqld_safe --defaults-file=/data/3307/my.cnf --read-only &

    方法二:在my.cnf里[mysqld]模块下加read-only参数重启数据库,配置如下:

    [mysqld]
    read-only
    

    15.如何实现对主数据库锁表只读

    • 前言:假设某公司有一主库,一从库(主从复制),由于从库1压力过大,公司决定再搭建一个从库2,写出具体流程
    • 答:可以先把主库设为只读状态,打包备份到从库2,使主从数据一致,这时主库再手动解除只读

    15.1对主数据库锁表只读(当前窗口不要关掉)

    mysql> flush table with read lock;      #对主数据库锁表只读
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> create database yunjisuan;       #已无法写入
    ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock
    

    在引擎不同的情况下,这个锁表命令的时间会受下面参数的控制。锁表时,如果超过设置时间不操作会自动解锁。

    15.2默认情况下自动解锁的时长参数值如下:

    mysql> show variables like '%timeout%';
    +----------------------------+----------+
    | Variable_name              | Value    |
    +----------------------------+----------+
    | connect_timeout            | 10       |
    | delayed_insert_timeout     | 300      |
    | innodb_lock_wait_timeout   | 120      |
    | innodb_rollback_on_timeout | OFF      |
    | interactive_timeout        | 28800    | #自动解锁时间受本参数影响
    | lock_wait_timeout          | 31536000 |
    | net_read_timeout           | 30       |
    | net_write_timeout          | 60       |
    | slave_net_timeout          | 3600     |
    | wait_timeout               | 28800    | #自动解锁时间受本参数影响
    +----------------------------+----------+
    10 rows in set (0.00 sec)
    

    15.3锁表后查看主库状态。可通过当前binlog日志文件名和二进制binlog日志偏移量来查看

    注意,show master status;命令显示的信息要记录在案,后面的从库导入全备后,继续和主库复制时就是要从这个位置开始。

    mysql> show master status;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000004 |      475 |              |                  |
    +------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)
    

    15.4锁表后,一定要单开一个新的SSH窗口,导出数据库的所有数据,如果数据量很大(50GB以上),并且允许停机,可以停库直接打包数据文件进行迁移,那样更快

    [root@yangwenbo /]# mkdir beifen    #可以临时创建一个目录
    [root@yangwenbo /]# mysqldump -uroot -p971108 -S /data/3306/mysql.sock --events -A -B | gzip >/beifen/mysql_bak.$(date +%F).sql.gz
    #注意:-A表示备份所有库;-B表示增加use DB和 drop 等(导库时会直接覆盖原有的)
    
    [root@localhost ~]# ll /server/backup/mysql_bak.2017-07-21.sql.gz 
    -rw-r--r--. 1 root root 137344 Jul 21 10:17 /server/backup/mysql_bak.2017-07-21.sql.gz
    

    15.5为了确保导出数据期间,数据库没有数据插入,导库完毕可以再次检查主库状态信息,结果如下:

    [root@yangwenbo /]# mysql -uroot -p971108 -S /data/3306/mysql.sock -e "show master status"
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000004 |      475 |              |                  |
    +------------------+----------+--------------+------------------+
    #提示:若无特殊情况,binlog文件及位置点和锁表后导出数据前是一致的,即没有变化。
    

    15.6解锁

    mysql> unlock tables;
    Query OK, 0 rows affected (0.00 sec)
    #导出数据完毕后,解锁主库,恢复可写,命令如下.因为主库还要对外提供服务,不能一直锁定不让用户访问
    
    

    15.7把主库导出的MySQL备份数据包迁移到从库(使其保证主从一致),再搭建主从复制,就OK了!

  • 相关阅读:
    iaas,paas,saas理解
    July 06th. 2018, Week 27th. Friday
    July 05th. 2018, Week 27th. Thursday
    July 04th. 2018, Week 27th. Wednesday
    July 03rd. 2018, Week 27th. Tuesday
    July 02nd. 2018, Week 27th. Monday
    July 01st. 2018, Week 27th. Sunday
    June 30th. 2018, Week 26th. Saturday
    June 29th. 2018, Week 26th. Friday
    June 28th. 2018, Week 26th. Thursday
  • 原文地址:https://www.cnblogs.com/ywb123/p/11206352.html
Copyright © 2011-2022 走看看