On this page
MongoDB Wire 协议
在本页面
Introduction
MongoDB Wire Protocol 是一个简单的基于套接字的请求-响应样式协议。Client 端通过常规的 TCP/IP 套接字与数据库服务器通信。
TCP/IP Socket
Client 端应使用常规的 TCP/IP 套接字连接到数据库。没有连接握手。
Port
mongod和mongos实例的默认端口号是 27017.mongod和mongos的端口号是可配置的,可能会有所不同。
Byte Ordering
MongoDB 有线协议中的所有整数都使用低位字节序:即,最低有效字节在前。
邮件类型和格式
消息有两种类型:Client 端请求和数据库响应。
Note
该页面使用类似于 C 的
struct
来描述消息结构。本文档中使用的类型(
cstring
,int32
等)与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_QUERY和OP_GET_MORE),它将在OP_REPLY消息的responseTo 字段中返回。Client 端可以使用requestID 和responseTo 字段将查询响应与原始查询相关联。 |
responseTo |
对于来自数据库的消息,它将是来自 Client 端的OP_QUERY或OP_GET_MORE消息中的requestID 。Client 端可以使用requestID 和responseTo 字段将查询响应与原始查询相关联。 |
opCode |
消息类型。有关详情,请参见Request Opcodes。 |
Request Opcodes
Note
从 MongoDB 2.6 和maxWireVersion 3
开始,MongoDB 驱动程序使用database commands insert,update和delete代替OP_INSERT
,OP_UPDATE
和OP_DELETE
进行确认的写入。大多数驱动程序 continue 使用操作码进行未确认的写入。
Warning
OP_COMMAND
和OP_COMMANDREPLY
是群集内部的,不应由 Client 端或驱动程序实现。
在 3.6 版中进行了更改:OP_COMMAND
和OP_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_QUERY和OP_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 端驱动程序来确保将不超过指定数量的文档返回给调用应用程序。如果numberToReturn
是0
,则数据库将使用默认的返回大小。如果数字为负,则数据库将返回该数字并关闭游标。无法获取该查询的其他结果。如果numberToReturn
是1
,则服务器会将其视为-1
(自动关闭光标)。
| query
|代表查询的 BSON 文档。该查询将包含一个或多个元素,所有这些元素都必须匹配才能使文档包含在结果集中。可能的元素包括$query
,$orderby
,$hint
和$explain
。
| returnFieldsSelector
|可选。 BSON 文档,用于限制返回文档中的字段。 returnFieldsSelector
包含一个或多个元素,每个元素都是应返回的字段的名称,以及整数值1
。在 JSON 表示法中,用于限制字段a
,b
和c
的returnFieldsSelector
为:{ 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 端驱动程序来确保将不超过指定数量的文档返回给调用应用程序。如果numberToReturn 是0 ,则数据库将使用默认的返回大小。 |
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_QUERY或OP_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_QUERY或OP_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] | *(1,2)*如https://tools.ietf.org/html/rfc4960#page-140所述,使用 Castagnoli 多项式计算的 32 位 CRC。 |