Exchange 存储体系结构

 

上一次修改主题: 2005-05-23

Exchange 服务器将数据存储在两种文件中:.edb 文件和 .stm 文件。.edb 文件和 .stm 文件一起形成 Exchange 存储库。例如,Exchange 服务器上的默认邮箱存储使用名为 Priv1.edb 和 Priv1.stm 的两个文件。默认公用文件夹存储使用文件 Pub1.edb 和 Pub1.stm。.edb 文件包含很多表,除了存放 MAPI 邮件的内容以外,这些表用于存放 Exchange 存储中的所有电子邮件的元数据以及其他项目。.edb 文件是 ESE 数据库,因为它主要用于存储 MAPI 邮件和附件,因此它也称为基于 MAPI 的数据库。相比之下,.stm 文件则存储本机 Internet 内容。因为 Internet 内容是以本机格式写入的,因此不需要将邮件和其他项转换为 Exchange 格式(像 Exchange 5.5 和更早版本那样)。.stm 文件也是 ESE 数据库,它被称为流式数据库。.edb 和 .stm 文件作为一个配对工作,并且数据库签名(与数据库创建时间组合的 32 位随机数字)作为头信息存储于这两个文件中。.stm 页的内部架构存储在 .edb 文件中。

note注意:
可以在 Exchange 系统管理器中重命名 .edb 和 .stm 数据库,并将它们移动到其他目录。因为 .edb 和 .stm 文件一起建成一个完整的 Exchange 存储库,所以应当始终将它们放在一起,为它们指定一个公用名,并且使用不同的扩展名(即 .edb 和 .stm)。

Exchange Server 2003 使用事务来控制存储组中的更改。这些事务记录在事务日志中,类似于将事务存储在传统数据库中所采用的方式。更改将基于事务是否成功而被提交或回滚。如果发生故障,可以使用事务日志(以及数据库文件,某些情况下还包括检查点文件)来还原数据库。管理事务的设备是 Microsoft Exchange Information Store 服务 (Store.exe)。任何未提交的事务日志条目也被看作当前 Exchange 数据库的一部分,如下图所示。

c236b0b1-1e8b-4f56-9643-4813d0d54acc

以下两个数据库类型在 Exchange Server 2003 中可用:

  • 私人存储数据库:这些数据库用于存储基于 MAPI 的邮件连接器的邮箱和邮件队列。
  • 公用存储数据库:这些数据库用于存储公用文件夹层次结构和公用文件夹内容。

下图说明了内部的 Exchange 存储体系结构。Microsoft Exchange Information Store 服务 (Store.exe) 使用可扩展存储引擎 (ESE) 来访问文件系统中的数据库文件,并通过各种接口(例如,MAPIsvr、ExPOP、ExIMAP、ExSMTP 和 ExOLEDB)提供对数据的访问支持。客户端应用程序和应用程序编程接口(例如,Collaboration Data Objects for Exchange (CDOEX))可以使用这些接口,也可以与邮件数据库 (MDB) 模块通信。

40668745-b91e-4505-a7b9-ab88974a9ad0

存储组

每个存储组均由用于存储组中所有数据库(.edb 文件, .stm 文件)的一组日志文件和辅助文件(内部的临时数据库、检查点文件和保留日志)组成。在每个存储组中,Exchange Server 2003 支持多个存储组和多个数据库。在 Exchange Server 2003 中,一个服务器最多支持四个存储组,而一个存储组最多支持五个数据库。多数据库支持使您能够将很多邮箱和公用文件夹分散在许多更小的数据库中,从而使数据库更容易管理。在一个服务器上,Exchange 2000 Server 和 Exchange Server 2003 最多可以支持 20 个邮箱和公用文件夹数据库。

存储组体系结构

如下图所示,所有存储组均由同一个 Store.exe 进程主持。每个存储组均以一个 ESE 实例表示。

6ff925c2-ec78-489a-b8ed-30891a3d25f2

在每个存储组中,每个 .edb 和 .stm 数据库配对表示一个邮箱存储或公用文件夹存储。如图 10.3 所示,特定存储组中的所有邮箱和公用文件夹存储共享一组公用的日志文件和其他系统文件。这些文件用于启用面向事务的处理。

