运维

MySQL replication 高级进阶

2020-04-05  本文已影响0人  麟之趾a

延时从库

解决逻辑损坏问题 ,实际上是让SQL线程慢点回放relay-log,一般企业建议延迟3-6小时,具体看运维对故障的反应时间

mysql> stop slave;
mysql> CHANGE MASTER TO  MASTER_DELAY=300;
mysql> start slave;
mysql>show slave status\G;
              SQL_Delay: 300                           #延时300秒
          SQL_Remaining_Delay: 296          #还剩296秒执行relay-log日志

延时从库故障处理逻辑问题

发现主库drop库

延时从库恢复思路

mysql> stop slave sql_thread;
mysql> show slave status\G;
       Relay_Log_File: mysql-relay-bin.000002    #SQL线程回放的relay-log日志
                Relay_Log_Pos: 473                        #SQL线程回放的relay-log日志的pos号
mysql> show relaylog events in 'mysql-relay-bin.000002';
+------------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name               | Pos | Event_type     | Server_id | End_log_pos | Info                                  |
+------------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-relay-bin.000002 |   4 | Format_desc    |         6 |         123 | Server ver: 5.7.26-log, Binlog ver: 4 |
| mysql-relay-bin.000002 | 123 | Previous_gtids |         6 |         154 |                                       |
| mysql-relay-bin.000002 | 154 | Rotate         |         5 |           0 | mysql-bin.000009;pos=154              |
| mysql-relay-bin.000002 | 201 | Format_desc    |         5 |           0 | Server ver: 5.7.26-log, Binlog ver: 4 |
| mysql-relay-bin.000002 | 320 | Anonymous_Gtid |         5 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-relay-bin.000002 | 385 | Query          |         5 |         307 | create database aa                    |
| mysql-relay-bin.000002 | 473 | Anonymous_Gtid |         5 |         372 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-relay-bin.000002 | 538 | Query          |         5 |         467 | drop database world                   |
+------------------------+-----+----------------+-----------+-------------+---------------------------------------+


# POS 节点号为relay-log中的pos节点号
# End_log_pos 为binlog中的pos节点号

过滤复制

需求

image.png

blog和zh都是测试库,只有wordpre是核心业务,为了减轻主库压力,只复制WordPress库

思路

可以在主库中,让dump_T线程只取WordPress库,即binlog只记录wrodpress库的。
也可以在从库中,让SQL_T只回放wordpress库

主库

vim  /etc/my.cnf
[mysqld]
binlog_do_db=wordpress        #相当于白名单

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000010 |      154 | wordpress    |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

# binlog_do_DB: 只记录哪个库的binlog
#binlog_ignore_DB: 不记录哪个库的binlog

从库

mysql>show slave status\G
# 基于库级别的回放
  Replicate_Do_DB:                
          Replicate_Ignore_DB: 
# 基于表级别的回放
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
# 模糊匹配的表  库.t*  表示只匹配这个库下,以t开头的表
  Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 

vim /etc/my.cnf
[mysqld]
replicate_do_db=wordpress

过滤复制另一种架构

image.png

采用读写分离,减轻读的压力

GTID复制配置

环境准备

# db01
[root@mysql data]# cat /etc/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/data/mysql/data
user=mysql
port=3306
socket=/tmp/mysql.socket
#secure-file-priv=
server_id=5
log_bin=mysql-bin
gtid_mode=on
enforce_gtid_consistency=true
log_slave_updates=1
[mysql]
socket=/tmp/mysql.socket


gitd_mode=on   # 开启gtid
enforce_gtid_consistency=true  #强制gtid的一致性
log_slave_updates=1  #slave更新是否写入日志,在多住和高可用环境中必须加入这个参数

# db02
[root@db02 data]# cat /etc/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/data/mysql/data
user=mysql
port=3306
socket=/tmp/mysql.socket
#secure-file-priv=
server_id=7
log_bin=mysql-bin
gtid_mode=on
enforce_gtid_consistency=true
log_slave_updates=1
[mysql]
socket=/tmp/mysql.socket

# db03
[root@db03 ~]# cat /etc/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/data/mysql/data
user=mysql
port=3306
socket=/tmp/mysql.socket
#secure-file-priv=
server_id=6
log_bin=mysql-bin
gtid_mode=on
enforce_gtid_consistency=true
log_slave_updates=1
[mysql]
socket=/tmp/mysql.socket

#master
grant replication slave on *.* to repl@'10.0.0.%' identified by '123';
# slave
CHANGE MASTER TO
MASTER_HOST='10.0.0.11',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3306,
MASTER_AUTO_POSITION=1;

start slave;
show slave status\G;

# master_auto_position  开启读取relay-log的最后一个事件,告诉主库这个事件之后给我

GTID复制和普通复制的区别

非GTID

CHANGE MASTER TO
MASTER_HOST='10.0.0.11',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000009',
MASTER_LOG_POS=183134,
MASTER_CONNECT_RETRY=10;

GTID

CHANGE MASTER TO
MASTER_HOST='10.0.0.11',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3306,
MASTER_AUTO_POSITION=1;

GTID 从库写入错误

查看监控信息:
Last_SQL_Error: Error 'Can't create database 'oldboy'; database exists' on query. Default database: 'oldboy'. Query: 'create database oldboy'

Retrieved_Gtid_Set: 71bfa52e-4aae-11e9-ab8c-000c293b577e:1-3
Executed_Gtid_Set:  71bfa52e-4aae-11e9-ab8c-000c293b577e:1-2,
7ca4a2b7-4aae-11e9-859d-000c298720f6:1

注入空事物的方法:

stop slave;
set gtid_next='99279e1e-61b7-11e9-a9fc-000c2928f5dd:3';
begin;commit;
set gtid_next='AUTOMATIC';
    
这里的xxxxx:N 也就是你的slave sql thread报错的GTID,或者说是你想要跳过的GTID。
最好的解决方案:重新构建主从环境

半同步(了解)

解决主从复制数据一致性问题

主从数据不一致的原因

当IO线程拿到数据到TCP/IP缓存时,从库宕机,导致数据没有写入成功。从库在启动会导致主从数据不一致

解决办法(数据库层面的ACK)

从库relay log 落地,IO线程会返回一个ACK,主库的ACK_reciver收到ack,才会写入事务成功,如果超过10秒,ACK没有返回,会自动切换为异步复制

上一篇 下一篇

猜你喜欢

热点阅读