MySQL主从复制

1.概述:

主从复制是数据库管理中的一种技术,它允许将一个数据库服务器(主服务器)上的数据复制到一个或多个数据库服务器(从服务器)。在MySQL中,这通常是通过异步复制来实现的,意味着从服务器不需要实时连接到主服务器来更新数据。从服务器可以复制主服务器中的所有数据库、特定数据库或特定表。

2.高可用架构方案

(1)负载均衡:有一定的高可用性

LVS、Nginx、 haproxy

(2)主备系统:有高可用性,但是需要10-30s切换,是单活的架构

Keepalived , MHA, MMM

(3)真正高可用(多活系统):

NDB Cluster  Oracle RAC  Sybase cluster   , InnoDB Cluster(MGR),PXC(percona) , MGC(mariadb)

==============================================================

MySQL Replication(主从复制)

io线程负责抓取master的二进制,放到自己的日志文件(中继日志)。日志文件有了新数据,那么sql线程就会起作用。sql线程执行中继日志,从而和master保持一致。

1.DBA职责(关于主从复制)

(1) 搭建主从复制   

(2) 主从原理熟悉   

(3) 主从的故障处理

(4) 主从延时,同步不及时   

(5) 主从的特殊架构(过滤复制、延时从库)的配置使用

(6) 主从架构的演变(读写分离、高可用、分布式架构)

2. 主从复制介绍

(1) 主从复制基于binlog来实现的

(2) 主库发生新的操作,都会记录binlog

(3) 从库取得主库的binlog进行回放

(4) 主从复制的过程是异步

3. 主从复制的前提 (搭建主从复制)

(1) 2个或以上的数据库实例

(2) 主库需要开启二进制日志

(3) server_id要不同,区分不同的节点

(4) 主库需要建立专用的复制用户 (replication slave)

(5) 从库应该通过备份主库、恢复的方法进行复制历史数据

(6) 人为告诉从库一些复制信息(ip port user pass,二进制日志起点)

(7) 从库应该开启专门的复制线程

主从从结构

4. 主从复制搭建过程(生产)

两台服务器实现主从:

master:192.168.8.36,主机名master

[root@CentOS ~]# hostnamectl set-hostname master

[root@CentOS ~]# bash

修改配置文件:

cat > /etc/my.cnf << EOF

[mysqld]

user=mysql

basedir=/usr/local/mysql

datadir=/usr/local/mysql/data

socket=/tmp/mysql.sock

server_id=1

log_bin=/data/binlog/master-bin

port=3306

[mysql]

socket=/tmp/mysql.sock

prompt=master>

EOF

mkdir -p /data/binlog

chown -R mysql.mysql /data

systemctl restart mysqld

查询server_id,如果没有改变,则重启mysql服务器

pkill mysql

systemctl start mysqld

master>select @@server_id;

+-------------+

| @@server_id |

+-------------+

|           1 |

+-------------+

1 row in set (0.00 sec)

master>show master status;

+-------------------+----------+--------------+------------------+-------------------+

| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+-------------------+----------+--------------+------------------+-------------------+

| master-bin.000001 |      154 |              |                  |                   |

+-------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

如果不是154,就执行reset master清空一下

slave: 192.168.8.37 ,主机名slave

[root@mysql2 ~]# hostnamectl set-hostname slave

[root@mysql2 ~]# bash

cat > /etc/my.cnf << EOF

[mysqld]

user=mysql

basedir=/usr/local/mysql

datadir=/usr/local/mysql/data

socket=/tmp/mysql.sock

server_id=2

log_bin=/data/binlog/slave-bin

port=3306

[mysql]

socket=/tmp/mysql.sock

prompt=slave>

EOF

mkdir -p /data/binlog

chown -R mysql.mysql /data

systemctl restart mysqld

slave>select @@server_id;

+-------------+

| @@server_id |

+-------------+

|           2 |

+-------------+

1 row in set (0.00 sec)

slave>show master status;

+------------------+----------+--------------+------------------+-------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------+