每个存储组中的日志文件和其他系统文件均有以下用途:

  • <Log Prefix>xxx.chk:这是检查点文件(例如,E00.chk),用于确定哪些事务需要处理过程将它们从事务日志文件移动到数据库。当 ESE 将特定事务写入磁盘上的数据库文件时,将更新检查点文件。该更新总是使检查点文件指向被成功传输到数据库的最后一个事务。该更新提供了快速恢复机制。但是,在将事务提交给数据库时,检查点文件不是必需的。ESE 能够直接处理事务日志文件,并自行确定尚未传输哪个事务。与使用检查点相比,该过程需要占用的时间多了很多。

    note注意:
    可扩展存储引擎保证事务不会多次写入数据库。
  • Exx.log:这是存储组的当前事务日志文件。事务日志文件使 ESE 能够以高速度的效率来管理数据存储。ESE 将新的事务(例如,邮件传递)同时存储在内存缓存中和事务日志中。数据被按顺序写入。新数据被追加到现有数据末尾,而不需要执行复杂的数据库操作。在随后的某个时间,事务按组从内存缓存传输到实际的数据库,并由数据库更新它们。
    默认情况下,默认的存储组(名为“第一个存储组”)使用前缀 E00,这导致事务日志文件被命名为 E00.log。该存储组中的所有邮箱和公用存储均使用 E00.log。如果创建其他存储组,则前缀数字将增加为 E01、E02 和 E03。

  • <日志前缀>XXXXX.log:表示事务日志文件,这些文件不会为后继数据保留空间。默认情况下,事务日志文件的大小总是正好等于 5.242.880 字节 (5 MB)。在理论上可以更改日志文件大小,但不推荐这样做。日志已满时,它会被重命名,以便允许创建新的空事务日志文件。被重命名的事务日志文件以前面的日志文件命名。前面的日志文件的命名格式是 <日志前缀>XXXXX.log(例如,E00XXXXX.log),其中 XXXXX 代表五位十六进制数字,范围从 00000 到 FFFFF。前面的日志文件与当前事务日志文件均驻留在同一个目录中。

  • Res1.log 和 Res2.log:这些是存储组的保留事务日志文件。保留日志文件是事务的紧急存储库。它们提供了足够的磁盘空间以便将事务从内存写入硬盘,即使服务器的磁盘已经太满而无法在日志文件中容纳新的事务。可以在事务日志目录中找到保留日志文件。它们是在数据库初始化时自动创建的。随后无法再创建它们。
    ESE 使用保留事务日志文件只是为了完成当前事务过程。然后,它向 Store.exe 发送错误通知,以便安全地卸除 Exchange 存储。在应用程序事件日志中,有相应的条目指示这个问题。在这种情况下,应当先创建额外的可用硬盘空间(例如,添加新硬盘),然后再次装入数据库。

  • Tmp.edb:这是用于处理事务的临时工作区。Tmp.edb 包含临时信息,当存储组中的所有存储被卸除或者 Exchange Information Store 服务停止时,将删除这些临时信息。

    note注意:
    联机备份中不包括 Tmp.edb。
  • <文件名>.edb:这些是各个私人或公用存储的 RTF 数据库文件。默认私人存储的 RTF 数据库文件被命名为 Priv1.edb。默认公用存储的文件被命名为 Pub1.edb。

  • <文件名>.stm:这些是各个数据库的流式 Internet 内容文件。默认私人存储的流式数据库文件被命名为 Priv1.stm。默认公用存储的文件被命名为 Pub1.stm。

Active Directory 中的存储组属性

可以在 Exchange 系统管理器中确定存储组的事务日志文件的路径和日志文件的名称。用鼠标右键单击要查看的存储组,选择“属性”,并在“常规”选项卡中查看“事务日志位置”和“日志文件前缀”字段中的信息。使用“浏览”按钮可以将事务日志和系统文件移动到新位置,例如单独的物理驱动器。

