WiredTiger 存储引擎
WiredTiger 存储引擎是默认存储引擎。对于现有部署,如果您未指定 --storageEngine
或 storage.engine
设置,mongod
实例可以自动确定用于在 --dbpath
或 storage.dbPath
中创建数据文件的存储引擎。
在以下环境中托管的部署可以使用 WiredTiger 存储引擎:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
注意
所有 MongoDB Atlas 部署均使用 WiredTiger 存储引擎。
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
如需详细了解 MongoDB Atlas 托管的部署使用 WiredTiger 内存的情况,请参阅内存。
操作和限制
以下操作说明和限制适用于 WiredTiger 引擎:
您不能将文档固定到 WiredTiger 缓存中。
WiredTiger 不会保留一部分缓存用于读取,并将另一部分缓存用于写入。
大量的写入工作负载可能会影响性能,不过在此种情况下,WiredTiger 会优先确保索引缓存。
WiredTiger 会将其缓存分配给整个
mongod
实例。WiredTiger 不会在每数据库或每集合级别分配缓存。
事务(读写)并发
从版本7.0开始, MongoDB使用默认算法来动态调整并发存储引擎事务(读取和写入票证)的最大数量。 动态并发存储引擎ACID 事务算法可优化集群过载期间的数据库吞吐量。 并发存储引擎事务(读取和写入票证)的最大数量永远不会超过128读取票证和128写入票证,并且可能因集群中的节点而异。 单个节点内的读取票证和写入票证的最大数量始终相等。
要指定动态最大值不能超过的读写事务(读取和写入工单)的最大数量,请使用 storageEngineConcurrentReadTransactions
和 storageEngineConcurrentWriteTransactions
。
如果您想要禁用动态并发存储引擎的事务算法,请提交支持请求,与 MongoDB 技术服务工程师合作。
要查看 WiredTiger 存储引擎支持的并发读事务(读票证)和写事务(写票证)的数量,请执行 serverStatus
命令并检查 wiredTiger.concurrentTransactions
参数。
注意
wiredTiger.concurrentTransactions
的低值并不表示存在集群过载。使用排队读取和写入票证数量作为集群过载的指示。
文档级并发性
WiredTiger 会对写入操作使用文档级并发控制。因此,多个客户端可同时修改某一集合的不同文档。
对于大多数读取和写入操作,WiredTiger 均使用乐观并发控制。WiredTiger 仅在全局、数据库和集合级别使用意向锁。当存储引擎检测到两个操作之间存在冲突时,其中一个操作会引发写入冲突,从而导致 MongoDB 以透明方式重试该操作。
某些全局操作(通常是涉及多个数据库的短期操作)仍需全局性的“实例范围”锁。 在某些情况下,其他一些操作(例如renameCollection
)仍然需要独占数据库锁。
快照和检查点
WiredTiger 使用多版本并发控制 (MVCC)。在一个操作开始时,WiredTiger 会向该操作提供数据在该时间点的快照。快照提供的视图将与内存中数据保持一致。
写入磁盘时,WiredTiger 将快照中的所有数据以一致的方式跨所有数据文件写入磁盘。即时持久性数据充当数据文件中的检查点。检查点确可确保数据文件在最后一个检查点之前(包括最后一个检查点)保持一致;即检查点可以充当恢复点。
MongoDB 配置 WiredTiger 创建检查点,具体而言,就是以 60 秒的间隔将快照数据写入磁盘。
在写入新检查点期间,前一检查点仍然有效。因此,即使 MongoDB 在写入新检查点时终止或出错,它在重新启动后便可从上一有效检查点恢复。
当 WiredTiger 的元数据表被原子性更新以引用新检查点时,新检查点将变得可访问且被永久保存。一旦新检查点可供访问,WiredTiger 就会释放来自旧检查点的页面。
快照历史记录保留
从 MongoDB 5.0 开始,可以使用 minSnapshotHistoryWindowInSeconds
参数来指定 WiredTiger 保留快照历史记录的时长。
增大 minSnapshotHistoryWindowInSeconds
的值会增加磁盘使用量,因为服务器必须在指定的时间窗口内维护早期已修改值的历史记录。使用的磁盘空间量取决于工作负载,工作负载量越大,需要的磁盘空间越多。
MongoDB 在 WiredTigerHS.wt
文件中维护快照历史记录,该文件位于您指定的 dbPath
中。
日志
WiredTiger 将预写日志与检查点结合使用,确保数据的持久性。
WiredTiger 日志会保留各检查点之间的所有数据修改。如果 MongoDB 在检查点之间退出,它会使用日志来重放自上一检查点以来修改的所有数据。如需了解 MongoDB 将日志数据写入磁盘的频率,请参阅日志进程。
WiredTiger 日志使用 snappy 压缩库进行压缩。要指定其他压缩算法或不压缩,请使用 storage.wiredTiger.engineConfig.journalCompressor
设置。有关更改日志压缩器的详细信息,请参阅更改 WiredTiger 日志压缩器。
注意
如果日志记录小于等于 128 字节(WiredTiger 的最小日志记录大小),WiredTiger 不会压缩该记录。
压缩
利用 WiredTiger,MongoDB 能够支持对所有集合和索引进行压缩。压缩能够最大限度减少存储使用量,但会消耗额外的 CPU 资源。
默认情况下,WiredTiger 对所有集合利用快速压缩库使用区块压缩,对所有索引使用前缀压缩。
对于集合,还可以使用以下区块压缩库:
要指定另一种压缩算法或不压缩,请使用 storage.wiredTiger.collectionConfig.blockCompressor
设置。
对于索引,要禁用前缀压缩,请使用 storage.wiredTiger.indexConfig.prefixCompression
设置。
在创建集合和索引期间,还可以在每个集合和每个索引的基础上配置压缩设置。请参阅指定存储引擎选项和 db.collection.createIndex() storageEngine 选项。
对于大多数工作负载,默认的压缩设置可以在存储效率和处理需求之间取得平衡。
默认情况下,WiredTiger 日志也会被压缩。有关日志压缩的信息,请参阅日志。
内存使用
借助 WiredTiger,MongoDB 可同时利用 WiredTiger 内部缓存和文件系统缓存。
默认 WiredTiger 内部缓存大小为以下两者中的较大者:
(RAM 大小 - 1 GB)的 50%,或
256 MB.
例如,在总 RAM 为 4GB 的系统上,WiredTiger 缓存使用 1.5GB RAM (0.5 * (4 GB - 1 GB) =
1.5 GB
)。相反,在总 RAM 为 1.25GB 的系统上,WiredTiger 为 WiredTiger 缓存分配了 256 MB,因为这大于总 RAM 的一半减去 1 GB (0.5 * (1.25 GB - 1 GB) = 128 MB < 256 MB
)。
注意
在某些情况下,比如在容器中运行时,数据库的内存约束可以低于系统总内存。在此类情况下,将此内存限制而非系统总内存用作最大可用 RAM。
如需查看内存限制,请参阅 hostInfo.system.memLimitMB
。
默认情况下,WiredTiger 对所有集合使用 Snappy 区块压缩,对所有索引使用前缀压缩。压缩默认值可以在全局级别进行配置,也可以在集合和索引创建期间针对每个集合和每个索引进行设置。
WiredTiger 内部缓存和磁盘格式中的数据使用不同的表示形式:
文件系统缓存中的数据与磁盘上的数据格式相同,并且同样拥有数据文件压缩带来的好处。操作系统使用文件系统缓存来减少磁盘 I/O。
WiredTiger 内部缓存中加载的索引具有与磁盘上格式不同的数据表示形式,但仍可利用索引前缀压缩来减少 RAM 使用量。索引前缀压缩会对被索引字段中的常用前缀去重。
WiredTiger 内部缓存中的集合数据未压缩,并使用与磁盘上格式不同的表示形式。区块压缩可大幅节省磁盘上存储空间,但数据必须解压缩才能由服务器操作。
借助文件系统缓存,MongoDB 会自动使用 WiredTiger 缓存或其他进程未使用的所有空闲内存。
如需调整 WiredTiger 内部缓存大小,请参阅 storage.wiredTiger.engineConfig.cacheSizeGB
和 --wiredTigerCacheSizeGB
。避免将 WiredTiger 内部缓存大小增加到超过其默认值。