MongoDB Wire 协议

在本页面

Introduction

MongoDB Wire Protocol 是一个简单的基于套接字的请求-响应样式协议。Client 端通过常规的 TCP/IP 套接字与数据库服务器通信。

TCP/IP Socket

Client 端应使用常规的 TCP/IP 套接字连接到数据库。没有连接握手。

Port

mongodmongos实例的默认端口号是 27017.mongodmongos的端口号是可配置的,可能会有所不同。

Byte Ordering

MongoDB 有线协议中的所有整数都使用低位字节序:即,最低有效字节在前。

邮件类型和格式

消息有两种类型:Client 端请求和数据库响应。

Note

  • 该页面使用类似于 C 的struct来描述消息结构。

  • 本文档中使用的类型(cstringint32等)与BSON specification中定义的类型相同。

  • 为了表示重复,文档使用BSON specification中的星号表示。例如,int64*表示可以将一种或多种指定类型的内容一个接一个地写入套接字。

  • 标准消息头的类型为MsgHeader。整数常量使用大写字母(例如ZERO表示整数值 0)。

标准邮件标题

通常,每个消息都由一个标准消息头和随后的请求特定数据组成。标准消息头的结构如下:

struct MsgHeader {
    int32   messageLength; // total message size, including this
    int32   requestID;     // identifier for this message
    int32   responseTo;    // requestID from the original request
                           //   (used in responses from db)
    int32   opCode;        // request type - see table below for details
}
Field Description
messageLength 消息的总大小(以字节为单位)。该总数包括保存消息长度的 4 个字节。
requestID Client 端或数据库生成的标识符,用于唯一标识此消息。对于 Client 端生成的消息(例如OP_QUERYOP_GET_MORE),它将在OP_REPLY消息的responseTo字段中返回。Client 端可以使用requestIDresponseTo字段将查询响应与原始查询相关联。
responseTo 对于来自数据库的消息,它将是来自 Client 端的OP_QUERYOP_GET_MORE消息中的requestID。Client 端可以使用requestIDresponseTo字段将查询响应与原始查询相关联。
opCode 消息类型。有关详情,请参见Request Opcodes

Request Opcodes

Note

从 MongoDB 2.6 和maxWireVersion 3开始,MongoDB 驱动程序使用database commands insertupdatedelete代替OP_INSERTOP_UPDATEOP_DELETE进行确认的写入。大多数驱动程序 continue 使用操作码进行未确认的写入。

Warning

OP_COMMANDOP_COMMANDREPLY是群集内部的,不应由 Client 端或驱动程序实现。

在 3.6 版中进行了更改:OP_COMMANDOP_COMMANDREPLY格式和协议已弃用,并且在以后的 MongoDB 版本中可能会删除。

以下是受支持的opCode

Opcode Name Value Comment
OP_REPLY 1 回复 Client 请求。设置为responseTo
OP_UPDATE 2001 Update document.
OP_INSERT 2002 插入新文件。
RESERVED 2003 以前用于 OP_GET_BY_OID。
OP_QUERY 2004 查询集合。
OP_GET_MORE 2005 从查询中获取更多数据。请参见游标。
OP_DELETE 2006 Delete documents.
OP_KILL_CURSORS 2007 通知数据库 Client 端已完成游标。
OP_COMMAND 2010 表示命令请求的集群内部协议。
OP_COMMANDREPLY 2011 表示对OP_COMMAND的答复的群集内部协议。
OP_MSG 2013 使用 MongoDB 3.6 中引入的格式发送消息。

Client 端请求消息

Client 端可以发送指定除OP_REPLY opCode 之外的所有内容的请求消息。 OP_REPLY保留供数据库使用。

只有OP_QUERYOP_GET_MORE消息会导致数据库响应。对于其他任何消息,将不会发送任何响应。

您可以使用 getLastError 命令确定消息是否成功。

OP_UPDATE

OP_UPDATE 消息用于更新集合中的文档。 OP_UPDATE 消息的格式如下:

struct OP_UPDATE {
    MsgHeader header;             // standard message header
    int32     ZERO;               // 0 - reserved for future use
    cstring   fullCollectionName; // "dbname.collectionname"
    int32     flags;              // bit vector. see below
    document  selector;           // the query to select the document
    document  update;             // specification of the update to perform
}
Field Description
header 消息头,如标准消息头中所述。
ZERO 整数值 0.保留以备将来使用。
fullCollectionName 完整的收藏名称;即命名空间。完整的集合名称是数据库名称与集合名称的串联,并使用.进行串联。例如,对于数据库foo和集合bar,完整的集合名称是foo.bar
flags 位向量,用于指定操作标志。这些位值对应于以下内容:


0对应于 Upsert。如果设置,则如果找不到匹配的文档,数据库将把提供的对象插入集合中。
1对应于 MultiUpdate。如果设置,则数据库将更新集合中的所有匹配对象。否则,仅更新第一个匹配的文档。
2-31被保留。必须设置为 0.
| selector | BSON 文档,该文档指定用于选择要更新的文档的查询。
| update | BSON 文档,该文档指定要执行的更新。有关指定更新的信息,请参阅《 MongoDB 手册》中的Update Operations文档。

对 OP_UPDATE 消息无响应。

OP_INSERT

OP_INSERT 消息用于将一个或多个文档插入到集合中。 OP_INSERT 消息的格式为

struct {
    MsgHeader header;             // standard message header
    int32     flags;              // bit vector - see below
    cstring   fullCollectionName; // "dbname.collectionname"
    document* documents;          // one or more documents to insert into the collection
}
Field Description
header 消息头,如标准消息头中所述。
flags 位向量,用于指定操作标志。这些位值对应于以下内容:


0对应于 ContinueOnError。如果设置,则数据库将不会停止处理批量插入(如果失败)(例如,由于重复的 ID)。这使得批量插入的行为类似于一系列单次插入,不同的是,如果任何插入失败(不仅是最后一个插入)失败,那么将设置 lastError。如果发生多个错误,则 getLastError 将仅报告最新错误。 (1.9.1 中的新功能)
1-31被保留。必须设置为 0.
| fullCollectionName |完整的收藏名称;即命名空间。完整集合名称是数据库名称与集合名称的串联,串联中使用.。例如,对于数据库foo和集合bar,完整的集合名称是foo.bar
| documents |要插入到集合中的一个或多个文档。如果有多个,则依次将它们依次写入套接字。

对 OP_INSERT 消息无响应。

OP_QUERY

OP_QUERY 消息用于在数据库中查询集合中的文档。 OP_QUERY 消息的格式为:

struct OP_QUERY {
    MsgHeader header;                 // standard message header
    int32     flags;                  // bit vector of query options.  See below for details.
    cstring   fullCollectionName ;    // "dbname.collectionname"
    int32     numberToSkip;           // number of documents to skip
    int32     numberToReturn;         // number of documents to return
                                      //  in the first OP_REPLY batch
    document  query;                  // query object.  See below for details.
  [ document  returnFieldsSelector; ] // Optional. Selector indicating the fields
                                      //  to return.  See below for details.
}
Field Description
header 消息头,如标准消息头中所述。
flags 位向量,用于指定操作标志。这些位值对应于以下内容:


0已保留。必须设置为 0.
1对应于 TailableCursor。可拖尾表示检索到最后一个数据时光标未关闭。而是,光标标记最终对象的位置。如果收到更多数据,您可以稍后从其所在位置 continue 使用光标。像任何“潜在游标”一样,游标可能会在某个时候失效(CursorNotFound)–例如,如果删除了它所引用的最终对象。
2对应于 SlaveOk。允许查询副本从站。通常,这些返回错误,但名称空间“ local”除外。
3对应于 OplogReplay。仅供内部复制使用-不应设置驱动程序。
4对应于 NoCursorTimeout。服务器通常在闲置时间(10 分钟)后使空闲的游标超时,以防止过多的内存使用。设置此选项可以防止这种情况。
5对应于 AwaitData。与 TailableCursor 一起使用。如果我们在数据的末尾,请阻塞一会而不是不返回任何数据。超时后,我们照常返回。
6对应于排气。假设 Client 端将完全读取所有查询的数据,则将数据以多个“更多”包的形式完整传输。当您提取大量数据并知道要全部提取时,速度更快。注意:除非 Client 端关闭连接,否则不允许 Client 端不读取所有数据。
7对应于部分。如果某些分片发生故障,则从 mongos 获得部分结果(而不是引发错误)
8-31被保留。必须设置为 0.
| fullCollectionName |完整的收藏名称;即命名空间。完整集合名称是数据库名称与集合名称的串联,串联中使用.。例如,对于数据库foo和集合bar,完整的集合名称是foo.bar
| numberToSkip |设置要省略的文档数-从结果数据集中的第一个文档开始-返回查询结果时。
| numberToReturn |限制查询的第一条OP_REPLY消息中的文档数。但是,如果结果多于numberToReturn,则数据库仍将构建游标并将cursorID返回给 Client 端。如果 Client 端驱动程序提供了“限制”功能(例如 SQL LIMIT 关键字),则由 Client 端驱动程序来确保将不超过指定数量的文档返回给调用应用程序。如果numberToReturn0,则数据库将使用默认的返回大小。如果数字为负,则数据库将返回该数字并关闭游标。无法获取该查询的其他结果。如果numberToReturn1,则服务器会将其视为-1(自动关闭光标)。
| query |代表查询的 BSON 文档。该查询将包含一个或多个元素,所有这些元素都必须匹配才能使文档包含在结果集中。可能的元素包括$query$orderby$hint$explain
| returnFieldsSelector |可选。 BSON 文档,用于限制返回文档中的字段。 returnFieldsSelector包含一个或多个元素,每个元素都是应返回的字段的名称,以及整数值1。在 JSON 表示法中,用于限制字段abcreturnFieldsSelector为:
{ a : 1, b : 1, c : 1}|

数据库将以OP_REPLY消息响应 OP_QUERY 消息。

OP_GET_MORE

OP_GET_MORE 消息用于在数据库中查询集合中的文档。 OP_GET_MORE 消息的格式为:

struct {
    MsgHeader header;             // standard message header
    int32     ZERO;               // 0 - reserved for future use
    cstring   fullCollectionName; // "dbname.collectionname"
    int32     numberToReturn;     // number of documents to return
    int64     cursorID;           // cursorID from the OP_REPLY
}
Field Description
header 消息头,如标准消息头中所述。
ZERO 整数值 0.保留以备将来使用。
fullCollectionName 完整的收藏名称;即命名空间。完整的集合名称是数据库名称与集合名称的串联,并使用.进行串联。例如,对于数据库foo和集合bar,完整的集合名称是foo.bar
numberToReturn 将第一条OP_REPLY消息中的文档数限制为该查询。但是,如果结果多于numberToReturn,则数据库仍将构建游标并将cursorID返回给 Client 端。如果 Client 端驱动程序提供了“限制”功能(例如 SQL LIMIT 关键字),则由 Client 端驱动程序来确保将不超过指定数量的文档返回给调用应用程序。如果numberToReturn0,则数据库将使用默认的返回大小。
cursorID OP_REPLY中的光标标识符。这必须是来自数据库的值。

数据库将以OP_REPLY消息响应 OP_GET_MORE 消息。

OP_DELETE

OP_DELETE 消息用于从集合中删除一个或多个文档。 OP_DELETE 消息的格式为:

struct {
    MsgHeader header;             // standard message header
    int32     ZERO;               // 0 - reserved for future use
    cstring   fullCollectionName; // "dbname.collectionname"
    int32     flags;              // bit vector - see below for details.
    document  selector;           // query object.  See below for details.
}
Field Description
header 消息头,如标准消息头中所述。
ZERO 整数值 0.保留以备将来使用。
fullCollectionName 完整的收藏名称;即命名空间。完整的集合名称是数据库名称与集合名称的串联,并使用.进行串联。例如,对于数据库foo和集合bar,完整的集合名称是foo.bar
flags 位向量,用于指定操作标志。这些位值对应于以下内容:


0对应于 SingleRemove。如果设置,数据库将仅删除集合中的第一个匹配文档。否则,所有匹配的文档将被删除。
1-31被保留。必须设置为 0.
| selector | BSON 文档,代表用于选择要删除的文档的查询。selectors 将包含一个或多个元素,所有这些元素都必须匹配才能将文档从集合中删除。

对 OP_DELETE 消息无响应。

OP_KILL_CURSORS