存储组的配置设置存储在 Active Directory 中。如果想使用 ADSI Edit 找到存储组的目录对象,必须打开配置命名联系人,并展开服务节点,然后展开 CN=Microsoft Exchange,接着再展开 Exchange 组织对象、管理组和服务器容器。在它下面,可以找到名为 CN=InformationStore 的容器,该容器中包含存储组(例如,CN=First Storage Group)。存储组对象的对象类是 msExchStorageGroup。如果计划使用自定义脚本来管理 Exchange 存储资源,可以通过使用 Active Directory 服务接口 (ADSI) 来访问 msExchStorageGroup 对象。

以下代码示例演示了如何访问 Exchange 组织(名为 Contoso)中 SERVER01 服务器上的默认存储组。它显示了该存储组的事务日志文件的当前路径。

strStorageGroupDN = "CN=First Storage Group," _
                  & "CN=InformationStore," _
                  & "CN=SERVER01,CN=Servers," _
                  & "CN=First Administrative Group," _
                  & "CN=Administrative Groups," _
                  & "CN=Contoso,CN=Microsoft Exchange," _
                  & "CN=Services,CN=Configuration," _
                  & "DC=Contoso,DC=com"
Set oStorageGroup = GetObject("LDAP://" & strStorageGroupDN)
MsgBox oStorageGroup.Get("msExchESEParamLogFilePath")

下面是可以在基于 ADSI 的自定义脚本中使用的 msExchStorageGroup 对象的重要 Exchange 属性:

  • msExchESEParamCircularLog:这是布尔标志,用于确定是否启用或禁用循环日志记录。值为 0 表示禁用循环日志记录;值为 1 表示启用循环日志记录。
    当被提交的更改传输到磁盘上的数据库文件时,循环日志记录会导致 ESE 放弃事务。检查点文件指示哪些日志文件和事务条目已成功提交到数据库。将删除任何现有的以前日志,同时将当前事务日志文件中的事务标记为已过时。在创建新的日志文件之前,新的事务最终会覆盖当前事务日志中已过时的条目。

    note注意:
    通过清除事务,循环日志记录可以减少磁盘空间使用量。但是,循环日志记录与复杂的容错配置,以及几个依赖于事务日志存在的联机备份类型不兼容。启用循环日志记录时,可以只执行完整备份。无法执行依赖于事务日志文件的备份,例如,差异备份或增量备份。恢复数据时,无法重播事务日志文件,因而无法还原在最新备份以后出现的数据。相反,如果没有通过循环日志记录自动删除事务,则有可能还可以通过重播仍然存在于硬盘上的事务来恢复在最新备份后出现的数据。尽管在 Exchange Server 5.5 中默认情况下启用了循环日志记录,但在 Exchange 2000 Server 和 Exchange Server 2003 中默认情况下禁用循环日志记录。
  • msExchESEParamEventSource:这是独立于语言的过程描述符字符串,该字符串指向注册表中 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 下面的 Microsoft Exchange Information Store 服务项 (MsExchangeIS)。

  • msExchESEParamLogFilePath:该属性确定存储组的事务日志文件的路径,例如 C:\Program Files\Exchsrvr\mdbdata。

  • msExchESEParamLogFileSize:该属性指定日志文件大小 (KB)。默认值是 5120。应当永远不更改该值。

  • msExchESEParamSystemPath:该属性指定除任何可能存在的临时数据库的路径以外的检查点文件的路径,例如 C:\Program Files\Exchsrvr\mdbdata。

  • msExchESEParamZeroDatabaseDuringBackup:这是布尔标志,用于确定在备份操作期间是否用零覆盖被删除的记录和长数值。值为 0 表示不覆盖记录。值为 1 表示用零覆盖数据库。

  • msExchESEParamEnableOnlineDefrag:这是布尔标志,用于确定 Microsoft Exchange Information Store 服务是否应当对数据库执行联机碎片整理。值为 0 表示不应当执行联机碎片整理。值为 1 表示应当在所安排的维护周期内执行联机碎片整理。

    note注意:
    联机碎片整理可以腾出数据库中的空间,但不会减小数据库文件的大小。在称为软恢复的过程中,在每次服务器启动和关机期间将纠正数据库不一致。
  • msExchESEParamEnableIndexChecking:这是布尔标志,用于确定是否检查操作系统版本的 Unicode 索引。值为 0 表示不执行索引检查。值为 1 表示执行索引检查。该参数用于检测由于升级到较新版本或应用了 Service Pack 而导致的操作系统中发生的更改。该标志确定 Unicode 的排序顺序是否已经更改。一旦操作系统发生这种方式的更改,则自动执行重新索引。

  • msExchESEParamBaseName:该属性指定在该存储组中的日志文件的基名称。例如,如果基名称是 E00,则事务日志文件名为 E00.log。

  • msExchESEParamDbExtensionSize:该属性指定数据库扩展大小,单位为页。默认值为 2 MB。

  • msExchESEParamPageTempDBMin:该属性指定临时数据库的大小下限,单位为页。默认值为 0。

  • msExchESEParamCheckpointDepthMax:该属性指定首选的(不是必需的)最大检查点深度,单位为字节。

