高可用架构方案

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

LVS Nginx

主备系统:有高可用性,但是需要切换,是单活的架构

KA , MHA, MMM

真正高可用(多活系统)

NDB Cluster Oracle RAC Sysbase cluster , InnoDB Cluster(MGR),PXC , MGC

主从复制前提

1、两台以上mysql实例 ,server_id,server_uuid不同

2、主库开启二进制日志

3、专用的复制用户

4、保证主从开启之前的某个时间点,从库数据是和主库一致(补课)

5、告知从库,复制user,passwd,IP port,以及复制起点(change master to)

6、线程(三个):Dump thread IO thread SQL thread 开启(start slave)

主从复制过程描述

1.change master to 时,ip pot user password binlog position写入到master.info进行记录

2. start slave 时,从库会启动IO线程和SQL线程

3.IO_T,读取master.info信息,获取主库信息连接主库

4. 主库会生成一个准备binlog DUMP线程,来响应从库

5. IO_T根据master.info记录的binlog文件名和position号,请求主库DUMP最新日志

6. DUMP线程检查主库的binlog日志,如果有新的,TP(传送)给从从库的IO_T

7. IO_T将收到的日志存储到了TCP/IP 缓存,立即返回ACK给主库 ,主库工作完成

8.IO_T将缓存中的数据,存储到relay-log日志文件,更新master.info文件binlog 文件名和postion,IO_T工作完成

9.SQL_T读取relay-log.info文件,获取到上次执行到的relay-log的位置,作为起点,回放relay-log

10.SQL_T回放完成之后,会更新relay-log.info文件。

11. relay-log会有自动清理的功能。

细节:

1.主库一旦有新的日志生成,会发送“信号”给binlog dump ,IO线程再请求

过程

准备一个多实例环境

这里使用3307(主) 3308(从)

3307操作内容

1、主库授权复制用户rep

[root@db1 3307]# mysql -uroot -p -S /opt/data/3307/mysql.sock
grant replication slave on *.* to rep@'11.11.11.19' identified by 'YANqi123!';
mysql> show grants for rep@'11.11.11.19';
+-------------------------------------------------------+
| Grants for rep@11.11.11.19 |
+-------------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO 'rep'@'11.11.11.19' |
+-------------------------------------------------------+
1 row in set (0.00 sec)
mysql> flush privileges;

2、锁表备份

mysql> flush table with read lock;

注:锁表后不能退出窗口,需要另开连接窗口。

3、导出备份

mysqldump -uroot -pv,qZo#%?q0z* -A -S /opt/data/3307/mysql.sock --master-data=2 --single-transaction -R --triggers|gzip >/data/backup/rep_bak_$(date +%F).sql.gz

如果不在同一台服务器上,备份出来的数据拷贝到3308服务器上

4、解锁,开放用户写入功能。

mysql> unlock table;

Query OK, 0 rows affected (0.00 sec)

3308操作内容

1、把主库的全备导入到从库

[root@db02 backup]# gzip -cd rep_bak_2016-08-28.sql.gz >rep.sql

2、重置从数据库

[root@db1 3308]# mysql -uroot -pv,qZo#%?q0z* -S /opt/data/3308/mysql.sock
mysql> reset slave all;
[root@db1 ~]# grep mysql-bin.00 /data/backup/rep_bak_2020-10-21.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=2034;

3、导入数据

mysql> source /data/backup/rep.sql

mysql -uroot -pv,qZo#%?q0z* -S /opt/data/3308/mysql.sock

4、执行change master to语句,生成master.info文件

需mysql终端执行如下语句;(主库的信息)

mysql> change master to
-> MASTER_HOST='11.11.11.19', #主库地址
-> MASTER_PORT=3307, #主库端口
-> MASTER_USER='rep', #同步的账号
-> MASTER_PASSWORD='YANqi123!', #同步账号的密码
-> MASTER_LOG_FILE='mysql-bin.000004', #全量备份后,生成的binlog文件名
-> MASTER_LOG_POS=2034 #全量备份后的位置点
-> MASTER_CONNECT_RETRY=10; #主从连接失败,间隔多久后重试。
Query OK, 0 rows affected, 2 warnings (0.02 sec)