OP_KILL_CURSORS 消息用于关闭数据库中的活动游标。这是确保在查询结束时回收数据库资源所必需的。 OP_KILL_CURSORS 消息的格式为:

struct {
    MsgHeader header;            // standard message header
    int32     ZERO;              // 0 - reserved for future use
    int32     numberOfCursorIDs; // number of cursorIDs in message
    int64*    cursorIDs;         // sequence of cursorIDs to close
}
Field Description
header 消息头,如标准消息头中所述。
ZERO 整数值 0.保留以备将来使用。
numberOfCursorIDs 消息中的游标 ID 的数量。
cursorIDs 要关闭的游标 ID 的“数组”。如果有多个,则依次将它们依次写入套接字。

如果游标被读取直到用尽(直到OP_QUERYOP_GET_MORE返回的游标 ID 均为零为止),则无需终止游标。

OP_COMMAND

在 3.6 版中进行了更改:OP_COMMAND格式和协议已弃用,并且在以后的 MongoDB 版本中可能会删除。

Warning

OP_COMMAND是群集内部的,不应由 Client 端或驱动程序实现。

OP_COMMAND是一种有线协议消息,在内部用于一台 MongoDB 服务器向另一台 MongoDB 服务器发出的集群内数据库命令请求。接收数据库发回OP_COMMANDREPLY作为对OP_COMMAND的响应。

struct {
   MsgHeader header;     // standard message header
   cstring database;     // the name of the database to run the command on
   cstring commandName;  // the name of the command
   document metadata;    // a BSON document containing any metadata
   document commandArgs; // a BSON document containing the command arguments
   inputDocs;            // a set of zero or more documents
}
Field Description
header 标准消息头,如标准消息头中所述。
database 在其上运行命令的数据库的名称。
commandName 命令名称。有关数据库命令的列表,请参见Database Commands
metadata 系统可用于将任何元数据附加到内部命令,这些元数据不是 Client 端驱动程序提供的适当的命令参数的一部分
commandArgs 包含命令参数的 BSON 文档。


有关指定的commandName的信息,请参见文档。
| inputDocs |零个或多个文档充当命令的 Importing。对于可能需要从 Client 端发送大量数据的命令(例如批处理插入)很有用。

OP_MSG

MongoDB 版本中的新功能:3.6

OP_MSG是一种可扩展的消息格式,旨在包含其他操作码的功能。此操作码具有以下格式:

OP_MSG {
    MsgHeader header;          // standard message header
    uint32 flagBits;           // message flags
    Sections[] sections;       // data sections
    optional<uint32> checksum; // optional CRC-32C checksum
}
Field Description
header 标准消息头,如标准消息头中所述。
flagBits 包含消息标志的整数位掩码,如Flag Bits中所述。
sections 邮件正文部分,如Sections中所述。
checksum 可选的 CRC-32C 校验和,如Checksum中所述。

Flag Bits

flagBits整数是位掩码编码标志,用于修改OP_MSG的格式和行为。

如果设置了未知位,则前* 16 位(0-15)为必填项,并且解析器必须错误。

最后 16 位(16-31)是* optional *,并且解析器 必须 忽略任何未知的设置位。代理和其他消息转发器 必须 在转发消息之前清除所有未知的可选位。

Bit Name Request Response Description
0 checksumPresent 该消息以包含 CRC-32C [1]校验和的 4 个字节结尾。有关详情,请参见Checksum
1 moreToCome 另一条消息将跟随此消息,而无需接收者采取进一步措施。接收方“不得”发送另一条消息,直到接收到moreToCome设置为 0 的消息为止,因为发送可能会阻塞,从而导致死锁。设置了moreToCome位的请求将不会收到回复。设置为exhaustAllowed位的请求将仅在答复中设置此位。
16 exhaustAllowed Client 端已准备好使用moreToCome位对此请求进行多次答复。除非请求设置了该位,否则服务器将永远不会产生设置了moreToCome位的答复。


这样可以确保仅在请求者的网络层已准备好多个答复时才发送它们。

Important





MongoDB 3.6 会忽略此标志,并将以一条消息进行响应。



|

Sections

OP_MSG消息包含一个或多个部分。每个部分都以一个kind字节开头,指示其类型。 kind字节之后的所有内容均构成该节的有效负载。