存储组最低磁盘空间要求

每个存储组消耗大约 50 MB 可用磁盘空间。存储组所需的上述文件最低要使用 11 MB 磁盘空间。私人和公用存储的最低磁盘空间分别是 5 MB 和 8 MB。尽管所使用的总磁盘空间是大约 24 MB,但实际创建存储组和执行读取及写入操作还需要额外的磁盘空间。

使用存储组时,请记住以下事项:

  • 运行 Exchange Server 2003 的服务器可以有最多五个存储组。因为有一个存储组是为数据库恢复操作而保留的,因此只有四个存储组可以用来存放可供客户端访问的数据库。试图创建四个以上的存储组将产生错误消息。
  • 在一个存储组中只能创建五个数据库。试图创建更多数据库将产生错误消息。

Exchange 存储数据库

Exchange Server 使用 ESE 作为嵌入数据库引擎,该引擎确定数据库结构并管理内存。数据库引擎通过将 4 KB 数据块(页)传进和传出内存,从而在内存中缓存数据库。它更新内存中的数据页,并将新的数据页或经过更新的数据页写入磁盘。当请求到达系统时,数据库引擎可以在内存中缓冲数据,这样就不必经常访问磁盘。这使系统更有效,因为写入内存比写入磁盘快大约 200,000 倍。用户发出请求时,数据库引擎开始将请求加载到内存中,并将数据页标记为脏页。脏页是内存中包含数据的页。这些脏页随后被写入磁盘上的 Microsoft Exchange Information Store 服务数据库。

尽管在内存中缓存数据是处理数据的最快和最有效的方式,但它意味着当 Exchange 正在运行时,磁盘上的信息永远不是完全最新的。数据库的最新版本在内存中,并且由于内存中的很多更改也不在磁盘上,因此数据库和内存没有同步。如果内存中有任何脏页尚未传输并写入磁盘,数据库将被标记为不一致。只有当内存中的所有脏页都传输到磁盘后,才会同步 Exchange 数据库。同步发生在正常关闭 Microsoft Exchange Information Store 服务时。在关机过程中,Microsoft Exchange Information Store 服务将把所有页刷新到磁盘。

MAPI 数据库文件

Exchange Server 2003 MAPI 数据库文件所包含的表用于存放所有电子邮件的元数据、数据库中的其他对象和 MAPI 邮件的内容。在 Microsoft Office Outlook 中显示的每个文件夹都是 Exchange 存储中的单独数据库表。用来查看这些文件夹的每个排序顺序均由该表上单独的索引表示。Store.exe 进程负责管理这些排序顺序。

来自 MAPI 客户端(例如 Outlook)的邮件存储在 MAPI 数据库中,这与在以前的 Exchange Server 版本中存储这类邮件的方式是一样的。然后,基于 MAPI 的客户端可以直接访问这些邮件,而不需要对它们进行转换。但是,如果基于 Internet 协议的客户端试图读取该数据库中的邮件,则邮件将转换成所请求的格式。

