基于主从同步实现高可用、高性能的MySQL架构,有如下三种方案,权衡对比如下。
通常备库设置为
readonly
模式(对超级权限无效),以此来判断该节点为从节点。可以防止在备库上出现误操作,防止切换逻辑有BUG,在切换过程中出现双写,造成主备不一致。
方案 | 高可用 | 可能丢数据 | 性能 |
---|---|---|---|
一主一从(异步复制,手动切换) | 否 | 可控 | 好 |
一主一从(异步复制,自动切换) | 是 | 是 | 好 |
一主二从(同步复制,自动切换) | 是 | 否 | 差 |
MySQL 自身就提供了主从复制的功能,通过配置就可以让一主一备两台 MySQL 的数据库保持数据同步,具体的配置方法可以参考MySQ官方文档。
从库的数据是有可能比主库上的数据旧一些的,这个主从之间复制数据的延迟,称为“主从延迟”。正常情况下,主从延迟基本都是毫秒级别,你可以认为主从就是实时保持同步的。麻烦的是不正常的情况,一旦主库或者从库繁忙的时候,有可能会出现明显的主从延迟。
MySQL内置有binlog
(实时的增量备份)和relay log
两种日志文件。
MySQL 也支持同步复制,开启同步复制时,MySQL 主库会等待数据成功复制到从库之后,再给客户端返回响应。配置多个从库来解决从库宕机阻塞主库的问题。
binlog
中binlog
中的数据内容,通过网络发送给从数据库中的relay log
中relay log
记录,对主数据库进行备份操作
mysqlbinlog
工具可以解析并查看binlog
中的内容。mysqlbinlog -vv data/master.000001 --start-position=8900;
mysql> show variables like '%log_bin%';
+---------------------------------+-----------------------------------------+
| Variable_name | Value |
+---------------------------------+-----------------------------------------+
| log_bin | ON |
| log_bin_basename | /var/lib/mysql/mysql-master-0-bin |
| log_bin_index | /var/lib/mysql/mysql-master-0-bin.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
| sql_log_bin | ON |
+---------------------------------+-----------------------------------------+
6 rows in set (0.00 sec)
mysql> show master status;
+---------------------------+-----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------------------+-----------+--------------+------------------+-------------------+
| mysql-master-0-bin.000053 | 464152221 | | | |
+---------------------------+-----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
可以看到当前这个数据库已经开启了 binlog
,log_bin_basename
表示 binlog 文件在服务器磁盘上的具体位置。
show master status
命令可查看当前 binlog
的状态,显示正在写入的 binlog 文件,及当前的位置。
假设每天凌晨用 mysqldump 做一个全量备份,然后开启了
binlog
,有了这些,就可以把数据恢复到全量备份之后的任何一个时刻。
binlog
# 1. 恢复全量备份的数据
mysql -uroot test < dump.sql
# 2. 恢复binlog记录的数据
mysqlbinlog --start-datetime "2020-02-20 00:00:00" --stop-datetime "2020-02-20 15:09:00" /usr/local/var/mysql/binlog.000001 | mysql -uroot
注意点:
因为回放 binlog 的操作是具备幂等性的(为了确保回放幂等,需要设置 binlog 的格式为 ROW 格式),多次操作和一次操作对系统的影响是一样的,所以重复回放的那部分 binlog 并不会影响数据的准确性。
海量请求会使数据库的读写操作处于长期的高并发环境中,为了保证高并发环境下的数据安全,需要设计数据库的事务隔离级别,或者采用一些加锁机制。
将数据库的读操作和写操作分离,将大部分的读操作汇聚到从数据库中,将相对较少的写操作集中在主数据中。读写分离后:
用户与数据库之间的拦截处理:读写分离,分库分表等。
原理:通过算法将对同一对象的写操作映射到多个数据库形成一对多的关系,读操作需要在拆分后的库或者表中进行数据拼接操作。
分库分表都是水平拆分。基于微服务可以采用垂直拆分,让每个微服务独立的存储到一个数据库里边。
MyCat
实现分库分表和读写分离操作。
中间件单点故障问题。
部署去中心化的中间件集群,使用多个MyCat实例,通过一个虚拟IP来访问。
可以借助
explain
关键字来查询SQL执行计划,在通过SQL执行计划来进行具体的分析和调优。
使用慢查询日志或者mysqldumpslow
等一些慢查询工具,直接找到性能较低的SQL语句,从而有针对性的进行优化。