连续复制(也称为日志传送和重播)是Microsoft Exchange Server 2007 中的一个新技术。它创建和维护数据库备份来为邮箱数据库提供完全的高可用性和灾难恢复解决方案。随着Exchange Server 2007 Service Pack 1 (SP1)的发布,现在有三种形式的连续复制。
本地连续复制(LCR) LCR是单服务器解决方案,在与主动存储组所在的服务器相连接的另一个磁盘集上创建并维护存储组的副本。
群集连续复制(CCR)CCR是 一项高可用性功能,它为电子邮件服务和邮箱数据提供故障转移功能,通过群集技术使用连续复制来为服务器冗余提供数据冗余的一个备份。
备用连续复制 (SCR) SCR是一个灾难恢复功能,它通过连续复制来创建和维护存储组的多个备份。SCR 实现了高可用性(包含服务和数据可用性)与站点弹性的分离。例如,SCR 可以与 CCR 相结合,以在主数据中心本地复制存储组(使用 CCR 实现高可用性),并在辅助或备份数据中心远程复制存储组(使用 SCR 实现站点弹性)。辅助数据中心可以在 SCR 目标所在的故障转移群集中驻有一个被动节点。这种类型的群集称作备用群集,因为它并不包含任何群集邮箱服务器,但是可以在恢复方案中为其快速提供一个替代群集邮箱服务器。如果主数据中心发生故障或丢失数据,可以在备用群集上快速激活该备用群集中的 SCR 目标。
连续复制基础
连续复制利用Exchange 服务器数据库恢复支持,来提供异步更新一个邮箱数据库的一个或多个副本技术。每个邮箱服务器记录主动数据库生成的数据库更新,将它以日志的形式记录在连续的1MB的事务日志文件中。这些文件的集合被当作日志流。日志流被用来备份和服务器崩溃后恢复。
在连续复制中,日志流也被用来异步更新一个数据库的一个或多个副本。这是通过传送日志到包含主动存储组副本的位置,然后重播它们到数据库副本中。如果来自主动数据库的所有日志都被重播到数据库的副本中,那么这两个数据库是相同的。
连续复制在存储组级别上配置和管理。然而,因为连续复制要求一个存储组只能包含一个数据库,连续复制有效地运行在数据库级别上。
该文章将深入研究连续复制的内部原理,解释使用连续复制成为可能的邮箱服务器角色的关键组件。
用简单的话来说,连续复制执行下面这些步骤:
复制组件
代表日志生成、日志传送和日志重播活动的两个关键服务是:
1. Microsoft Exchange Information Store service 代表服务用户和应用请求,执行写前面的日志,通过Extensible Storage Engine (ESE) 更新数据库文件。
2. Microsoft Exchange Replication Service 代表日志传送和重播数据库副本上的日志。
Information Store 服务功能
当数据库中的数据被检索、插入或修改的时候,ESE执行下面的步骤:
1. 一个操作发生于数据库(一个客户端发送了一个新的邮件),请求更新的页面从数据库中读出并被放到ESE的缓存(假设该页面不在内存中),而日志缓冲器被通知,它在内存中记录这个操作。
2. 这些更改被数据库引擎记录下来,但是这些更改没有被立刻写到硬盘上的数据库文件中 。实际 上,这些更改保存在ESE的缓存中,它们被称为使用过的页面,因为它们还没有被提交到数据库文件。存储版本被用来跟踪这些更改,这样可以确保被隔离,并且保持一致性。
3. 当数据库页面发生更改,日志缓冲器被通知来提交更改,事务被记录在事务日志文件中,它也许要求或不要求关闭现有的Exx.log文件并开始生成一个新的日志。(注意ESE也代表关闭一个日志文件一旦它达到最大值(1MB)并开始生成一个新的。)
4. 最终使用过的数据库页面被写到硬盘上的数据库文件中。
5. 检查点被增加。
复制服务功能
当连续复制被激活后,Microsoft Exchange 复制服务 (简称复制服务)用来检测当现有日志文件被ESE关闭的时候,拷贝它,检查它,然后重播它到数据库副本中。该服务在缺省情况下被安装在所有的已经安装邮箱服务器角色的服务器上。
复制服务的可执行文件是Microsoft.Exchange.Cluster.ReplayService.exe,在缺省情况下它位于<安装路径>\bin。复制服务依赖于Microsoft Exchange Active Directory Topology Service 。复制服务能够被停止和启动使用服务控制台或命令行,它也能够被配置为自动启动万一失败或意外发生。
复制服务存储它自己的关于诊断信息在注册表中下面的位置:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\MSExchange Repl\Diagnostics
注意:通过Exchange Management Shell(例如,Get-EventLogLevel -Identity "MSExchange Repl"或 Set-EventLogLevel -Identity "MSExchange Repl" -Level High),您能够查询或设置复制服务的当前的诊断级别。
复制服务组件
复制服务使用几个组件来提供活动存储组和活动存储组的一个或多个副本之间的连续复制。下面的组件参与了连续复制过程。
LogCopier 代表拷贝关闭的日志从源存储组到包含副本存储组的目的服务器上。这是一个异步的操作,复制服务连续监视源存储组的日志文件目录。它通过订阅Windows 文件系统通知事件来完成该监视。当源服务器上一个新的日志文件被关闭,触发一个事件来通知复制服务一个新的文件存在。LogCopier将接着拷贝该日志文件到目标服务器上的检查位置。
LogInspector 代表验证日志文件是有效的。它周期性地检查目的检查目录。如果发现一个日志文件损坏或不能被重播,复制服务将请求重新拷贝该文件。
LogReplayer 代表重播被检查过的日志文件到数据库副本中。
LogTruncater 代表删除那些已经被成功重播到数据库副本中的日志文件。这相当重要,因为通常在一次完整或增量备份后,位于检查点以下的日志文件将被删除因为包含在这些日志文件中的日志记录已经被写入到数据库中。当连续复制被使用的话,LogTruncator 只删除那些不需要用于恢复和重播的日志文件。任何主动副本上还没有被复制和重播到数据库副本的日志文件不会被主动副本的在线备份删除。
Incremental Reseeder 代表确保主动数据库和数据库副本没有分歧在执行一次数据库恢复之后,或在CCR环境中发生一次切换之后。
Seeder 代表创建存储组的基线内容用于启动重播过程。复制服务为新的存储组执行自动种子设定,也为包含所有可用日志(包括第一个日志文件,它包含了CreateDB记录)的任何已经存在的存储组自动设定种子。
Replay Manager 代表跟踪所有复制的实例。它根据需要创建和销毁实例,基于存储组的在线状态。复制实例的配置是静态的。因此,当一个复制实例配置被更改,该复制将被重启同时更新配置。此外,在关闭复制服务的期间,复制实例配置是不被保存的。结果是,每次复制服务启动的时候有一个空的复制实例列表。在启动期间,重播管理器发现那些目前在线的存储组,并创建一个运行的实例列表。
重播管理器周期性运行一个名称为configupdater的线程来扫描新配置的复制实例。configupdater 线程运行在复制服务进程中,对于LCR或CCR每隔30秒,对于SCR每隔3分钟。它将基于当前的数据库状态创建和销毁复制实例(不管数据库是否在线)。configupdater 线程使用下面这些算法:
因此,重播管理器总是拥有复制实例的动态列表。
复制服务配置信息
每个激活了LCR的存储组和数据库有msExchHasLocalCopy 属性。复制服务使用下面的算法来查找活动目录中复制信息。
a) 对msExchHasLocalCopy 设置为true的每个存储组,检索系统文件、日志文件和数据库文件的源和目的路径。
在一个CCR的环境中,复制服务执行下面的任务来检索群集邮箱服务器的配置。
1. 建立到群集数据库的连接。
2. 判断哪个节点拥有群集邮箱服务器。
3. 枚举源和目的节点上所有的存储组,用于复制的不同设置有下面这些:
a) 系统文件、日志文件和数据库文件的源和目的路径。
b) 返回存储组的最后的拥有者(假设该存储组以前已经被加载)。
c) 用于日志发送的网络共享。
d) AutoDatabaseMountDial 设置。
e) ForcedDatabaseMountAfter 设置。
f) 决定正确的日志发送网络路径。
4. 验证源节点上的配置和目的节点一样。
对于SCR环境,复制服务使用msExchStandbyCopyMachines 属性来识别哪个存储组激活和复制,然后它执行下面的任务:
1. 使用计算机名称来查找Exchange 服务器对象。如果没有服务器对象的话就返回。
2. 枚举这台Exchange 服务器上所有的存储组。对含有msExchStandbyCopyMachines 设置的每个存储组,执行下面的操作:
a) 为每个目的服务器检索ReplayLagTime 和TruncationLagTime 参数。
b) 检索系统文件、日志文件和数据库文件的源和目的路径。
复制服务通信协调
主动实例和被动实例之间的复制服务通信通过下面三种机制来实现:
日志文件 特定的信息,像备份状态和数据库头变化,被记录在主动实例的日志文件中,并被复制到副本,从而更新数据库副本。
群集数据库或注册表 在群集数据库(CCR)或注册表(LCR/SCR)中,复制服务基于每个存储组存储重播状态数据。被写到这些地方和从这些地方读取的数据是永久状态信息,例如:
在Exchange 2007的RTM版本中,注册表和群集数据库被用来存储运行时间状态(准确地说我们处于复制过程中)。然而,在SP1中这个发生了变化以便管理任务直接通过RPC和复制服务通信来获得该信息。运行时间状态数据仍被写到注册表和群集数据库,然而管理任务不在从这些地方读取这些数据。
存储过程 复制服务将生成RPC 调用给活动实例上的存储过程用于配合日志截断。
日志发送和重播
现在我们对涉及到的核心组件有一个基本的了解,我们能够讨论日志发送如何工作的。在日志文件能够被发送到被动副本之前,主动数据库副本必须先被设置种子。这能够通过几种方法来完成。
1. 自动种子设定 自动种子设定将在目标中产生存储组数据库的副本。自动种子设定要求 所有的日志文件包括被存储组创建的第一个日志文件(它包含了数据库创建日志记录)在源中可用。自动种子设定只发生在新建服务器、新建存储组和数据库期间。
2. 使用 Update-StorageGroupCopy cmdlet 设定种子 可以在 Exchange 命令行管理程序中使用 Update-StorageGroupCopy cmdlet 将存储组副本设定为种子。您也能够使用Exchange 管理控制台中的Update Storage Group Copy 向导来将存储组副本设定为种子。
3. 手动复制脱机数据库 此过程卸除数据库并将数据库文件复制到被动节点的相同位置。如果使用此方法,会出现服务中断,因为此过程需要卸除数据库。
第二个选择是利用流备份API来将数据库从主动位置拷贝到目标位置。
注意: 您能够根据需要手动抑制速度通过修改位于HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Replay\Parameters 中ESE Read Hint Size (KB)键值。支持的值的范围从24K到 (200*1024) KB,缺省值为1024KB。如果您决定改变该值,您应该在模拟生产环境的实验环境中验证该更改,并通过更改该值调整测试直到您找到满足您的要求的一个设置。缺省的值将给您一个最好的吞吐量,如果您考虑更改该值,它将只能使拷贝的速度减少。
复制服务也确保所有相关的路径为日志检查目录、日志目录和检查点文件目录创建。
在CCR或SCR环境中,有两个复制服务参与了拷贝存储组数据。一个在源节点上;另外一个在被动节点或目标上。源节点上的服务代表创建只读隐藏共享为每个存储组的日志目录。共享有下面的结构:
共享名称: <存储组 GUID>$
文件夹路径: <drive>:\<存储组日志文件夹路径>
共享权限: <根域>\Exchange Servers – 读
文件夹权限: <根域>\Exchange Servers –读, <计算机>\Administrators – 完全控制, SYSTEM –完全控制
注意:尽管文件能够被列出和拷贝,当您通过Windows Explorer 来查看共享的时候,您将发现Exchange Servers security group 的'Read' 权限选项没有被选中。这是由于一个访问标记没有被设置。
取决于环境,SCR目标的服务将使用特定的名称空间连接。
· CCR被动节点上的复制服务始终连接到\\nodenameActive 去拉日志到被动节点。
· SCR目标上的复制服务,当连接到CCR源环境,连接到\\nodenameActive 去拉日志到SCR目标。
· SCR目标上的复制服务,当连接到SCC源环境,连接到\\CMSName 去拉日志到SCR目标。
· SCR目标上的复制服务,当连接到独立邮箱服务器,连接到\\ServerName 去拉日志到SCR目标。
每次复制服务启动,它将检查保证邮箱服务器上的每个存储组有日志文件夹被共享。当新的存储组被创建,一个共享被创建。如果共享存在的话,它们不会被重建。如果共享上的权限被修改,复制服务将不会重新应用权限。对于这种情况,只要简单地删除共享然后回收源节点上的复制服务来重建它。
目标上的复制服务使用文件系统通知来检测新的日志文件当它们被关闭的时候。下面的步骤解释复制服务如何处理日志拷贝、检查和重播。对于这些步骤中的每一个,对应的标志被被目标节点上的复制服务更新和维护。这些被复制服务使用的标志用来跟踪它在日志复制过程(存储在群集数据库中,可以通过Get-StorageGroupCopyStatus和目标节点上的性能监视器来得到)中的位置。
注意:在LCR和CCR之间有两个关键的不同。首先,在LCR中只有一个单一的复制服务,由于LCR是单服务器解决方案。第二,LCR不会用到文件共享。实际上,复制服务简单使用文件系统通知来检测新的日志文件然后拷贝日志到被动实例位置。
1. 源日志目录中的一个日志文件被关闭。在源目录中看到的LastLogCopyNotified被最后生成的日志更新。
注意:存储过程每隔20秒更新群集数据库(或注册表)中的LastLogGenerated 字段。目标上的复制服务也观察日志更改通知,并更新它自己的反映在状态中的内部计数器。 作为结果,如果目标上的复制服务没有运行的话,接着LastLogGenerated 值将会被用作标记,它在20秒后过期。
2. 目标节点的复制服务在管理代码级别(LogCopier) 利用一个进程来拉日志文件到目的节点通过服务器消息块(SMB)。拷贝的日志文件接着被放置到位于存储组的日志文件中的检查目录。日志被放置到检查目录以便它们被隔离,同时不会因为意外重播到副本数据库中直到它们已经完成了检查。LastLogCopied 被更新当一个日志被成功拷贝到检查目录。
3. 日志文件通过LogInspector 被检查并被移动到被动日志目录。LastLogInspected 被更新当一个日志被成功检查。
a) 如果日志拷贝或日志检查失败,复制服务将企图重新拷贝日志文件并重新检查。复制服务在标记日志文件为不可恢复之前将执行三次,并要求数据库重新设定种子。
4. 日志文件被复制服务(LogReplayer)重播到数据库副本。LastLogReplayed 被更新当一个日志文件被成功地重播到数据库中。
注意:在RTM中,LCR利用一个计量器逻辑用于日志重播。在缺省情况下,日志重播队列组间隔设置为10。这是一次重播最小数量的日志数。如果在日志重播计量器期间(缺省60秒)没有日志收到,接着一个更小的队列被使用。该逻辑在SP1中已经被删除,由于结构更改保持被动数据库实例在日志反复重播之间被及时更新,它减少了被动实例上的I/O负载,从RTM负载 2-3倍主动实例到0.5-1倍主动实例。
日志检查
下面的动作被LogInspector 执行:
1. 物理的完整性检查 该验证利用ESEUTIL /K 对日志文件,验证日志文件中的校验和记录与内存中生成的校验和匹配。
2. 头检查 复制服务验证日志文件头的下面这些方面:
a. 对正被讨论的存储组生成不高于最高生成记录。
b. 日志头中的生成记录匹配日志文件名称中的生成记录。
c. 记录中日志头中的日志文件签名匹配日志文件的。
3. 删除Exx.log 在检查过的日志文件能够被移动到日志文件夹之前,复制服务需要删除任何Exx.log 文件。这些日志被放置到日志目录的另外一个子目录ExxOutofDate 目录。Exx.log 文件将只存在于目标上如果它以前作为源运行。Exx.log 文件需要被移动在日志重播发生之前。因为它包含旧的数据,已经被相同一代的完整日志文件取代。如果关闭的日志文件不是现有的Exx.log 文件的超集,接着我们将必须执行一个增量或完整的重设种子。
日志重播
在日志文件被检查后,它们被放置到日志目录以便它们能够在数据库副本中重播。在复制服务重播日志文件之前,它执行一系列的验证测试。
1. 重新计算要求的日志以便重播能够成功。它验证被检查数据库头需要的最高和最低日志文件。
2. 决定日志目录中出现的最高的日志来保证日志文件存在。如果没有日志文件,那么重播将不能继续。
3. 将日志目录中出现的最高的日志和要求的最高日志文件做比较。只要出现的最高日志等于或高于要求的最高日志,重播能够继续。
4. 确认日志组成了正确的顺序。检查目录中的所有的日志文件是一个慢的过程,因此只有要求的日志被验证。这个被执行用来决定如果恢复立刻失败(假设如果恢复在生成N的时候失败,数据库头将要求生成N-1)。此外验证所有要求的日志文件是可用的,下面额外的验证步骤被执行:
a. 确保日志文件的产生匹配预期的顺序。
b. 确保日志文件的签名是正确的。
c. 确保日志文件的创建时间组成了一个含有以前日志文件的顺序。
5. 查询检查点文件,如果存在的话。
a. 如果检查点文件太高的话,通过定义一个高于要求的最低日志的日志,接着该检查点文件将被删除。
b. 如果检查点太低并指向一个不存在的文件,那么该检查点文件将被删除。
一旦验证检查完成 ,复制服务将重播日志。这实际上是一个特定的恢复模式,它不同于ESEUTIL /R 执行的重播。通常当ESEUTIL /R 执行的时候,它重播所有可用的日志文件包括Exx.log文件,这样保证所有的事务要么被提交到数据库要么被退回。然而,由于在连续复制中,复制引擎总是在一个日志文件的后面(主动Exx.log 文件),恢复的撤消阶段(这里没有提交的事务叫做退回)被跳过用于保证数据库分歧不会发生。
在日志文件被重播后,下面的额外步骤被执行:
1. 验证数据库头中请求的日志被更新。有几种情况数据库头不会更新在一次日志重播事件后。当重播的日志只包含终止和初始的记录将会发生。在这种情况下,毕竟,数据库应该处于一致性状态。
2. 执行LogTruncater 阶段从被动和主动路径删除不需要的日志。这个调用读取完整和增量备份的数据库头信息,因此在这个期间重播被锁定。
计划中断
在计划中断期间,主动存储组实例以干净的方式卸载,被动实例被激活并成为新的活动存储组。在这种情况下,没有数据丢失会发生。当主动存储组被离线,打开的日志文件被关闭。复制服务拷贝任何剩余的还没有被拷贝的日志,它包含最高的生成的日志(打开的Exx.log 文件之前已经被关闭)对每个存储组。每个存储组的日志被检查,接着重播到对应的数据库副本中。数据库副本接着被激活,这样包含了和源一样的数据。
<