| slave-bin.000001 |      154 |              |                  |                   |

+------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

4.3 主库创建复制用户

登录数据库:

grant replication slave on *.* to repl@'192.168.8.%' identified by '123';

master>grant replication slave on *.* to repl@'192.168.8.%' identified by '123';

Query OK, 0 rows affected, 1 warning (0.00 sec)

4.4 "复制历史数据"

准备数据库,把world和t100w导入到master服务器

导入:

master>source world.sql

master>create database t100w;

Query OK, 1 row affected (0.00 sec)

master>use t100w;

master>source t100w.sql

主:

mysqldump -uroot -p123456  -A --master-data=2 --single-transaction -R -E --triggers >/tmp/full.sql

scp /tmp/full.sql  root@192.168.8.37:/root

[root@master ~]# mysqldump -uroot -p123456  -A --master-data=2 --single-transaction -R -E --triggers >/tmp/full.sql

[root@master ~]# scp /tmp/full.sql  root@192.168.8.37:/root

root@192.168.8.37's password:

full.sql                                                                            100%   99MB 126.6MB/s   00:00    

从:

mysql> set sql_log_bin=0;

mysql> source /root/full.sql

mysql> set sql_log_bin=1;

4.5 告诉从库信息

先查看主库的二进制日志名和position号:

show master status;

master>show master status;

+-------------------+----------+--------------+------------------+-------------------+

| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+-------------------+----------+--------------+------------------+-------------------+

| master-bin.000001 | 22433604 |              |                  |                   |

+-------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

在从库使用命令连接主库:

CHANGE MASTER TO

MASTER_HOST='192.168.8.36',

MASTER_USER='repl',

MASTER_PASSWORD='123',

MASTER_PORT=3306,

MASTER_LOG_FILE='master-bin.000001',

MASTER_LOG_POS= 22433604,

MASTER_CONNECT_RETRY=10;

4.6 从库开启复制线程(IO,SQL)

start slave;

4.7 在从库检查主从复制状态

show slave status \G

显示信息:

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

slave>show slave status \G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.8.36

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 10

              Master_Log_File: master-bin.000001

          Read_Master_Log_Pos: 22433604

               Relay_Log_File: slave-relay-bin.000002

                Relay_Log_Pos: 321

        Relay_Master_Log_File: master-bin.000001

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

    

            。。。。。。          

4.8 测试主从同步

主库:

create database ms;

use ms;

create table t1 (id int,name varchar(20));

insert into t1 values (1,'z3'),(2,'l4'),(3,'w5');

master>show master status;

+-------------------+----------+--------------+------------------+-------------------+

| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+-------------------+----------+--------------+------------------+-------------------+

| master-bin.000001 | 22434204 |              |                  |                   |

+-------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

从库:

slave>show slave status \G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.8.36

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 10

              Master_Log_File: master-bin.000001

          Read_Master_Log_Pos: 22434204

               Relay_Log_File: slave-relay-bin.000002

                Relay_Log_Pos: 921

        Relay_Master_Log_File: master-bin.000001

             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: 22434204

              Relay_Log_Space: 1128

              Until_Condition: None

show databases;

use ms;

select * from t1;

slave>select * from t1;

+------+------+

| id   | name |

+------+------+

|    1 | z3   |

|    2 | l4   |

|    3 | w5   |

+------+------+

3 rows in set (0.00 sec)

5. 主从复制原理 *****

5.1 主从复制中涉及的文件

主库:

binlog 主库的二进制日志

从库:

relaylog  中继日志

master.info  主库信息文件(主从建立联系)

relaylog.info relaylog应用的信息(存储从服务器日志执行的进度,执行过的不再执行)

