前言
最近一直在思考一个问题,我们的数据库是如何保证高可用的,比如突然因为掉电或者其他原因导致数据库不可用了,因为是基于内存的数据库,理论上来说数据库断电后,内存中的东西就会清空了。那么多数据突然丢失很难处理。虽然一直在搞这些国产化数据库的内容,但是做为应用端很少关注这些组件的部署情况。今天就记录一下内存数据库如何做高可用。
一条修改语句的执行流程
下面分析一下存储引擎层面的操作是怎么样的。 当update一条数据时,数据首先会写入redo日志,然后再写入缓冲池,此时数据库的缓冲池的数据是最新的,而磁盘的数据是未修改之前的,需要将缓冲池中的内容刷新到磁盘中。但是如果一条数据更新之后就要将缓冲池中的内容刷新到磁盘显然效率不是很高。如果等到缓冲池中有多个修改记录时一把刷入磁盘,那显然效率更高一些。mysql其实就是这么干的,什么时候去统一刷新数据到磁盘,这个时间点就叫做Check Point。但是如果在还没有刷入磁盘时进行查询,岂不是要获取到脏数据了?实际上当查询时还是会先查询缓存页,如果缓存页没有则再从磁盘查询。
上面的修改场景,如果在执行check point之前数据库发生了意外,比如掉电或者其他问题导致数据库故障,那么前面被修改的数据还没有被持久化到磁盘,这个时候如果再启动数据库刚才修改的数据是没有的,需要从redo日志中恢复数据。据我了解到的真实场景是这样的,如果数据库一个节点发生了异常,那么数据库会切换到新节点,保持高可用。
问题
了解下来,我其实还有以下疑惑,需要咨询专家答疑。
1、数据库节点发生意外,通过什么手段感知到的?什么情况下才会选举主节点?
20231015 公司分布式数据库有类似zookeeper的注册中心,通过心跳检测来发现节点是否可用
2、数据库采用分布式,如果判断数据存储在哪个节点?
根据数据库的分片键
3、数据库进行动态扩容时,数据是怎么保存的,会影响之前节点所保存的数据吗?
一致性哈希算法
4、单个节点发生意外之后,redo日志就停止更新了,之后恢复是根据什么恢复的?
redo日志也会从主节点同步
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第28天,点击查看活动详情