可用的部分如下。

种类 0:身体

正文部分被编码为** BSON object。 BSON 对象中的大小也用作部分的大小。此部分类型是标准命令请求和答复正文。

所有顶级字段 必须 具有唯一的名称。

类型 1:文件 Sequences
Type Description
int32 节的大小(以字节为单位)。
C String 文档序列标识符。在所有当前命令中,此字段是从正文部分替换的(可能是嵌套的)字段。


正文部分中还必须存在此字段“不得”。
|零个或多个 BSON 对象|对象以无分隔符的 Sequences 排列。
每个对象仅限于服务器的maxBSONObjectSize。所有对象的组合不限于maxBSONObjSize
一旦消耗了size个字节,文档序列就结束了。
当转换为语言级对象时,解析器 MAY 选择将这些对象作为数组在序列标识符指定的路径处合并为主体。

Checksum

Note

MongoDB 3.6 不支持验证消息校验和,但会正确跳过它(如果存在)。

每个邮件 MAY 以 CRC-32C [1]校验和结尾,该校验和覆盖了邮件中所有字节,除了校验和本身。 checksumPresent标志位指示校验和的存在。

数据库响应消息

OP_REPLY

数据库响应OP_QUERYOP_GET_MORE消息发送OP_REPLY消息。 OP_REPLY 消息的格式为:

struct {
    MsgHeader header;         // standard message header
    int32     responseFlags;  // bit vector - see details below
    int64     cursorID;       // cursor id if client needs to do get more's
    int32     startingFrom;   // where in the cursor this reply is starting
    int32     numberReturned; // number of documents in the reply
    document* documents;      // documents
}
Field Description
header 消息头,如标准消息头中所述。
responseFlags 指定标志的位向量。这些位值对应于以下内容:


0对应于 CursorNotFound。在调用getMore但在服务器上的游标 ID 无效时设置。返回结果为零。
1对应于 QueryFailure。查询失败时设置。结果由一个文档组成,其中包含描述失败的“ $ err”字段。
2对应于 ShardConfigStale。驾驶员应忽略这一点。只有mongos会看到此设置,在这种情况下,它需要从服务器更新配置。
3对应于 AwaitCapable。当服务器支持 AwaitData 查询选项时设置。如果不是这样,Client 端应该在一个 Tailable 游标的 getMore 之间睡一会儿。 Mongod 1.6 版支持 AwaitData,因此始终设置 AwaitCapable。
4-31被保留。忽略。
| cursorID |此 OP_REPLY 所属的cursorID。如果查询的结果集适合一条 OP_REPLY 消息,则cursorID将为 0.此cursorID必须在用于获取更多数据的任何OP_GET_MORE消息中使用,并且当不再需要通过 Client 端关闭时,也必须由 Client 端关闭此cursorID OP_KILL_CURSORS条消息。|
| startingFrom |光标的起始位置。
| numberReturned |答复中的文档数。
| documents |退回的文档。

OP_COMMANDREPLY

在 3.6 版中进行了更改:OP_COMMANDREPLY格式和协议已弃用,并且在以后的 MongoDB 版本中可能会删除。

Warning

OP_COMMANDREPLY是群集内部的,不应由 Client 端或驱动程序实现。

OP_COMMANDREPLY是一种有线协议消息,在内部用于答复一个 MongoDB 服务器向另一个 MongoDB 服务器发出的集群内OP_COMMAND请求。

OP_COMMANDREPLY的格式为:

struct {
   MsgHeader header;       // A standard wire protocol header
   document metadata;      // A BSON document containing any required metadata
   document commandReply;  // A BSON document containing the command reply
   document outputDocs;    // A variable number of BSON documents
}
Field Description
header 标准消息头,如标准消息头中所述。
metadata 系统可用于将任何元数据附加到内部命令,这些元数据不是 Client 端驱动程序提供的适当命令参数的一部分。
commandReply 包含命令回复的 BSON 文档。
outputDocs 对于可以返回大量数据的命令(例如查找或聚合)很有用。


当前未使用该字段。

Footnotes

[1] *(12)*如https://tools.ietf.org/html/rfc4960#page-140所述,使用 Castagnoli 多项式计算的 32 位 CRC。
首页