主要理解为:业务不能使用数据库mysql
外在缘由:sql
一、网络问题数据库
二、业务应用有问题,客户端损坏服务器
数据库自己的缘由:网络
一、物理损坏:机器坏了、硬盘坏了、存储坏了架构
二、逻辑损坏:误drop、delete、truncate、、update。并发
解决方案:app
一、备份负载均衡
二、主从复制异步
指将主数据库的DDL和DML操做经过二进制日志传到复制服务器上,而后在复制服务器上将这些日志文件从新执行,从而使复制服务器和主服务器的数据保持同步。复制过程当中一个服务器充当主服务器(master),而一个或多个其它服务器充当从服务器(slaves)。主服务器将更新从新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志能够记录发送到从服务器的更新。当一个从服务器链接主服务器时,它通知主服务器、从服务器在日志中读取的最后一次成功更新的位置。从服务器接受从那时起发生的任何更新,而后封锁并等待主服务器通知新的更新。
复制的用途:
经过主从复制(master-slave)的方式来同步数据,再经过读写分离(mysql-proxy)来提高数据库的并发负载能力,或者用来做为主备机的设计,保证在主机中止响应以后在很短的时间内就能够将应用切换到备机上继续运行。
优点:
(1)数据库集群系统具备多个数据库节点,在单个节点出现故障的状况下,其余正常节点能够继续提供服务。
(2)若是主服务器上出现了问题能够切换到从服务器上
(3)经过复制能够在从服务器上执行查询操做,下降了主服务器的访问压力,实现数据分布和负载均衡
(4)能够在从服务器上进行备份,以免备份期间影响主服务器的服务。
1、能作什么?
² 高可用
² 辅助备份
² 分担负载
2.主从是怎么实现的?
² 经过二进制日志
² 至少两台(主, 从)
² 主服务器的二进制日志”拿“到从服务器上再运行一遍。
² 经过网络链接两台机器,通常都会出现延迟的状态。也能够说是异步。
3.MySQL主从复制的企业应用场景
² 应用场景1:从服务器做为主服务器的实时数据备份
² 应用场景2:主从服务器实现读写分离,从服务器实现负载均衡
² 应用场景3:把多个从服务器根据业务重要性进行拆分访问
1. 前提
² 主服务器必定要打开二进制日志
² 必须两台服务器(或者是多个实例)
² 从服务器须要一次数据初始化
² 若是主从服务器都是新搭建的话,能够不作初始化
² 若是主服务器已经运行很长时间了,能够经过备份将主库数据恢复到从库
² 主库必需要有对从库复制请求的用户。
² 从库须要有relay-log设置,存放从主库传过来的二进制日志
² 在第一次的时候,从库须要change master to 去链接主库
² change mater 信息须要存放到master.info中
² 从库经过relay-log.info记录了已经应用过的relaylog信息发现了主库发生了新的变化
² 在复制过程当中涉及到的线程
n 从库会开启一个IO thread 负责链接主库,请求binlog,接收binlog并写入relay-log中。
n 从库会开启一个SQ thread 负责执行relay-log中的事件
n 主库会开启一个dump thread 复制响应从IO thread中请求
复制过程
复制原理
原理:第一次开启主从
1.从库经过change master to 语句链接主库,而且让从库知道,二进制日志的起点位置(file名 position号)
2.从库的IO和主库的dump线程创建链接
3.从库根据changemaster to 语句提供的file名和position号,IO线程向主库发起binlog请求
4.主库dump线程根据从库的请求,将本地binlog以events方式发给从库IO线程
5.从库IO线程接收binlog events,并存放到本地relay-log中,传送过来的信息,会记录到master.info中。
6.从库应用relay-log,而且把应用过来的记录到relay-log.info,默认状况下,已经应用过来饿的relay会自动被清理purge。
到此,一次主从复制就完成,一旦主从运行起来,就不须要手工执行changemaster to,由于信息都会被存放到master.info 中,其余的过程也是同样的。
注意:若是不是新搭建的主从,须要将原来的数据全备,进行同步到从库中,而后在开启change master to。
过程:
1.初始化数据,使用备份将主库数据恢复到从库。
2.主库开启binlog server id,从库开启server id 默认开启relay log,建议本身设置relay-log,防止从库忽然修改主机名,relaylog会生成新的名字,原来的就找不到了
3.主库中建立复制用户
4.从库开启change change master to
5.开启slave
6.验证主从
1.在主库中添加用户权限
grant replication slave on *.* to repl@'10.0.0.%' identified by '123456';
flush privileges;
初始化数据
2.mysqldump -uroot -p123456 -A -B -F --master-data=2 >/tmp/full.sql
scp /tmp/server.sql 10.0.0.53:/tmp
在从库中进行source恢复
3.进入二进制文件找position号
在主库中查看binlog起点
mysql> mysql> show master;
+----------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| log-bin.000013 | 120 | | | |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
[root@db02 ~]# vi /tmp/full.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=120;
4.进入从库开启主从复制
set sql_log_bin=0;
CHANGE MASTER TO
MASTER_HOST='10.0.0.52 ',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000004',
MASTER_LOG_POS=120;
注意:也能够设置relay-bin的名称。
检查状态
start slave;
show slave status\G
成功的标志是:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
查看状态
[root@db02 ~]# mysql -S /data/3307/mysql.sock -e "show slave status\G"|egrep "_Running|Behind_Master"|head -3
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
[root@db02 ~]#mysql> show slave status\G #查看状态
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.52
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000005
Read_Master_Log_Pos: 544
Relay_Log_File: DB03-relay-bin.000002
Relay_Log_Pos: 754
Relay_Master_Log_File: mysql-bin.000005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 544
Relay_Log_Space: 957
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: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 52
Master_UUID: 9cd29dbb-d003-11e7-a49d-000c29310c49
Master_Info_File: /application/mysql-5.6.36/data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 9cd29dbb-d003-11e7-a49d-000c29310c49:1-2
Executed_Gtid_Set: 9cd29dbb-d003-11e7-a49d-000c29310c49:1-2,
e19e3a5b-d33f-11e7-b9b6-000c29af0efd:1-123
Auto_Position: 1
1 row in set (0.00 sec)
mysql>
出现故障:
一、缘由:
² 主机没启动,或者宕机
² 网络通讯问题
² 防火墙
² 复制用户密码(用户密码错误)
二、故障
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
或者
Slave_IO_Running: NO
Slave_SQL_Running: NO
缘由:在change master to 的时候,填错了用户密码,端口
Slave_*_Running:
Slave_IO_RunningI/O 线程正在运行、未运行仍是正在运行但还没有链接到主服务器。可能值分别为Yes、No 或Connecting。
Slave_SQL_RunningSQL 线程当前正在运行、未运行,可能值分别为Yes、No
主服务器日志坐标:
Master_Log_File和Read_Master_Log_Pos标识主服务器二进制日志中I/O 线程已经传输的最近事件的坐标。
若是Master_Log_File和Read_Master_Log_Pos的值远远落后于主服务器上的那些值,这表示主服务器与从属服务器之间事件的网络传输可能存在延迟。
中继日志坐标:
Relay_Log_File和Relay_Log_Pos列标识从属服务器中继日志中SQL 线程已经执行的最近事件的坐标。这些坐标对应于Relay_Master_Log_File和Exec_Master_Log_Pos列标识的主服务器二进制日志中的坐标。
若是Relay_Master_Log_File和Exec_Master_Log_Pos列的输出远远落后于Master_Log_File和Read_Master_Log_Pos列(表示I/O 线程的坐标),这表示SQL 线程(而不是I/O 线程)中存在延迟。即,它表示复制日志事件快于执行这些事件。
Last_IO_Error、Last_SQL_Error:
+分别致使I/O 线程或SQL 线程中止的最新错误的错误消息。在正常复制过程当中,这些字段是空的。若是发生错误并致使消息显示在以上任一字段中,则错误值也显示在错误日志中。
Last_IO_Errno、Last_SQL_Errno:
与分别致使I/O 线程或SQL 线程中止的最新错误关联的错误编号。在正常复制过程当中,这些字段包含编号0。
Last_IO_Error_Timestamp、Last_SQL_Error_Timestamp:
分别致使I/O 线程或SQL 线程中止的最新错误的时间戳,格式为YYMMDD HH:MM:SS。在正常复制过程当中,这些字段是空的。
主库方面:
白名单:只记录白名单中列出的库的二进制日志
binlog-do-db
黑名单:不记录黑名单列出的库的二进制日志
binlog-ignore-db
从库
白名单:只执行白名单中列出的库或者表的中继日志
--replicate-do-db=test
--replicate-do-table=test.t1
--replicate-wild-do-table=test.x*
黑名单:不执行黑名单中列出的库或者表的中继日志
--replicate-ignore-db
--replicate-ignore-table
--replicate-wild-ignore-table
从库binlog落后于主库
Master_Log_File: log-bin.000014
Read_Master_Log_Pos: 120
从库的logbin比主库的logbin慢的缘由:
网络问题
主库dump线程繁忙
从库IO线程繁忙
【扩展】
延时节点概念:是SQL线程延时,不是IO线程延时。
SQL线程报错
缘由:
² 主库操做对象在从库中不存在
² 主库操做对象的属性和从库不一致
² 主从操做顺序颠倒
解决方法:
跳过错误
stop slave;
set global sql_slave_skip_counter = 1;
start slave;
也能够在配置文件中跳过错误号码:
[mysqld]
slave-skip-errors = 1032,1062,1007
背景:标准主从复制结构,在业务逻辑中有oldboy数据库,oldboy数据库下有t1表为生产表。
故障缘由:开发人员在从库建立了一个oldgirl库,以为不对,后又在主库中作了相同的操做。致使了从库复制失效。
解决方案:
主从复制故障及解决
stop slave; #<==临时中止同步开关。
set global sql_slave_skip_counter= 1 ; #<==将同步指针向下移动一个,若是屡次不一样步,能够重复操做。
start slave;
/etc/my.cnf
slave-skip-errors = 1032,1062,1007
如何避免问题?
从库设置为只读库
在my.cnf中添加read_only=1
单独在从库建立一个只读用户
在主库建立写用户
优势:
配置时不须要重启
故障切换时也不须要重启
备份
问题:
若是从库只是做为备份服务器使用,那么主库的压力会增长,由于全部的业务都在主库进行读写(dump线程读取并发送给binlog)
解决方法:
性能
² 读写分离——MySQLproxy、amoeba、xx-dbproxy等。
² 分库分表——cobar、自主研发等。
² 比较依赖于业务
² 实施思路:
² 判断语句类型
² 根据语句类型进行分发
² 负载均衡,分发到从库
² 会话持续性(减小用户认证之类的操做)
² 判断语句是否执行过(提升性能,减小重复操做)
高可用
² MMM架构——mysql-mmm(google)(不在使用)
² MHA架构——mysql-master-ha(日本DeNa)
² MGR ——5.7 新特性MySQLGroup replication
² PXC、MySQLCluster架构
相似于一主一从的部署
不一样之处在于主从之间多了一个中间服务器
[mysqld]
basedir = /application/mysql/
datadir = /application/mysql/data/
socket = /application/mysql/tmp/mysql.sock
character_set_server=utf8
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
server-id = 2
log-bin=/tmp/log-bin
binlog-format=row
autocommit=1
log-slave-updates
[client]
socket = /application/mysql/tmp/mysql.sock
在中间服务器的my.cnf文件中须要开启binlog并添加log-slave-updates参数,表示强制刷新binlog,不然binlog日志不会刷新。
至关于作了两套主从。
reset slave;重置slave(关闭状态)