日志发送和重播
现在我们对涉及到的核心组件有一个基本的了解,我们能够讨论日志发送如何工作的。在日志文件能够被发送到被动副本之前,主动数据库副本必须先被设置种子。这能够通过几种方法来完成。
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. 重新计算要求的日志以便重播能够成功。它验证被检查数据库头需要的最高和最低日志文件。
1. 数据库头包含了一个日志签名,这将和日志文件的签名做比较保证它们匹配。
2. 数据库头将报告两种条件中的一个:要么数据库处于一致状态(干净关闭)要么处于不一致状态(异常关闭)。如果数据库是一致的,接着下一个日志文件被提交到 日志位置(LGPOS)将被用来推算出要求的最低和最高的日志文件。如果数据库处于不一致状态,那么要求的日志标记定义要求的日志的最低和最高,。此外, 存储在数据库头中的备份信息被重新阅览来决定被备份的最后生成的日志。
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 文件之前已经被关闭)对每个存储组。每个存储组的日志被检查,接着重播到对应的数据库副本中。数据库副本接着被激活,这样包含了和源一样的数据。
未计划中断
由 于连续复制涉及发送关闭的日志文件,正在被ESE 写的活动的Exx.log 文件仍然被打开在发生故障的时候,不能被拷贝到被动节点。正如传输转储程序部分描述的这个打开的日志代表的数据大多数被中心传输服务器重新提交在发生故障 后。如果我们考虑群集环境,有多种不同的故障能够发生,像服务器硬件故障、存储硬件故障和操作系统故障,还可以列举一些。在未计划中断事件发生,它影响主 动节点,被动节点将使群集邮箱服务器实例上线,那个节点上的复制服务将尝试从遇到故障的节点拷贝丢失的日志文件。如果该拷贝过程成功了(例如,因为服务器 是在线的,共享和必须的数据都可访问),接着存储将加载,不会有数据丢失。如果拷贝过程不成功,接着数据库将根据群集邮箱服务器的 AutoDatabaseMountDial 设置来加载,对于每个存储组的日志复制在它之后有多少日志。对于服务器设置AutoDatabaseMountDial有三种可能的值:
a. Lossless Lossless表示丢失的日志数为零。该属性设置为"Lossless"时,大多数情况下,系统将等到故障节点重新联机后再装入数据库。尽管那样,故障 的系统返回时其所有日志也都必须可访问并且未损坏。发生故障之后,被动节点会成为主动节点,并使 Microsoft Exchange Information Store 服务联机。它将检查是否可装入数据库而不造成任何数据丢失。如果可以,则装入数据库。如果不能,则系统会定期尝试复制日志。如果服务器返回时其日志保持原 样,则该尝试最终会成功,数据库将进行装入。如果服务器返回时其日志未保持原样,则其余日志将不可用,受影响的数据库将不会进行装入。在这种情况下,需要 强制加载数据库这时日志会丢失。
b. Good availability Good availability表示丢失三个日志。"Good availability"可在复制正在正常进行并以生成日志的速率复制日志时,提供完全自动的恢复。
c. Best availability Best availability表示丢失六个日志。"Best availability"是默认设置,其运行方式类似于"Good availability",但允许在复制出现稍长的延迟时进行自动恢复。这样,在故障转移之后,新的主动节点的状态可能会稍微落后于旧的主动节点的状 态,因此增加了数据库出现分歧的可能性,这需要完全重新设定种子来更正。
丢失日志回弹
在有损耗故障的情况下,数据库的源活动和新的活动副本之间有分歧有潜在的可能,要求源活动上的数据库执行完整的重新设定种子当它恢复的时候。一个名为丢失日志回弹的ESE特性提供了数据库源副本的保护,为了让执行完整数据库重设种子的可能性最小化。
在有损耗的故障中,每个存储组至少有一个日志文件丢失(Exx.log),但是也可能有其他关闭的日志丢失。这意味着如果数据库被加载上线,存储在NodeA(故障节点)上的数据和NodeB 上生成的数据不同。这个叫做分歧。
当存储组副本拥有的信息不在主动存储组中这叫分歧。分歧能够在数据库中或日志文件中。有损耗故障能够引起分歧,例如,管理员也能够引起分歧(通过执行离线整理或主动副本的硬修复)。
分歧是有问题的,因为它意味着数据已经丢失。数据库分歧是最坏的情形,因为它担保需要重新设定种子,在时间和可能的带宽方面它是一个昂贵的操作。日志文件分歧也意味着数据已经丢失。然而,日志文件分歧不一定会引起数据库分歧因为LLR。
记住Exchange 数据的写操作总是内存、日志文件然后是数据库文件。LLR通过推迟写到数据库直到特定数量的日志生成已经被创建生效。LLR将最近的更新推迟一个很短的时间才写到数据库文件中。写入延迟时间的长短取决于日志是多么快地被生成。
LLR 提供强制数据库更改加载在内存中知道一个或更多其他的日志生成被创建的能力。简言之,它强制主动数据库文件在被创建的日志后面保留很少量的日志,这样减少 了副本之间的数据库分歧的可能性,注意:LLR只运行在主动存储组副本上。如果您分析被动副本,您将发现它的数据库总是最新的(根据被动节点上存在的日志 文件)
LLR为日志文件使用一个新的标记。从日志重播角度出发,有两个关键的标记。
Committed 这个标记告诉ESE最后一个日志产生。该术语有点用词不当,因为它不意味着包含在日志文件中日的志记录实际上被写到数据库文件中。
Checkpoint 该标记告诉ESE对于重播来说要求的最小的日志文件数。检查点之前(下面)的所有日志文件包含的日志记录已经被写到数据库文件中。
Exchange 2007 为LLR和分歧检测增加了一个额外的标记。
Waypoint 该标记告诉ESE用于重播的要求的最大数量日志文件数。Waypoint 之前(下面)所有的日志都要求用于恢复因为这些日志中包含的数据已经被提交到数据库。Waypoint 之后(上面)所有日志都没有提交到数据库。
为了确保理解这些标记,让我们看一个没有干净关闭的数据库的输出的例子:
Initiating FILE DUMP mode...
Database: priv1.edb
...
State: Dirty Shutdown
Log Required: 2-12 (0x2-0xC)
Log Committed: 0-20 (0x0-0x14)
...
该EDB文件的输出告诉我们三个标记。
Committed是第20个日志(最后产生的一个日志列在“Log Committed”中)
Checkpoint是第二个日志(第一个产生的日志列在“Log Required”)
Waypoint 是第十二个日志(最后产生的日志列在“Log required”)
这意味着产生的第13个到第20个日志还没有提交到EDB文件。但是这究竟意味着什么?由于第13到20的日志还没有提交到数据库,它们能够被LLR丢弃。只要我们有第2个到12个日志,我们没有必要执行数据库重设种子。
LLR深度值取决于邮箱服务器配置。在运行SP1的CCR环境中,LLR深度值为10,它意味着在任何时间,最后10个日志文件中包含的数据还没有提交到数据库文件。对于所有其他的SP1邮箱服务器(SCC和独立邮箱服务器有LCR或没有),LLR深度值为1。
注 意:在Exchange 2007 RTM版本中,CCR中的LLR深度值是不同的因为它取决于AutoDatabaseMountDial 设置,并等于AutoDatabaseMountDial+1。如果AutoDatabaseMountDial 设置为缺省的,在RTM版本中,CCR环境中LLR深度值为6+1 or 7。这意味着如果您在复制后面的七个日志文件之外,不但数据库不能在有损耗故障中加载,而且您也必须执行数据库重设种子。通过删除依赖于 AutoDatabaseMountDial,在SP1中对于CCR来说LLR深度值为10,像数据库重设种子的可能性进一步减少,即使在数据库没有自动 加载的情况下。
在没有用户或数据库活动的情况下,ESE也强制活动的日志文件关闭,这样确保如果该日志文件有数据的话,它将被复制到数据库的副本中。日志回滚行为基于LLR深度的基础。在系统经过一个计算的空闲时间之后日志回滚将发生。要计算什么时候日志回滚发生,系统使用下面的公式:
[15 (分钟) ÷ LLR 深度值] = 日志回滚活动的频率 (分钟)