传统的 .edb 文件与和它配对的 .stm 文件作为一个单元。如果其中一个文件不存在了,则另一个文件几乎没什么用处。要知道 Microsoft Exchange Server 信息存储服务中一个数据库包含两个文件:.edb 文件和 .stm 文件。

.edb 文件中的记录包含一个列(数据类型为 JET_coltypSLV),这个列引用包含原始数据的流式文件中的一个页面列表。流式文件中数据的空间使用量(页码最大可达到 4 KB)与校验和数据均存储在 .edb 文件中。

流式数据库文件

Exchange Server 5.5 和更早版本以邮件数据库封装格式 (MDBEF) 来存储邮件。这是 Outlook 客户端的本机格式。非 MAPI 客户端请求邮件时,Microsoft Exchange Information Store 服务将基于客户端所请求的内容把内容从 MDBEF 转换为合适的格式。该转换会消耗处理器带宽,并降低服务器性能。

ESE 的更高版本使 Internet 邮件客户端能够以本机格式存储原始数据。该原始数据的存储库称为流式数据库,或简单叫做流式文件。流式文件没有平衡树(B 树)开销,而是包含两个 4 KB 的头信息页,然后将原始数据包含在 4 KB 页中。该平面数据结构是为不大可能需要内容转换的数据以及可以非常快速地接收和传输的数据的二进制大型对象 (BLOB) 而设计的。

属性升级

属性升级确定在 ESE 数据库中将数据存储在哪里,因此它是一个要了解的重要概念。Microsoft Exchange Information Store 服务支持将包含在 .stm 文件中的数据属性升级到 .edb 文件。属性升级使文件夹视图和索引能够得到有效维护。例如,流入 .stm 文件中的邮件的属性(例如,发件人、主题、发送日期和接收日期)被升级到描述 .edb 文件中的邮件的记录。

MAPI 客户端(例如,Microsoft Outlook)将邮件提交到 Microsoft Exchange Information Store 服务时,该邮件的内容将存储在 .edb 文件中。如果非 MAPI 客户端打开邮件,Microsoft Exchange Information Store 服务会立即将 MAPI 内容转换为 Internet 格式,该过程需要执行某种转换,并调用 IMAIL,而 IMAIL 又会调用 RTFHTML 来完成转换。该转换不是永久性的,这意味着数据不会从 .edb 文件移出并写入 .stm 文件。

如果 Internet 客户端向 Microsoft Exchange Information Store 服务提交邮件,则邮件内容会存储在 .stm 文件中。Internet 邮件中的某些头信息会复制到 .edb 文件中,以便 Microsoft Exchange Information Store 服务可以找到这些邮件。这称为状态 0 转换。

如果任何客户端请求某个属性(例如,PR_Subject)或它的很多别名中的某一个,那么 Microsoft Exchange Information Store 服务将把所有 Internet 邮件的头信息升级为属性。这称为状态 1 转换。

如果任何客户端请求附件信息,那么 Microsoft Exchange Information Store 服务将创建 Internet 邮件的近似副本(以 MAPI 形式)。首先,邮件仍然在 .stm 文件中。但是,进行 MAPI 访问所需的很多数据则在 .edb 文件中。如果客户端以更改多用途 Internet 邮件扩展 (MIME) 的方式改变邮件,那么,将放弃邮件的 .stm 文件版本,并保留邮件的 .edb 文件。这称为状态 2 转换。

不管邮件如何提交到 Microsoft Exchange Information Store 服务,如果 Exchange Server 收到包括 Application/ms-tnef 内容的 Internet 内容,则邮件一开始会进入 .stm 文件,但然后会被立即解码并移动到 .edb 文件中。带有 winmail.dat 附件(使用 UUEncode 进行编码)的邮件将执行同样的步骤。传输非特定封装格式 (TNEF) 和 Winmail.dat 是用于 MAPI 邮件的封装方法,可以在不支持 MAPI 的传输中保留 MAPI 属性。因此,一般原则为 MAPI 邮件位于 .edb 文件中,Internet 邮件位于 .stm 文件中。当前功能会在读取任何一个 MAPI 属性之前将 TNEF 解码。