日志存储在以下位置:`

[root@slave ~]# cd /usr/local/mysql/data/

[root@slave data]# ls

auto.cnf        ib_logfile1  mysql               slave.pid               sys

ib_buffer_pool  ibtmp1       mysql2.err          slave-relay-bin.000001  t100w

ibdata1         master.info  performance_schema  slave-relay-bin.000002  world

ib_logfile0     ms           relay-log.info      slave-relay-bin.index

5.2 主从复制中涉及的线程

主库:

Binlog_Dump Thread : DUMP_T(检测主主服务器有没有数据变化,就是二进制有没有变化,有变化就会主动通知io线程)

从库:

SLAVE_IO_THREAD     : IO_T

SLAVE_SQL_THREAD    : SQL_T

5.3 主从复制工作(过程)原理******

1.从库执行change master to 命令(主库的连接信息+复制的起点)

2.从库会将以上信息,记录到master.info文件(系统重启便于下次重连)

3.从库执行 start slave 命令,立即开启IO_T和SQL_T

4. 从库 IO_T,读取master.info文件中的信息,获取到IP,PORT,User,Pass,binlog的位置信息(联系主库)

5. 从库IO_T请求连接主库,主库专门提供一个DUMP_T,负责和IO_T交互

6. IO_T根据binlog的位置信息(mysql-bin.000004 , 444),请求主库新的binlog

7. 主库通过DUMP_T将最新的binlog,通过网络TP给从库的IO_T

8. IO_T接收到新的binlog日志,存储到TCP/IP缓存,立即返回ACK给主库,并更新master.info

9.IO_T将TCP/IP缓存中数据,转储到磁盘relaylog中.

10. SQL_T读取relay.info中的信息,获取到上次已经应用过的relaylog的位置信息

11. SQL_T会按照上次的位置点回放最新的relaylog,再次更新relay.info信息

12. 从库会自动purge应用过relay进行定期清理

补充说明:

一旦主从复制构建成功,主库当中发生了新的变化,都会通过dump_T发送信号给IO_T,增强了主从复制的实时性.

5.4 主从复制监控

命令:

show slave status \G

主库有关的信息(master.info):

Master_Host: 192.168.8.10

Master_User: repl

Master_Port: 3306

Connect_Retry: 10

*******************************

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 608

*******************************

从库relay应用信息有关的(relay.info):

Relay_Log_File: mysql-relay-bin.000002

Relay_Log_Pos: 479

Relay_Master_Log_File: mysql-bin.000001

从库线程运行状态(排错)

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

Last_IO_Errno: 0

Last_IO_Error:

Last_SQL_Errno: 0

Last_SQL_Error:

过滤复制有关的信息:

Replicate_Do_DB:

Replicate_Ignore_DB:

Replicate_Do_Table:

Replicate_Ignore_Table:

Replicate_Wild_Do_Table:

Replicate_Wild_Ignore_Table:

从库延时同步主库的时间(秒):  

Seconds_Behind_Master: 0

测试:

在master:

master>drop database t100w;

Query OK, 1 row affected (0.03 sec)

master>create database t100w;

master>source t100w.sql;

在slave:

 Seconds_Behind_Master: 1

延迟一秒,但是如果服务器性能好,延迟可能也会显示0

slave>show slave status \G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.8.36

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 10

              Master_Log_File: master-bin.000001

          Read_Master_Log_Pos: 65919840

               Relay_Log_File: slave-relay-bin.000002

                Relay_Log_Pos: 43486557

        Relay_Master_Log_File: master-bin.000001

             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: 65919840

              Relay_Log_Space: 43486764

              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: 1

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: 1

                  Master_UUID: 42d66685-b23f-11ef-a2d6-000c296dec8d

             Master_Info_File: /usr/local/mysql/data/master.info

                    SQL_Delay: 0

          SQL_Remaining_Delay: NULL

      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates

           Master_Retry_Count: 86400

                  Master_Bind:

      Last_IO_Error_Timestamp:

     Last_SQL_Error_Timestamp:

               Master_SSL_Crl:

           Master_SSL_Crlpath:

           Retrieved_Gtid_Set:

            Executed_Gtid_Set:

                Auto_Position: 0

         Replicate_Rewrite_DB:

                 Channel_Name:

           Master_TLS_Version:

1 row in set (0.00 sec)

延时从库(延时误操作):

SQL_Delay: 0      (秒)及时还原数据(例如master误删除数据,从的经过7200秒才会同步)

SQL_Remaining_Delay: NULL

GTID复制有关的状态信息(下次课详细介绍)  

Retrieved_Gtid_Set:

Executed_Gtid_Set:

Auto_Position: 0

5.5 主从复制故障 *****

5.5.1 IO 线程故障

(1) 连接主库: connecting

网络,连接信息错误或变更了,防火墙,连接数上限

排查思路:

1. 使用复制用户手工登录

测试是否用户名、密码、IP出错。

解决:

从库

1. stop slave #停止同步

2. reset slave all;  #清空master.info

3. change master to ...#重新查看master,再次连接master

4. start slave#再次开启同步

(2) 请求Binlog

binlog 没开

binlog 损坏,不存在

解决:

主库开启binlog

终极解决方案

主库 reset master 处理:

从库

stop slave ;

reset slave all;

CHANGE MASTER TO

MASTER_HOST='192.168.8.10',

MASTER_USER='repl',

MASTER_PASSWORD='123',

MASTER_PORT=3306,

MASTER_LOG_FILE='master-bin.000001',

MASTER_LOG_POS=154,

MASTER_CONNECT_RETRY=10;

start slave;

(3) 存储binlog到relaylog

5.5.2 SQL线程故障

relay-log损坏

回放relaylog

研究一条SQL语句为什么执行失败?

insert delete  update     ---> t1 表 不存在

create table  t1     ---> t1 已存在

约束冲突(主键,唯一键,非空..)

合理处理方法:

把握一个原则,一切以主库为准进行解决.

如果出现问题,尽量进行反操作

最直接稳妥办法,重新构建主从

暴力的解决方法

方法一:

stop slave;

set global sql_slave_skip_counter = 1;

start slave;

#将同步指针向下移动一个,如果多次不同步,可以重复操作。

start slave;

方法二:

/etc/my.cnf

slave-skip-errors = 1032,1062,1007

常见错误代码:

1007:对象已存在

1032:无法执行DML,可能对象不存在

1062:主键冲突,或约束冲突

但是,以上操作有时是有风险的,最安全的做法就是重新构建主从。把握一个原则,一切以主库为主.(都在主库上改,除非有读写分离)

为了避免SQL线程故障

(1) 从库只读

read_only

super_read_only

(2) 使用读写分离中间件

amoeba(淘宝)

atlas (奇虎360)

mycat

ProxySQL

MaxScale

5.6 主从延时监控及原因 *****

5.6.1 主库方面原因

(1) binlog写入不及时

sync_binlog=1

(2) 默认情况下dump_t 是串行传输binlog *****

在并发事务量大时或者大事务,由于dump_t 是串型工作的,导致传送日志较慢

如何解决问题?

必须GTID,使用Group commit方式.可以支持DUMP_T并行(同时打开多个DUMP_T)

(3) 主库极其繁忙

慢语句

锁等待

从库个数

网络延时

5.6.2 从库方面原因

(1) 传统复制(Classic)中 *****

如果主库并发事务量很大,或者出现大事务

由于从库是单SQL线程,导致,不管传的日志有多少,只能一次执行一个事务.

5.6 版本,有了GTID,可以实现多SQL线程,但是只能基于不同库的事务进行并发回放.(database)

5.7 版本中,有了增强的GTID,增加了seq_no,增加了新型的并发SQL线程模式(logical_clock),MTS技术(多版本并发技术)

(2) 主从硬件差异太大

(3) 主从的参数配置

(4) 从库和主库的索引不一致

(5) 版本有差异

5.6.3 主从延时的监控

show slave  status\G

Seconds_Behind_Master: 0

主库方面原因的监控

主库:

mysql> show master status ;

File: mysql-bin.000001

Position: 1373

从库

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 1373

从库方面原因监控:

拿了多少:

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 691688

执行了多少:

Relay_Log_File: db01-relay-bin.000004

Relay_Log_Pos: 690635

Exec_Master_Log_Pos: 691000

Relay_Log_Space: 690635

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值