5、开启从库开关

mysql> start slave;

测试:

主库创建数据库或表后,在从库上查是否有同步过来

查看同步状态

mysql -uroot -pv,qZo#%?q0z* -S /opt/data/3308/mysql.sock -e "show slave status\G;" |egrep "Yes|Seconds_Behind_Master"

Slave_IO_Running: Yes #客户端IO进程的工作状态

Slave_SQL_Running: Yes #客户端sql进程的工作状态

Seconds_Behind_Master: 0 #数据同步延时,0代表是实时同步的,主库比从库延迟多少秒

主从状态说明

主库

如果显示非一下信息表示主从有问题

mysql> show full processlist;
+----+------+-------------------+------+-------------+-------+---------------------------------------------------------------+-----------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-------------------+------+-------------+-------+---------------------------------------------------------------+-----------------------+
| 9 | rep | 11.11.11.19:33664 | NULL | Binlog Dump | 11232 | Master has sent all binlog to slave; waiting for more updates | NULL |
| 11 | root | localhost | NULL | Query | 0 | starting | show full processlist |
+----+------+-------------------+------+-------------+-------+---------------------------------------------------------------+-----------------------+
2 rows in set (0.00 sec)

从库

mysql> show slave status\G

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

主库相关信息

Slave_IO_State: Waiting for master to send event

Master_Host: 11.11.11.19

Master_User: rep

Master_Port: 3307

Connect_Retry: 60

Master_Log_File: mysql-bin.000004

Read_Master_Log_Pos: 2626

从库中继日志应用状态

Relay_Log_File: db1-relay-bin.000002

Relay_Log_Pos: 912

从库复制线程有关状态

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:

延时从库有关的状态(人为)

SQL_Delay: 0

SQL_Remaining_Delay: NULL

主从延时相关状态(非人为)

Seconds_Behind_Master: 0

GTID 复制有关的状态

Retrieved_Gtid_Set:

Executed_Gtid_Set:

Auto_Position: 0

FAQ:报错处理

mysql> show slave status\G

*

Replicate_Wild_Ignore_Table:

Last_Errno: 1007

Last_Error: Error 'Can't create database 'test'; database exists' on query. Default database: 'test'. Query: 'create database test'

Skip_Counter: 0

Exec_Master_Log_Pos: 4244

Relay_Log_Space: 18413

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 'test'; database exists' on query. Default database: 'test'. Query: 'create database test'

Replicate_Ignore_Server_Ids:

Master_Server_Id: 1

1 row in set (0.00 sec)

方法一

mysql> stop slave; # 临时关闭
Query OK, 0 rows affected (0.00 sec
# 将同步指针,向下移动一个,如果多次不同步,可以重复操作
mysql> set global sql_slave_skip_counter=1;
# 也可以像下面一样移除多个;
mysql> set global sql_slave_skip_counter=2;
Query OK, 0 rows affected (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

方法二

配置文件my.cnf修改如下,根据可以忽略的错误号事先在配置文件中添加好,跳过指定的不影响与业务数据的错误。

具体的错误代码可看官方手册。

grep slave-skip /data/3307/my.cnf

slave-skip-errros = 1032,1062,1007

常见错误代码:

1007:对象已存在

1032:无法执行DML

1062: 主键冲突或约束冲突

其他可能引起复制故障的问题:

1、mysql自身的原因及认为重复插入数据。

2、不同版本的数据库版本,引起不能同步。

3、mysql运行错误或程序bug

4、binlog记录模式。如row level模式比默认模式statement语句模式要好。

但是,以上操作有时是有风险的,最安全的做法就是重新构建主从。把握一个原则,一切以主库为主.

其他