`
m635674608
  • 浏览: 5004640 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

日志技术 no redo log

 
阅读更多

分布式系统原理 -- 日志技术 Redo Log

 

 

 

 

 

问题概述

 

在分布式系统中,宕机是需要考虑的重要组成部分。日志技术是宕机恢复的重要技术之一。日志技术应用广泛,早些更是广泛应用在数据库设计实现中。本文先介绍基本原理概念,最后通过 redis 介绍生产环境中的实现方法。

 

 

 

Redo Log

 

数据库设计中,需要满足 ACID,尤其是在支持事务的系统中。当系统遇到未知错误时,可以恢复到一个稳定可靠的状态。有一个很简单的思路,就是记录所有对数据库的写操作日志。那么一旦发生故障,即使丢失掉内存中所有数据,当下一次启动时,通过复现已经记录的数据库写操作日志,依然可以回到故障之前的状态(如果在写操作作日志的时候发生故障,那么这次数据库操作失败)。

 

操作流程简单如下(假设每次数据变化,都提交):

  1. 更新的操作方式依次记录到磁盘日志文件。

  2. 更新内存中的数据。

  3. 返回更新成功结果。

 

恢复流程:

  1. 读取日志文件,依次修改内存中的数据。

 

优点:

  1. 日志文件有序,可以通过 append 的方式写入磁盘,性能很高。

  2. 简单可靠,应用广泛。可以把内存中的数据,做备份在磁盘中。

 

缺点:

  1. 使用时间一长,恢复宕机的时间很慢。

 

 

 

解决办法

 

先具体化下,如果我们内存中保留一个 a 的值,记录了写操作比如 a = 4; a++; a--; 当这些操作上千万、亿之后,恢复非常慢。甚至可能最后一条就是a=0,按照之前的算法,我们却跑了很长时间。

 

那么根据这个场景,很容易想到一个解决方案。

 

操作流程:

  1. 日志文件记录begin check point

  2. 在某个时刻,把内存中的数值,直接 snapshot 或 dump 到磁盘上。(比如直接记录 a=4)

  3. 日志文件记录end check point

 

恢复流程:

  1. 扫描日志文件,找到最后的end check point中配对的begin check point

  2. 读入 dump 文件。

  3. 依次回放记录的日志操作。

 

优点:

  1. 应用广泛,包括 mysql,oracle。

 

一些棘手的问题:

  1. 在做 snapshot 的时候,往往不能停止数据库的服务,那么很可能记录了begin check point之后的日志。那么在重新 load begin check point之后的日志时,最后恢复的数据很有可能不对。比如我们记录的是a++这样的日志, 那么重复一条日志,就会让 a 的值加 1。反之如果我们记录是幂等的,比如一直是 a=5 这种操作,那么就对最后结果没有影响。很显然,设计幂等操作系统很麻烦。

  2. 设计一个支持 snapshot 的内存数据结构,也比较麻烦。

 

典型的是通过 copy-on-write 机制。和操作系统中的概念一样。当这个数据结构被修改,就创建一份真正的 copy。老数据增加一份 dirty flag。如果没有修改就继续使用之前的内存。这样在做 snapshot 的时候,保证我们的 dump 数据是begin check point这个时刻的数据。显然这个也比较麻烦。

 

还有一种支持 snapshot 的思路是begin check point后,不动老的数据。内存中的数据在新的地方,日志也写在新的地方。最后在end check point做一次 merge。这个实现起来简单,但是内存消耗不小。

 

 

 

 

 

Redis 是如何解决日志问题的

 

Redis 是一个基于内存的 database,不同于 memcached,他支持持久化。另外由于 redis 处理 client request 和 response 都是在一个 thread 里面,也没有抢占式的调度系统,核心业务都是按照 event loop 顺序执行,而磁盘写日志又开销很大,所以 redis 实现日志功能做了很多优化。并且提供 2 种持久化方案。我们需要在不同的场景下,采用不同的方式配置。

 

 

 

snapshotting

 

某个时刻,redis 会把内存中的所有数据 snapshot 到磁盘文件。更通俗的说法是 fork 一个 child process,把内存中的数据序列化到临时文件,然后在 main event loop 中原子的更换文件名。redis,利用了操作系统 VM 的 copy-on-write 机制,在不阻塞主线程的情况下,利用子进程和父进程共享的 data segment 实现 snapshot。具体是代码实现在rdb.c, function at rdbSaveBackground

  1. 简单可靠,如果 database 不大,执行的效果非常好。

  2. 如果 database size 很大,每一次 snapshot 时间非常长。不得不配置大的间隔,提高了宕机时数据丢失的风险。

 

为了解决上面的问题,redis 增加了 AOF。

 

 

 

Append Only File(AOF)

 

在 database 术语中,也被叫做 WAL。如果开启的 AOF 的配置,redis 会记录所有写操作到日志文件中。那么 redis 同样会遇到之前我们提到过的问题。

  1. 即便是追加写,磁盘的操作依然比内存慢好几个数量级,频繁的操作容易产生瓶颈。

  2. 如果数据量操作频繁,会产生大量的重复日志数据,导致恢复时间太长。比如记录一条微博的浏览量,会记录大量重复的+1日志。

 

那么 redis 是如何解决的呢?

  1. 文件写操作消耗的时间很长,redis 会先把记录日志写在内存 buffer 中,在每一次 event loop 结束之后,根据配置判断是否做写操作。每个 buffer 的大小有限制,这样每次写操作时间不会太长。

  2. 即便是调用 write 操作,OS 并没有立即写入磁盘,redis 同样提供了一些方案决定刷新 OS IO buffer 的时机(1 秒、从不、每次)。

  3. redis 提供一种 AOF 重写的方式rewriteAppendOnlyFile来处理 AOF 文件过大情况。

 

前面我们知道了,这种check point的机制还是比较麻烦的。那么 redis 是这么设计的。

 

  1. 为了避免加锁,redis 依然创建了一个 child process,利用 VM 的 copy-on-write,共享数据。同时保证主线程依然可以处理 client 请求。

  2. 根据 KV 的类型,先从内存读取数据,然后再写数据到磁盘,和之前的 AOF 文件无关。

  3. 那么当子进程 rewrite AOF 的过程中,main thread 依然可以处理新的 client request。新增的数据会被放在 rewrite buffer 中,而且写到原有的 AOF 文件中。

  4. child process 完成后会通知主线程。主线程有一个定时任务,也就是会不断轮询 child process 是否已经完成(通过信号量)。

  5. 主线程会 merge 变化的数据到 temp file。

  6. 主线程原子的 rename 到一个新的 AOF 文件,之前的 AOF 就不起作用了。

 

优点:

  1. 除了 merge 和 rename 需要阻塞主线程,rewrite 不会阻塞主线程。(前提是使用 bgrewrite command)。

 

 

 

 

 

最后

 

这些都是性能和稳定性之间做的权衡,根据不同场景需要调整。

 

 

 

 

 

参考

 

 

  • Redis latency problems troubleshooting

  • 分布式系统原理介绍

  • Thoughts on Redis

 

 

 

 

 

http://studentdeng.github.io/blog/2014/10/13/log-system/

 

 

 

 

 

分布式系统原理 -- 日志技术 No Redo Log

 

 

 

 

 

上一篇介绍了 Redo Log,这篇介绍 No Redo Log。

 

在分布式系统中,某些情况下我们依然需要实现原子操作,有很多方式,其中 No Redo(Undo) Log 便是在工程中运用最广泛的思想之一。他的过程非常简单。

 

下面是一个简单系统的状态。

 

为了实现原子的修改 A,B,C 的值。我们把 A,B,C 看成一个集合,或是一个 “目录”。

 

1. 做一次 copy

 

2. 对于每个更新的操作,创建一个新的 item,然后在新的目录中保存修改后的新值。

 

3. 原子性的修改生效目录指针。

 

通过原子性的修改一个值,切换一个状态,完成一系列分布式操作原子性的修改。

 

 

 

 

 

http://studentdeng.github.io/blog/2014/10/17/log-system2/

 

 

 

 

分享到:
评论

相关推荐

    Log Explorer for SQL Server v4.22

    恢复完后,再打开log explorer 提示No log recorders found that match the filter,would you like to view unfiltered data 选择yes 就看不到刚才在2中修改的日志记录,所以无法做恢复. 3) 不要用SQL的备份...

    RAC下的REDO和UNDO管理

    执行`ALTER SYSTEM SWITCH LOGFILE`命令时,只会影响当前节点的当前redo thread进行日志切换,而`ALTER SYSTEM ARCHIVE LOG CURRENT`命令则会作用于所有可用节点,使得所有实例的redo thread进行切换并归档到归档...

    Oracle 11G GUARD

    以上步骤详细介绍了如何在 Oracle 11g 中搭建 Data Guard,从修改日志模式、创建密码文件到创建 Standby Redo Log 日志组,每一个环节都至关重要。通过这些步骤,可以确保在主数据库出现故障时,备用数据库能够快速...

    Log Explorer for SQL Server v4.22 含注册机

    恢复完后,再打开log explorer 提示No log recorders found that match the filter,would you like to view unfiltered data 选择yes 就看不到刚才在2中修改的日志记录,所以无法做恢复. 3) 不要用SQL的备份功能...

    oracle日志丢失数据库恢复技巧

    这些错误表明数据库在启动过程中未能找到第2组线程1的日志文件`redo02.log`和`redo02_1.log`。进一步确认发现这些文件确实不存在于指定路径中。 #### 重做日志的重要性 在Oracle数据库中,重做日志文件是非常重要...

    Log Explorer4.2帮助文档

    恢复完后,再打开log explorer 提示No log recorders found that match the filter,would you like to view unfiltered data 选择yes 就看不到刚才在2中修改的日志记录,所以无法做恢复. 3) 不要用SQL的备份...

    sql2000 Log Explorer4.2(含注册码)+汉化

    恢复完后,再打开log explorer 提示No log recorders found that match the filter,would you like to view unfiltered data 选择yes 就看不到刚才在2中修改的日志记录,所以无法做恢复. 3) 不要用SQL的备份...

    MySQL零拷贝技术详解.pdf

    innodb_flush_method 参数同时控制 redo log buffer 和 innodb buffer pool 缓冲区刷新策略,其中 log files 是 redo log buffer 在内存中的缓存区,log files 是磁盘上的 Redo Log 文件;data files 是 innodb ...

    AWR 报告深度解读:Redo Nowait指标的算法和诊断泄露二十多万名用户数据

    导读:本文将对Redo Nowait指标的算法和诊断进行深度解析。 AWR知识体系:https://www.modb.pro/topic/6165(复制到浏览器打开或者点击“阅读原文”) 曾经遇到过一个性能故障,数据库的检查点执行的非常缓慢,直接...

    LOG FILE SYNC概述

    当事务执行完一系列操作后,需要将redo日志记录写入磁盘,以保证数据的一致性和持久性,此时就会发生LOG FILE SYNC等待。这个等待事件通常具有极短的等待时间,大约在1-5毫秒之间,但在某些情况下,如果出现性能问题...

    联机日志文件损坏后的恢复方法

    例如,在Windows系统重启之后尝试使用`startup`命令启动Oracle数据库时,可能遇到ORA-00333错误,提示为:“redolog read error block string count string”。这通常意味着在读取某个特定的日志文件时发生了I/O错误...

    oracle里的常用命令

    5. **changing the name of the online redo logfile(更改在线重做日志文件名)** - 命令示例: - `ALTER DATABASE RENAME FILE 'c:/oracle/oradata/oradb/redo01.log' TO 'c:/oracle/oradata/redo01.log';` - ...

    DataGuard安装

    但在使用实时日志应用时,RFS 进程会将 primary 的 redo 条目写入 standby 的 standby redolog 文件中,此时日志应用进程可直接读取 standby redolog 文件进行应用。 - **开始日志应用(Starting Redo Apply)** ...

    Oracle 11g物理Active Data Guard详细过程

    - Standby Redo Log 组数 = 主库日志组总数 + 1 - 本例中为 4 组。 - **确认 MAXLOGFILES 和 MAXLOGMEMBERS 参数**: - 需要确保这些参数不会限制 Standby Redo Log 的创建。 - 如果之前设置了限制,则需要修改...

    Oracle的Archive Log模式下的恢复

    在非归档模式下,数据库只能恢复到最近一次完整备份的时间点,而在归档模式下,由于每次事务提交后的redo日志都会被保存为归档日志,因此可以实现时间点恢复,确保数据的完整性。 开启Archive Log模式需要以下步骤...

    oralce基本命令日志

    ALTER DATABASE RENAME FILE 'c:/oracle/oradata/oradb/redo01.log' TO 'c:/oracle/oradata/redo01.log'; ``` **6. 删除在线重做日志组** 当某个重做日志组不再需要时,可以将其删除。 ```sql ALTER DATABASE ...

    oracle系统管理和开发技术要点

    - `$svrmgrl>alter database rename file ‘/dev/rredolog111’ to ‘/dev/billing/redolog111’;` 5. **增加日志文件成员**:如果需要增加日志文件成员,可以通过`alter database add logfile member`命令完成,...

    oracle11g体系架构学习文档

    而数据库(database)本身由数据文件(datafile)、控制文件(control file)和重做日志文件(redo log file)组成。 系统全局区(SGA)是一个共享内存区域,实例中所有用户都可以访问。SGA包含以下几个基本组件: 1. 共享池...

    Oracle 11g体系-全面详解

    - **System Global Area (SGA)**: 分为共享池(Shared Pool)、数据缓冲区缓存(Database Buffer Cache)、重做日志缓冲区(Redolog Buffer)和其他几个组成部分。 - **Program Global Area (PGA)**: 每个会话(Session)...

Global site tag (gtag.js) - Google Analytics