diff --git a/doc/dev_guide/internals/box_protocol.rst b/doc/dev_guide/internals/box_protocol.rst index 8ac8cdecc4..9ee0d82e8e 100644 --- a/doc/dev_guide/internals/box_protocol.rst +++ b/doc/dev_guide/internals/box_protocol.rst @@ -1,2104 +1,35 @@ .. _box_protocol-iproto_protocol: - +.. _box_protocol: .. _internals-box_protocol: Binary protocol =============== -The binary protocol is called a "request/response" protocol because it is -for sending requests to a Tarantool server and receiving responses. -There is complete access to Tarantool functionality, including: - -- request multiplexing, for example ability to issue multiple requests - asynchronously via the same connection -- response format that supports zero-copy writes - -The protocol can be called "binary" because the most-frequently-used database accesses -are done with binary codes instead of Lua request text. Tarantool experts use it -to write their own connectors, -to understand network messages, -to support new features that their favorite connector doesn't support yet, -or to avoid repetitive parsing by the server. - -.. _box_protocol-notation: - -Symbols and terms ------------------ - -Words that start with **MP_** mean: -a `MessagePack `_ type or a range of MessagePack types, -including the signal and possibly including a value, with slight modification: - -* **MP_NIL** nil -* **MP_UINT** unsigned integer -* **MP_INT** either integer or unsigned integer -* **MP_STR** string -* **MP_BIN** binary string -* **MP_ARRAY** array -* **MP_MAP** map -* **MP_BOOL** boolean -* **MP_FLOAT** float -* **MP_DOUBLE** double -* **MP_EXT** extension (including the :ref:`DECIMAL type ` and UUID type) -* **MP_OBJECT** any MessagePack object - -Short descriptions are in MessagePack's `"spec" page `_. - -And words that start with **IPROTO_** mean: -a Tarantool constant which is either defined or mentioned in the -`iproto_constants.h file `_. - -The IPROTO constants that identify requests that we will mention in this section are: - -.. code-block:: lua - - IPROTO_SELECT=0x01 - IPROTO_INSERT=0x02 - IPROTO_REPLACE=0x03 - IPROTO_UPDATE=0x04 - IPROTO_DELETE=0x05 - IPROTO_CALL_16=0x06 - IPROTO_AUTH=0x07 - IPROTO_EVAL=0x08 - IPROTO_UPSERT=0x09 - IPROTO_CALL=0x0a - IPROTO_EXECUTE=0x0b - IPROTO_NOP=0x0c - IPROTO_PREPARE=0x0d - IPROTO_BEGIN=0x0e - IPROTO_COMMIT=0x0f - IPROTO_ROLLBACK=0x10 - IPROTO_RAFT_CONFIRM=0x28 - IPROTO_RAFT_ROLLBACK=0x29 - IPROTO_RAFT=0x1e - IPROTO_RAFT_PROMOTE=0x1f - IPROTO_RAFT_DEMOTE=0x20 - IPROTO_PING=0x40 - IPROTO_JOIN=0x41 - IPROTO_SUBSCRIBE=0x42 - IPROTO_VOTE_DEPRECATED=0x43 - IPROTO_VOTE=0x44 - IPROTO_FETCH_SNAPSHOT=0x45 - IPROTO_REGISTER=0x46 - IPROTO_ID=0x49 - IPROTO_WATCH=0x4a - IPROTO_UNWATCH=0x4b - IPROTO_EVENT=0x4c - - -The IPROTO constants that appear within requests or responses that we will describe in this section are: - -.. code-block:: lua - - IPROTO_OK=0x00 - IPROTO_REQUEST_TYPE=0x00 - IPROTO_SYNC=0x01 - IPROTO_REPLICA_ID=0x02 - IPROTO_LSN=0x03 - IPROTO_TIMESTAMP=0x04 - IPROTO_SCHEMA_VERSION=0x05 - IPROTO_FLAGS=0x09 - IPROTO_STREAM_ID=0x0a - IPROTO_SPACE_ID=0x10 - IPROTO_INDEX_ID=0x11 - IPROTO_LIMIT=0x12 - IPROTO_OFFSET=0x13 - IPROTO_ITERATOR=0x14 - IPROTO_INDEX_BASE=0x15 - IPROTO_KEY=0x20 - IPROTO_TUPLE=0x21 - IPROTO_FUNCTION_NAME=0x22 - IPROTO_USER_NAME=0x23 - IPROTO_INSTANCE_UUID=0x24 - IPROTO_CLUSTER_UUID=0x25 - IPROTO_VCLOCK=0x26 - IPROTO_EXPR=0x27 - IPROTO_OPS=0x28 - IPROTO_BALLOT=0x29 - IPROTO_BALLOT_IS_RO_CFG=0x01 - IPROTO_BALLOT_VCLOCK=0x02 - IPROTO_BALLOT_GC_VCLOCK=0x03 - IPROTO_BALLOT_IS_RO=0x04 - IPROTO_BALLOT_IS_ANON=0x05 - IPROTO_BALLOT_IS_BOOTED=0x06 - IPROTO_BALLOT_CAN_LEAD=0x07 - IPROTO_TUPLE_META=0x2a - IPROTO_OPTIONS=0x2b - IPROTO_DATA=0x30 - IPROTO_ERROR_24=0x31 - IPROTO_METADATA=0x32 - IPROTO_BIND_METADATA=0x33 - IPROTO_BIND_COUNT=0x34 - IPROTO_SQL_TEXT=0x40 - IPROTO_SQL_BIND=0x41 - IPROTO_SQL_INFO=0x42 - IPROTO_STMT_ID=0x43 - IPROTO_ERROR=0x52 - IPROTO_FIELD_NAME=0x00 - IPROTO_FIELD_TYPE=0x01 - IPROTO_FIELD_COLL=0x02 - IPROTO_FIELD_IS_NULLABLE=0x03 - IPROTO_FIELD_IS_AUTOINCREMENT=0x04 - IPROTO_FIELD_SPAN=0x05 - IPROTO_CHUNK=0x80 - IPROTO_RAFT_TERM=0x00 - IPROTO_RAFT_VOTE=0x01 - IPROTO_RAFT_STATE=0x02 - IPROTO_RAFT_VCLOCK=0x03 - IPROTO_RAFT_LEADER_ID=0x04 - IPROTO_RAFT_IS_LEADER_SEEN=0x05 - IPROTO_VERSION=0x54 - IPROTO_FEATURES=0x55 - IPROTO_TIMEOUT=0x56 - IPROTO_EVENT_KEY=0x57 - IPROTO_EVENT_DATA=0x58 - IPROTO_TXN_ISOLATION=0x59 - - -To denote message descriptions we will say ``msgpack(...)`` and within it we will use modified -`YAML `_ so: |br| - -:code:`{...}` braces enclose an associative array, also called map, which in MsgPack is MP_MAP, |br| -:samp:`{k}: {v}` is a key-value pair, also called map-item, in this section k is always an unsigned-integer value = one of the IPROTO constants, |br| -:samp:`{italics}` are for replaceable text, which is the convention throughout this manual. Usually this is a data type but we do not show types of IPROTO constants -which happen to always be unsigned 8-bit integers, |br| -:code:`[...]` is for non-associative arrays, |br| -:code:`#` starts a comment, especially for the beginning of a section, |br| -everything else is "as is". |br| -Map-items may appear in any order but in examples we usually use the order that net_box.c happens to use. - -.. _internals-unified_packet_structure: - -.. _box_protocol-header: - -Header and body ---------------- - -Except during connection (which involves a greeting from the server and optional -:ref:`authentication ` that we will discuss later -in this section), the protocol is pure request/response (the client requests and -the server responds). It is legal to put more than one request in a packet. - -Almost all requests and responses contain three sections: size, header, and body. -The size is an (MP_UINT) unsigned integer, usually a 32-bit unsigned integer. -The header and body are (MP_MAP) maps. - -.. cssclass:: highlight -.. parsed-literal:: - - # - :samp:`{{MP_UINT unsigned integer}}` - #
- :samp:`{{MP_MAP with
map-items}}` - # - :samp:`{{MP_MAP with map-items}}` - -```` is the size of the header plus the size of the body. -It may be useful to compare it with the number of bytes remaining in the packet. - -``
`` may contain, in any order: - -.. cssclass:: highlight -.. parsed-literal:: - - msgpack({ - IPROTO_REQUEST_TYPE: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_SCHEMA_VERSION: :samp:`{{MP_UINT unsigned integer}}` - IPROTO_STREAM_ID: :samp:`{{MP_UINT unsigned integer}}` - }) - -**IPROTO_REQUEST_TYPE** or Response-Code-Indicator = 0x00. -An unsigned number that indicates what will be in the ````. -In requests IPROTO_REQUEST_TYPE will be followed by IPROTO_SELECT etc. -In responses Response-Code-Indicator will be followed by IPROTO_OK etc. - -**IPROTO_SYNC** = 0x01. -An unsigned integer that should be incremented so that it is unique in every -request. This integer is also returned from :doc:`/reference/reference_lua/box_session/sync`. -The IPROTO_SYNC value of a response should be the same as -the IPROTO_SYNC value of a request. - -**IPROTO_SCHEMA_VERSION** = 0x05. -An unsigned number, sometimes called SCHEMA_ID, that goes up when there is a -major change. -In a request header IPROTO_SCHEMA_VERSION is optional, so the version will not -be checked if it is absent. -In a response header IPROTO_SCHEMA_VERSION is always present, and it is up to -the client to check if it has changed. - -.. _box_protocol-iproto_stream_id: - -**IPROTO_STREAM_ID** = 0x0a. -An unsigned number that should be unique in every stream. -In requests IPROTO_STREAM_ID is optional and is useful for two things: -ensuring that requests within transactions are done in separate groups, -and ensuring strictly consistent execution of requests (whether or not they are within transactions). -In responses IPROTO_STREAM_ID does not appear. -See :ref:`Binary protocol -- streams `. - -Have a look at file -`xrow.c `_ -function ``xrow_header_encode``, to see how Tarantool encodes the header. -Have a look at file net_box.c, function ``netbox_decode_data``, to see how Tarantool -decodes the header. For example, in a successful response to ``box.space:select()``, -the Response-Code-Indicator value will be 0 = IPROTO_OK and the -array will have all the tuples of the result. - -The ```` has the details of the request or response. In a request, it can also -be absent or be an empty map. Both these states will be interpreted equally. -Responses will contain the ```` anyway even for an -:ref:`IPROTO_PING ` request. - -.. _box_protocol-requests: - -Requests --------- - -A request has a size, a :ref:`header ` -that contains the IPROTO key, and a body as described here. - - -.. _box_protocol-select: - -IPROTO_SELECT = 0x01 -~~~~~~~~~~~~~~~~~~~~ - -See :ref:`space_object:select() `. -The body is a 6-item map. - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_SELECT, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_LIMIT: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_OFFSET: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_ITERATOR: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_KEY: :samp:`{{MP_ARRAY array of key values}}` - }) - -Example: if the id of 'tspace' is 512 and this is the fifth message, |br| -:samp:`{conn}.`:code:`space.tspace:select({0},{iterator='GT',offset=1,limit=2})` will cause: - -.. code-block:: none - - - msgpack(21) - #
- msgpack({ - IPROTO_SYNC: 5, - IPROTO_REQUEST_TYPE: IPROTO_SELECT - }) - # - msgpack({ - IPROTO_SPACE_ID: 512, - IPROTO_INDEX_ID: 0, - IPROTO_ITERATOR: 6, - IPROTO_OFFSET: 1, - IPROTO_LIMIT: 2, - IPROTO_KEY: [1] - }) - -Later in :ref:`Binary protocol -- illustration ` -we will show actual byte codes of an IPROTO_SELECT message. - - -.. _box_protocol-insert: - -IPROTO_INSERT = 0x02 -~~~~~~~~~~~~~~~~~~~~ - -See :ref:`space_object:insert() `. -The body is a 2-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_INSERT, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_TUPLE: :samp:`{{MP_ARRAY array of field values}}` - }) - -Example: if the id of 'tspace' is 512 and this is the fifth message, |br| -:samp:`{conn}.`:code:`space.tspace:insert{1, 'AAA'}` will cause: - -.. code-block:: none - - # - msgpack(17) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_INSERT, - IPROTO_SYNC: 5 - }) - # - msgpack({ - IPROTO_SPACE_ID: 512, - IPROTO_TUPLE: [1, 'AAA'] - }) - - -.. _box_protocol-replace: - -IPROTO_REPLACE = 0x03 -~~~~~~~~~~~~~~~~~~~~~ - -See :ref:`space_object:replace() `. -The body is a 2-item map, the same as for IPROTO_INSERT: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_REPLACE, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_TUPLE: :samp:`{{MP_ARRAY array of field values}}` - }) - - -.. _box_protocol-update: - -IPROTO_UPDATE = 0x04 -~~~~~~~~~~~~~~~~~~~~ - -See :ref:`space_object:update() `. - -The body is usually a 4-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_UPDATE, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_KEY: :samp:`{{MP_ARRAY array of index keys}}`, - IPROTO_TUPLE: :samp:`{{MP_ARRAY array of update operations}}` - }) - -If the operation specifies no values, then IPROTO_TUPLE is a 2-item array: |br| -:samp:`[{MP_STR OPERATOR = '#', {MP_INT FIELD_NO = field number starting with 1}]`. -Normally field numbers start with 1. - -If the operation specifies one value, then IPROTO_TUPLE is a 3-item array: |br| -:samp:`[{MP_STR string OPERATOR = '+' or '-' or '^' or '^' or '|' or '!' or '='}, {MP_INT FIELD_NO}, {MP_OBJECT VALUE}]`. |br| - -Otherwise IPROTO_TUPLE is a 5-item array: |br| -:samp:`[{MP_STR string OPERATOR = ':'}, {MP_INT integer FIELD_NO}, {MP_INT POSITION}, {MP_INT OFFSET}, {MP_STR VALUE}]`. |br| - -Example: if the id of 'tspace' is 512 and this is the fifth message, |br| -:samp:`{conn}.`:code:`space.tspace:update(999, {{'=', 2, 'B'}})` will cause: - -.. code-block:: none - - # - msgpack(17) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_UPDATE, - IPROTO_SYNC: 5 - }) - # ... the map-item IPROTO_INDEX_BASE is optional - msgpack({ - IPROTO_SPACE_ID: 512, - IPROTO_INDEX_ID: 0, - IPROTO_INDEX_BASE: 1, - IPROTO_TUPLE: [['=',2,'B']], - IPROTO_KEY: [999] - }) - -Later in :ref:`Binary protocol -- illustration ` -we will show actual byte codes of an IPROTO_UPDATE message. - - -.. _box_protocol-delete: - -IPROTO_DELETE = 0x05 -~~~~~~~~~~~~~~~~~~~~ - -See :ref:`space_object:delete() `. -The body is a 3-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_DELETE, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_KEY: :samp:`{{MP_ARRAY array of key values}}` - }) - - -.. _box_protocol-call16: - -IPROTO_CALL_16 = 0x06 -~~~~~~~~~~~~~~~~~~~~~ - -See :ref:`conn:call() `. The suffix ``_16`` is a hint that this is -for the ``call()`` until Tarantool 1.6. It is deprecated. -Use :ref:`IPROTO_CALL ` instead. -The body is a 2-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_CALL_16, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_FUNCTION_NAME: :samp:`{{MP_STR string}}`, - IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}` - }) - -The return value is an array of tuples. - - -.. _box_protocol-auth: - -IPROTO_AUTH = 0x07 -~~~~~~~~~~~~~~~~~~ - -See :ref:`authentication `. -See the later section :ref:`Binary protocol -- authentication `. - - -.. _box_protocol-eval: - -IPROTO_EVAL = 0x08 -~~~~~~~~~~~~~~~~~~ - -See :ref:`conn:eval() `. -Since the argument is a Lua expression, this is -Tarantool's way to handle non-binary with the -binary protocol. Any request that does not have -its own code, for example :samp:`box.space.{space-name}:drop()`, -will be handled either with :ref:`IPROTO_CALL ` -or IPROTO_EVAL. -The :ref:`tarantoolctl ` administrative utility -makes extensive use of ``eval``. -The body is a 2-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_EVAL, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_EXPR: :samp:`{{MP_STR string}}`, - IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}` - }) - -Example: if this is the fifth message, :samp:`conn:eval('return 5;')` will cause: - -.. code-block:: none - - # - msgpack(19) - #
- msgpack({ - IPROTO_SYNC: 5 - IPROTO_REQUEST_TYPE: IPROTO_EVAL - }) - # - msgpack({ - IPROTO_EXPR: 'return 5;', - IPROTO_TUPLE: [] - }) - - -.. _box_protocol-upsert: - -IPROTO_UPSERT = 0x09 -~~~~~~~~~~~~~~~~~~~~ - -See :ref:`space_object:upsert() `. - -The body is usually a 4-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_UPSERT, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_INDEX_BASE: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_OPS: :samp:`{{MP_ARRAY array of update operations}}`, - IPROTO_TUPLE: :samp:`{{MP_ARRAY array of primary-key field values}}` - }) - -The IPROTO_OPS is the same as the IPROTO_TUPLE of :ref:`IPROTO_UPDATE `. - - -.. _box_protocol-call: - -IPROTO_CALL = 0x0a -~~~~~~~~~~~~~~~~~~ - -See :ref:`conn:call() `. -The body is a 2-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_CALL, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_FUNCTION_NAME: :samp:`{{MP_STR string}}`, - IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}` - }) - -The response will be a list of values, similar to the -:ref:`IPROTO_EVAL ` response. - - -.. _box_protocol-execute: - -IPROTO_EXECUTE = 0x0b -~~~~~~~~~~~~~~~~~~~~~ - -See :ref:`box.execute() `, this is only for SQL. -The body is a 3-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_EXECUTE, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_STMT_ID: :samp:`{{MP_INT integer}}` or IPROTO_SQL_TEXT: :samp:`{{MP_STR string}}`, - IPROTO_SQL_BIND: :samp:`{{MP_INT integer}}`, - IPROTO_OPTIONS: :samp:`{{MP_ARRAY array}}` - }) - -Use IPROTO_STMT_ID (0x43) and statement-id (MP_INT) if executing a prepared statement, -or use -IPROTO_SQL_TEXT (0x40) and statement-text (MP_STR) if executing an SQL string, then -IPROTO_SQL_BIND (0x41) and array of parameter values to match ? placeholders or -:name placeholders, IPROTO_OPTIONS (0x2b) and array of options (usually empty). - -For example, suppose we prepare a statement -with two ? placeholders, and execute with two parameters, thus: |br| -:code:`n = conn:prepare([[VALUES (?, ?);]])` |br| -:code:`conn:execute(n.stmt_id, {1,'a'})` |br| -Then the body will look like this: - -.. code-block:: none - - # - msgpack({ - IPROTO_STMT_ID: 0xd7aa741b, - IPROTO_SQL_BIND: [1, 'a'], - IPROTO_OPTIONS: [] - }) - -Later in :ref:`Binary protocol -- illustration ` -we will show actual byte codes of the IPROTO_EXECUTE message. - -To call a prepared statement with named parameters from a connector pass the -parameters within an array of maps. A client should wrap each element into a map, -where the key holds a name of the parameter (with a colon) and the value holds -an actual value. So, to bind foo and bar to 42 and 43, a client should send -``IPROTO_SQL_TEXT: <...>, IPROTO_SQL_BIND: [{"foo": 42}, {"bar": 43}]``. - -If a statement has both named and non-named parameters, wrap only named ones -into a map. The rest of the parameters are positional and will be substituted in order. - - -.. _box_protocol-nop: - -IPROTO_NOP = 0x0c -~~~~~~~~~~~~~~~~~ - -There is no Lua request exactly equivalent to IPROTO_NOP. -It causes the LSN to be incremented. -It could be sometimes used for updates where the old and new values -are the same, but the LSN must be increased because a data-change -must be recorded. -The body is: nothing. - - -.. _box_protocol-prepare: - -IPROTO_PREPARE = 0x0d -~~~~~~~~~~~~~~~~~~~~~ - -See :ref:`box.prepare `, this is only for SQL. -The body is a 1-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_PREPARE, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_STMT_ID: :samp:`{{MP_INT integer}}` or IPROTO_SQL_TEXT: :samp:`{{MP_STR string}}` - }) - -IPROTO_STMT_ID (0x43) and statement-id (MP_INT) if executing a prepared statement -or -IPROTO_SQL_TEXT (0x40) and statement-text (string) if executing an SQL string. -Thus the IPROTO_PREPARE map item is the same as the first item of the -:ref:`IPROTO_EXECUTE ` body. - -.. _box_protocol-begin: - -IPROTO_BEGIN = 0x0e -~~~~~~~~~~~~~~~~~~~ - -Begin a transaction in the specified stream. -See :ref:`stream:begin() `. -The body is optional and can contain two items: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_BEGIN, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_STREAM_ID: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_TIMEOUT: :samp:`{{MP_DOUBLE}}`, - IPROTO_TXN_ISOLATION: :samp:`{{MP_UINT unsigned integer}}` - }) - -IPROTO_TIMEOUT is an optional timeout (in seconds). After it expires, -the transaction will be rolled back automatically. - -IPROTO_TXN_ISOLATION is the :ref:`transaction isolation level `. -It can take the following values: - -- ``TXN_ISOLATION_DEFAULT = 0`` -- use the default level from ``box.cfg`` (default value) -- ``TXN_ISOLATION_READ_COMMITTED = 1`` -- read changes that are committed but not confirmed yet -- ``TXN_ISOLATION_READ_CONFIRMED = 2`` -- read confirmed changes -- ``TXN_ISOLATION_BEST_EFFORT = 3`` -- determine isolation level automatically - -See :ref:`Binary protocol -- streams ` to learn more about -stream transactions in the binary protocol. - -.. _box_protocol-commit: - -IPROTO_COMMIT = 0x0f -~~~~~~~~~~~~~~~~~~~~ - -Commit the transaction in the specified stream. -See :ref:`stream:commit() `. - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(7) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_COMMIT, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_STREAM_ID: :samp:`{{MP_UINT unsigned integer}}` - }) - -See :ref:`Binary protocol -- streams ` to learn more about -stream transactions in the binary protocol. - - -.. _box_protocol-rollback: - -IPROTO_ROLLBACK = 0x10 -~~~~~~~~~~~~~~~~~~~~~~ - -Rollback the transaction in the specified stream. -See :ref:`stream:rollback() `. - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(7) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_ROLLBACK, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_STREAM_ID: :samp:`{{MP_UINT unsigned integer}}` - }) - -See :ref:`Binary protocol -- streams ` to learn more about -stream transactions in the binary protocol. - - -.. _box_protocol-ping: - -IPROTO_PING = 0x40 -~~~~~~~~~~~~~~~~~~ - -See :ref:`conn:ping() `. The body will be an empty map because IPROTO_PING -in the header contains all the information that the server instance needs. - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(5) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_PING, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - -.. _box_protocol-join: - -.. code-block:: lua - - IPROTO_JOIN = 0x41 -- for replication - IPROTO_SUBSCRIBE = 0x42 -- for replication SUBSCRIBE - IPROTO_VOTE_DEPRECATED = 0x43 -- for old style vote, superseded by IPROTO_VOTE - IPROTO_VOTE = 0x44 -- for master election - IPROTO_FETCH_SNAPSHOT = 0x45 -- for starting anonymous replication - IPROTO_REGISTER = 0x46 -- for leaving anonymous replication. - -Tarantool constants 0x41 to 0x46 (decimal 65 to 70) are for replication. -Connectors and clients do not need to send replication packets. -See :ref:`Binary protocol -- replication `. - -The next two IPROTO messages are used in replication connections between -Tarantool nodes in :ref:`synchronous replication `. -The messages are not supposed to be used by any client applications in their -regular connections. - -.. _box_protocol-raft_confirm: - -IPROTO_RAFT_CONFIRM = 0x28 -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This message confirms that the transactions originated from the instance -with id = IPROTO_REPLICA_ID have achieved quorum and can be committed, -up to and including LSN = IPROTO_LSN. -Prior to Tarantool :tarantool-release:`2.10.0`, IPROTO_RAFT_CONFIRM was called IPROTO_CONFIRM. - -The body is a 2-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_RAFT_CONFIRM, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_REPLICA_ID: :samp:`{{MP_INT integer}}`, - IPROTO_LSN: :samp:`{{MP_INT integer}}` - }) - - -.. _box_protocol-raft_rollback: - -IPROTO_RAFT_ROLLBACK = 0x29 -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This message says that the transactions originated from the instance -with id = IPROTO_REPLICA_ID couldn't achieve quorum for some reason -and should be rolled back, down to LSN = IPROTO_LSN and including it. -Prior to Tarantool version 2.10, IPROTO_RAFT_ROLLBACK was called IPROTO_ROLLBACK. - -The body is a 2-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_RAFT_ROLLBACK, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_REPLICA_ID: :samp:`{{MP_INT integer}}`, - IPROTO_LSN: :samp:`{{MP_INT integer}}` - }) - -.. _box_protocol-id: - -IPROTO_ID = 0x49 -~~~~~~~~~~~~~~~~ - -Clients send this message to inform the server about the protocol version and -features they support. Based on this information, the server can enable or -disable certain features in interacting with these clients. - -The body is a 2-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_ID, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_VERSION: :samp:`{{MP_UINT unsigned integer}}}`, - IPROTO_FEATURES: :samp:`{{MP_ARRAY array of unsigned integers}}}` - }) - -IPROTO_VERSION is an integer number reflecting the version of protocol that the -client supports. The latest IPROTO_VERSION is |iproto_version|. - -Available IPROTO_FEATURES are the following: - -- ``IPROTO_FEATURE_STREAMS = 0`` -- streams support: :ref:`IPROTO_STREAM_ID ` - in the request header. -- ``IPROTO_FEATURE_TRANSACTIONS = 1`` -- transaction support: IPROTO_BEGIN, - IPROTO_COMMIT, and IPROTO_ROLLBACK commands (with :ref:`IPROTO_STREAM_ID ` - in the request header). Learn more about :ref:`sending transaction commands `. -- ``IPROTO_FEATURE_ERROR_EXTENSION = 2`` -- :ref:`MP_ERROR ` - MsgPack extension support. Clients that don't support this feature will receive - error responses for :ref:`IPROTO_EVAL ` and - :ref:`IPROTO_CALL ` encoded to string error messages. -- ``IPROTO_FEATURE_WATCHERS = 3`` -- remote watchers support: :ref:`IPROTO_WATCH `, - :ref:`IPROTO_UNWATCH `, and :ref:`IPROTO_EVENT ` commands. - -IPROTO_ID requests can be processed without authentication. - -IPROTO_WATCH = 0x4a -~~~~~~~~~~~~~~~~~~~ - -See the :ref:`Watchers ` section below. - -IPROTO_UNWATCH = 0x4b -~~~~~~~~~~~~~~~~~~~~~ - -See the :ref:`Watchers ` section below. - -IPROTO_EVENT = 0x4c -~~~~~~~~~~~~~~~~~~~ - -See the :ref:`Watchers ` section below. - - -.. _box-protocol-watchers: - -Watchers --------- - -Since :doc:`2.10.0 `. - -The commands below support asynchronous server-client notifications signalled -with :ref:`box.broadcast() `. -Servers that support the new feature set the ``IPROTO_FEATURE_WATCHERS`` feature in reply to the ``IPROTO_ID`` command. -When the connection is closed, all watchers registered for it are unregistered. - -The remote :ref:`watcher ` protocol works in the following way: - -#. The client sends an ``IPROTO_WATCH`` packet to subscribe to the updates of a specified key defined on the server. - -#. The server sends an ``IPROTO_EVENT`` packet to the subscribed client after registration. - The packet contains the key name and its current value. - After that, the packet is sent every time the key value is updated with - ``box.broadcast()``, provided that the last notification was acknowledged (see below). - -#. After receiving the notification, the client sends an ``IPROTO_WATCH`` packet to acknowledge the notification. - -#. If the client doesn't want to receive any more notifications, it unsubscribes by sending - an ``IPROTO_UNWATCH`` packet. - -All the three request types are asynchronous -- the receiving end doesn't send a packet in reply to any of them. -Therefore, neither of them has a sync number. - -.. _box_protocol-watch: - -IPROTO_WATCH = 0x4a -~~~~~~~~~~~~~~~~~~~ - -Registers a new watcher for the given notification key or confirms a notification if the watcher is -already subscribed. -The watcher is notified after registration. -After that, the notification is sent every time the key is updated. -The server doesn't reply to the request unless it fails to parse the packet. - -The body is a 2-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_WATCH - }) - # - msgpack({ - IPROTO_EVENT_KEY: :samp:`{{MP_STR string}}}` - }) - -``IPROTO_EVENT_KEY`` (code 0x56) contains the key name. - -.. _box_protocol-unwatch: - -IPROTO_UNWATCH = 0x4b -~~~~~~~~~~~~~~~~~~~~~ - -Unregisters a watcher subscribed to the given notification key. -The server doesn't reply to the request unless it fails to parse the packet. - -The body is a 2-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_UNWATCH - }) - # - msgpack({ - IPROTO_EVENT_KEY: :samp:`{{MP_STR string}}}` - }) - -``IPROTO_EVENT_KEY`` (code 0x56) contains a key name. - -.. _box_protocol-event: - -IPROTO_EVENT = 0x4c -~~~~~~~~~~~~~~~~~~~ - -Sent by the server to notify a client about an update of a key. - -The body is a 2-item map: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_EVENT - }) - # - msgpack({ - IPROTO_EVENT_KEY: :samp:`{{MP_STR string}}}`, - IPROTO_EVENT_DATA: :samp:`{{MP_OBJECT value}}}` - }) - -``IPROTO_EVENT_KEY`` (code 0x56) contains the key name. - -``IPROTO_EVENT_DATA`` (code 0x57) contains data sent to a remote watcher. -The parameter is optional, the default value is ``nil``. - -.. _box-protocol-shutdown: - -Graceful shutdown protocol --------------------------- - -Since :doc:`2.10.0 `. - -The graceful shutdown protocol is a mechanism that helps to prevent data loss in requests in case of a shutdown command. -According to the protocol, when a server receives an ``os.exit()`` command or a ``SIGTERM`` signal, -it does not exit immediately. -Instead of that, first, the server stops listening for new connections. -Then, the server sends the shutdown packets to all connections that support the graceful shutdown protocol. -When a client is notified about the upcoming server exit, it stops serving any new requests and -waits for active requests to complete before closing the connections. -Once all connections are terminated, the server will be shut down. - -The protocol uses the event subscription system. -That is, the feature is available if the server supports the :ref:`box.shutdown ` event -and ``IPROTO_WATCH``. -For more information about it, see :ref:`reference for the event watchers ` -and the :ref:`corresponding section ` of this document. - -The shutdown protocol works in the following way: - -#. First, the server receives a shutdown request. - It can be either an ``os.exit()`` command or a :ref:`SIGTERM ` signal. - -#. Then the :ref:`box.shutdown ` event is generated. - The server broadcasts it to all subscribed remote watchers (see :ref:`IPROTO_WATCH `). - That is, the server calls :ref:`box.broadcast('box.shutdown', true) ` - from the :ref:`box.ctl.on_shutdown() ` trigger callback. - Once this is done, the server stops listening for new connections. - -#. From now on, the server waits until all subscribed connections are terminated. - -#. At the same time, the client gets the ``box.shutdown`` event and shuts the connection down gracefully. - -#. After all connections are closed, the server will be stopped. - Otherwise, a timeout occurs, and the Tarantool exits immediately. - You can set up the required timeout with the - :ref:`set_on_shutdown_timeout() ` function. - -.. _box_protocol-responses: - -Responses if no error and no SQL --------------------------------- - -After the :ref:`header `, for a response, -there will be a body. -If there was no error, it will contain IPROTO_OK (0x00). -If there was an error, it will contain an error code other than IPROTO_OK. -Responses to SQL statements are slightly different and will be described -in the later section, -:ref:`Binary protocol -- responses for SQL `. - -For IPROTO_OK, the header Response-Code-Indicator will be 0 and the body is a 1-item map. - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - Response-Code-Indicator: IPROTO_OK, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer, may be 64-bit}}`, - IPROTO_SCHEMA_VERSION: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_DATA: :samp:`{{any type}}` - }) - -- For :ref:`IPROTO_PING ` the body will be an empty map. - -- For most data-access requests (:ref:`IPROTO_SELECT `, - :ref:`IPROTO_INSERT `, :ref:`IPROTO_DELETE ` - , etc.) the body is an IPROTO_DATA map with an array of tuples that contain - an array of fields. - -- For :ref:`IPROTO_EVAL ` and :ref:`IPROTO_CALL ` - it will usually be an array but, since Lua requests can result in a wide variety - of structures, bodies can have a wide variety of structures. - -- For :ref:`IPROTO_ID `, the response body has the same structure as - the request body. It informs the client about the protocol version and features - that the server supports. - -Example: if this is the fifth message and the request is -:codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:insert{6}`, -and the previous schema version was 100, -a successful response will look like this: - -.. code-block:: none - - # - msgpack(32) - #
- msgpack({ - Response-Code-Indicator: IPROTO_OK, - IPROTO_SYNC: 5, - IPROTO_SCHEMA_VERSION: 100 - }) - # - msgpack({ - IPROTO_DATA: [[6]] - }) - -Later in :ref:`Binary protocol -- illustration ` -we will show actual byte codes of the response to the IPROTO_INSERT message. - -IPROTO_DATA is what we get with net_box and :ref:`Module buffer ` -so if we were using net_box we could decode with -:ref:`msgpack.decode_unchecked() `, -or we could convert to a string with :samp:`ffi.string({pointer},{length})`. -The :ref:`pickle.unpack() ` function might also be helpful. - -.. _box_protocol-responses_out_of_band: - -Responses for no error and out-of-band --------------------------------------- - -If the response is out-of-band, due to use of -:ref:`box.session.push() `, -then the header Response-Code-Indicator will be IPROTO_CHUNK instead of IPROTO_OK. - -.. _box_protocol-responses_error: - -Responses for errors --------------------- - -For a response other than IPROTO_OK, the header Response-Code-Indicator will be -``0x8XXX`` and the body will be a 1-item map. - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(32) - #
- msgpack({ - Response-Code-Indicator: :samp:`{{0x8XXX}}`, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer, may be 64-bit}}`, - IPROTO_SCHEMA_VERSION: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_ERROR: :samp:`{{MP_STRING string}}` - }) - -where ``0x8XXX`` is the indicator for an error and ``XXX`` is a value in -`src/box/errcode.h `_. -``src/box/errcode.h`` also has some convenience macros which define hexadecimal -constants for return codes. - -Example: in version 2.4.0 and earlier, -if this is the fifth message and the request is to create a duplicate -space with -``conn:eval([[box.schema.space.create('_space');]])`` -the unsuccessful response will look like this: - -.. code-block:: none - - # - msgpack(32) - #
- msgpack({ - Response-Code-Indicator: 0x800a, - IPROTO_SYNC: 5, - IPROTO_SCHEMA_VERSION: 0x78 - }) - # - msgpack({ - IPROTO_ERROR: "Space '_space' already exists" - }) - -Later in :ref:`Binary protocol -- illustration ` -we will show actual byte codes of the response to the IPROTO_EVAL message. - -Looking in errcode.h we find that error code 0x0a (decimal 10) is -ER_SPACE_EXISTS, and the string associated with ER_SPACE_EXISTS is -"Space '%s' already exists". - -Since version :doc:`2.4.1 `, responses for errors have extra information -following what was described above. This extra information is given via -MP_ERROR extension type. See details in :ref:`MessagePack extensions -` section. - - -.. _box_protocol-sql_protocol: - -Responses for SQL ------------------ - -After the :ref:`header `, for a response to an SQL statement, -there will be a body that is slightly different from the body for -:ref:`Binary protocol -- responses if no error and no SQL `. - -If the SQL request is not SELECT or VALUES or PRAGMA, then the response body -contains only IPROTO_SQL_INFO (0x42). Usually IPROTO_SQL_INFO is a map with only -one item -- SQL_INFO_ROW_COUNT (0x00) -- which is the number of changed rows. - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - Response-Code-Indicator: IPROTO_OK, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer, may be 64-bit}}`, - IPROTO_SCHEMA_VERSION: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_SQL_INFO: { - SQL_INFO_ROW_COUNT: :samp:`{{MP_UINT}}` - } - }) - -For example, if the request is -:samp:`INSERT INTO {table-name} VALUES (1), (2), (3)`, then the response body -contains an :samp:`IPROTO_SQL_INFO map with SQL_INFO_ROW_COUNT = 3`. -:samp:`SQL_INFO_ROW_COUNT` can be 0 for statements that do not change rows, -but can be 1 for statements that create new objects. - -The IPROTO_SQL_INFO map may contain a second item -- :samp:`SQL_INFO_AUTO_INCREMENT_IDS -(0x01)` -- which is the new primary-key value (or values) for an INSERT in a table -defined with PRIMARY KEY AUTOINCREMENT. In this case the MP_MAP will have two -keys, and one of the two keys will be 0x01: SQL_INFO_AUTO_INCREMENT_IDS, which -is an array of unsigned integers. - -If the SQL statement is SELECT or VALUES or PRAGMA, the response contains: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(32) - #
- msgpack({ - Response-Code-Indicator: IPROTO_OK, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer, may be 64-bit}}`, - IPROTO_SCHEMA_VERSION: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_METADATA: :samp:`{{array of column maps}}`, - IPROTO_DATA: :samp:`{{array of tuples}}` - }) - -* :samp:`IPROTO_METADATA: {array of column maps}` = array of column maps, with each column map containing - at least IPROTO_FIELD_NAME (0x00) and MP_STR, and IPROTO_FIELD_TYPE (0x01) and MP_STR. - Additionally, if ``sql_full_metadata`` in the - :ref:`_session_settings ` system space - is TRUE, then the array will have these additional column maps - which correspond to components described in the - :ref:`box.execute() ` section: - -.. code-block:: none - - IPROTO_FIELD_COLL (0x02) and MP_STR - IPROTO_FIELD_IS_NULLABLE (0x03) and MP_BOOL - IPROTO_FIELD_IS_AUTOINCREMENT (0x04) and MP_BOOL - IPROTO_FIELD_SPAN (0x05) and MP_STR or MP_NIL - -* :samp:`IPROTO_DATA:{array of tuples}` = the result set "rows". - -Example: -If we ask for full metadata by saying |br| -:code:`conn.space._session_settings:update('sql_full_metadata', {{'=', 'value', true}})` |br| -and we select the two rows from a table named t1 that has columns named DD and Д, with |br| -:code:`conn:execute([[SELECT dd, дд AS д FROM t1;]])` |br| -we could get this response, in the body: - -.. code-block:: none - - # - msgpack({ - IPROTO_METADATA: [ - IPROTO_FIELD_NAME: 'DD', - IPROTO_FIELD_TYPE: 'integer', - IPROTO_FIELD_IS_NULLABLE: false, - IPROTO_FIELD_IS_AUTOINCREMENT: true, - IPROTO_FIELD_SPAN: nil, - IPROTO_FIELD_NAME: 'Д', - IPROTO_FIELD_TYPE: 'string', - IPROTO_FIELD_COLL: 'unicode', - IPROTO_FIELD_IS_NULLABLE: true, - IPROTO_FIELD_SPAN: 'дд' - ], - IPROTO_DATA: [ - [1,'a'], - [2,'b']' - ] - }) - -If instead we said |br| -:code:`conn:prepare([[SELECT dd, дд AS д FROM t1;]])` |br| -then we could get almost the same response, but there would -be no IPROTO_DATA and there would be two additional items: |br| -``34 00 = IPROTO_BIND_COUNT and MP_UINT = 0`` (there are no parameters to bind), |br| -``33 90 = IPROTO_BIND_METADATA and MP_ARRAY, size 0`` (there are no parameters to bind). - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack({ - IPROTO_STMT_ID: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_BIND_COUNT: :samp:`{{MP_INT integer}}`, - IPROTO_BIND_METADATA: :samp:`{{array of parameter descriptors}}`, - IPROTO_METADATA: [ - IPROTO_FIELD_NAME: 'DD', - IPROTO_FIELD_TYPE: 'integer', - IPROTO_FIELD_IS_NULLABLE: false - IPROTO_FIELD_IS_AUTOINCREMENT: true - IPROTO_FIELD_SPAN: nil, - IPROTO_FIELD_NAME: 'Д', - IPROTO_FIELD_TYPE: 'string', - IPROTO_FIELD_COLL: 'unicode', - IPROTO_FIELD_IS_NULLABLE: true, - IPROTO_FIELD_SPAN: 'дд' - ] - }) - -Now read the source code file `net_box.c `_ -where the function "decode_metadata_optional" is an example of how Tarantool -itself decodes extra items. - -Later in :ref:`Binary protocol -- illustration ` -we will show actual byte codes of responses to the above SQL messages. - - -.. _box_protocol-authentication: - -Authentication --------------- - -Greeting message -~~~~~~~~~~~~~~~~ - -When a client connects to the server instance, the instance responds with -a 128-byte text greeting message, not in MsgPack format: |br| -64-byte Greeting text line 1 |br| -64-byte Greeting text line 2 |br| -44-byte base64-encoded salt |br| -20-byte NULL - -The greeting contains two 64-byte lines of ASCII text. -Each line ends with a newline character (:code:`\n`). The first line contains -the instance version and protocol type. The second line contains up to 44 bytes -of base64-encoded random string, to use in the authentication packet, and ends -with up to 23 spaces. - -Part of the greeting is a base64-encoded session salt - -a random string which can be used for authentication. The maximum length of an encoded -salt (44 bytes) is more than the amount necessary to create the authentication -message. An excess is reserved for future authentication -schemas. - -Authentication is optional -- if it is skipped, then the session user is ``'guest'`` -(the ``'guest'`` user does not need a password). - -If authentication is not skipped, then at any time an authentication packet -can be prepared using the greeting, the user's name and password, -and `sha-1 `_ functions, as follows. - -.. code-block:: none - - PREPARE SCRAMBLE: - - size_of_encoded_salt_in_greeting = 44; - size_of_salt_after_base64_decode = 32; - /* sha1() will only use the first 20 bytes */ - size_of_any_sha1_digest = 20; - size_of_scramble = 20; - - prepare 'chap-sha1' scramble: - - salt = base64_decode(encoded_salt); - step_1 = sha1(password); - step_2 = sha1(step_1); - step_3 = sha1(first_20_bytes_of_salt, step_2); - scramble = xor(step_1, step_3); - return scramble; - -IPROTO_AUTH = 0x07 -~~~~~~~~~~~~~~~~~~ - -The client sends an authentication packet as an IPROTO_AUTH message: - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_AUTH, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer, usually = 1}}` - }) - # - msgpack({ - IPROTO_USER_NAME: :samp:`{{MP_STRING string }}`, - IPROTO_TUPLE: ['chap-sha1', :samp:`{{MP_STRING 20-byte string}}`] - }) - -:code:`` holds the user name. :code:`` must be an array of 2 fields: -authentication mechanism ("chap-sha1" is the only supported mechanism right now) -and scramble, encrypted according to the specified mechanism. - -The server instance responds to an authentication packet with a standard response with 0 tuples. - -To see how Tarantool handles this, look at -`net_box.c `_ -function ``netbox_encode_auth``. - -.. _box_protocol-streams: - -Binary protocol -- streams --------------------------- - -The :ref:`Streams and interactive transactions ` -feature, which was added in Tarantool version -:tarantool-release:`2.10.0`, allows two things: -sequential processing and interleaving. - -Sequential processing: -With streams there is a guarantee that the server instance will not -handle the next request in a stream until it has completed the previous one. - -Interleaving: -For example, a series of requests can include -"begin for stream #1", "begin for stream #2", -"insert for stream #1", "insert for stream #2", "delete -for stream #1", "commit for stream #1", "rollback for stream #2". - -To make these things possible, -the engine should be :ref:`vinyl ` or :ref:`memtx with mvcc `, and -the client is responsible for ensuring that the stream identifier, -unsigned integer :ref:`IPROTO_STREAM_ID `, is in the request header. -IPROTO_STREAM_ID can be any positive 64-bit number, and should be unique for the connection. -If IPROTO_STREAM_ID equals zero the server instance will ignore it. - -For example, suppose that the client has started a stream with -the :ref:`net.box module ` - -.. code-block:: lua - - net_box = require('net.box') - conn = net_box.connect('localhost:3302') - stream = conn:new_stream() - -At this point the stream object will look like a duplicate of -the conn object, with just one additional member: ``stream_id``. -Now, using stream instead of conn, the client sends two requests: - -.. code-block:: lua - - stream.space.T:insert{1} - stream.space.T:insert{2} - -The header and body of these requests will be the same as in -non-stream :ref:`IPROTO_INSERT ` requests, except -that the header will contain an additional item: IPROTO_STREAM_ID=0x0a -with MP_UINT=0x01. It happens to equal 1 for this example because -each call to conn:new_stream() assigns a new number, starting with 1. - -.. _box_protocol-stream_transactions: - -The client makes stream transactions by sending, in order: - -1. IPROTO_BEGIN with an optional transaction timeout in the IPROTO_TIMEOUT field of the request body. -2. The transaction data-change and query requests. -3. IPROTO_COMMIT or IPROTO_ROLLBACK. - -All these requests must contain the same IPROTO_STREAM_ID value. - -A rollback will happen automatically if -a disconnect occurs or the transaction timeout expires before the commit is possible. - -Thus there are now multiple ways to do transactions: -with ``net_box`` ``stream:begin()`` and ``stream:commit()`` or ``stream:rollback()`` -which cause IPROTO_BEGIN and IPROTO_COMMIT or IPROTO_ROLLBACK with -the current value of stream.stream_id; -with :ref:`box.begin() ` and :ref:`box.commit() ` or :ref:`box.rollback() `; -with SQL and :ref:`START TRANSACTION ` and :ref:`COMMIT ` or :ref:`ROLLBACK `. -An application can use any or all of these ways. - -.. _box_protocol-replication: - -Replication ------------ - -IPROTO_JOIN = 0x41 -~~~~~~~~~~~~~~~~~~ - -First you must send an initial IPROTO_JOIN request. - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_JOIN, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_INSTANCE_UUID: :samp:`{{uuid}}` - }) - -Then the instance which you want to connect to will send its last SNAP file, -by simply creating a number of INSERTs (with additional LSN and ServerID) -(do not reply to this). Then that instance will send a vclock's MP_MAP and -close a socket. - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - Response-Code-Indicator: 0, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - IPROTO_VCLOCK: :samp:`{{MP_INT SRV_ID, MP_INT SRV_LSN}}` - }) - -IPROTO_SUBSCRIBE = 0x42 -~~~~~~~~~~~~~~~~~~~~~~~ - -Then you must send an IPROTO_SUBSCRIBE request. - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_SUBSCRIBE, - IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`, - IPROTO_INSTANCE_UUID: :samp:`{{uuid}}`, - IPROTO_CLUSTER_UUID: :samp:`{{uuid}}`, - }) - # - msgpack({ - IPROTO_VCLOCK: :samp:`{{MP_INT SRV_ID, MP_INT SRV_LSN}}` - }) - -Then you must process every request that could come through other masters. -Every request between masters will have additional LSN and SERVER_ID. - - -.. _box_protocol-heartbeat: - -HEARTBEATS -~~~~~~~~~~ - -Frequently a master sends a :ref:`heartbeat ` message to a replica. -For example, if there is a replica with id = 2, -and a timestamp with a moment in 2020, a master might send this: - -.. cssclass:: highlight -.. parsed-literal:: - - #
- msgpack({ - IPROTO_REQUEST_TYPE: 0 - IPROTO_REPLICA_ID: 2 - IPROTO_TIMESTAMP: :samp:`{{Float 64 MP_DOUBLE 8-byte timestamp}}` - }) - -and the replica might send back this: - -.. code-block:: none - - #
- msgpack({ - Response-Code-Indicator: IPROTO_OK - IPROTO_REPLICA_ID: 2 - IPROTO_VCLOCK: {1, 6} - }) - -Later in :ref:`Binary protocol -- illustration ` -we will show actual byte codes of the above heartbeat examples. - -.. _box_protocol-ballots: - -BALLOTS -~~~~~~~ - -While connecting for replication, an instance sends a request with header IPROTO_VOTE (0x44). -The normal response is ER_OK,and IPROTO_BALLOT (0x29). -The fields within IPROTO_BALLOT are map items: - -.. code-block:: none - - IPROTO_BALLOT_IS_RO_CFG (0x01) + MP_BOOL - IPROTO_BALLOT_VCLOCK (0x02) + vclock - IPROTO_BALLOT_GC_VCLOCK (0x03) + vclock - IPROTO_BALLOT_IS_RO (0x04) + MP_BOOL - IPROTO_BALLOT_IS_ANON = 0x05 + MP_BOOL - IPROTO_BALLOT_IS_BOOTED = 0x06 + MP_BOOL - IPROTO_BALLOT_CAN_LEAD = 0x07 + MP_BOOL - - -IPROTO_BALLOT_IS_RO_CFG and IPRO_BALLOT_VCLOCK and IPROTO_BALLOT_GC_VCLOCK and IPROTO_BALLOT_IS_RO -were added in version :doc:`2.6.1 `. -IPROTO_BALLOT_IS_ANON was added in version :doc:`2.7.1 `. -IPROTO_BALLOT_IS_BOOTED was added in version 2.7.3 and 2.8.2 and 2.9.1. -There have been some name changes starting with version 2.7.3 and 2.8.2 and 2.9.1: -IPROTO_BALLOT_IS_RO_CFG was formerly called IPROTO_BALLOT_IS_RO, -and IPROTO_BALLOT_IS_RO was formerly called IPROTO_BALLOT_IS_LOADING. - -IPROTO_BALLOT_IS_RO_CFG corresponds to :ref:`box.cfg.read_only `. - -IPROTO_BALLOT_GC_VCLOCK can be the vclock value of the instance's oldest -WAL entry, which corresponds to :ref:`box.info.gc().vclock `. - -IPROTO_BALLOT_IS_RO is true if the instance is not writable, -which may happen for a variety of reasons, such as: -it was configured as :ref:`read_only `, -or it has :ref:`orphan status `, -or it is a :ref:`Raft ` follower. - -IPROTO_BALLOT_IS_ANON corresponds to :ref:`box.cfg.replication_anon `. - -IPROTO_BALLOT_IS_BOOTED is true if the instance has finished its -bootstrap or recovery process. - -IPROTO_BALLOT_CAN_LEAD is true if the :ref:`election_mode ` -configuration setting is either 'candidate' or 'manual', so that -during the :ref:`leader election process ` -this instance may be preferred over instances whose configuration -setting is 'voter'. -IPROTO_BALLOT_CAN_LEAD support was added simultaneously in -version :doc:`2.7.3 ` -and version :doc:`2.8.2 `. - -.. _box_protocol-flags: - -FLAGS -~~~~~ - -For replication of :ref:`synchronous transactions ` -a header may contain a key = IPROTO_FLAGS and an MP_UINT value = one or more -bits: IPROTO_FLAG_COMMIT or IPROTO_FLAG_WAIT_SYNC or IPROTO_FLAG_WAIT_ACK. - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - # ... other header items ..., - IPROTO_FLAGS: :samp:`{{MP_UINT unsigned integer}}` - }) - # - msgpack({ - # ... message for a transaction ... - }) - -IPROTO_FLAG_COMMIT (0x01) will be set if this is the last message for a transaction, -IPROTO_FLAG_WAIT_SYNC (0x02) will be set if this is the last message for a transaction which cannot be completed immediately, -IPROTO_FLAG_WAIT_ACK (0x04) will be set if this is the last message for a synchronous transaction. - -.. _box_protocol-raft: - -IPROTO_RAFT = 0x1e -~~~~~~~~~~~~~~~~~~ - -A node broadcasts the IPROTO_RAFT request to all the replicas connected to it when the RAFT state of the node changes. -It can be any actions changing the state, like starting a new election, bumping the term, voting for another node, becoming the leader, and so on. - -If there should be a response, for example, in case of a vote request to other nodes, the response will also be an IPROTO_RAFT message. -In this case, the node should be connected as a replica to another node from which the response is expected because the response is sent via the replication channel. -In other words, there should be a full-mesh connection between the nodes. - -.. cssclass:: highlight -.. parsed-literal:: - - # - msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`) - #
- msgpack({ - IPROTO_REQUEST_TYPE: IPROTO_RAFT, - IPROTO_REPLICA_ID: :samp:`{{MP_INT integer}}`, # ID of the replica which the request came from - - }) - # - msgpack({ - IPROTO_RAFT_TERM: :samp:`{{MP_UINT unsigned integer}}`, # RAFT term of the instance - IPROTO_RAFT_VOTE: :samp:`{{MP_UINT unsigned integer}}`, # Instance vote in the current term (if any). - IPROTO_RAFT_STATE: :samp:`{{MP_UINT unsigned integer}}`, # Instance state. Possible values: 1 -- follower, 2 -- candidate, 3 -- leader. - IPROTO_RAFT_VCLOCK: :samp:`{{MP_ARRAY {{MP_INT SRV_ID, MP_INT SRV_LSN}, {MP_INT SRV_ID, MP_INT SRV_LSN}, ...}}}`, # Current vclock of the instance. Presents only on the instances in the "candidate" state (IPROTO_RAFT_STATE == 2). - IPROTO_RAFT_LEADER_ID: :samp:`{{MP_UINT unsigned integer}}`, # Current leader node ID as seen by the node that issues the request. Since version :doc:`2.10.0 `. - IPROTO_RAFT_IS_LEADER_SEEN: :samp:`{{MP_BOOL boolean}}` # Shows whether the node has a direct connection to the leader node. Since version :doc:`2.10.0 `. - - }) - -.. _box_protocol-illustration: - -Examples --------- - - -To follow the examples in this section, -get a single Linux computer and start three command-line shells ("terminals"). - --- On terminal #1, Start monitoring port 3302 with `tcpdump `_: |br| - -.. code-block:: bash - - sudo tcpdump -i lo 'port 3302' -X - -On terminal #2, start a server with: - -.. code-block:: lua - - box.cfg{listen=3302} - box.schema.space.create('tspace') - box.space.tspace:create_index('I') - box.space.tspace:insert{280} - box.schema.user.grant('guest','read,write,execute,create,drop','universe') - -On terminal #3, start another server, which will act as a client, with: - -.. code-block:: lua - - box.cfg{} - net_box = require('net.box') - conn = net_box.connect('localhost:3302') - conn.space.tspace:select(280) - -Now look at what tcpdump shows for the job connecting to 3302 -- the "request". -After the words "length 32" is a packet that ends with these 32 bytes -(we have added indented comments): - -.. code-block:: none - - ce 00 00 00 1b MP_UINT = decimal 27 = number of bytes after this - 82 MP_MAP, size 2 (we'll call this "Main-Map") - 01 IPROTO_SYNC (Main-Map Item#1) - 04 MP_INT = 4 = number that gets incremented with each request - 00 IPROTO_REQUEST_TYPE (Main-Map Item#2) - 01 IPROTO_SELECT - 86 MP_MAP, size 6 (we'll call this "Select-Map") - 10 IPROTO_SPACE_ID (Select-Map Item#1) - cd 02 00 MP_UINT = decimal 512 = id of tspace (could be larger) - 11 IPROTO_INDEX_ID (Select-Map Item#2) - 00 MP_INT = 0 = id of index within tspace - 14 IPROTO_ITERATOR (Select-Map Item#3) - 00 MP_INT = 0 = Tarantool iterator_type.h constant ITER_EQ - 13 IPROTO_OFFSET (Select-Map Item#4) - 00 MP_INT = 0 = amount to offset - 12 IPROTO_LIMIT (Select-Map Item#5) - ce ff ff ff ff MP_UINT = 4294967295 = biggest possible limit - 20 IPROTO_KEY (Select-Map Item#6) - 91 MP_ARRAY, size 1 (we'll call this "Key-Array") - cd 01 18 MP_UINT = 280 (Select-Map Item#6, Key-Array Item#1) - -- 280 is the key value that we are searching for - -Now read the source code file -`net_box.c `_ -and skip to the line ``netbox_encode_select(lua_State *L)``. -From the comments and from simple function calls like -``mpstream_encode_uint(&stream, IPROTO_SPACE_ID);`` -you will be able to see how net_box put together the packet contents that you -have just observed with tcpdump. - -There are libraries for reading and writing MessagePack objects. -C programmers sometimes include `msgpuck.h `_. - -Now you know how Tarantool itself makes requests with the binary protocol. -When in doubt about a detail, consult ``net_box.c`` -- it has routines for each -request. Some :ref:`connectors ` have similar code. - -For an IPROTO_UPDATE example, suppose a user changes field #2 in tuple #2 -in space #256 to ``'BBBB'``. The body will look like this: -(notice that in this case there is an extra map item -IPROTO_INDEX_BASE, to emphasize that field numbers -start with 1, which is optional and can be omitted): - -.. code-block:: none - - 04 IPROTO_UPDATE - 85 IPROTO_MAP, size 5 - 10 IPROTO_SPACE_ID, Map Item#1 - cd 02 00 MP_UINT 256 - 11 IPROTO_INDEX_ID, Map Item#2 - 00 MP_INT 0 = primary-key index number - 15 IPROTO_INDEX_BASE, Map Item#3 - 01 MP_INT = 1 i.e. field numbers start at 1 - 21 IPROTO_TUPLE, Map Item#4 - 91 MP_ARRAY, size 1, for array of operations - 93 MP_ARRAY, size 3 - a1 3d MP_STR = OPERATOR = '=' - 02 MP_INT = FIELD_NO = 2 - a5 42 42 42 42 42 MP_STR = VALUE = 'BBBB' - 20 IPROTO_KEY, Map Item#5 - 91 MP_ARRAY, size 1, for array of key values - 02 MP_UINT = primary-key value = 2 - -Byte codes for the :ref:`IPROTO_EXECUTE ` example: - -.. code-block:: none - - 0b IPROTO_EXECUTE - 83 MP_MAP, size 3 - 43 IPROTO_STMT_ID Map Item#1 - ce d7 aa 74 1b MP_UINT value of n.stmt_id - 41 IPROTO_SQL_BIND Map Item#2 - 92 MP_ARRAY, size 2 - 01 MP_INT = 1 = value for first parameter - a1 61 MP_STR = 'a' = value for second parameter - 2b IPROTO_OPTIONS Map Item#3 - 90 MP_ARRAY, size 0 (there are no options) - -Byte codes for the response to the :codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:insert{6}` -example: - -.. code-block:: none - - ce 00 00 00 20 MP_UINT = HEADER AND BODY SIZE - 83 MP_MAP, size 3 - 00 Response-Code-Indicator - ce 00 00 00 00 MP_UINT = IPROTO_OK - 01 IPROTO_SYNC - cf 00 00 00 00 00 00 00 53 MP_UINT = sync value - 05 IPROTO_SCHEMA_VERSION - ce 00 00 00 68 MP_UINT = schema version - 81 MP_MAP, size 1 - 30 IPROTO_DATA - dd 00 00 00 01 MP_ARRAY, size 1 (row count) - 91 MP_ARRAY, size 1 (field count) - 06 MP_INT = 6 = the value that was inserted - -Byte codes for the response to the ``conn:eval([[box.schema.space.create('_space');]])`` -example: - -.. code-block:: none - - ce 00 00 00 3b MP_UINT = HEADER AND BODY SIZE - 83 MP_MAP, size 3 (i.e. 3 items in header) - 00 Response-Code-Indicator - ce 00 00 80 0a MP_UINT = hexadecimal 800a - 01 IPROTO_SYNC - cf 00 00 00 00 00 00 00 26 MP_UINT = sync value - 05 IPROTO_SCHEMA_VERSION - ce 00 00 00 78 MP_UINT = schema version value - 81 MP_MAP, size 1 - 31 IPROTO_ERROR_24 - db 00 00 00 1d 53 70 61 63 etc. MP_STR = "Space '_space' already exists" - -Byte codes, if we use the same net.box connection that -we used for :ref:`Binary protocol -- illustration ` -and we say |br| -``conn:execute([[CREATE TABLE t1 (dd INT PRIMARY KEY AUTOINCREMENT, дд STRING COLLATE "unicode");]])`` |br| -``conn:execute([[INSERT INTO t1 VALUES (NULL, 'a'), (NULL, 'b');]])`` |br| -and we watch what tcpdump displays, we will see two noticeable things: -(1) the CREATE statement caused a schema change so the response has -a new IPROTO_SCHEMA_VERSION value and the body includes -the new contents of some system tables (caused by requests from net.box which users will not see); -(2) the final bytes of the response to the INSERT will be: - -.. code-block:: none - - 81 MP_MAP, size 1 - 42 IPROTO_SQL_INFO - 82 MP_MAP, size 2 - 00 Tarantool constant (not in iproto_constants.h) = SQL_INFO_ROW_COUNT - 02 1 = row count - 01 Tarantool constant (not in iproto_constants.h) = SQL_INFO_AUTOINCREMENT_ID - 92 MP_ARRAY, size 2 - 01 first autoincrement number - 02 second autoincrement number - -Byte codes for the SQL SELECT example, -if we ask for full metadata by saying |br| -:code:`conn.space._session_settings:update('sql_full_metadata', {{'=', 'value', true}})` |br| -and we select the two rows from the table that we just created |br| -:code:`conn:execute([[SELECT dd, дд AS д FROM t1;]])` |br| -then tcpdump will show this response, after the header: - -.. code-block:: none - - 82 MP_MAP, size 2 (i.e. metadata and rows) - 32 IPROTO_METADATA - 92 MP_ARRAY, size 2 (i.e. 2 columns) - 85 MP_MAP, size 5 (i.e. 5 items for column#1) - 00 a2 44 44 IPROTO_FIELD_NAME and 'DD' - 01 a7 69 6e 74 65 67 65 72 IPROTO_FIELD_TYPE and 'integer' - 03 c2 IPROTO_FIELD_IS_NULLABLE and false - 04 c3 IPROTO_FIELD_IS_AUTOINCREMENT and true - 05 c0 PROTO_FIELD_SPAN and nil - 85 MP_MAP, size 5 (i.e. 5 items for column#2) - 00 a2 d0 94 IPROTO_FIELD_NAME and 'Д' upper case - 01 a6 73 74 72 69 6e 67 IPROTO_FIELD_TYPE and 'string' - 02 a7 75 6e 69 63 6f 64 65 IPROTO_FIELD_COLL and 'unicode' - 03 c3 IPROTO_FIELD_IS_NULLABLE and true - 05 a4 d0 b4 d0 b4 IPROTO_FIELD_SPAN and 'дд' lower case - 30 IPROTO_DATA - 92 MP_ARRAY, size 2 - 92 MP_ARRAY, size 2 - 01 MP_INT = 1 i.e. contents of row#1 column#1 - a1 61 MP_STR = 'a' i.e. contents of row#1 column#2 - 92 MP_ARRAY, size 2 - 02 MP_INT = 2 i.e. contents of row#2 column#1 - a1 62 MP_STR = 'b' i.e. contents of row#2 column#2 - -Byte code for the SQL PREPARE example. If we said |br| -:code:`conn:prepare([[SELECT dd, дд AS д FROM t1;]])` |br| -then tcpdump would show almost the same response, but there would -be no IPROTO_DATA. Instead, additional items will appear: - -.. code-block:: none - - 34 IPROTO_BIND_COUNT - 00 MP_UINT = 0 - - 33 IPROTO_BIND_METADATA - 90 MP_ARRAY, size 0 - -``MP_UINT = 0`` and ``MP_ARRAY`` has size 0 because there are no parameters to bind. -Full output: - -.. code-block:: none - - 84 MP_MAP, size 4 - 43 IPROTO_STMT_ID - ce c2 3c 2c 1e MP_UINT = statement id - 34 IPROTO_BIND_COUNT - 00 MP_INT = 0 = number of parameters to bind - 33 IPROTO_BIND_METADATA - 90 MP_ARRAY, size 0 = there are no parameters to bind - 32 IPROTO_METADATA - 92 MP_ARRAY, size 2 (i.e. 2 columns) - 85 MP_MAP, size 5 (i.e. 5 items for column#1) - 00 a2 44 44 IPROTO_FIELD_NAME and 'DD' - 01 a7 69 6e 74 65 67 65 72 IPROTO_FIELD_TYPE and 'integer' - 03 c2 IPROTO_FIELD_IS_NULLABLE and false - 04 c3 IPROTO_FIELD_IS_AUTOINCREMENT and true - 05 c0 PROTO_FIELD_SPAN and nil - 85 MP_MAP, size 5 (i.e. 5 items for column#2) - 00 a2 d0 94 IPROTO_FIELD_NAME and 'Д' upper case - 01 a6 73 74 72 69 6e 67 IPROTO_FIELD_TYPE and 'string' - 02 a7 75 6e 69 63 6f 64 65 IPROTO_FIELD_COLL and 'unicode' - 03 c3 IPROTO_FIELD_IS_NULLABLE and true - 05 a4 d0 b4 d0 b4 IPROTO_FIELD_SPAN and 'дд' lower case - -Byte code for the heartbeat example. The master might send this body: - -.. code-block:: none - - 83 MP_MAP, size 3 - 00 Main-Map Item #1 IPROTO_REQUEST_TYPE - 00 MP_UINT = 0 - 02 Main-Map Item #2 IPROTO_REPLICA_ID - 02 MP_UINT = 2 = id - 04 Main-Map Item #3 IPROTO_TIMESTAMP - cb MP_DOUBLE (MessagePack "Float 64") - 41 d7 ba 06 7b 3a 03 21 8-byte timestamp - -Byte code for the heartbeat example. The replica might send back this body - -.. code-block:: none - - 81 MP_MAP, size 1 - 00 Main-Map Item #1 Response-code-indicator - 00 MP_UINT = 0 = IPROTO_OK - 81 Main-Map Item #2, MP_MAP, size 1 - 26 Sub-Map Item #1 IPROTO_VCLOCK - 81 Sub-Map Item #2, MP_MAP, size 1 - 01 MP_UINT = 1 = id (part 1 of vclock) - 06 MP_UINT = 6 = lsn (part 2 of vclock) - - - -.. _box_protocol-xlog: - -XLOG / SNAP ------------ - -.xlog and .snap files have nearly the same format. The header looks like: - -.. code-block:: none - - \n SNAP\n or XLOG\n - \n currently 0.13\n - Server: \n where UUID is a 36-byte string - VClock: \n e.g. {1: 0}\n - \n - -After the file header come the data tuples. -Tuples begin with a row marker ``0xd5ba0bab`` and -the last tuple may be followed by an EOF marker -``0xd510aded``. -Thus, between the file header and the EOF marker, there -may be data tuples that have this form: - -.. code-block:: none - - 0 3 4 17 - +-------------+========+============+===========+=========+ - | | | | | | - | 0xd5ba0bab | LENGTH | CRC32 PREV | CRC32 CUR | PADDING | - | | | | | | - +-------------+========+============+===========+=========+ - MP_FIXEXT2 MP_INT MP_INT MP_INT --- - - +============+ +===================================+ - | | | | - | HEADER | | BODY | - | | | | - +============+ +===================================+ - MP_MAP MP_MAP - -See the example in the :ref:`File formats ` section. +This section provides information on the Tarantool binary protocol, iproto. +The protocol is called "binary" because the database is most frequently accessed +via binary code instead of Lua request text. Tarantool experts use it: + +* to write their own connectors +* to understand network messages +* to support new features that their favorite connector doesn't support yet +* to avoid repetitive parsing by the server + +The binary protocol provides complete access to Tarantool functionality, including: + +* request multiplexing, for example ability to issue multiple requests + asynchronously via the same connection +* response format that supports zero-copy writes + +.. toctree:: + :maxdepth: 1 + + iproto/mp_types + iproto/format + iproto/keys + iproto/requests + iproto/authentication + iproto/streams + iproto/events + iproto/sql + iproto/replication + Examples <../../how-to/other/iproto> diff --git a/doc/dev_guide/internals/file_formats.rst b/doc/dev_guide/internals/file_formats.rst index 698d5525c1..f2c45215c0 100644 --- a/doc/dev_guide/internals/file_formats.rst +++ b/doc/dev_guide/internals/file_formats.rst @@ -1,14 +1,12 @@ .. _internals-data_persistence: --------------------------------------------------------------------------------- File formats --------------------------------------------------------------------------------- +============ .. _internals-wal: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Data persistence and the WAL file format -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------------------- To maintain data persistence, Tarantool writes each data change request (insert, update, delete, replace, upsert) into a write-ahead log (WAL) file in the @@ -114,9 +112,8 @@ a secondary key, the record in the .xlog file will contain the primary key. .. _internals-snapshot: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The snapshot file format -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ The format of a snapshot .snap file is nearly the same as the format of a WAL .xlog file. However, the snapshot header differs: it contains the instance's global unique identifier @@ -131,3 +128,43 @@ and ``_cluster`` -- will be at the start of the .snap file, before the records o any spaces that were created by users. Secondarily, the .snap file's records are ordered by primary key within space id. + +.. _box_protocol-xlog: + +Example +------- + +The header of a ``.snap`` or ``.xlog`` file looks like: + +.. code-block:: none + + \n SNAP\n or XLOG\n + \n currently 0.13\n + Server: \n where UUID is a 36-byte string + VClock: \n e.g. {1: 0}\n + \n + +After the file header come the data tuples. +Tuples begin with a row marker ``0xd5ba0bab`` and +the last tuple may be followed by an EOF marker +``0xd510aded``. +Thus, between the file header and the EOF marker, there +may be data tuples that have this form: + +.. code-block:: none + + 0 3 4 17 + +-------------+========+============+===========+=========+ + | | | | | | + | 0xd5ba0bab | LENGTH | CRC32 PREV | CRC32 CUR | PADDING | + | | | | | | + +-------------+========+============+===========+=========+ + MP_FIXEXT2 MP_INT MP_INT MP_INT --- + + +============+ +===================================+ + | | | | + | HEADER | | BODY | + | | | | + +============+ +===================================+ + MP_MAP MP_MAP + diff --git a/doc/dev_guide/internals/iproto/authentication.rst b/doc/dev_guide/internals/iproto/authentication.rst new file mode 100644 index 0000000000..428bf3d806 --- /dev/null +++ b/doc/dev_guide/internals/iproto/authentication.rst @@ -0,0 +1,64 @@ +.. _box_protocol-authentication: + +Session start and authentication +================================ + +Every iproto session begins with a greeting and optional authentication. + +Greeting message +---------------- + +When a client connects to the server instance, the instance responds with +a 128-byte text greeting message, not in MsgPack format: + +.. code-block:: none + + Tarantool () + + +For example: + +.. code-block:: none + + Tarantool 2.10.0 (Binary) 29b74bed-fdc5-454c-a828-1d4bf42c639a + QK2HoFZGXTXBq2vFj7soCsHqTo6PGTF575ssUBAJLAI= + +The greeting contains two 64-byte lines of ASCII text. +Each line ends with a newline character (:code:`\n`). If the line content is less than 64 bytes long, +the rest of the line is filled up with symbols with an ASCII code of 0 that aren't displayed in the console. + +The first line contains +the instance version and protocol type. The second line contains the session salt -- +a base64-encoded random string, which is usually 44 bytes long. +The salt is used in the authentication packet -- the :ref:`IPROTO_AUTH message `. + +.. _box_protocol-authentication_sequence: + +Authentication +-------------- + +If authentication is skipped, then the session user is ``'guest'`` +(the ``'guest'`` user does not need a password). + +If authentication is not skipped, then at any time an :ref:`authentication packet ` +can be prepared using the greeting, the user's name and password, +and `sha-1 `_ functions, as follows. + +.. code-block:: none + + PREPARE SCRAMBLE: + + size_of_encoded_salt_in_greeting = 44; + size_of_salt_after_base64_decode = 32; + /* sha1() will only use the first 20 bytes */ + size_of_any_sha1_digest = 20; + size_of_scramble = 20; + + prepare 'chap-sha1' scramble: + + salt = base64_decode(encoded_salt); + step_1 = sha1(password); + step_2 = sha1(step_1); + step_3 = sha1(first_20_bytes_of_salt, step_2); + scramble = xor(step_1, step_3); + return scramble; diff --git a/doc/dev_guide/internals/iproto/events.rst b/doc/dev_guide/internals/iproto/events.rst new file mode 100644 index 0000000000..0dfaa50df5 --- /dev/null +++ b/doc/dev_guide/internals/iproto/events.rst @@ -0,0 +1,71 @@ +.. _internals-events: +.. _box-protocol-watchers: + +Events and subscriptions +======================== + +The commands below support asynchronous server-client notifications signalled +with :ref:`box.broadcast() `. +Servers that support the new feature set the ``IPROTO_FEATURE_WATCHERS`` feature in reply to the ``IPROTO_ID`` command. +When the connection is closed, all watchers registered for it are unregistered. + +The remote watcher (event subscription) protocol works in the following way: + +#. The client sends an ``IPROTO_WATCH`` packet to subscribe to the updates of a specified key defined on the server. + +#. The server sends an ``IPROTO_EVENT`` packet to the subscribed client after registration. + The packet contains the key name and its current value. + After that, the packet is sent every time the key value is updated with + ``box.broadcast()``, provided that the last notification was acknowledged (see below). + +#. After receiving the notification, the client sends an ``IPROTO_WATCH`` packet to acknowledge the notification. + +#. If the client doesn't want to receive any more notifications, it unsubscribes by sending + an ``IPROTO_UNWATCH`` packet. + +All the three request types are asynchronous -- the receiving end doesn't send a packet in reply to any of them. +Therefore, neither of them has a sync number. + +.. _box_protocol-watch: + +IPROTO_WATCH +------------ + +Code: 0x4a. + +Register a new watcher for the given notification key or confirms a notification if the watcher is +already subscribed. +The watcher is notified after registration. +After that, the notification is sent every time the key is updated. +The server doesn't reply to the request unless it fails to parse the packet. + +.. raw:: html + :file: images/events_watch.svg + +.. _box_protocol-unwatch: + +IPROTO_UNWATCH +-------------- + +Code: 0x4b. + +Unregister a watcher subscribed to the given notification key. +The server doesn't reply to the request unless it fails to parse the packet. + +.. raw:: html + :file: images/events_unwatch.svg + +.. _box_protocol-event: + +IPROTO_EVENT +------------ + +Code: 0x4c. + +Sent by the server to notify a client about an update of a key. + +.. raw:: html + :file: images/event.svg + +``IPROTO_EVENT_DATA`` contains data sent to a remote watcher. +The parameter is optional, the default value is ``MP_NIL``. diff --git a/doc/dev_guide/internals/iproto/format.rst b/doc/dev_guide/internals/iproto/format.rst new file mode 100644 index 0000000000..ced4d31c21 --- /dev/null +++ b/doc/dev_guide/internals/iproto/format.rst @@ -0,0 +1,145 @@ +.. _internals-iproto-format: + +Request and response format +=========================== + +The types referred to in this document are `MessagePack `_ types. +For their definitions, see the :ref:`MP_* MessagePack types ` section. + +.. _internals-unified_packet_structure: + +Packet structure +---------------- + +Requests and responses have similar structure. They contain three sections: size, header, and body. + +.. raw:: html + :file: images/format.svg + +It is legal to put more than one request in a packet. + +Size +---- + +The size is an MP_UINT -- unsigned integer, usually 32-bit. +It the size of the header plus the size of the body. +It may be useful to compare it with the number of bytes remaining in the packet. + +.. _box_protocol-header: + +Header +------ + +The header is an MP_MAP. It may contain, in any order: + +.. raw:: html + :file: images/header.svg + +* Both the request and response make use of the :ref:`IPROTO_REQUEST_TYPE ` key. + It denotes the type of the packet. + +* The request and the matching response have the same sync number (:ref:`IPROTO_SYNC `). + +* :ref:`IPROTO_SCHEMA_VERSION ` is an optional key that indicates + whether there was a major change in the schema. + +* In :ref:`interactive transactions `, + every stream is identified by a unique :ref:`IPROTO_STREAM_ID `. + +In case of replicating :ref:`synchronous transactions `, +the header also contains the :ref:`IPROTO_FLAGS ` key. + +Encoding and decoding +~~~~~~~~~~~~~~~~~~~~~ + +To see how Tarantool encodes the header, have a look at file +`xrow.c `_, +function ``xrow_header_encode``. + +To see how Tarantool decodes the header, have a look at file +`net_box.c `__, +function ``netbox_decode_data``. + +For example, in a successful response to ``box.space:select()``, +the IPROTO_REQUEST_TYPE value will be 0 = ``IPROTO_OK`` and the +array will have all the tuples of the result. + +Read the source code file `net_box.c `__ +where the function ``decode_metadata_optional`` is an example of how Tarantool +itself decodes extra items. + +Body +---- + +The body is an MP_MAP. Maximal iproto package body length is 2 GiB. + +The body has the details of the request or response. In a request, it can also +be absent or be an empty map. Both these states will be interpreted equally. +Responses will contain the body anyway even for an +:ref:`IPROTO_PING ` request, where it will be an empty MP_MAP. + +A lot of responses contain the IPROTO_DATA map: + +.. raw:: html + :file: images/body.svg + +For most data-access requests (:ref:`IPROTO_SELECT `, +:ref:`IPROTO_INSERT `, :ref:`IPROTO_DELETE `, etc.) +the body is an IPROTO_DATA map with an array of tuples that contain an array of fields. + +IPROTO_DATA is what we get with net_box and :ref:`Module buffer ` +so if we were using net_box we could decode with +:ref:`msgpack.decode_unchecked() `, +or we could convert to a string with :samp:`ffi.string({pointer},{length})`. +The :ref:`pickle.unpack() ` function might also be helpful. + +.. note:: + + For SQL-specific requests and responses, the body is a bit different. + :ref:`Learn more ` about this type of packets. + +.. _box_protocol-responses_error: + +Error responses +--------------- + +Instead of :ref:`IPROTO_OK `, an error response header +has IPROTO_REQUEST_TYPE = :ref:`IPROTO_TYPE_ERROR `. +Its code is ``0x8XXX``, where ``XXX`` is the error code -- a value in +`src/box/errcode.h `_. +``src/box/errcode.h`` also has some convenience macros which define hexadecimal +constants for return codes. + +The error response body is a map that contains two keys: :ref:`IPROTO_ERROR ` +and :ref:`IPROTO_ERROR_24 `. +While IPROTO_ERROR contains an MP_EXT value, IPROTO_ERROR_24 contains a string. +The two keys are provided to accommodate clients with older and newer Tarantool versions. + +.. raw:: html + :file: images/error.svg + +Error responses before 2.4.1 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Before Tarantool v. :doc:`2.4.1 `, the key IPROTO_ERROR contained a string +and was identical to the current IPROTO_ERROR_24 key. + +Let's consider an example. This is the fifth message, and the request was to create a duplicate +space with ``conn:eval([[box.schema.space.create('_space');]])``. +The unsuccessful response looks like this: + +.. raw:: html + :file: images/error_24.svg + +The tutorial :ref:`Understanding the binary protocol ` +shows actual byte codes of the response to the IPROTO_EVAL message. + +Looking in `errcode.h `__, +we find that the error code ``0x0a`` (decimal 10) is +ER_SPACE_EXISTS, and the string associated with ER_SPACE_EXISTS is +"Space '%s' already exists". + +Since version :doc:`2.4.1 `, responses for errors have extra information +following what was described above. This extra information is given via the +MP_ERROR extension type. See details in the :ref:`MessagePack extensions +` section. diff --git a/doc/dev_guide/internals/iproto/images/auth.puml b/doc/dev_guide/internals/iproto/images/auth.puml new file mode 100644 index 0000000000..047cacd447 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/auth.puml @@ -0,0 +1,24 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_AUTH**" as auth_request { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_AUTH", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_USER_NAME]]": "MP_STR", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TUPLE]]": { + "MP_ARRAY": "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/authentication Authentication mechanism]], [[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/authentication scramble]]" + } + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/auth.svg b/doc/dev_guide/internals/iproto/images/auth.svg new file mode 100644 index 0000000000..dfa72f11a2 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/auth.svg @@ -0,0 +1,34 @@ +IPROTO_AUTHSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_AUTHIPROTO_SYNCMP_UINTBodyIPROTO_USER_NAMEMP_STRIPROTO_TUPLEMP_ARRAYAuthentication mechanism,scramble \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/body.puml b/doc/dev_guide/internals/iproto/images/body.puml new file mode 100644 index 0000000000..b251bafa04 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/body.puml @@ -0,0 +1,14 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +map "**Body**" as Body { + [[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_DATA]] => MP_OBJECT +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/body.svg b/doc/dev_guide/internals/iproto/images/body.svg new file mode 100644 index 0000000000..2840455f8a --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/body.svg @@ -0,0 +1,24 @@ +BodyIPROTO_DATAMP_OBJECT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/call.puml b/doc/dev_guide/internals/iproto/images/call.puml new file mode 100644 index 0000000000..96a02ad63a --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/call.puml @@ -0,0 +1,34 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_CALL**" as call_request { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_CALL", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FUNCTION_NAME]]": "MP_STR", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TUPLE]]": "MP_ARRAY of arguments" + } +} + +json "**Response to IPROTO_CALL**" as call_response { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_DATA]]": "MP_OBJECT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/call.svg b/doc/dev_guide/internals/iproto/images/call.svg new file mode 100644 index 0000000000..db675f38bd --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/call.svg @@ -0,0 +1,44 @@ +IPROTO_CALLSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_CALLIPROTO_SYNCMP_UINTBodyIPROTO_FUNCTION_NAMEMP_STRIPROTO_TUPLEMP_ARRAY of argumentsResponse to IPROTO_CALLSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTBodyIPROTO_DATAMP_OBJECT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/delete.puml b/doc/dev_guide/internals/iproto/images/delete.puml new file mode 100644 index 0000000000..29a8c11fe1 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/delete.puml @@ -0,0 +1,35 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_DELETE**" as delete_request { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_DELETE", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SPACE_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_INDEX_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_KEY]]": "MP_ARRAY of key values" + } +} + +json "**Response to IPROTO_DELETE**" as delete_response { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_DATA]]": "MP_OBJECT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/delete.svg b/doc/dev_guide/internals/iproto/images/delete.svg new file mode 100644 index 0000000000..d338e42e43 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/delete.svg @@ -0,0 +1,45 @@ +IPROTO_DELETESizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_DELETEIPROTO_SYNCMP_UINTBodyIPROTO_SPACE_IDMP_UINTIPROTO_INDEX_IDMP_UINTIPROTO_KEYMP_ARRAY of key valuesResponse to IPROTO_DELETESizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTBodyIPROTO_DATAMP_OBJECT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/error.puml b/doc/dev_guide/internals/iproto/images/error.puml new file mode 100644 index 0000000000..34fedb889b --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/error.puml @@ -0,0 +1,23 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Error response**" as error_response { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "0x8XXX", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_ERROR]]": "MP_ERROR", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_ERROR_24]]": "MP_STR" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/error.svg b/doc/dev_guide/internals/iproto/images/error.svg new file mode 100644 index 0000000000..e7e7708274 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/error.svg @@ -0,0 +1,33 @@ +Error responseSizeMP_UINTHeaderIPROTO_REQUEST_TYPE0x8XXXIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTBodyIPROTO_ERRORMP_ERRORIPROTO_ERROR_24MP_STR \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/error_24.puml b/doc/dev_guide/internals/iproto/images/error_24.puml new file mode 100644 index 0000000000..2f303f09d2 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/error_24.puml @@ -0,0 +1,22 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Error response before 2.4.1**" as error_response { + "Size": "32", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "0x800a", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "5", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "0x78" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_ERROR]]": "Space '_space' already exists" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/error_24.svg b/doc/dev_guide/internals/iproto/images/error_24.svg new file mode 100644 index 0000000000..afd1f9dccd --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/error_24.svg @@ -0,0 +1,32 @@ +Error response before 2.4.1Size32HeaderIPROTO_REQUEST_TYPE0x800aIPROTO_SYNC5IPROTO_SCHEMA_VERSION0x78BodyIPROTO_ERRORSpace '_space' already exists \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/eval.puml b/doc/dev_guide/internals/iproto/images/eval.puml new file mode 100644 index 0000000000..8543affcc9 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/eval.puml @@ -0,0 +1,34 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_EVAL**" as eval_request { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_EVAL", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_EXPR]]": "MP_STR", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TUPLE]]": "MP_ARRAY of arguments" + } +} + +json "**Response to IPROTO_EVAL**" as eval_response { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_DATA]]": "MP_OBJECT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/eval.svg b/doc/dev_guide/internals/iproto/images/eval.svg new file mode 100644 index 0000000000..18551880de --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/eval.svg @@ -0,0 +1,44 @@ +IPROTO_EVALSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_EVALIPROTO_SYNCMP_UINTBodyIPROTO_EXPRMP_STRIPROTO_TUPLEMP_ARRAY of argumentsResponse to IPROTO_EVALSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTBodyIPROTO_DATAMP_OBJECT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/eval_example.puml b/doc/dev_guide/internals/iproto/images/eval_example.puml new file mode 100644 index 0000000000..fd287ae8ed --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/eval_example.puml @@ -0,0 +1,22 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_EVAL** example request" as eval_request { + "Size": "24", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_EVAL", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_EXPR]]": "'return 5;'", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TUPLE]]": "[]" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/eval_example.svg b/doc/dev_guide/internals/iproto/images/eval_example.svg new file mode 100644 index 0000000000..5f0ccbfe18 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/eval_example.svg @@ -0,0 +1,32 @@ +IPROTO_EVALexample requestSize24HeaderIPROTO_REQUEST_TYPEIPROTO_EVALIPROTO_SYNCMP_UINTBodyIPROTO_EXPR'return 5;'IPROTO_TUPLE[] \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/event.puml b/doc/dev_guide/internals/iproto/images/event.puml new file mode 100644 index 0000000000..61cd58a50b --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/event.puml @@ -0,0 +1,21 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_EVENT**" as event { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_EVENT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_EVENT_KEY]]": "MP_STR", + "(Optional) [[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_EVENT_DATA]]": "MP_OBJECT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/event.svg b/doc/dev_guide/internals/iproto/images/event.svg new file mode 100644 index 0000000000..523a34f0b6 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/event.svg @@ -0,0 +1,31 @@ +IPROTO_EVENTSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_EVENTBodyIPROTO_EVENT_KEYMP_STR(Optional)IPROTO_EVENT_DATAMP_OBJECT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/events_unwatch.puml b/doc/dev_guide/internals/iproto/images/events_unwatch.puml new file mode 100644 index 0000000000..1674204e07 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/events_unwatch.puml @@ -0,0 +1,20 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_UNWATCH**" as unwatch { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_UNWATCH" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_EVENT_KEY]]": "MP_STR" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/events_unwatch.svg b/doc/dev_guide/internals/iproto/images/events_unwatch.svg new file mode 100644 index 0000000000..43ef51e660 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/events_unwatch.svg @@ -0,0 +1,30 @@ +IPROTO_UNWATCHSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_UNWATCHBodyIPROTO_EVENT_KEYMP_STR \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/events_watch.puml b/doc/dev_guide/internals/iproto/images/events_watch.puml new file mode 100644 index 0000000000..e3336b6fb0 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/events_watch.puml @@ -0,0 +1,20 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_WATCH**" as watch { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_WATCH" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_EVENT_KEY]]": "MP_STR" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/events_watch.svg b/doc/dev_guide/internals/iproto/images/events_watch.svg new file mode 100644 index 0000000000..177c68f97c --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/events_watch.svg @@ -0,0 +1,30 @@ +IPROTO_WATCHSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_WATCHBodyIPROTO_EVENT_KEYMP_STR \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/execute.puml b/doc/dev_guide/internals/iproto/images/execute.puml new file mode 100644 index 0000000000..3ee1c4d0fd --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/execute.puml @@ -0,0 +1,36 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_EXECUTE**, prepared statement" as execute_request_prepared { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_EXECUTE", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_STMT_ID]]": "MP_INT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SQL_BIND]]": "MP_ARRAY", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_OPTIONS]]": "MP_ARRAY" + } +} + +json "**IPROTO_EXECUTE**, SQL string" as execute_request_string { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_EXECUTE", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SQL_TEXT]]": "MP_STR", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SQL_BIND]]": "MP_ARRAY", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_OPTIONS]]": "MP_ARRAY" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/execute.svg b/doc/dev_guide/internals/iproto/images/execute.svg new file mode 100644 index 0000000000..d5c7896cde --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/execute.svg @@ -0,0 +1,46 @@ +IPROTO_EXECUTE, prepared statementSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_EXECUTEIPROTO_SYNCMP_UINTBodyIPROTO_STMT_IDMP_INTIPROTO_SQL_BINDMP_ARRAYIPROTO_OPTIONSMP_ARRAYIPROTO_EXECUTE, SQL stringSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_EXECUTEIPROTO_SYNCMP_UINTBodyIPROTO_SQL_TEXTMP_STRIPROTO_SQL_BINDMP_ARRAYIPROTO_OPTIONSMP_ARRAY \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/execute_example_1.puml b/doc/dev_guide/internals/iproto/images/execute_example_1.puml new file mode 100644 index 0000000000..b9d81e177d --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/execute_example_1.puml @@ -0,0 +1,16 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Body**" as execute_body_1 { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_STMT_ID]]": "0xd7aa741b", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SQL_BIND]]": "[1, 'a']", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_OPTIONS]]": "[]" +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/execute_example_1.svg b/doc/dev_guide/internals/iproto/images/execute_example_1.svg new file mode 100644 index 0000000000..352a622bb0 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/execute_example_1.svg @@ -0,0 +1,26 @@ +BodyIPROTO_STMT_ID0xd7aa741bIPROTO_SQL_BIND[1, 'a']IPROTO_OPTIONS[] \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/execute_example_2.puml b/doc/dev_guide/internals/iproto/images/execute_example_2.puml new file mode 100644 index 0000000000..c341e34783 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/execute_example_2.puml @@ -0,0 +1,28 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Body**" as execute_body_2 { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_STMT_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_BIND_COUNT]]": "MP_INT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_BIND_METADATA]]": "MP_ARRAY", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_METADATA]]": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_NAME]]": "'DD'", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_TYPE]]": "'integer'", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_IS_NULLABLE]]": "false", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_IS_AUTOINCREMENT]]": "true", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_SPAN]]": "nil", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_NAME]]": "'Д'", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_TYPE]]": "'string'", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_COLL]]": "'unicode'", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_IS_NULLABLE]]": "true", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_SPAN]]": "'дд'" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/execute_example_2.svg b/doc/dev_guide/internals/iproto/images/execute_example_2.svg new file mode 100644 index 0000000000..a3109e8afb --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/execute_example_2.svg @@ -0,0 +1,38 @@ +BodyIPROTO_STMT_IDMP_UINTIPROTO_BIND_COUNTMP_INTIPROTO_BIND_METADATAMP_ARRAYIPROTO_METADATAIPROTO_FIELD_NAME'DD'IPROTO_FIELD_TYPE'integer'IPROTO_FIELD_IS_NULLABLEfalseIPROTO_FIELD_IS_AUTOINCREMENTtrueIPROTO_FIELD_SPANnilIPROTO_FIELD_NAME'Д'IPROTO_FIELD_TYPE'string'IPROTO_FIELD_COLL'unicode'IPROTO_FIELD_IS_NULLABLEtrueIPROTO_FIELD_SPAN'дд' \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/flags_example.puml b/doc/dev_guide/internals/iproto/images/flags_example.puml new file mode 100644 index 0000000000..ffeb1f41af --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/flags_example.puml @@ -0,0 +1,20 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Example of IPROTO_FLAGS usage**" as flags_example { + "Size": "MP_UINT", + "Header": { + "...": "...", + "...": "...", + "IPROTO_FLAGS": "MP_UINT" + }, + "Body": "..." +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/flags_example.svg b/doc/dev_guide/internals/iproto/images/flags_example.svg new file mode 100644 index 0000000000..60f11e79a4 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/flags_example.svg @@ -0,0 +1,30 @@ +Example of IPROTO_FLAGS usageSizeMP_UINTHeader............IPROTO_FLAGSMP_UINTBody... \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/format.puml b/doc/dev_guide/internals/iproto/images/format.puml new file mode 100644 index 0000000000..14225d4021 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/format.puml @@ -0,0 +1,16 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +map "**Packet**" as Packet { + size => MP_UINT + header => MP_MAP + body => MP_MAP +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/format.svg b/doc/dev_guide/internals/iproto/images/format.svg new file mode 100644 index 0000000000..6dc1528e23 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/format.svg @@ -0,0 +1,26 @@ +PacketsizeMP_UINTheaderMP_MAPbodyMP_MAP \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/header.puml b/doc/dev_guide/internals/iproto/images/header.puml new file mode 100644 index 0000000000..a866475797 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/header.puml @@ -0,0 +1,17 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +map "**Header**" as Header { + [[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]] => MP_UINT + [[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]] => MP_UINT + [[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]] => MP_UINT + [[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_STREAM_ID]] => MP_UINT +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/header.svg b/doc/dev_guide/internals/iproto/images/header.svg new file mode 100644 index 0000000000..3bc5b38744 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/header.svg @@ -0,0 +1,27 @@ +HeaderIPROTO_REQUEST_TYPEMP_UINTIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTIPROTO_STREAM_IDMP_UINT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/id.puml b/doc/dev_guide/internals/iproto/images/id.puml new file mode 100644 index 0000000000..2274abc723 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/id.puml @@ -0,0 +1,22 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_ID**" as id_request { + "Size": "MP_INT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_ID", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_VERSION]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FEATURES]]": "MP_ARRAY of MP_UINT items" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/id.svg b/doc/dev_guide/internals/iproto/images/id.svg new file mode 100644 index 0000000000..a8c9febd5d --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/id.svg @@ -0,0 +1,32 @@ +IPROTO_IDSizeMP_INTHeaderIPROTO_REQUEST_TYPEIPROTO_IDIPROTO_SYNCMP_UINTBodyIPROTO_VERSIONMP_UINTIPROTO_FEATURESMP_ARRAY of MP_UINT items \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/insert.puml b/doc/dev_guide/internals/iproto/images/insert.puml new file mode 100644 index 0000000000..435e25af56 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/insert.puml @@ -0,0 +1,34 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_INSERT**" as insert_request { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_INSERT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SPACE_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TUPLE]]": "MP_ARRAY" + } +} + +json "**Response to IPROTO_INSERT**" as insert_response { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_DATA]]": "MP_ARRAY of tuples" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/insert.svg b/doc/dev_guide/internals/iproto/images/insert.svg new file mode 100644 index 0000000000..e518fb53f6 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/insert.svg @@ -0,0 +1,44 @@ +IPROTO_INSERTSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_INSERTIPROTO_SYNCMP_UINTBodyIPROTO_SPACE_IDMP_UINTIPROTO_TUPLEMP_ARRAYResponse to IPROTO_INSERTSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTBodyIPROTO_DATAMP_ARRAY of tuples \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/insert_example.puml b/doc/dev_guide/internals/iproto/images/insert_example.puml new file mode 100644 index 0000000000..c8cbc60e18 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/insert_example.puml @@ -0,0 +1,34 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_INSERT** example request" as insert_example_request { + "Size": "17", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_INSERT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "5" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SPACE_ID]]": "512", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TUPLE]]": "[1, 'AAA']" + } +} + +json "**IPROTO_INSERT** example response" as insert_example_response { + "Size": "36", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "5", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "100" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_DATA]]": "[1, 'AAA']" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/insert_example.svg b/doc/dev_guide/internals/iproto/images/insert_example.svg new file mode 100644 index 0000000000..aba1a7225e --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/insert_example.svg @@ -0,0 +1,44 @@ +IPROTO_INSERTexample requestSize17HeaderIPROTO_REQUEST_TYPEIPROTO_INSERTIPROTO_SYNC5BodyIPROTO_SPACE_ID512IPROTO_TUPLE[1, 'AAA']IPROTO_INSERTexample responseSize36HeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNC5IPROTO_SCHEMA_VERSION100BodyIPROTO_DATA[1, 'AAA'] \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/ok_example.puml b/doc/dev_guide/internals/iproto/images/ok_example.puml new file mode 100644 index 0000000000..dc0208a318 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/ok_example.puml @@ -0,0 +1,22 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Example of IPROTO_OK usage**" as ok_example { + "Size": "MP_UINT", + "Header": { + "IPROTO_REQUEST_TYPE": "IPROTO_OK", + "IPROTO_SYNC": "MP_UINT", + "IPROTO_SCHEMA_VERSION": "MP_UINT" + }, + "Body": { + "IPROTO_DATA": "MP_OBJECT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/ok_example.svg b/doc/dev_guide/internals/iproto/images/ok_example.svg new file mode 100644 index 0000000000..8a7acc5670 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/ok_example.svg @@ -0,0 +1,32 @@ +Example of IPROTO_OK usageSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTBodyIPROTO_DATAMP_OBJECT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/ping.puml b/doc/dev_guide/internals/iproto/images/ping.puml new file mode 100644 index 0000000000..590345323b --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/ping.puml @@ -0,0 +1,31 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_PING**" as ping_request { + "Size": "5", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_PING", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": "MP_MAP, empty" +} + +json "**Response to IPROTO_PING**" as insert_response { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_DATA]]": "MP_MAP, empty" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/ping.svg b/doc/dev_guide/internals/iproto/images/ping.svg new file mode 100644 index 0000000000..aaecfce508 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/ping.svg @@ -0,0 +1,41 @@ +IPROTO_PINGSize5HeaderIPROTO_REQUEST_TYPEIPROTO_PINGIPROTO_SYNCMP_UINTBodyMP_MAP, emptyResponse to IPROTO_PINGSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTBodyIPROTO_DATAMP_MAP, empty \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/prepare.puml b/doc/dev_guide/internals/iproto/images/prepare.puml new file mode 100644 index 0000000000..2fa2367f45 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/prepare.puml @@ -0,0 +1,21 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_PREPARE**" as prepare_request { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_PREPARE", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_STMT_ID]]": "MP_INT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/prepare.svg b/doc/dev_guide/internals/iproto/images/prepare.svg new file mode 100644 index 0000000000..be8f1aef01 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/prepare.svg @@ -0,0 +1,31 @@ +IPROTO_PREPARESizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_PREPAREIPROTO_SYNCMP_UINTBodyIPROTO_STMT_IDMP_INT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/repl_ballot.puml b/doc/dev_guide/internals/iproto/images/repl_ballot.puml new file mode 100644 index 0000000000..867783559e --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_ballot.puml @@ -0,0 +1,20 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_BALLOT body**" as ballot { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_BALLOT_IS_RO_CFG]]": "MP_BOOL", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_BALLOT_VCLOCK]]": "MP_MAP", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_BALLOT_GC_VCLOCK]]": "MP_MAP", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_BALLOT_IS_RO]]": "MP_BOOL", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_BALLOT_IS_ANON]]": "MP_BOOL", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_BALLOT_IS_BOOTED]]": "MP_BOOL", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_BALLOT_CAN_LEAD]]": "MP_BOOL" +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/repl_ballot.svg b/doc/dev_guide/internals/iproto/images/repl_ballot.svg new file mode 100644 index 0000000000..30d71b6af0 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_ballot.svg @@ -0,0 +1,30 @@ +IPROTO_BALLOT bodyIPROTO_BALLOT_IS_RO_CFGMP_BOOLIPROTO_BALLOT_VCLOCKMP_MAPIPROTO_BALLOT_GC_VCLOCKMP_MAPIPROTO_BALLOT_IS_ROMP_BOOLIPROTO_BALLOT_IS_ANONMP_BOOLIPROTO_BALLOT_IS_BOOTEDMP_BOOLIPROTO_BALLOT_CAN_LEADMP_BOOL \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/repl_heartbeat.puml b/doc/dev_guide/internals/iproto/images/repl_heartbeat.puml new file mode 100644 index 0000000000..c1ace790af --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_heartbeat.puml @@ -0,0 +1,31 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Heartbeat message from master**" as heartbeat_request { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REPLICA_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TIMESTAMP]]": "MP_DOUBLE" + } +} + +json "**Response from replica**" as heartbeat_response { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REPLICA_ID]]": "MP_UINT", + "(Optional) [[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TIMESTAMP]]": "MP_DOUBLE" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_VCLOCK]]": "MP_MAP" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/repl_heartbeat.svg b/doc/dev_guide/internals/iproto/images/repl_heartbeat.svg new file mode 100644 index 0000000000..0131e329ea --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_heartbeat.svg @@ -0,0 +1,41 @@ +Heartbeat message from masterSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_REPLICA_IDMP_UINTIPROTO_TIMESTAMPMP_DOUBLEResponse from replicaSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_REPLICA_IDMP_UINT(Optional)IPROTO_TIMESTAMPMP_DOUBLEBodyIPROTO_VCLOCKMP_MAP \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/repl_join_request.puml b/doc/dev_guide/internals/iproto/images/repl_join_request.puml new file mode 100644 index 0000000000..df1959d293 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_join_request.puml @@ -0,0 +1,21 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_JOIN**" as join_request { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_JOIN", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_INSTANCE_UUID]]": "MP_STR – UUID of this instance" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/repl_join_request.svg b/doc/dev_guide/internals/iproto/images/repl_join_request.svg new file mode 100644 index 0000000000..0574319331 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_join_request.svg @@ -0,0 +1,31 @@ +IPROTO_JOINSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_JOINIPROTO_SYNCMP_UINTBodyIPROTO_INSTANCE_UUIDMP_STR - UUID of this instance \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/repl_join_response.puml b/doc/dev_guide/internals/iproto/images/repl_join_response.puml new file mode 100644 index 0000000000..2be78495bc --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_join_response.puml @@ -0,0 +1,21 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Response to IPROTO_JOIN**" as join_response { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_VCLOCK]]": "MP_MAP" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/repl_join_response.svg b/doc/dev_guide/internals/iproto/images/repl_join_response.svg new file mode 100644 index 0000000000..35b4f780be --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_join_response.svg @@ -0,0 +1,31 @@ +Response to IPROTO_JOINSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNCMP_UINTBodyIPROTO_VCLOCKMP_MAP \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/repl_raft.puml b/doc/dev_guide/internals/iproto/images/repl_raft.puml new file mode 100644 index 0000000000..76d6f85676 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_raft.puml @@ -0,0 +1,26 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_RAFT**" as raft { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_RAFT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REPLICA_ID]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_RAFT_TERM]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_RAFT_VOTE]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_RAFT_STATE]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_RAFT_VCLOCK]]": "MP_MAP", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_RAFT_LEADER_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_RAFT_IS_LEADER_SEEN]]": "MP_BOOL" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/repl_raft.svg b/doc/dev_guide/internals/iproto/images/repl_raft.svg new file mode 100644 index 0000000000..9f6106bf89 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_raft.svg @@ -0,0 +1,36 @@ +IPROTO_RAFTSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_RAFTIPROTO_REPLICA_IDMP_UINTBodyIPROTO_RAFT_TERMMP_UINTIPROTO_RAFT_VOTEMP_UINTIPROTO_RAFT_STATEMP_UINTIPROTO_RAFT_VCLOCKMP_MAPIPROTO_RAFT_LEADER_IDMP_UINTIPROTO_RAFT_IS_LEADER_SEENMP_BOOL \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/repl_raft_confirm.puml b/doc/dev_guide/internals/iproto/images/repl_raft_confirm.puml new file mode 100644 index 0000000000..7fffabf92a --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_raft_confirm.puml @@ -0,0 +1,24 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_RAFT_CONFIRM**" as raft_confirm { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_RAFT_CONFIRM", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REPLICA_ID]]": "MP_INT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_LSN]]": "MP_INT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REPLICA_ID]]": "MP_INT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_LSN]]": "MP_INT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/repl_raft_confirm.svg b/doc/dev_guide/internals/iproto/images/repl_raft_confirm.svg new file mode 100644 index 0000000000..9ab6bedde8 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_raft_confirm.svg @@ -0,0 +1,34 @@ +IPROTO_RAFT_CONFIRMSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_RAFT_CONFIRMIPROTO_REPLICA_IDMP_INTIPROTO_LSNMP_INTIPROTO_SYNCMP_UINTBodyIPROTO_REPLICA_IDMP_INTIPROTO_LSNMP_INT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/repl_raft_demote.puml b/doc/dev_guide/internals/iproto/images/repl_raft_demote.puml new file mode 100644 index 0000000000..5813a438d0 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_raft_demote.puml @@ -0,0 +1,24 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_RAFT_DEMOTE**" as demote { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_RAFT_DEMOTE", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REPLICA_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_LSN]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REPLICA_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_LSN]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TERM]]": "MP_UINT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/repl_raft_demote.svg b/doc/dev_guide/internals/iproto/images/repl_raft_demote.svg new file mode 100644 index 0000000000..c2df8dc095 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_raft_demote.svg @@ -0,0 +1,34 @@ +IPROTO_RAFT_DEMOTESizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_RAFT_DEMOTEIPROTO_REPLICA_IDMP_UINTIPROTO_LSNMP_UINTBodyIPROTO_REPLICA_IDMP_UINTIPROTO_LSNMP_UINTIPROTO_TERMMP_UINT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/repl_raft_promote.puml b/doc/dev_guide/internals/iproto/images/repl_raft_promote.puml new file mode 100644 index 0000000000..4291405870 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_raft_promote.puml @@ -0,0 +1,24 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_RAFT_PROMOTE**" as promote { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_RAFT_PROMOTE", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REPLICA_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_LSN]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REPLICA_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_LSN]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TERM]]": "MP_UINT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/repl_raft_promote.svg b/doc/dev_guide/internals/iproto/images/repl_raft_promote.svg new file mode 100644 index 0000000000..85c2ca77ba --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_raft_promote.svg @@ -0,0 +1,34 @@ +IPROTO_RAFT_PROMOTESizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_RAFT_PROMOTEIPROTO_REPLICA_IDMP_UINTIPROTO_LSNMP_UINTBodyIPROTO_REPLICA_IDMP_UINTIPROTO_LSNMP_UINTIPROTO_TERMMP_UINT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/repl_raft_rollback.puml b/doc/dev_guide/internals/iproto/images/repl_raft_rollback.puml new file mode 100644 index 0000000000..56ebfbb50d --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_raft_rollback.puml @@ -0,0 +1,24 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_RAFT_ROLLBACK**" as raft_rollback { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_RAFT_ROLLBACK", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REPLICA_ID]]": "MP_INT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_LSN]]": "MP_INT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REPLICA_ID]]": "MP_INT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_LSN]]": "MP_INT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/repl_raft_rollback.svg b/doc/dev_guide/internals/iproto/images/repl_raft_rollback.svg new file mode 100644 index 0000000000..5e824dbe0f --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_raft_rollback.svg @@ -0,0 +1,34 @@ +IPROTO_RAFT_ROLLBACKSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_RAFT_ROLLBACKIPROTO_REPLICA_IDMP_INTIPROTO_LSNMP_INTIPROTO_SYNCMP_UINTBodyIPROTO_REPLICA_IDMP_INTIPROTO_LSNMP_INT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/repl_subscribe_request.puml b/doc/dev_guide/internals/iproto/images/repl_subscribe_request.puml new file mode 100644 index 0000000000..33b1026a78 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_subscribe_request.puml @@ -0,0 +1,26 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_SUBSCRIBE**" as subscribe_request { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_SUBSCRIBE", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_INSTANCE_UUID]]": "MP_STR", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_CLUSTER_UUID]]": "MP_STR", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_VCLOCK]]": "MP_MAP", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SERVER_VERSION]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REPLICA_ANON]]": "MP_BOOL", + "(Optional) [[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_ID_FILTER]]": "MP_ARRAY" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/repl_subscribe_request.svg b/doc/dev_guide/internals/iproto/images/repl_subscribe_request.svg new file mode 100644 index 0000000000..b8f5b01e75 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_subscribe_request.svg @@ -0,0 +1,36 @@ +IPROTO_SUBSCRIBESizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_SUBSCRIBEIPROTO_SYNCMP_UINTBodyIPROTO_INSTANCE_UUIDMP_STRIPROTO_CLUSTER_UUIDMP_STRIPROTO_VCLOCKMP_MAPIPROTO_SERVER_VERSIONMP_UINTIPROTO_REPLICA_ANONMP_BOOL(Optional)IPROTO_ID_FILTERMP_ARRAY \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/repl_vote.puml b/doc/dev_guide/internals/iproto/images/repl_vote.puml new file mode 100644 index 0000000000..dc99420f10 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_vote.puml @@ -0,0 +1,17 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_VOTE**" as vote { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_VOTE" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/repl_vote.svg b/doc/dev_guide/internals/iproto/images/repl_vote.svg new file mode 100644 index 0000000000..d756a8a6c0 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/repl_vote.svg @@ -0,0 +1,27 @@ +IPROTO_VOTESizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_VOTE \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/replace.puml b/doc/dev_guide/internals/iproto/images/replace.puml new file mode 100644 index 0000000000..d28d1c2211 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/replace.puml @@ -0,0 +1,34 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_REPLACE**" as replace_request { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_REPLACE", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SPACE_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TUPLE]]": "MP_ARRAY of field values" + } +} + +json "**Response to IPROTO_REPLACE**" as replace_response { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_DATA]]": "MP_OBJECT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/replace.svg b/doc/dev_guide/internals/iproto/images/replace.svg new file mode 100644 index 0000000000..f32496fdba --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/replace.svg @@ -0,0 +1,44 @@ +IPROTO_REPLACESizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_REPLACEIPROTO_SYNCMP_UINTBodyIPROTO_SPACE_IDMP_UINTIPROTO_TUPLEMP_ARRAY of field valuesResponse to IPROTO_REPLACESizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTBodyIPROTO_DATAMP_OBJECT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/select.puml b/doc/dev_guide/internals/iproto/images/select.puml new file mode 100644 index 0000000000..5976cfc270 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/select.puml @@ -0,0 +1,38 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_SELECT**" as select { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_SELECT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SPACE_ID]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_INDEX_ID]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_LIMIT]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_OFFSET]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_ITERATOR]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_KEY]]": "MP_ARRAY" + } +} + +json "**Response to IPROTO_SELECT**" as select_response { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_DATA]]": "MP_OBJECT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/select.svg b/doc/dev_guide/internals/iproto/images/select.svg new file mode 100644 index 0000000000..6c6e9ca5a9 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/select.svg @@ -0,0 +1,48 @@ +IPROTO_SELECTSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_SELECTIPROTO_SYNCMP_UINTBodyIPROTO_SPACE_IDMP_UINTIPROTO_INDEX_IDMP_UINTIPROTO_LIMITMP_UINTIPROTO_OFFSETMP_UINTIPROTO_ITERATORMP_UINTIPROTO_KEYMP_ARRAYResponse to IPROTO_SELECTSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTBodyIPROTO_DATAMP_OBJECT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/select_example.puml b/doc/dev_guide/internals/iproto/images/select_example.puml new file mode 100644 index 0000000000..7b0decd165 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/select_example.puml @@ -0,0 +1,26 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_SELECT** example request" as select_example { + "Size": "21", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_SELECT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "5" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SPACE_ID]]": "512", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_INDEX_ID]]": "0", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_ITERATOR]]": "6", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_OFFSET]]": "1", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_LIMIT]]": "2", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_KEY]]": "[1]" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/select_example.svg b/doc/dev_guide/internals/iproto/images/select_example.svg new file mode 100644 index 0000000000..e88d1ec523 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/select_example.svg @@ -0,0 +1,36 @@ +IPROTO_SELECTexample requestSize21HeaderIPROTO_REQUEST_TYPEIPROTO_SELECTIPROTO_SYNC5BodyIPROTO_SPACE_ID512IPROTO_INDEX_ID0IPROTO_ITERATOR6IPROTO_OFFSET1IPROTO_LIMIT2IPROTO_KEY[1] \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/sql_response_other.puml b/doc/dev_guide/internals/iproto/images/sql_response_other.puml new file mode 100644 index 0000000000..df7863ab04 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/sql_response_other.puml @@ -0,0 +1,25 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Response to SQL requests other than SELECT, VALUES, or PRAGMA**" as sql_response_other { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys SQL_INFO]]": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys SQL_INFO_ROW_COUNT]]": "MP_UINT", + "(Optional) [[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys SQL_INFO_AUTO_INCREMENT_IDS]]": "MP_ARRAY" + } + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/sql_response_other.svg b/doc/dev_guide/internals/iproto/images/sql_response_other.svg new file mode 100644 index 0000000000..f11eda0031 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/sql_response_other.svg @@ -0,0 +1,35 @@ +Response to SQL requests other than SELECT, VALUES, or PRAGMASizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTBodySQL_INFOSQL_INFO_ROW_COUNTMP_UINT(Optional)SQL_INFO_AUTO_INCREMENT_IDSMP_ARRAY \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/sql_response_select.puml b/doc/dev_guide/internals/iproto/images/sql_response_select.puml new file mode 100644 index 0000000000..d98da42510 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/sql_response_select.puml @@ -0,0 +1,23 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Response to SELECT, VALUES, or PRAGMA**" as sql_response_select { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_METADATA]]": "MP_ARRAY of column maps", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_DATA]]": "MP_ARRAY of tuples" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/sql_response_select.svg b/doc/dev_guide/internals/iproto/images/sql_response_select.svg new file mode 100644 index 0000000000..0124fa190b --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/sql_response_select.svg @@ -0,0 +1,33 @@ +Response to SELECT, VALUES, or PRAGMASizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTBodyIPROTO_METADATAMP_ARRAY of column mapsIPROTO_DATAMP_ARRAY of tuples \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/sql_response_select_example.puml b/doc/dev_guide/internals/iproto/images/sql_response_select_example.puml new file mode 100644 index 0000000000..862115a2db --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/sql_response_select_example.puml @@ -0,0 +1,28 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Body**" as sql_response_select_example { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_METADATA]]": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_NAME]]": "'DD'", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_TYPE]]": "'integer'", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_IS_NULLABLE]]": "false", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_IS_AUTOINCREMENT]]": "true", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_SPAN]]": "nil", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_NAME]]": "'Д'", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_TYPE]]": "'string'", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_COLL]]": "'unicode'", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_IS_NULLABLE]]": "true", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_FIELD_SPAN]]": "'дд'" + }, + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_DATA]]": { + "MP_ARRAY": "[1, 'a'], [2, 'b']" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/sql_response_select_example.svg b/doc/dev_guide/internals/iproto/images/sql_response_select_example.svg new file mode 100644 index 0000000000..1a7a9d55bb --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/sql_response_select_example.svg @@ -0,0 +1,38 @@ +BodyIPROTO_METADATAIPROTO_FIELD_NAME'DD'IPROTO_FIELD_TYPE'integer'IPROTO_FIELD_IS_NULLABLEfalseIPROTO_FIELD_IS_AUTOINCREMENTtrueIPROTO_FIELD_SPANnilIPROTO_FIELD_NAME'Д'IPROTO_FIELD_TYPE'string'IPROTO_FIELD_COLL'unicode'IPROTO_FIELD_IS_NULLABLEtrueIPROTO_FIELD_SPAN'дд'IPROTO_DATAMP_ARRAY[1, 'a'], [2, 'b'] \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/stream_begin.puml b/doc/dev_guide/internals/iproto/images/stream_begin.puml new file mode 100644 index 0000000000..17b559fe90 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/stream_begin.puml @@ -0,0 +1,23 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_BEGIN**" as begin { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_BEGIN", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_STREAM_ID]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TIMEOUT]]": "MP_DOUBLE", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TXN_ISOLATION]]": "MP_UINT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/stream_begin.svg b/doc/dev_guide/internals/iproto/images/stream_begin.svg new file mode 100644 index 0000000000..ad7c93c155 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/stream_begin.svg @@ -0,0 +1,33 @@ +IPROTO_BEGINSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_BEGINIPROTO_SYNCMP_UINTIPROTO_STREAM_IDMP_UINTBodyIPROTO_TIMEOUTMP_DOUBLEIPROTO_TXN_ISOLATIONMP_UINT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/stream_commit.puml b/doc/dev_guide/internals/iproto/images/stream_commit.puml new file mode 100644 index 0000000000..535f1efd91 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/stream_commit.puml @@ -0,0 +1,19 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_COMMIT**" as commit { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_COMMIT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_STREAM_ID]]": "MP_UINT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/stream_commit.svg b/doc/dev_guide/internals/iproto/images/stream_commit.svg new file mode 100644 index 0000000000..47ea2b1dc6 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/stream_commit.svg @@ -0,0 +1,29 @@ +IPROTO_COMMITSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_COMMITIPROTO_SYNCMP_UINTIPROTO_STREAM_IDMP_UINT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/stream_rollback.puml b/doc/dev_guide/internals/iproto/images/stream_rollback.puml new file mode 100644 index 0000000000..34185d4ba5 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/stream_rollback.puml @@ -0,0 +1,19 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_ROLLBACK**" as rollback { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_ROLLBACK", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_STREAM_ID]]": "MP_UINT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/stream_rollback.svg b/doc/dev_guide/internals/iproto/images/stream_rollback.svg new file mode 100644 index 0000000000..322c630bbb --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/stream_rollback.svg @@ -0,0 +1,29 @@ +IPROTO_ROLLBACKSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_ROLLBACKIPROTO_SYNCMP_UINTIPROTO_STREAM_IDMP_UINT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/update.puml b/doc/dev_guide/internals/iproto/images/update.puml new file mode 100644 index 0000000000..32e3f657f6 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/update.puml @@ -0,0 +1,36 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_UPDATE**" as update_request { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_UPDATE", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SPACE_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_INDEX_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_KEY]]": "MP_ARRAY of index keys", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TUPLE]]": "MP_ARRAY of update ops" + } +} + +json "**Response to IPROTO_UPDATE**" as update_response { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_DATA]]": "MP_OBJECT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/update.svg b/doc/dev_guide/internals/iproto/images/update.svg new file mode 100644 index 0000000000..513d766bb7 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/update.svg @@ -0,0 +1,46 @@ +IPROTO_UPDATESizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_UPDATEIPROTO_SYNCMP_UINTBodyIPROTO_SPACE_IDMP_UINTIPROTO_INDEX_IDMP_UINTIPROTO_KEYMP_ARRAY of index keysIPROTO_TUPLEMP_ARRAY of update opsResponse to IPROTO_UPDATESizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTBodyIPROTO_DATAMP_OBJECT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/update_example.puml b/doc/dev_guide/internals/iproto/images/update_example.puml new file mode 100644 index 0000000000..7bb521ddd0 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/update_example.puml @@ -0,0 +1,25 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_UPDATE** example request" as update_example { + "Size": "32", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_UPDATE", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "5" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SPACE_ID]]": "512", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_INDEX_ID]]": "0", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_INDEX_BASE]]": "1", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TUPLE]]": "['=',2,'B']", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_KEY]]": "[999]" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/update_example.svg b/doc/dev_guide/internals/iproto/images/update_example.svg new file mode 100644 index 0000000000..cece2712a5 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/update_example.svg @@ -0,0 +1,35 @@ +IPROTO_UPDATEexample requestSize32HeaderIPROTO_REQUEST_TYPEIPROTO_UPDATEIPROTO_SYNC5BodyIPROTO_SPACE_ID512IPROTO_INDEX_ID0IPROTO_INDEX_BASE1IPROTO_TUPLE['=',2,'B']IPROTO_KEY[999] \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/update_example_0.puml b/doc/dev_guide/internals/iproto/images/update_example_0.puml new file mode 100644 index 0000000000..03b44263a4 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/update_example_0.puml @@ -0,0 +1,16 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Body**" as update_body_0 { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TUPLE]]": { + "[[https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/update/ Operator]]": "MP_STR: '#'", + "[[https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/update/ Field number]]": "MP_INT" + } +} +@enduml diff --git a/doc/dev_guide/internals/iproto/images/update_example_0.svg b/doc/dev_guide/internals/iproto/images/update_example_0.svg new file mode 100644 index 0000000000..d0266f61f9 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/update_example_0.svg @@ -0,0 +1,26 @@ +BodyIPROTO_TUPLEOperatorMP_STR: '#'Field numberMP_INT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/update_example_1.puml b/doc/dev_guide/internals/iproto/images/update_example_1.puml new file mode 100644 index 0000000000..47462289d5 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/update_example_1.puml @@ -0,0 +1,18 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Body**" as update_body_1 { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TUPLE]]": { + "[[https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/update/ Operator]]": "MP_STR: '+', '-', '^', '|', '!', or '='", + "[[https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/update/ Field number]]": "MP_INT", + "[[https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/update/ Value]]": "MP_OBJECT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/update_example_1.svg b/doc/dev_guide/internals/iproto/images/update_example_1.svg new file mode 100644 index 0000000000..8958f5663a --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/update_example_1.svg @@ -0,0 +1,28 @@ +BodyIPROTO_TUPLEOperatorMP_STR: '+', '-', '^', '|', '!', or '='Field numberMP_INTValueMP_OBJECT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/update_example_regular.puml b/doc/dev_guide/internals/iproto/images/update_example_regular.puml new file mode 100644 index 0000000000..8b81ff91fb --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/update_example_regular.puml @@ -0,0 +1,20 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**Body**" as update_body_regular { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TUPLE]]": { + "[[https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/update/ Operator]]": "MP_STR: ':'", + "[[https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/update/ Field number]]": "MP_INT", + "[[https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/update/ Position]]": "MP_INT", + "[[https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/update/ Offset]]": "MP_INT", + "[[https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/update/ Value]]": "MP_STR" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/update_example_regular.svg b/doc/dev_guide/internals/iproto/images/update_example_regular.svg new file mode 100644 index 0000000000..df933af818 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/update_example_regular.svg @@ -0,0 +1,30 @@ +BodyIPROTO_TUPLEOperatorMP_STR: ':'Field numberMP_INTPositionMP_INTOffsetMP_INTValueMP_STR \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/upsert.puml b/doc/dev_guide/internals/iproto/images/upsert.puml new file mode 100644 index 0000000000..38582176dc --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/upsert.puml @@ -0,0 +1,36 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +json "**IPROTO_UPSERT**" as upsert_request { + "Size": "MP_UINT", + "Header": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_UPSERT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT" + }, + "Body": { + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SPACE_ID]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_INDEX_BASE]]": "MP_UINT", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_OPS]]": "MP_ARRAY", + "[[https://tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_TUPLE]]": "MP_ARRAY" + } +} + +json "**Response to IPROTO_UPSERT**" as upsert_response { + "Size": "MP_UINT", + "Header": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_REQUEST_TYPE]]": "IPROTO_OK", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SYNC]]": "MP_UINT", + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_SCHEMA_VERSION]]": "MP_UINT" + }, + "Body": { + "[[tarantool.io/en/doc/latest/dev_guide/internals/iproto/keys IPROTO_DATA]]": "MP_OBJECT" + } +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/upsert.svg b/doc/dev_guide/internals/iproto/images/upsert.svg new file mode 100644 index 0000000000..dba2c6cfb0 --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/upsert.svg @@ -0,0 +1,46 @@ +IPROTO_UPSERTSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_UPSERTIPROTO_SYNCMP_UINTBodyIPROTO_SPACE_IDMP_UINTIPROTO_INDEX_BASEMP_UINTIPROTO_OPSMP_ARRAYIPROTO_TUPLEMP_ARRAYResponse to IPROTO_UPSERTSizeMP_UINTHeaderIPROTO_REQUEST_TYPEIPROTO_OKIPROTO_SYNCMP_UINTIPROTO_SCHEMA_VERSIONMP_UINTBodyIPROTO_DATAMP_OBJECT \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/images/vclock.puml b/doc/dev_guide/internals/iproto/images/vclock.puml new file mode 100644 index 0000000000..65c645296f --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/vclock.puml @@ -0,0 +1,16 @@ +@startuml + +skinparam map { + HyperlinkColor #0077FF + FontColor #313131 + BorderColor #313131 + BackgroundColor transparent +} + +map "**vclock**" as vclock { + replica_id1 => LSN1 + replica_id2 => LSN2 + ... => ... +} + +@enduml diff --git a/doc/dev_guide/internals/iproto/images/vclock.svg b/doc/dev_guide/internals/iproto/images/vclock.svg new file mode 100644 index 0000000000..a4905a580b --- /dev/null +++ b/doc/dev_guide/internals/iproto/images/vclock.svg @@ -0,0 +1,26 @@ +vclockreplica_id1LSN1replica_id2LSN2...... \ No newline at end of file diff --git a/doc/dev_guide/internals/iproto/keys.rst b/doc/dev_guide/internals/iproto/keys.rst new file mode 100644 index 0000000000..3b2581f3bb --- /dev/null +++ b/doc/dev_guide/internals/iproto/keys.rst @@ -0,0 +1,716 @@ +.. _box_protocol-key_list: +.. _internals-iproto-keys: + +Keys used in requests and responses +=================================== + +This section describes ``iproto`` keys contained in requests and responses. +The keys are Tarantool constants that are either defined or mentioned in the +`iproto_constants.h file `_. + +While the keys themselves are unsigned 8-bit integers, their values can have different types. + +Basic description +----------------- + +General +~~~~~~~ + +.. container:: table + + .. list-table:: + :header-rows: 1 + :widths: 40 20 40 + + * - Name + - Code and |br| value type + - Description + + * - :ref:`IPROTO_VERSION ` + - 0x54 |br| MP_INT + - Binary protocol version supported by the client + + * - :ref:`IPROTO_FEATURES ` + - 0x55 |br| MP_ARRAY + - Supported binary protocol features + + * - :ref:`IPROTO_SYNC ` + - 0x01 |br| MP_UINT + - Unique request identifier + + * - :ref:`IPROTO_SCHEMA_VERSION ` + - 0x05 |br| MP_UINT + - Version of the database schema + + * - IPROTO_TIMESTAMP + - 0x04 |br| MP_DOUBLE + - Time in seconds since the Unix epoch + + * - :ref:`IPROTO_REQUEST_TYPE ` + - 0x00 |br| MP_UINT + - Request type or response type + + * - :ref:`IPROTO_ERROR ` + - 0x52 |br| :ref:`MP_ERROR ` + - Error response + + * - :ref:`IPROTO_ERROR_24 ` + - 0x31 |br| MP_STR + - Error as a string + + * - IPROTO_DATA + - 0x30 |br| MP_OBJECT + - Data passed in the transaction. Can be empty. Used in all requests and responses + + * - IPROTO_SPACE_ID + - 0x10 |br| MP_UINT + - Space identifier + + * - IPROTO_INDEX_ID + - 0x11 |br| MP_UINT + - Index identifier + + * - :ref:`IPROTO_TUPLE ` + - 0x21 |br| MP_ARRAY + - Tuple, arguments, operations, or authentication pair. + :ref:`See details ` + + * - IPROTO_KEY + - 0x20 |br| MP_ARRAY + - Array of index keys in the request. See :ref:`space_object:select() ` + + * - IPROTO_LIMIT + - 0x12 |br| MP_UINT + - Maximum number of tuples in the space + + * - IPROTO_OFFSET + - 0x13 |br| MP_UINT + - Number of tuples to skip in the select + + * - :ref:`IPROTO_ITERATOR ` + - 0x14 |br| MP_UINT + - Iterator type + + * - IPROTO_INDEX_BASE + - 0x15 |br| MP_UINT + - Indicates whether the first field number is 1 or 0 + + * - IPROTO_FUNCTION_NAME + - 0x22 |br| MP_STR + - Name of the called function. Used in :ref:`IPROTO_CALL ` + + * - IPROTO_USER_NAME + - 0x23 |br| MP_STR + - User name. Used in :ref:`IPROTO_AUTH ` + + * - IPROTO_OPS + - 0x28 |br| MP_ARRAY + - Array of operations. Used in :ref:`IPROTO_UPSERT ` + + * - IPROTO_EXPR + - 0x27 |br| MP_STR + - Command argument. Used in :ref:`IPROTO_EVAL ` + + +Streams +~~~~~~~ + +.. container:: table + + .. list-table:: + :header-rows: 1 + :widths: 40 20 40 + + * - Name + - Code and |br| value type + - Description + + * - :ref:`IPROTO_STREAM_ID ` + - 0x0a |br| MP_UINT + - Unique :ref:`stream ` identifier + + * - IPROTO_TIMEOUT + - 0x56 |br| MP_DOUBLE + - Timeout in seconds, after which the transactions are rolled back + + * - :ref:`IPROTO_TXN_ISOLATION ` + - 0x59 |br| MP_UINT + - Transaction isolation level + + +.. _internals-iproto-keys-replication-general: + +General replication +~~~~~~~~~~~~~~~~~~~ + +.. container:: table + + .. list-table:: + :header-rows: 1 + :widths: 40 20 40 + + * - Name + - Code and |br| value type + - Description + + * - IPROTO_REPLICA_ID + - 0x02 |br| MP_INT + - Replica ID + + * - IPROTO_INSTANCE_UUID + - 0x24 |br| MP_STR + - Instance UUID + + * - :ref:`IPROTO_VCLOCK ` + - 0x26 |br| MP_MAP + - The instance's vclock + + * - IPROTO_CLUSTER_UUID + - 0x25 |br| MP_STR + - Cluster UUID + + * - IPROTO_LSN + - 0x03 |br| MP_UINT + - Log sequence number of the transaction + + * - IPROTO_TSN + - 0x08 |br| MP_UINT + - Transaction sequence number + + * - IPROTO_BALLOT_IS_RO_CFG + - 0x01 |br| MP_BOOL + - True if the instance is configured as :ref:`read_only `. + Since :doc:`2.6.1 ` + + * - :ref:`IPROTO_BALLOT_VCLOCK ` + - 0x02 |br| MP_MAP + - Current vclock of the instance + + * - :ref:`IPROTO_BALLOT_GC_VCLOCK ` + - 0x03 |br| MP_MAP + - Vclock of the instance’s oldest WAL entry + + * - IPROTO_BALLOT_IS_RO + - 0x04 |br| MP_BOOL + - True if the instance is not writable: configured as :ref:`read_only `, + has :ref:`orphan status `, or + is a :ref:`Raft follower `. + Since :doc:`2.6.1 ` + + * - IPROTO_BALLOT_IS_ANON + - 0x05 |br| MP_BOOL + - True if the replica is anonymous. + Corresponds to :ref:`box.cfg.replication_anon `. + Since :doc:`2.7.1 ` + + * - IPROTO_BALLOT_IS_BOOTED + - 0x06 |br| MP_BOOL + - True if the instance has finished its bootstrap or recovery process. + Since :doc:`2.7.3 `, :doc:`2.8.2 `, :doc:`2.10.0 ` + + * - IPROTO_BALLOT_CAN_LEAD + - 0x07 |br| MP_BOOL + - True if :ref:`box.cfg.election_mode ` is ``candidate`` or ``manual``. + Since v. :doc:`2.7.3 ` and :doc:`2.8.2 ` + + * - :ref:`IPROTO_FLAGS ` + - 0x09 |br| MP_UINT + - Auxiliary data to indicate the last transaction message state. + Included in the header of any DML request that is recorded in the WAL. + + * - IPROTO_SERVER_VERSION + - 0x06 |br| MP_UINT + - Tarantool version of the subscribing node, + in a compact representation + + * - IPROTO_REPLICA_ANON + - 0x50 |br| MP_BOOL + - Optional key used in :ref:`SUBSCRIBE request `. + True if the subscribing replica is anonymous + + * - IPROTO_ID_FILTER + - 0x51 |br| MP_ARRAY + - Optional key used in :ref:`SUBSCRIBE request `, + followed by an array of ids of instances whose rows won't be relayed to the replica. + Since v. :doc:`2.10.0 ` + +All IPROTO_BALLOT_* keys are only used in :ref:`IPROTO_BALLOT ` requests. +There have been some name changes starting with versions 2.7.3, 2.8.2, and 2.10.0: + +* IPROTO_BALLOT_IS_RO_CFG was formerly called IPROTO_BALLOT_IS_RO. +* IPROTO_BALLOT_IS_RO was formerly called IPROTO_BALLOT_IS_LOADING. + + +Synchronous replication +~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: table + + .. list-table:: + :header-rows: 1 + :widths: 40 20 40 + + * - Name + - Code and |br| value type + - Description + + * - IPROTO_TERM + - 0x53 |br| MP_UINT + - The term in which the node becomes the :ref:`synchronous queue owner `. + Used in :ref:`IPROTO_RAFT_PROMOTE ` + + * - IPROTO_RAFT_TERM + - 0x00 |br| MP_UINT + - :ref:`RAFT term ` on an instance + + * - IPROTO_RAFT_VOTE + - 0x01 |br| MP_UINT + - Instance vote in the current term (if any) + + * - IPROTO_RAFT_STATE + - 0x02 |br| MP_UINT + - RAFT state. Possible values: ``1`` -- follower, ``2`` -- candidate, ``3`` -- leader + + * - :ref:`IPROTO_RAFT_VCLOCK ` + - 0x03 |br| MP_MAP + - Current vclock of the instance + + * - IPROTO_RAFT_LEADER_ID + - 0x04 |br| MP_UINT + - Current leader node ID as seen by the node that issues the request + Since version :doc:`2.10.0 ` + + * - IPROTO_RAFT_IS_LEADER_SEEN + - 0x05 |br| MP_BOOL + - True if the node has a direct connection to the leader node. + Since version :doc:`2.10.0 ` + +All ``IPROTO_RAFT_*`` keys are used only in ``IPROTO_RAFT*`` requests. + +Events and subscriptions +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: table + + .. list-table:: + :header-rows: 1 + :widths: 40 20 40 + + * - Name + - Code and |br| value type + - Description + + * - IPROTO_EVENT_KEY + - 0x56 |br| MP_STR + - :ref:`Event ` key name + + * - IPROTO_EVENT_DATA + - 0x57 |br| MP_OBJECT + - :ref:`Event ` data sent to a remote watcher + +:ref:`Learn more about events and subscriptions in iproto `. + +SQL-specific +~~~~~~~~~~~~ + +These keys are used with SQL within :ref:`SQL-specific requests and responses ` +like :ref:`IPROTO_EXECUTE ` +and :ref:`IPROTO_PREPARE `. + +.. container:: table + + .. list-table:: + :header-rows: 1 + :widths: 40 20 40 + + * - Name + - Code and |br| value type + - Description + + * - IPROTO_SQL_TEXT + - 0x40 |br| MP_STR + - SQL statement text + + * - IPROTO_STMT_ID + - 0x43 |br| MP_INT + - Identifier of the prepared statement + + * - IPROTO_OPTIONS + - 0x2b |br| MP_ARRAY + - SQL transaction options. Usually empty + + * - :ref:`IPROTO_METADATA ` + - 0x32 |br| MP_ARRAY of MP_MAP items + - SQL transaction metadata + + * - IPROTO_FIELD_NAME + - 0x00 |br| MP_STR + - Field name. Nested in :ref:`IPROTO_METADATA ` + + * - IPROTO_FIELD_TYPE + - 0x01 |br| MP_STR + - Field type. Nested in :ref:`IPROTO_METADATA ` + + * - IPROTO_FIELD_COLL + - 0x02 |br| MP_STR + - Field collation. Nested in :ref:`IPROTO_METADATA ` + + * - IPROTO_FIELD_IS_NULLABLE + - 0x03 |br| MP_BOOL + - True if the field is nullable. Nested in :ref:`IPROTO_METADATA `. + + * - IPROTO_FIELD_IS_AUTOINCREMENT + - 0x04 |br| MP_BOOL + - True if the field is auto-incremented. + Nested in :ref:`IPROTO_METADATA `. + + * - IPROTO_FIELD_SPAN + - 0x05 |br| MP_STR or MP_NIL + - Original expression under SELECT. + Nested in :ref:`IPROTO_METADATA `. + See :ref:`box.execute() ` + + * - IPROTO_BIND_METADATA + - 0x33 |br| MP_ARRAY + - Bind variable names and types + + * - IPROTO_BIND_COUNT + - 0x34 |br| MP_INT + - Number of parameters to bind + + * - :ref:`IPROTO_SQL_BIND ` + - 0x41 |br| MP_ARRAY + - Parameter values to match ? placeholders or :name placeholders + + * - IPROTO_SQL_INFO + - 0x42 |br| MP_MAP + - Additional SQL-related parameters + + * - SQL_INFO_ROW_COUNT + - 0x00 |br| MP_UINT + - Number of changed rows. Is ``0`` for statements that do not change rows. Nested in IPROTO_SQL_INFO + + * - SQL_INFO_AUTO_INCREMENT_IDS + - 0x01 |br| MP_ARRAY of MP_UINT items + - New primary key value (or values) for an INSERT in a table + defined with PRIMARY KEY AUTOINCREMENT. + Nested in IPROTO_SQL_INFO + + +Details on individual keys +-------------------------- + +.. _internals-iproto-keys-version: + +IPROTO_VERSION +~~~~~~~~~~~~~~ + +Code: 0x54. + +IPROTO_VERSION is an integer number reflecting the version of protocol that the +client supports. The latest IPROTO_VERSION is |iproto_version|. + + +.. _internals-iproto-keys-features: + +IPROTO_FEATURES +~~~~~~~~~~~~~~~ + +Code: 0x55. + +Available IPROTO_FEATURES are the following: + +- ``IPROTO_FEATURE_STREAMS = 0`` -- streams support: :ref:`IPROTO_STREAM_ID ` + in the request header. + +- ``IPROTO_FEATURE_TRANSACTIONS = 1`` -- transaction support: IPROTO_BEGIN, + IPROTO_COMMIT, and IPROTO_ROLLBACK commands (with :ref:`IPROTO_STREAM_ID ` + in the request header). Learn more about :ref:`sending transaction commands `. + +- ``IPROTO_FEATURE_ERROR_EXTENSION = 2`` -- :ref:`MP_ERROR ` + MsgPack extension support. Clients that don't support this feature will receive + error responses for :ref:`IPROTO_EVAL ` and + :ref:`IPROTO_CALL ` encoded to string error messages. + +- ``IPROTO_FEATURE_WATCHERS = 3`` -- remote watchers support: :ref:`IPROTO_WATCH `, + :ref:`IPROTO_UNWATCH `, and :ref:`IPROTO_EVENT ` commands. + +.. _internals-iproto-keys-sync: + +IPROTO_SYNC +~~~~~~~~~~~ + +Code: 0x01. + +This is an unsigned integer that should be incremented so that it is unique in every +request. This integer is also returned from :doc:`/reference/reference_lua/box_session/sync`. + +The IPROTO_SYNC value of a response should be the same as +the IPROTO_SYNC value of a request. + +.. _internals-iproto-keys-schema_version: + +IPROTO_SCHEMA_VERSION +~~~~~~~~~~~~~~~~~~~~~ + +Code: 0x05. + +Version of the database schema -- +an unsigned number that goes up when there is a major change in the schema. + +In a *request* header, IPROTO_SCHEMA_VERSION is optional, so the version will not +be checked if it is absent. + +In a *response* header, IPROTO_SCHEMA_VERSION is always present, and it is up to +the client to check if it has changed. + +.. _internals-iproto-keys-iterator: + +IPROTO_ITERATOR +~~~~~~~~~~~~~~~ + +Code: 0x14. + +Possible values (see `iterator_type.h `_): + +.. container:: table + + .. list-table:: + :header-rows: 0 + :widths: 15 85 + + * - ``0`` + - :ref:`EQ ` + * - ``1`` + - :ref:`REQ ` + * - ``2`` + - :ref:`ALL `, all tuples + * - ``3`` + - :ref:`LT `, less than + * - ``4`` + - :ref:`LE `, less than or equal + * - ``5`` + - :ref:`GE `, greater than or equal + * - ``6`` + - :ref:`GT `, greater than + * - ``7`` + - :ref:`BITS_ALL_SET `, all bits of the value are set in the key + * - ``8`` + - :ref:`BITS_ANY_SET `, at least one bit of the value is set + * - ``9`` + - :ref:`BITS_ALL_NOT_SET `, no bits are set + * - ``10`` + - :ref:`OVERLAPS `, overlaps the rectangle or box + * - ``11`` + - :ref:`NEIGHBOR `, neighbors the rectangle or box + + +.. _box_protocol-iproto_stream_id: + +IPROTO_STREAM_ID +~~~~~~~~~~~~~~~~ + +Code: 0x0a. + +Only used in :ref:`streams `. +This is an unsigned number that should be unique in every stream. + +In requests, IPROTO_STREAM_ID is useful for two things: +ensuring that requests within transactions are done in separate groups, +and ensuring strictly consistent execution of requests (whether or not they are within transactions). + +In responses, IPROTO_STREAM_ID does not appear. + +See :ref:`Binary protocol -- streams `. + + +.. _internals-iproto-keys-txn_isolation: + +IPROTO_TXN_ISOLATION +~~~~~~~~~~~~~~~~~~~~ + +IPROTO_TXN_ISOLATION is the :ref:`transaction isolation level `. +It can take the following values: + +- ``TXN_ISOLATION_DEFAULT = 0`` -- use the default level from ``box.cfg`` (default value) +- ``TXN_ISOLATION_READ_COMMITTED = 1`` -- read changes that are committed but not confirmed yet +- ``TXN_ISOLATION_READ_CONFIRMED = 2`` -- read confirmed changes +- ``TXN_ISOLATION_BEST_EFFORT = 3`` -- determine isolation level automatically + +See :ref:`Binary protocol -- streams ` to learn more about +stream transactions in the binary protocol. + + +.. _internals-iproto-keys-request_type: + +IPROTO_REQUEST_TYPE +~~~~~~~~~~~~~~~~~~~ + +Code: 0x00. + +The key is used both in requests and responses. It indicates the request or response type +and has any request or response name for the value (example: IPROTO_AUTH). +See requests and responses for :ref:`client-server communication `, +:ref:`replication `, +:ref:`events and subscriptions `, +:ref:`streams and interactive transactions `. + +.. _internals-iproto-keys-error: + +IPROTO_ERROR +~~~~~~~~~~~~ + +Code: 0x52. + +In case of error, the response body contains IPROTO_ERROR and :ref:`IPROTO_ERROR_24 ` +instead of IPROTO_DATA. + +To learn more about error responses, check the section :ref:`Request and response format `. + +.. _internals-iproto-keys-error_24: + +IPROTO_ERROR_24 +~~~~~~~~~~~~~~~ + +Code: 0x31. + +IPROTO_ERROR_24 is used in Tarantool versions prior to :doc:`2.4.1 `. +The key contains the error in the string format. + +Since :doc:`Tarantool 2.4.1 `, +Tarantool packs errors as the :ref:`MP_ERROR ` MessagePack extension, +which includes extra information. Two keys are passed in the error response body: IPROTO_ERROR and IPROTO_ERROR_24. + +To learn more about error responses, check the section :ref:`Request and response format `. + +.. _internals-iproto-keys-tuple: + +IPROTO_TUPLE +~~~~~~~~~~~~ + +Code: 0x21. + +Multiple operations make use of this key in different ways: + +.. container:: table + + .. list-table:: + :widths: 25 75 + :header-rows: 0 + + * - :ref:`IPROTO_INSERT `, + :ref:`IPROTO_REPLACE `, + :ref:`IPROTO_UPSERT ` + - Tuple to be inserted + * - :ref:`IPROTO_UPSERT ` + - Operations to perform + * - :ref:`IPROTO_AUTH ` + - Array of 2 fields: + authentication mechanism ("chap-sha1" is the only supported mechanism right now) + and scramble, encrypted according to the specified mechanism. + See more on the :ref:`authentication ` sequence. + * - :ref:`IPROTO_CALL `, :ref:`IPROTO_EVAL ` + - Array of arguments + +.. _internals-iproto-keys-flags: +.. _box_protocol-flags: + +IPROTO_FLAGS +~~~~~~~~~~~~ + +Code: 0x09. + +When it comes to replicating synchronous transactions, the IPROTO_FLAGS key is included in the header. +The key contains an MP_UINT value of one or more bits: + +* IPROTO_FLAG_COMMIT (0x01) will be set if this is the last message for a transaction. +* IPROTO_FLAG_WAIT_SYNC (0x02) will be set if this is the last message + for a transaction which cannot be completed immediately. +* IPROTO_FLAG_WAIT_ACK (0x04) will be set if this is the last message for a synchronous transaction. + +Example: + +.. raw:: html + :file: images/flags_example.svg + +.. _internals-iproto-keys-vclock: + +Vclock keys +~~~~~~~~~~~ + +The vclock (vector clock) is a log sequence number map that defines the version of the dataset stored on the node. +In fact, it represents the number of logical operations executed on a specific node. A vclock looks like this: + +.. raw:: html + :file: images/vclock.svg + +There are four keys that correspond to vector clocks in different contexts of replication. +They all have the MP_MAP type: + +* IPROTO_VCLOCK (0x26) is passed to a new instance :ref:`joining the replica set `. + +* IPROTO_BALLOT_VCLOCK (0x02) is sent in response to :ref:`IPROTO_VOTE `. + This key was introduced in :doc:`/release/2.6.1`. + +* IPROTO_BALLOT_GC_VCLOCK (0x03) is also sent in response to :ref:`IPROTO_VOTE `. + It is the vclock of the oldest WAL entry on the instance. + Corresponds to :ref:`box.info.gc().vclock `. + This key was introduced in :doc:`/release/2.6.1`. + +* IPROTO_RAFT_VCLOCK (0x03) is included in the :ref:`IPROTO_RAFT ` message. + It is present only on the instances in the :ref:`"candidate" state ` + (IPROTO_RAFT_STATE == 2). + +.. _internals-iproto-keys-metadata: + +IPROTO_METADATA +~~~~~~~~~~~~~~~ + +Code: 0x32. + +Used with SQL within :ref:`IPROTO_EXECUTE `. + +The key contains an array of column maps, with each column map containing +at least IPROTO_FIELD_NAME (0x00) and MP_STR, and IPROTO_FIELD_TYPE (0x01) and MP_STR. + +Additionally, if ``sql_full_metadata`` in the +:ref:`_session_settings ` system space +is TRUE, then the array will have these additional column maps +which correspond to components described in the :ref:`box.execute() ` section. + +.. _internals-iproto-keys-sql_bind: + +IPROTO_SQL_BIND +~~~~~~~~~~~~~~~ + +Code: 0x41. + +Used with SQL within :ref:`IPROTO_EXECUTE `. + +IPROTO_SQL_BIND is an array of parameter values to match ? placeholders or :name placeholders. +It can contain values of any type, including MP_MAP. + +* Values that are not MP_MAP replace the ``?`` placeholders in the request. + +* MP_MAP values must have the format ``{[name] = value}``, + where ``name`` is the named parameter in the request. Here is an example of such a request: + + .. code-block:: tarantoolsession + + tarantool> conn:execute('SELECT ?, ?, :name1, ?, :name2, :name1', {1, 2, {[':name1'] = 5}, 'str', {[':name2'] = true}}) + --- + - metadata: + - name: COLUMN_1 + type: integer + - name: COLUMN_2 + type: integer + - name: COLUMN_3 + type: integer + - name: COLUMN_4 + type: text + - name: COLUMN_5 + type: boolean + - name: COLUMN_6 + type: boolean + rows: + - [1, 2, 5, 'str', true, 5] diff --git a/doc/dev_guide/internals/iproto/mp_types.rst b/doc/dev_guide/internals/iproto/mp_types.rst new file mode 100644 index 0000000000..8234a6fb6c --- /dev/null +++ b/doc/dev_guide/internals/iproto/mp_types.rst @@ -0,0 +1,44 @@ +.. _box_protocol-notation: + +MP_* MessagePack types +====================== + +The binary protocol handles data in the `MessagePack `_ format. +Short descriptions of the basic MessagePack data types +are on MessagePack's `specification page `_. +Tarantool also introduces several MessagePack type :ref:`extensions `. + +In this document, MessagePack types are described by words that start with **MP_**. +See this table: + + +.. container:: table + + .. list-table:: + :widths: 40 60 + :header-rows: 0 + + * - **MP_NIL** + - nil + * - **MP_UINT** + - unsigned integer + * - **MP_INT** + - either integer or unsigned integer + * - **MP_STR** + - string + * - **MP_BIN** + - binary string + * - **MP_ARRAY** + - array + * - **MP_MAP** + - map + * - **MP_BOOL** + - boolean + * - **MP_FLOAT** + - float + * - **MP_DOUBLE** + - double + * - **MP_EXT** + - :ref:`extension ` + * - **MP_OBJECT** + - any MessagePack object diff --git a/doc/dev_guide/internals/iproto/replication.rst b/doc/dev_guide/internals/iproto/replication.rst new file mode 100644 index 0000000000..cc262f690c --- /dev/null +++ b/doc/dev_guide/internals/iproto/replication.rst @@ -0,0 +1,332 @@ +.. _internals-iproto-replication: +.. _box_protocol-replication: + +Replication requests and responses +================================== + +This section describes internal requests and responses that happen during replication. +Each of them is distinguished by the header, +containing a unique :ref:`IPROTO_REQUEST_TYPE ` value. +These values and the corresponding packet body structures are considered below. + +Connectors and clients do not need to send replication packets. + +General +------- + +.. container:: table + + .. list-table:: + :widths: 40 20 40 + :header-rows: 1 + + * - Name + - Code + - Description + + * - :ref:`IPROTO_JOIN ` + - 0x41 + - Request to join a replica set + + * - :ref:`IPROTO_SUBSCRIBE ` + - 0x42 + - Request to subscribe to a specific node in a replica set + + * - :ref:`IPROTO_VOTE ` + - 0x44 + - Request for replication + + * - :ref:`IPROTO_BALLOT ` + - 0x29 + - Response to IPROTO_VOTE. Used during replica set bootstrap + + * - IPROTO_FETCH_SNAPSHOT + - 0x45 + - Fetch the master's snapshot and start anonymous replication. + See :ref:`replication_anon ` + + * - IPROTO_REGISTER + - 0x46 + - Register an anonymous replica so it is not anonymous anymore + +The master also sends :ref:`heartbeat ` messages to the replicas. +The heartbeat message's IPROTO_REQUEST_TYPE is ``0``. + +Below are details on individual replication requests. +For synchronous replication requests, see :ref:`below `. + +.. _box_protocol-heartbeat: + +Heartbeats +~~~~~~~~~~ + +Once in :ref:`replication_timeout ` seconds, +a master sends a :ref:`heartbeat ` message to a replica, +and the replica sends a response. +Both messages' IPROTO_REQUEST_TYPE is IPROTO_OK. +Note that the master's heartbeat has no body: + +.. raw:: html + :file: images/repl_heartbeat.svg + +IPROTO_TIMESTAMP is a float-64 MP_DOUBLE 8-byte timestamp. + +The tutorial :ref:`Understanding the binary protocol ` +shows actual byte codes of the above heartbeat examples. + +.. _box_protocol-join: + +IPROTO_JOIN +~~~~~~~~~~~ + +Code: 0x41. + +To join a replica set, an instance must send an initial IPROTO_JOIN request to any node in the replica set: + +.. raw:: html + :file: images/repl_join_request.svg + +The node that receives the request does the following in response: + +#. It sends its vclock: + + .. raw:: html + :file: images/repl_join_response.svg + +#. It sends a number of :ref:`INSERT ` requests (with additional LSN and ServerID). + In this way, the data is updated on the instance that sent the IPROTO_JOIN request. + The instance should not reply to these INSERT requests. + +#. It sends the new vclock's MP_MAP in a response similar to the one above + and closes the socket. + +.. _internals-iproto-replication-subscribe: + +IPROTO_SUBSCRIBE +~~~~~~~~~~~~~~~~ + +Code: 0x42. + +If :ref:`IPROTO_JOIN ` was successful, +the initiator instance must send an IPROTO_SUBSCRIBE request +to all the nodes listed in its :ref:`box.cfg.replication `: + +.. raw:: html + :file: images/repl_subscribe_request.svg + +After a successful IPROTO_SUBSCRIBE request, +the instance must process every request that could come from other masters. +Each master's request includes a vclock pair corresponding to that master -- +its instance ID and its LSN, independent from other masters. + +IPROTO_ID_FILTER (0x51) +is an optional key used in the SUBSCRIBE request followed by an array +of ids of instances whose rows won't be relayed to the replica. +The field is encoded only when the id list is not empty. + +.. _internals-iproto-replication-vote: + +IPROTO_VOTE +~~~~~~~~~~~ + +Code: 0x44. + +When connecting for replication, an instance sends an IPROTO_VOTE request. It has no body: + +.. raw:: html + :file: images/repl_vote.svg + +IPROTO_VOTE is critical during replica set bootstrap. +The response to this request is :ref:`IPROTO_BALLOT `. + +.. _box_protocol-ballots: + +IPROTO_BALLOT +~~~~~~~~~~~~~ + +Code: 0x29. + +This value of IPROTO_REQUEST_TYPE indicates a message sent in response to IPROTO_VOTE +(not to be confused with the key IPROTO_RAFT_VOTE). + +IPROTO_BALLOT and IPROTO_VOTE are critical during replica set bootstrap. +IPROTO_BALLOT corresponds to a map containing the following fields: + +.. raw:: html + :file: images/repl_ballot.svg + +.. _internals-iproto-replication-synchronous: + +Synchronous +----------- + +.. container:: table + + .. list-table:: + :widths: 40 20 40 + :header-rows: 1 + + * - Name + - Code + - Description + + * - :ref:`IPROTO_RAFT ` + - 0x1e + - Inform that the node changed its RAFT status + + * - :ref:`IPROTO_RAFT_PROMOTE ` + - 0x1f + - Wait, then choose new replication leader + + * - :ref:`IPROTO_RAFT_DEMOTE ` + - 0x20 + - Revoke the leader role from the instance + + * - :ref:`IPROTO_RAFT_CONFIRM ` + - 0x28 + - Confirm that the RAFT transactions have achieved quorum and can be committed + + * - :ref:`IPROTO_RAFT_ROLLBACK ` + - 0x29 + - Roll back the RAFT transactions because they haven't achieved quorum + + + +.. _box_protocol-raft: + +IPROTO_RAFT +~~~~~~~~~~~ + +Code: 0x1e. + +A node broadcasts the IPROTO_RAFT request to all the replicas connected to it +when the RAFT state of the node changes. +It can be any actions changing the state, like starting a new election, bumping the term, +voting for another node, becoming the leader, and so on. + +If there should be a response, for example, in case of a vote request to other nodes, +the response will also be an IPROTO_RAFT message. +In this case, the node should be connected as a replica to another node from which the response is expected +because the response is sent via the replication channel. +In other words, there should be a full-mesh connection between the nodes. + +.. raw:: html + :file: images/repl_raft.svg + +IPROTO_REPLICA_ID is the ID of the replica from which the request came. + +.. _internals-iproto-replication-raft_promote: + +IPROTO_RAFT_PROMOTE +~~~~~~~~~~~~~~~~~~~ + +Code: 0x1f. + +See :ref:`box.ctl.promote() `. +Here is what the request contains: + +.. raw:: html + :file: images/repl_raft_promote.svg + +In the header: + +* IPROTO_REPLICA_ID is the replica ID of the node that sent the request. +* IPROTO_LSN is the actual LSN of the promote operation as recorded in the WAL. + +In the body: + +* IPROTO_REPLICA_ID is the replica ID of the previous :ref:`synchronous queue owner `. +* IPROTO_LSN is the LSN of the last operation on the previous synchronous queue owner. +* IPROTO_TERM is the term in which the node that sent the request becomes the synchronous queue owner. + This term corresponds to the value of :ref:`box.info.synchro.queue.term ` on the instance. + +.. _internals-iproto-replication-raft_demote: + +IPROTO_RAFT_DEMOTE +~~~~~~~~~~~~~~~~~~ + +Code: 0x20. + +See :ref:`box.ctl.demote() `. +Here is what the request contains: + +.. raw:: html + :file: images/repl_raft_demote.svg + +In the header: + +* IPROTO_REPLICA_ID is the replica ID of the the node that sent the request. +* IPROTO_LSN is the actual LSN of the demote operation as recorded in the WAL. + +In the body: + +* IPROTO_REPLICA_ID is the replica ID of the the node that sent the request + (same as the value in the header). +* IPROTO_LSN is the LSN of the last synchronous transaction recorded in the node's WAL. +* IPROTO_TERM is the term in which the queue becomes empty. + +.. _box_protocol-raft_confirm: + +IPROTO_RAFT_CONFIRM +~~~~~~~~~~~~~~~~~~~ + +Code: 0x28. + +This message is used in replication connections between +Tarantool nodes in :ref:`synchronous replication `. +It is not supposed to be used by any client applications in their +regular connections. + +This message confirms that the transactions that originated from the instance +with id = IPROTO_REPLICA_ID (body) have achieved quorum and can be committed, +up to and including LSN = IPROTO_LSN (body). + +The body is a 2-item map: + +.. raw:: html + :file: images/repl_raft_confirm.svg + +In the header: + +* IPROTO_REPLICA_ID is the ID of the replica that sends the confirm message. +* IPROTO_LSN is the LSN of the confirmation action. + +In the body: + +* IPROTO_REPLICA_ID is the ID of the instance from which the transactions originated. +* IPROTO_LSN is the LSN up to which the transactions should be confirmed. + +Prior to Tarantool :tarantool-release:`2.10.0`, IPROTO_RAFT_CONFIRM was called IPROTO_CONFIRM. + +.. _box_protocol-raft_rollback: + +IPROTO_RAFT_ROLLBACK +~~~~~~~~~~~~~~~~~~~~ + +Code: 0x29. + +This message is used in replication connections between +Tarantool nodes in :ref:`synchronous replication `. +It is not supposed to be used by any client applications in their +regular connections. + +This message says that the transactions that originated from the instance +with id = IPROTO_REPLICA_ID (body) couldn't achieve quorum for some reason +and should be rolled back, down to LSN = IPROTO_LSN (body) and including it. + +The body is a 2-item map: + +.. raw:: html + :file: images/repl_raft_rollback.svg + +In the header: + +* IPROTO_REPLICA_ID is the ID of the replica that sends the rollback message. +* IPROTO_LSN is the LSN of the rollback action. + +In the body: + +* IPROTO_REPLICA_ID is the ID of the instance from which the transactions originated. +* IPROTO_LSN is the LSN starting with which all pending synchronous transactions should be rolled back. + +Prior to Tarantool :tarantool-release:`2.10.0`, IPROTO_RAFT_ROLLBACK was called IPROTO_ROLLBACK. diff --git a/doc/dev_guide/internals/iproto/requests.rst b/doc/dev_guide/internals/iproto/requests.rst new file mode 100644 index 0000000000..9d782d9e3e --- /dev/null +++ b/doc/dev_guide/internals/iproto/requests.rst @@ -0,0 +1,413 @@ +.. _internals-requests_responses: + +Client-server requests and responses +==================================== + +This section describes client requests, their arguments, and the values returned by the server. + +Some requests are described on separate pages. Those are the requests related to: + +* :ref:`stream transactions ` +* :ref:`asynchronous server-client notifications ` +* :ref:`replication ` +* :ref:`SQL ` -- + :ref:`IPROTO_EXECUTE ` and :ref:`IPROTO_PREPARE `. + +Overview +-------- + +.. container:: table + + .. list-table:: + :header-rows: 1 + :widths: 35 20 45 + + * - Name + - Code + - Description + + * - :ref:`IPROTO_OK ` + - 0x00 |br| MP_UINT + - Successful response + + * - :ref:`IPROTO_CHUNK ` + - 0x80 |br| MP_UINT + - Out-of-band response + + * - :ref:`IPROTO_TYPE_ERROR ` + - 0x8XXX |br| MP_INT + - Error response + + * - :ref:`IPROTO_SELECT ` + - 0x01 + - :ref:`Select ` request + + * - :ref:`IPROTO_INSERT ` + - 0x02 + - :ref:`Insert ` request + + * - :ref:`IPROTO_REPLACE ` + - 0x03 + - :ref:`Replace ` request + + * - :ref:`IPROTO_UPDATE ` + - 0x04 + - :ref:`Update ` request + + * - :ref:`IPROTO_UPSERT ` + - 0x09 + - :ref:`Upsert ` request + + * - :ref:`IPROTO_DELETE ` + - 0x05 + - :ref:`Delete ` request + + * - :ref:`IPROTO_CALL ` + - 0x0a + - Function remote call (:ref:`conn:call() `) + + * - :ref:`IPROTO_AUTH ` + - 0x07 + - Authentication request + + * - :ref:`IPROTO_EVAL ` + - 0x08 + - Evaluate a Lua expression (:ref:`conn:eval() `) + + * - :ref:`IPROTO_NOP ` + - 0x0c + - Increment the LSN and do nothing else + + * - :ref:`IPROTO_PING ` + - 0x40 + - Ping (:ref:`conn:ping() `) + + * - :ref:`IPROTO_ID ` + - 0x49 + - Share iproto version and supported features + + + +.. _internals-iproto-ok: + +IPROTO_OK +--------- + +Code: 0x00. + +This request/response type is contained in the header and signifies success. Here is an example: + +.. raw:: html + :file: images/ok_example.svg + +.. _internals-iproto-chunk: + +IPROTO_CHUNK +------------ + +Code: 0x80. + +If the response is out-of-band, due to use of :ref:`box.session.push() `, +then IPROTO_REQUEST_TYPE is IPROTO_CHUNK instead of IPROTO_OK. + +.. _internals-iproto-type_error: + +IPROTO_TYPE_ERROR +----------------- + +Code: 0x8XXX (see below). + +Instead of :ref:`IPROTO_OK `, an error response header +has ``0x8XXX`` for IPROTO_REQUEST_TYPE. ``XXX`` is the error code -- a value in +`src/box/errcode.h `_. +``src/box/errcode.h`` also has some convenience macros which define hexadecimal +constants for return codes. + +To learn more about error responses, +check the section :ref:`Request and response format `. + +.. _box_protocol-select: + +IPROTO_SELECT +------------- + +Code: 0x01. + +See :ref:`space_object:select() `. +The body is a 6-item map. + +.. raw:: html + :file: images/select.svg + +Example +~~~~~~~ + +If the id of 'tspace' is 512 and this is the fifth message, |br| +:samp:`{conn}.`:code:`space.tspace:select({0},{iterator='GT',offset=1,limit=2})` will cause: + +.. raw:: html + :file: images/select_example.svg + +In the :ref:`examples `, +you can find actual byte codes of an IPROTO_SELECT message. + +.. _box_protocol-insert: + +IPROTO_INSERT +------------- + +Code: 0x02. + +See :ref:`space_object:insert() `. +The body is a 2-item map: + +.. raw:: html + :file: images/insert.svg + +For example, if the request is +:samp:`INSERT INTO {table-name} VALUES (1), (2), (3)`, then the response body +contains an :samp:`IPROTO_SQL_INFO` map with :samp:`SQL_INFO_ROW_COUNT = 3`. +:samp:`SQL_INFO_ROW_COUNT` can be 0 for statements that do not change rows, +but can be 1 for statements that create new objects. + +Example +~~~~~~~ + +If the id of 'tspace' is 512 and this is the fifth message, |br| +:samp:`{conn}.`:code:`space.tspace:insert{1, 'AAA'}` will produce the following request and response packets: + +.. raw:: html + :file: images/insert_example.svg + +The tutorial :ref:`Understanding the binary protocol ` +shows actual byte codes of the response to the IPROTO_INSERT message. + +.. _box_protocol-replace: + +IPROTO_REPLACE +-------------- + +Code: 0x03. + +See :ref:`space_object:replace() `. +The body is a 2-item map, the same as for IPROTO_INSERT: + +.. raw:: html + :file: images/replace.svg + +.. _box_protocol-update: + +IPROTO_UPDATE +------------- + +Code: 0x04. + +See :ref:`space_object:update() `. + +The body is usually a 4-item map: + +.. raw:: html + :file: images/update.svg + +Examples +~~~~~~~~ + +If the operation specifies no values, then IPROTO_TUPLE is a 2-item array: + +.. raw:: html + :file: images/update_example_0.svg + +Normally field numbers start with 1. + +If the operation specifies one value, then IPROTO_TUPLE is a 3-item array: + +.. raw:: html + :file: images/update_example_1.svg + +Otherwise IPROTO_TUPLE is a 5-item array: + +.. raw:: html + :file: images/update_example_regular.svg + +If the id of 'tspace' is 512 and this is the fifth message, |br| +:samp:`{conn}.`:code:`space.tspace:update(999, {{'=', 2, 'B'}})` will cause: + +.. raw:: html + :file: images/update_example.svg + +The map item IPROTO_INDEX_BASE is optional. + +The tutorial :ref:`Understanding the binary protocol ` +shows the actual byte codes of an IPROTO_UPDATE message. + + +.. _box_protocol-upsert: + +IPROTO_UPSERT +------------- + +Code: 0x09. + +See :ref:`space_object:upsert() `. + +The body is usually a 4-item map: + +.. raw:: html + :file: images/upsert.svg + +IPROTO_OPS is the array of operations. It is the same as the IPROTO_TUPLE of :ref:`IPROTO_UPDATE `. + +IPROTO_TUPLE is an array of primary-key field values. + +.. _box_protocol-delete: + +IPROTO_DELETE +------------- + +Code: 0x05. + +See :ref:`space_object:delete() `. +The body is a 3-item map: + +.. raw:: html + :file: images/delete.svg + +.. _box_protocol-eval: + +IPROTO_EVAL +----------- + +Code: 0x08. + +See :ref:`conn:eval() `. +Since the argument is a Lua expression, this is +Tarantool's way to handle non-binary with the +binary protocol. Any request that does not have +its own code, for example :samp:`box.space.{space-name}:drop()`, +will be handled either with :ref:`IPROTO_CALL ` +or IPROTO_EVAL. + +The :ref:`tarantoolctl ` administrative utility +makes extensive use of ``eval``. + +The body is a 2-item map: + +.. raw:: html + :file: images/eval.svg + +* For :ref:`IPROTO_EVAL ` and :ref:`IPROTO_CALL ` + the response body will usually be an array but, since Lua requests can result in a wide variety + of structures, bodies can have a wide variety of structures. + +.. note:: + + For SQL-specific responses, the body is a bit different. + :ref:`Learn more ` about this type of packets. + +Example +~~~~~~~ + +If this is the fifth message, :samp:`conn:eval('return 5;')` will cause: + +.. raw:: html + :file: images/eval_example.svg + +.. _box_protocol-call: + +IPROTO_CALL +----------- + +Code: 0x0a. + +See :ref:`conn:call() `. +This is a remote stored-procedure call. +:doc:`/release/1.6` and earlier made use of the IPROTO_CALL_16 request (code: 0x06). It is now deprecated +and superseded by IPROTO_CALL. + +The body is a 2-item map. The response will be a list of values, similar to the +:ref:`IPROTO_EVAL ` response. The return from conn:call is whatever the function returns. + +.. raw:: html + :file: images/call.svg + +.. note:: + + For SQL-specific responses, the body is a bit different. + :ref:`Learn more ` about this type of packets. + +.. _box_protocol-auth: + +IPROTO_AUTH +----------- + +Code: 0x07. + +For general information, see the :ref:`Access control ` section in the administrator's guide. + +For more on how authentication is handled in the binary protocol, +see the :ref:`Authentication ` section of this document. + +The client sends an authentication packet as an IPROTO_AUTH message: + +.. raw:: html + :file: images/auth.svg + +IPROTO_USERNAME holds the user name. IPROTO_TUPLE must be an array of 2 fields: +authentication mechanism ("chap-sha1" is the only supported mechanism right now) +and scramble, encrypted according to the specified mechanism. + +The server instance responds to an authentication packet with a standard response with 0 tuples. + +To see how Tarantool handles this, look at +`net_box.c `_ +function ``netbox_encode_auth``. + +.. _box_protocol-nop: + +IPROTO_NOP +---------- + +Code: 0x0c. + +There is no Lua request exactly equivalent to IPROTO_NOP. +It causes the LSN to be incremented. +It could be sometimes used for updates where the old and new values +are the same, but the LSN must be increased because a data-change +must be recorded. +The body is: nothing. + + +.. _box_protocol-ping: + +IPROTO_PING +----------- + +Code: 0x40. + +See :ref:`conn:ping() `. The body will be an empty map because IPROTO_PING +in the header contains all the information that the server instance needs. + +.. raw:: html + :file: images/ping.svg + +.. _box_protocol-id: + +IPROTO_ID +--------- + +Code: 0x49. + +Clients send this message to inform the server about the protocol version and +features they support. Based on this information, the server can enable or +disable certain features in interacting with these clients. + +The body is a 2-item map: + +.. raw:: html + :file: images/id.svg + +The response body has the same structure as +the request body. It informs the client about the protocol version and features +that the server supports. + +IPROTO_ID requests can be processed without authentication. diff --git a/doc/dev_guide/internals/iproto/sql.rst b/doc/dev_guide/internals/iproto/sql.rst new file mode 100644 index 0000000000..5c9dd911e4 --- /dev/null +++ b/doc/dev_guide/internals/iproto/sql.rst @@ -0,0 +1,168 @@ +.. _internals-iproto-sql: + +SQL-specific requests and responses +=================================== + +Below are considered the :ref:`IPROTO_EXECUTE ` and +:ref:`IPROTO_PREPARE ` requests, +followed by a description of :ref:`responses `. + +Basic request description +------------------------- + +.. container:: table + + .. list-table:: + :header-rows: 1 + :widths: 35 20 45 + + * - Name + - Code + - Description + + * - :ref:`IPROTO_EXECUTE ` + - 0x0b + - Execute an SQL statement (:ref:`box.execute() `) + + * - :ref:`IPROTO_PREPARE ` + - 0x0d + - Prepare an SQL statement (:ref:`box.prepare() `) + + +.. _box_protocol-execute: + +IPROTO_EXECUTE +-------------- + +Code: 0x0b. + +The body is a 3-item map: + +.. raw:: html + :file: images/execute.svg + +* Use IPROTO_STMT_ID (0x43) and statement-id (MP_INT) if executing a prepared statement. + Use IPROTO_SQL_TEXT (0x40) and statement-text (MP_STR) if executing an SQL string. +* IPROTO_SQL_BIND (0x41) corresponds to the array of parameter values to match ? placeholders or + :name placeholders. +* IPROTO_OPTIONS (0x2b) corresponds to the array of options. It is usually empty. + +Example 1 +~~~~~~~~~ + +Suppose we prepare a statement +with two ? placeholders, and execute with two parameters, thus: + +.. code-block:: lua + + n = conn:prepare([[VALUES (?, ?);]]) + conn:execute(n.stmt_id, {1,'a'}) + +Then the body will look like this: + +.. raw:: html + :file: images/execute_example_1.svg + +The :ref:`Understanding binary protocol ` +tutorial shows actual byte codes of the IPROTO_EXECUTE message. + +To call a prepared statement with named parameters from a connector pass the +parameters within an array of maps. A client should wrap each element into a map, +where the key holds a name of the parameter (with a colon) and the value holds +an actual value. So, to bind foo and bar to 42 and 43, a client should send +``IPROTO_SQL_TEXT: <...>, IPROTO_SQL_BIND: [{"foo": 42}, {"bar": 43}]``. + +If a statement has both named and non-named parameters, wrap only named ones +into a map. The rest of the parameters are positional and will be substituted in order. + +Example 2 +~~~~~~~~~ + +Let's ask for full metadata and then +select the two rows from a table named t1 that has columns named DD and Д: + +.. code-block:: lua + + conn.space._session_settings:update('sql_full_metadata', {{'=', 'value', true}}) + conn:prepare([[SELECT dd, дд AS д FROM t1;]]) + +In the iproto request, there would be no IPROTO_DATA and there would be two additional items: + +* ``34 00 = IPROTO_BIND_COUNT and MP_UINT = 0`` (there are no parameters to bind). +* ``33 90 = IPROTO_BIND_METADATA and MP_ARRAY, size 0`` (there are no parameters to bind). + +Here is what the request body looks like: + +.. raw:: html + :file: images/execute_example_2.svg + +.. _box_protocol-prepare: + +IPROTO_PREPARE +-------------- + +Code: 0x0d. + +The body is a 1-item map: + +.. raw:: html + :file: images/prepare.svg + +Thus the IPROTO_PREPARE map item is the same as the first item of the +:ref:`IPROTO_EXECUTE ` body. + +.. _box_protocol-sql_protocol: + +Responses for SQL +----------------- + +After the :ref:`header `, for a response to an SQL statement, +there will be a body that is slightly different from the body for non-SQL requests/responses. + +Responses to SELECT, VALUES, or PRAGMA +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If the SQL statement is SELECT or VALUES or PRAGMA, the response contains: + +.. raw:: html + :file: images/sql_response_select.svg + + +Example +^^^^^^^ + +Let's ask for full metadata +and then select the two rows from a table named t1 that has columns named DD and Д: + +.. code-block:: lua + + conn.space._session_settings:update('sql_full_metadata', {{'=', 'value', true}}) + conn:execute([[SELECT dd, дд AS д FROM t1;]]) + +The response body might look like this: + +.. raw:: html + :file: images/sql_response_select_example.svg + +The tutorial :ref:`Understanding the binary protocol ` +shows actual byte codes of responses to the above SQL messages. + + +Responses to other requests +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If the SQL request is not SELECT or VALUES or PRAGMA, then the response body +contains only IPROTO_SQL_INFO (0x42). Usually IPROTO_SQL_INFO is a map with only +one item -- SQL_INFO_ROW_COUNT (0x00) -- which is the number of changed rows. + +.. raw:: html + :file: images/sql_response_other.svg + +For example, if the request is :samp:`INSERT INTO {table-name} VALUES (1), (2), (3)`, then the response body +contains an :samp:`IPROTO_SQL_INFO` map with :samp:`SQL_INFO_ROW_COUNT = 3`. + +The IPROTO_SQL_INFO map may contain a second item -- :samp:`SQL_INFO_AUTO_INCREMENT_IDS (0x01)` -- +which is the new primary-key value (or values) for an INSERT in a table +defined with PRIMARY KEY AUTOINCREMENT. In this case the MP_MAP will have two +keys, and one of the two keys will be 0x01: SQL_INFO_AUTO_INCREMENT_IDS, which +is an array of unsigned integers. diff --git a/doc/dev_guide/internals/iproto/streams.rst b/doc/dev_guide/internals/iproto/streams.rst new file mode 100644 index 0000000000..c53fd8b5f1 --- /dev/null +++ b/doc/dev_guide/internals/iproto/streams.rst @@ -0,0 +1,148 @@ +.. _internals-iproto-streams: +.. _box_protocol-streams: + +Streams +======= + +Overview +-------- + +The :ref:`Streams and interactive transactions ` +feature, which was added in Tarantool version +:tarantool-release:`2.10.0`, allows two things: +sequential processing and interleaving. + +**Sequential processing**: +With streams there is a guarantee that the server instance will not +handle the next request in a stream until it has completed the previous one. + +**Interleaving**: +For example, a series of requests can include +"begin for stream #1", "begin for stream #2", +"insert for stream #1", "insert for stream #2", "delete +for stream #1", "commit for stream #1", "rollback for stream #2". + +To work with stream transactions using iproto, the following is required: + +* The engine should be :ref:`vinyl ` or :ref:`memtx with mvcc `. +* The client is responsible for ensuring that the stream identifier, + unsigned integer :ref:`IPROTO_STREAM_ID `, is in the request header. + IPROTO_STREAM_ID can be any positive 64-bit number, and should be unique for the connection. + If IPROTO_STREAM_ID equals zero, the server instance will ignore it. + +Basic request description +------------------------- + +.. container:: table + + .. list-table:: + :header-rows: 1 + :widths: 35 20 45 + + * - Name + - Code + - Description + + * - :ref:`IPROTO_BEGIN ` + - 0x0e + - Begin a transaction in the specified stream + + * - :ref:`IPROTO_COMMIT ` + - 0x0f + - Commit the transaction in the specified stream + + * - :ref:`IPROTO_ROLLBACK ` + - 0x10 + - Rollback the transaction in the specified stream + +.. _box_protocol-begin: + +IPROTO_BEGIN +------------ + +Code: 0x0e. + +Begin a transaction in the specified stream. +See :ref:`stream:begin() `. +The body is optional and can contain two items: + +.. raw:: html + :file: images/stream_begin.svg + +IPROTO_TIMEOUT is an optional timeout (in seconds). After it expires, +the transaction will be rolled back automatically. + +.. _box_protocol-commit: + +IPROTO_COMMIT +------------- + +Code: 0x0f. + +Commit the transaction in the specified stream. +See :ref:`stream:commit() `. + +.. raw:: html + :file: images/stream_commit.svg + +.. _box_protocol-rollback: + +IPROTO_ROLLBACK +--------------- + +Codde: 0x10. + +Rollback the transaction in the specified stream. +See :ref:`stream:rollback() `. + +.. raw:: html + :file: images/stream_rollback.svg + + +Example +------- + +Suppose that the client has started a stream with +the :ref:`net.box module ` + +.. code-block:: lua + + net_box = require('net.box') + conn = net_box.connect('localhost:3302') + stream = conn:new_stream() + +At this point the stream object will look like a duplicate of +the conn object, with just one additional member: ``stream_id``. +Now, using stream instead of conn, the client sends two requests: + +.. code-block:: lua + + stream.space.T:insert{1} + stream.space.T:insert{2} + +The header and body of these requests will be the same as in +non-stream :ref:`IPROTO_INSERT ` requests, except +that the header will contain an additional item: IPROTO_STREAM_ID=0x0a +with MP_UINT=0x01. It happens to equal 1 for this example because +each call to conn:new_stream() assigns a new number, starting with 1. + +.. _box_protocol-stream_transactions: + +The client makes stream transactions by sending, in order: + +1. IPROTO_BEGIN with an optional transaction timeout in the IPROTO_TIMEOUT field of the request body. +2. The transaction data-change and query requests. +3. IPROTO_COMMIT or IPROTO_ROLLBACK. + +All these requests must contain the same IPROTO_STREAM_ID value. + +A rollback will happen automatically if +a disconnect occurs or the transaction timeout expires before the commit is possible. + +Thus there are now multiple ways to do transactions: +with ``net_box`` ``stream:begin()`` and ``stream:commit()`` or ``stream:rollback()`` +which cause IPROTO_BEGIN and IPROTO_COMMIT or IPROTO_ROLLBACK with +the current value of stream.stream_id; +with :ref:`box.begin() ` and :ref:`box.commit() ` or :ref:`box.rollback() `; +with SQL and :ref:`START TRANSACTION ` and :ref:`COMMIT ` or :ref:`ROLLBACK `. +An application can use any or all of these ways. diff --git a/doc/how-to/other/index.rst b/doc/how-to/other/index.rst index 3212fad3fd..6e597e4256 100644 --- a/doc/how-to/other/index.rst +++ b/doc/how-to/other/index.rst @@ -4,4 +4,5 @@ More guides .. toctree:: :maxdepth: 1 + iproto libslave \ No newline at end of file diff --git a/doc/how-to/other/iproto.rst b/doc/how-to/other/iproto.rst new file mode 100644 index 0000000000..9ea88413ef --- /dev/null +++ b/doc/how-to/other/iproto.rst @@ -0,0 +1,319 @@ +.. _how-to-iproto: +.. _box_protocol-illustration: + +Understanding the binary protocol +================================= + +Overview +-------- + +To communicate with each other, Tarantool instances use a binary protocol called iproto. +To learn more, see the :ref:`Binary protocol ` section. + +In this set of examples, the user will be looking at binary code transferred via iproto. +The code is intercepted with ``tcpdump``, a monitoring utility. + +Examples +-------- + +To follow the examples in this section, +get a single Linux computer and start three command-line shells ("terminals"). + +-- On terminal #1, Start monitoring port 3302 with `tcpdump `_: |br| + +.. code-block:: bash + + sudo tcpdump -i lo 'port 3302' -X + +On terminal #2, start a server with: + +.. code-block:: lua + + box.cfg{listen=3302} + box.schema.space.create('tspace') + box.space.tspace:create_index('I') + box.space.tspace:insert{280} + box.schema.user.grant('guest','read,write,execute,create,drop','universe') + +On terminal #3, start another server, which will act as a client, with: + +.. code-block:: lua + + box.cfg{} + net_box = require('net.box') + conn = net_box.connect('localhost:3302') + +IPROTO_SELECT +~~~~~~~~~~~~~ + +On terminal #3, run the following: + +.. code-block:: lua + + conn.space.tspace:select(280) + +Now look at what tcpdump shows for the job connecting to 3302 -- the "request". +After the words "length 32" is a packet that ends with these 32 bytes +(we have added indented comments): + +.. code-block:: none + + ce 00 00 00 1b MP_UINT = decimal 27 = number of bytes after this + 82 MP_MAP, size 2 (we'll call this "Main-Map") + 01 IPROTO_SYNC (Main-Map Item#1) + 04 MP_INT = 4 = number that gets incremented with each request + 00 IPROTO_REQUEST_TYPE (Main-Map Item#2) + 01 IPROTO_SELECT + 86 MP_MAP, size 6 (we'll call this "Select-Map") + 10 IPROTO_SPACE_ID (Select-Map Item#1) + cd 02 00 MP_UINT = decimal 512 = id of tspace (could be larger) + 11 IPROTO_INDEX_ID (Select-Map Item#2) + 00 MP_INT = 0 = id of index within tspace + 14 IPROTO_ITERATOR (Select-Map Item#3) + 00 MP_INT = 0 = Tarantool iterator_type.h constant ITER_EQ + 13 IPROTO_OFFSET (Select-Map Item#4) + 00 MP_INT = 0 = amount to offset + 12 IPROTO_LIMIT (Select-Map Item#5) + ce ff ff ff ff MP_UINT = 4294967295 = biggest possible limit + 20 IPROTO_KEY (Select-Map Item#6) + 91 MP_ARRAY, size 1 (we'll call this "Key-Array") + cd 01 18 MP_UINT = 280 (Select-Map Item#6, Key-Array Item#1) + -- 280 is the key value that we are searching for + +Now read the source code file +`net_box.c `_ +and skip to the line ``netbox_encode_select(lua_State *L)``. +From the comments and from simple function calls like +``mpstream_encode_uint(&stream, IPROTO_SPACE_ID);`` +you will be able to see how net_box put together the packet contents that you +have just observed with tcpdump. + +There are libraries for reading and writing MessagePack objects. +C programmers sometimes include `msgpuck.h `_. + +Now you know how Tarantool itself makes requests with the binary protocol. +When in doubt about a detail, consult ``net_box.c`` -- it has routines for each +request. Some :ref:`connectors ` have similar code. + +IPROTO_UPDATE +~~~~~~~~~~~~~ + +For an IPROTO_UPDATE example, suppose a user changes field #2 in tuple #2 +in space #256 to ``'BBBB'``. The body will look like this: +(notice that in this case there is an extra map item +IPROTO_INDEX_BASE, to emphasize that field numbers +start with 1, which is optional and can be omitted): + +.. code-block:: none + + 04 IPROTO_UPDATE + 85 IPROTO_MAP, size 5 + 10 IPROTO_SPACE_ID, Map Item#1 + cd 02 00 MP_UINT 256 + 11 IPROTO_INDEX_ID, Map Item#2 + 00 MP_INT 0 = primary-key index number + 15 IPROTO_INDEX_BASE, Map Item#3 + 01 MP_INT = 1 i.e. field numbers start at 1 + 21 IPROTO_TUPLE, Map Item#4 + 91 MP_ARRAY, size 1, for array of operations + 93 MP_ARRAY, size 3 + a1 3d MP_STR = OPERATOR = '=' + 02 MP_INT = FIELD_NO = 2 + a5 42 42 42 42 42 MP_STR = VALUE = 'BBBB' + 20 IPROTO_KEY, Map Item#5 + 91 MP_ARRAY, size 1, for array of key values + 02 MP_UINT = primary-key value = 2 + +IPROTO_EXECUTE +~~~~~~~~~~~~~~ + +Byte codes for the :ref:`IPROTO_EXECUTE ` example: + +.. code-block:: none + + 0b IPROTO_EXECUTE + 83 MP_MAP, size 3 + 43 IPROTO_STMT_ID Map Item#1 + ce d7 aa 74 1b MP_UINT value of n.stmt_id + 41 IPROTO_SQL_BIND Map Item#2 + 92 MP_ARRAY, size 2 + 01 MP_INT = 1 = value for first parameter + a1 61 MP_STR = 'a' = value for second parameter + 2b IPROTO_OPTIONS Map Item#3 + 90 MP_ARRAY, size 0 (there are no options) + +IPROTO_INSERT +~~~~~~~~~~~~~ + +Byte codes for the response to the :codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:insert{6}` +example: + +.. code-block:: none + + ce 00 00 00 20 MP_UINT = HEADER AND BODY SIZE + 83 MP_MAP, size 3 + 00 IPROTO_REQUEST_TYPE + ce 00 00 00 00 MP_UINT = IPROTO_OK + 01 IPROTO_SYNC + cf 00 00 00 00 00 00 00 53 MP_UINT = sync value + 05 IPROTO_SCHEMA_VERSION + ce 00 00 00 68 MP_UINT = schema version + 81 MP_MAP, size 1 + 30 IPROTO_DATA + dd 00 00 00 01 MP_ARRAY, size 1 (row count) + 91 MP_ARRAY, size 1 (field count) + 06 MP_INT = 6 = the value that was inserted + +IPROTO_EVAL +~~~~~~~~~~~ + +Byte codes for the response to the ``conn:eval([[box.schema.space.create('_space');]])`` +example: + +.. code-block:: none + + ce 00 00 00 3b MP_UINT = HEADER AND BODY SIZE + 83 MP_MAP, size 3 (i.e. 3 items in header) + 00 IPROTO_REQUEST_TYPE + ce 00 00 80 0a MP_UINT = hexadecimal 800a + 01 IPROTO_SYNC + cf 00 00 00 00 00 00 00 26 MP_UINT = sync value + 05 IPROTO_SCHEMA_VERSION + ce 00 00 00 78 MP_UINT = schema version value + 81 MP_MAP, size 1 + 31 IPROTO_ERROR_24 + db 00 00 00 1d 53 70 61 63 etc. MP_STR = "Space '_space' already exists" + +Creating a table with IPROTO_EXECUTE +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Byte codes, if we use the same net.box connection that +we used in the beginning +and we say |br| +``conn:execute([[CREATE TABLE t1 (dd INT PRIMARY KEY AUTOINCREMENT, дд STRING COLLATE "unicode");]])`` |br| +``conn:execute([[INSERT INTO t1 VALUES (NULL, 'a'), (NULL, 'b');]])`` |br| +and we watch what tcpdump displays, we will see two noticeable things: +(1) the CREATE statement caused a schema change so the response has +a new IPROTO_SCHEMA_VERSION value and the body includes +the new contents of some system tables (caused by requests from net.box which users will not see); +(2) the final bytes of the response to the INSERT will be: + +.. code-block:: none + + 81 MP_MAP, size 1 + 42 IPROTO_SQL_INFO + 82 MP_MAP, size 2 + 00 Tarantool constant (not in iproto_constants.h) = SQL_INFO_ROW_COUNT + 02 1 = row count + 01 Tarantool constant (not in iproto_constants.h) = SQL_INFO_AUTOINCREMENT_ID + 92 MP_ARRAY, size 2 + 01 first autoincrement number + 02 second autoincrement number + +SELECT with SQL +~~~~~~~~~~~~~~~ + +Byte codes for the SQL SELECT example, +if we ask for full metadata by saying |br| +:code:`conn.space._session_settings:update('sql_full_metadata', {{'=', 'value', true}})` |br| +and we select the two rows from the table that we just created |br| +:code:`conn:execute([[SELECT dd, дд AS д FROM t1;]])` |br| +then tcpdump will show this response, after the header: + +.. code-block:: none + + 82 MP_MAP, size 2 (i.e. metadata and rows) + 32 IPROTO_METADATA + 92 MP_ARRAY, size 2 (i.e. 2 columns) + 85 MP_MAP, size 5 (i.e. 5 items for column#1) + 00 a2 44 44 IPROTO_FIELD_NAME and 'DD' + 01 a7 69 6e 74 65 67 65 72 IPROTO_FIELD_TYPE and 'integer' + 03 c2 IPROTO_FIELD_IS_NULLABLE and false + 04 c3 IPROTO_FIELD_IS_AUTOINCREMENT and true + 05 c0 PROTO_FIELD_SPAN and nil + 85 MP_MAP, size 5 (i.e. 5 items for column#2) + 00 a2 d0 94 IPROTO_FIELD_NAME and 'Д' upper case + 01 a6 73 74 72 69 6e 67 IPROTO_FIELD_TYPE and 'string' + 02 a7 75 6e 69 63 6f 64 65 IPROTO_FIELD_COLL and 'unicode' + 03 c3 IPROTO_FIELD_IS_NULLABLE and true + 05 a4 d0 b4 d0 b4 IPROTO_FIELD_SPAN and 'дд' lower case + 30 IPROTO_DATA + 92 MP_ARRAY, size 2 + 92 MP_ARRAY, size 2 + 01 MP_INT = 1 i.e. contents of row#1 column#1 + a1 61 MP_STR = 'a' i.e. contents of row#1 column#2 + 92 MP_ARRAY, size 2 + 02 MP_INT = 2 i.e. contents of row#2 column#1 + a1 62 MP_STR = 'b' i.e. contents of row#2 column#2 + +IPROTO_PREPARE +~~~~~~~~~~~~~~ + +Byte code for the SQL PREPARE example. If we said |br| +:code:`conn:prepare([[SELECT dd, дд AS д FROM t1;]])` |br| +then tcpdump would show almost the same response, but there would +be no IPROTO_DATA. Instead, additional items will appear: + +.. code-block:: none + + 34 IPROTO_BIND_COUNT + 00 MP_UINT = 0 + + 33 IPROTO_BIND_METADATA + 90 MP_ARRAY, size 0 + +``MP_UINT = 0`` and ``MP_ARRAY`` has size 0 because there are no parameters to bind. +Full output: + +.. code-block:: none + + 84 MP_MAP, size 4 + 43 IPROTO_STMT_ID + ce c2 3c 2c 1e MP_UINT = statement id + 34 IPROTO_BIND_COUNT + 00 MP_INT = 0 = number of parameters to bind + 33 IPROTO_BIND_METADATA + 90 MP_ARRAY, size 0 = there are no parameters to bind + 32 IPROTO_METADATA + 92 MP_ARRAY, size 2 (i.e. 2 columns) + 85 MP_MAP, size 5 (i.e. 5 items for column#1) + 00 a2 44 44 IPROTO_FIELD_NAME and 'DD' + 01 a7 69 6e 74 65 67 65 72 IPROTO_FIELD_TYPE and 'integer' + 03 c2 IPROTO_FIELD_IS_NULLABLE and false + 04 c3 IPROTO_FIELD_IS_AUTOINCREMENT and true + 05 c0 PROTO_FIELD_SPAN and nil + 85 MP_MAP, size 5 (i.e. 5 items for column#2) + 00 a2 d0 94 IPROTO_FIELD_NAME and 'Д' upper case + 01 a6 73 74 72 69 6e 67 IPROTO_FIELD_TYPE and 'string' + 02 a7 75 6e 69 63 6f 64 65 IPROTO_FIELD_COLL and 'unicode' + 03 c3 IPROTO_FIELD_IS_NULLABLE and true + 05 a4 d0 b4 d0 b4 IPROTO_FIELD_SPAN and 'дд' lower case + +Heartbeat +~~~~~~~~~ + +Byte code for the :ref:`heartbeat ` example. The master might send this body: + +.. code-block:: none + + 83 MP_MAP, size 3 + 00 Main-Map Item #1 IPROTO_REQUEST_TYPE + 00 MP_UINT = 0 + 02 Main-Map Item #2 IPROTO_REPLICA_ID + 02 MP_UINT = 2 = id + 04 Main-Map Item #3 IPROTO_TIMESTAMP + cb MP_DOUBLE (MessagePack "Float 64") + 41 d7 ba 06 7b 3a 03 21 8-byte timestamp + +Byte code for the :ref:`heartbeat ` example. The replica might send back this body + +.. code-block:: none + + 81 MP_MAP, size 1 + 00 Main-Map Item #1 IPROTO_REQUEST_TYPE + 00 MP_UINT = 0 = IPROTO_OK + 81 Main-Map Item #2, MP_MAP, size 1 + 26 Sub-Map Item #1 IPROTO_VCLOCK + 81 Sub-Map Item #2, MP_MAP, size 1 + 01 MP_UINT = 1 = id (part 1 of vclock) + 06 MP_UINT = 6 = lsn (part 2 of vclock) diff --git a/doc/reference/reference_lua/net_box.rst b/doc/reference/reference_lua/net_box.rst index e4c4792555..5ff807f6c2 100644 --- a/doc/reference/reference_lua/net_box.rst +++ b/doc/reference/reference_lua/net_box.rst @@ -256,7 +256,8 @@ Below is a list of all ``net.box`` functions. - IPROTO_FEATURE_WATCHERS - 3 and newer - To learn more about IPROTO features, see :ref:`IPROTO_ID `. + To learn more about IPROTO features, see :ref:`IPROTO_ID ` + and the :ref:`IPROTO_FEATURES ` key. :return: conn object :rtype: userdata diff --git a/locale/ru/LC_MESSAGES/dev_guide/internals/box_protocol.po b/locale/ru/LC_MESSAGES/dev_guide/internals/box_protocol.po index e62de8f424..01fe11cf05 100644 --- a/locale/ru/LC_MESSAGES/dev_guide/internals/box_protocol.po +++ b/locale/ru/LC_MESSAGES/dev_guide/internals/box_protocol.po @@ -2,12 +2,15 @@ msgid "Binary protocol" msgstr "Бинарный протокол" +msgid "Introduction" +msgstr "Введение" + msgid "" -"The binary protocol is called a \"request/response\" protocol because it is " +"The binary protocol, iproto, is called a \"request/response\" protocol because it is " "for sending requests to a Tarantool server and receiving responses. There is" " complete access to Tarantool functionality, including:" msgstr "" -"Бинарный протокол передает данные по схеме \"запрос-ответ\", то есть он " +"Бинарный протокол iproto передает данные по схеме \"запрос-ответ\", то есть он " "предназначен для отправки запросов на сервер Tarantool и получения ответов. " "Протокол предоставляет полный доступ к функциям Tarantool, включая:" @@ -496,843 +499,6 @@ msgstr "" "``box.space:select()`` значение индикатора кода ответа будет 0 = IPROTO_OK, " "а массив будет содержать все кортежи из результата." -msgid "" -"The ```` has the details of the request or response. In a request, it " -"can also be absent or be an empty map. Both these states will be interpreted" -" equally. Responses will contain the ```` anyway even for an " -":ref:`IPROTO_PING ` request." -msgstr "" -"Тело сообщения ```` содержит детали запроса или ответа. В запросе оно " -"может отсутствовать или представлять собой пустой ассоциативный массив. И " -"то, и другое будет интерпретироваться одинаково. Ответы будут содержать " -"```` в любом случае, даже после запроса :ref:`IPROTO_PING " -"`." - -msgid "Requests" -msgstr "Запросы" - -msgid "" -"A request has a size, a :ref:`header ` that contains " -"the IPROTO key, and a body as described here." -msgstr "" -"Запрос содержит размер, :ref:`заголовок `, который " -"содержит ключ IPROTO, и тело сообщения, как описано в этом разделе." - -msgid "IPROTO_SELECT = 0x01" -msgstr "IPROTO_SELECT = 0x01" - -msgid "" -"See :ref:`space_object:select() `. The body is a 6-item " -"map." -msgstr "" -"См. :ref:`space_object:select() `. Тело сообщения " -"представляет собой ассоциативный массив из 6 элементов." - -msgid "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_SELECT,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_LIMIT: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_OFFSET: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_ITERATOR: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_KEY: :samp:`{{MP_ARRAY array of key values}}`\n" -"})" -msgstr "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_SELECT,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_LIMIT: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_OFFSET: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_ITERATOR: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_KEY: :samp:`{{MP_ARRAY array of key values}}`\n" -"})" - -msgid "" -"Example: if the id of 'tspace' is 512 and this is the fifth message, |br| " -":samp:`{conn}.`:code:`space.tspace:select({0},{iterator='GT',offset=1,limit=2})`" -" will cause:" -msgstr "" -"Пример: если ID спейса 'tspace' = 512 и это пятое сообщение, |br| " -":samp:`{conn}.`:code:`space.tspace:select({0},{iterator='GT',offset=1,limit=2})`" -" вызовет:" - -msgid "" -"\n" -"msgpack(21)\n" -"#
\n" -"msgpack({\n" -" IPROTO_SYNC: 5,\n" -" IPROTO_REQUEST_TYPE: IPROTO_SELECT\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: 512,\n" -" IPROTO_INDEX_ID: 0,\n" -" IPROTO_ITERATOR: 6,\n" -" IPROTO_OFFSET: 1,\n" -" IPROTO_LIMIT: 2,\n" -" IPROTO_KEY: [1]\n" -"})" -msgstr "" -"\n" -"msgpack(21)\n" -"#
\n" -"msgpack({\n" -" IPROTO_SYNC: 5,\n" -" IPROTO_REQUEST_TYPE: IPROTO_SELECT\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: 512,\n" -" IPROTO_INDEX_ID: 0,\n" -" IPROTO_ITERATOR: 6,\n" -" IPROTO_OFFSET: 1,\n" -" IPROTO_LIMIT: 2,\n" -" IPROTO_KEY: [1]\n" -"})" - -msgid "" -"Later in :ref:`Binary protocol -- illustration ` " -"we will show actual byte codes of an IPROTO_SELECT message." -msgstr "" -"Далее в разделе :ref:`Примеры` будут рассмотрены " -"байт-коды сообщения IPROTO_SELECT." - -msgid "IPROTO_INSERT = 0x02" -msgstr "IPROTO_INSERT = 0x02" - -msgid "" -"See :ref:`space_object:insert() `. The body is a 2-item " -"map:" -msgstr "" -"См. :ref:`space_object:insert() `. Тело сообщения " -"представляет собой ассоциативный массив из 2 элементов:" - -msgid "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_INSERT,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of field values}}`\n" -"})" -msgstr "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_INSERT,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of field values}}`\n" -"})" - -msgid "" -"Example: if the id of 'tspace' is 512 and this is the fifth message, |br| " -":samp:`{conn}.`:code:`space.tspace:insert{1, 'AAA'}` will cause:" -msgstr "" -"Пример: если ID спейса 'tspace' = 512 и это пятое сообщение, |br| " -":samp:`{conn}.`:code:`space.tspace:insert{1, 'AAA'}` вызовет:" - -msgid "" -"# \n" -"msgpack(17)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_INSERT,\n" -" IPROTO_SYNC: 5\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: 512,\n" -" IPROTO_TUPLE: [1, 'AAA']\n" -"})" -msgstr "" -"# \n" -"msgpack(17)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_INSERT,\n" -" IPROTO_SYNC: 5\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: 512,\n" -" IPROTO_TUPLE: [1, 'AAA']\n" -"})" - -msgid "IPROTO_REPLACE = 0x03" -msgstr "IPROTO_REPLACE = 0x03" - -msgid "" -"See :ref:`space_object:replace() `. The body is a 2-item" -" map, the same as for IPROTO_INSERT:" -msgstr "" -"См. :ref:`space_object:replace() `. Тело сообщения " -"представляет собой ассоциативный массив из 2 элементов, как и в случае " -"IPROTO_INSERT:" - -msgid "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_REPLACE,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of field values}}`\n" -"})" -msgstr "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_REPLACE,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of field values}}`\n" -"})" - -msgid "IPROTO_UPDATE = 0x04" -msgstr "IPROTO_UPDATE = 0x04" - -msgid "See :ref:`space_object:update() `." -msgstr "См. :ref:`space_object:update() `." - -msgid "The body is usually a 4-item map:" -msgstr "" -"Тело сообщения обычно представляет собой ассоциативный массив из 4 " -"элементов:" - -msgid "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_UPDATE,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_KEY: :samp:`{{MP_ARRAY array of index keys}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of update operations}}`\n" -"})" -msgstr "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_UPDATE,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_KEY: :samp:`{{MP_ARRAY array of index keys}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of update operations}}`\n" -"})" - -msgid "" -"If the operation specifies no values, then IPROTO_TUPLE is a 2-item array: " -"|br| :samp:`[{MP_STR OPERATOR = '#', {MP_INT FIELD_NO = field number " -"starting with 1}]`. Normally field numbers start with 1." -msgstr "" -"Если в операции не указаны значения, то IPROTO_TUPLE — это массив из 2 " -"элементов: |br| :samp:`[{MP_STR OPERATOR = '#', {MP_INT FIELD_NO = номер " -"поля, начиная с 1}]`. Обычно номера полей начинаются с 1." - -msgid "" -"If the operation specifies one value, then IPROTO_TUPLE is a 3-item array: " -"|br| :samp:`[{MP_STR string OPERATOR = '+' or '-' or '^' or '^' or '|' or " -"'!' or '='}, {MP_INT FIELD_NO}, {MP_OBJECT VALUE}]`. |br|" -msgstr "" -"Если в операции задано одно значение, то IPROTO_TUPLE — это массив из трех " -"элементов: |br| :samp:`[{MP_STR string OPERATOR = '+' or '-' or '^' or '^' " -"or '|' or '!' or '='}, {MP_INT FIELD_NO}, {MP_OBJECT VALUE}]`. |br|" - -msgid "" -"Otherwise IPROTO_TUPLE is a 5-item array: |br| :samp:`[{MP_STR string " -"OPERATOR = ':'}, {MP_INT integer FIELD_NO}, {MP_INT POSITION}, {MP_INT " -"OFFSET}, {MP_STR VALUE}]`. |br|" -msgstr "" -"В остальных случаях IPROTO_TUPLE — это массив из 5 элементов: |br| " -":samp:`[{MP_STR string OPERATOR = ':'}, {MP_INT integer FIELD_NO}, {MP_INT " -"POSITION}, {MP_INT OFFSET}, {MP_STR VALUE}]`. |br|" - -msgid "" -"Example: if the id of 'tspace' is 512 and this is the fifth message, |br| " -":samp:`{conn}.`:code:`space.tspace:update(999, {{'=', 2, 'B'}})` will cause:" -msgstr "" -"Пример: если ID спейса 'tspace' = 512 и это пятое сообщение, br| " -":samp:`{conn}.`:code:`space.tspace:update(999, {{'=', 2, 'B'}})` вызовет:" - -msgid "" -"# \n" -"msgpack(17)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_UPDATE,\n" -" IPROTO_SYNC: 5\n" -"})\n" -"# ... the map-item IPROTO_INDEX_BASE is optional\n" -"msgpack({\n" -" IPROTO_SPACE_ID: 512,\n" -" IPROTO_INDEX_ID: 0,\n" -" IPROTO_INDEX_BASE: 1,\n" -" IPROTO_TUPLE: [['=',2,'B']],\n" -" IPROTO_KEY: [999]\n" -"})" -msgstr "" -"# \n" -"msgpack(17)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_UPDATE,\n" -" IPROTO_SYNC: 5\n" -"})\n" -"# ... the map-item IPROTO_INDEX_BASE is optional\n" -"msgpack({\n" -" IPROTO_SPACE_ID: 512,\n" -" IPROTO_INDEX_ID: 0,\n" -" IPROTO_INDEX_BASE: 1,\n" -" IPROTO_TUPLE: [['=',2,'B']],\n" -" IPROTO_KEY: [999]\n" -"})" - -msgid "" -"Later in :ref:`Binary protocol -- illustration ` " -"we will show actual byte codes of an IPROTO_UPDATE message." -msgstr "" -"Далее в разделе :ref:`Примеры ` будут рассмотрены" -" байт-коды сообщения IPROTO_UPDATE." - -msgid "IPROTO_DELETE = 0x05" -msgstr "IPROTO_DELETE = 0x05" - -msgid "" -"See :ref:`space_object:delete() `. The body is a 3-item " -"map:" -msgstr "" -"См. :ref:`space_object:delete() `. Тело сообщения " -"представляет собой ассоциативный массив из 3 элементов:" - -msgid "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_DELETE,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_KEY: :samp:`{{MP_ARRAY array of key values}}`\n" -"})" -msgstr "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_DELETE,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_KEY: :samp:`{{MP_ARRAY array of key values}}`\n" -"})" - -msgid "IPROTO_CALL_16 = 0x06" -msgstr "IPROTO_CALL_16 = 0x06" - -msgid "" -"See :ref:`conn:call() `. The suffix ``_16`` is a hint that " -"this is for the ``call()`` until Tarantool 1.6. It is deprecated. Use " -":ref:`IPROTO_CALL ` instead. The body is a 2-item map:" -msgstr "" -"См. :ref:`conn:call() `. ``_16`` в конце подсказывает, что " -"константа используется для ``call()`` до версии Tarantool 1.6. Эта константа" -" объявлена устаревшей. Вместо нее используйте :ref:`IPROTO_CALL " -"`. Тело сообщения представляет собой ассоциативный массив" -" из 2 элементов:" - -msgid "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_CALL_16,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_FUNCTION_NAME: :samp:`{{MP_STR string}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}`\n" -"})" -msgstr "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_CALL_16,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_FUNCTION_NAME: :samp:`{{MP_STR string}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}`\n" -"})" - -msgid "The return value is an array of tuples." -msgstr "Возвращается массив кортежей." - -msgid "IPROTO_AUTH = 0x07" -msgstr "IPROTO_AUTH = 0x07" - -msgid "" -"See :ref:`authentication `. See the later section " -":ref:`Binary protocol -- authentication `." -msgstr "" -"См. раздел :ref:`Аутентификация ` в документации. См. " -"раздел об :ref:`аутентификации ` ниже." - -msgid "IPROTO_EVAL = 0x08" -msgstr "IPROTO_EVAL = 0x08" - -msgid "" -"See :ref:`conn:eval() `. Since the argument is a Lua " -"expression, this is Tarantool's way to handle non-binary with the binary " -"protocol. Any request that does not have its own code, for example " -":samp:`box.space.{space-name}:drop()`, will be handled either with " -":ref:`IPROTO_CALL ` or IPROTO_EVAL. The " -":ref:`tarantoolctl ` administrative utility makes extensive " -"use of ``eval``. The body is a 2-item map:" -msgstr "" -"См. :ref:`conn:eval() `. В качестве аргумента выступает " -"выражение на Lua — так Tarantool обрабатывает небинарный код с помощью " -"бинарного протокола. Любой запрос без собственного кода, например " -":samp:`box.space.{space-name}:drop()`, будет обработан с помощью либо " -":ref:`IPROTO_CALL `, либо IPROTO_EVAL. Административная " -"утилита :ref:`tarantoolctl ` активно использует ``eval``. Тело" -" сообщения представляет собой ассоциативный массив из 2 элементов:" - -msgid "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_EVAL,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_EXPR: :samp:`{{MP_STR string}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}`\n" -"})" -msgstr "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_EVAL,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_EXPR: :samp:`{{MP_STR string}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}`\n" -"})" - -msgid "" -"Example: if this is the fifth message, :samp:`conn:eval('return 5;')` will " -"cause:" -msgstr "" -"Пример. Если это пятое сообщение, :samp:`conn:eval('return 5;')` приведет к " -"следующему:" - -msgid "" -"# \n" -"msgpack(19)\n" -"#
\n" -"msgpack({\n" -" IPROTO_SYNC: 5\n" -" IPROTO_REQUEST_TYPE: IPROTO_EVAL\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_EXPR: 'return 5;',\n" -" IPROTO_TUPLE: []\n" -"})" -msgstr "" -"# \n" -"msgpack(19)\n" -"#
\n" -"msgpack({\n" -" IPROTO_SYNC: 5\n" -" IPROTO_REQUEST_TYPE: IPROTO_EVAL\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_EXPR: 'return 5;',\n" -" IPROTO_TUPLE: []\n" -"})" - -msgid "IPROTO_UPSERT = 0x09" -msgstr "IPROTO_UPSERT = 0x09" - -msgid "See :ref:`space_object:upsert() `." -msgstr "См. :ref:`space_object:upsert() `." - -msgid "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_UPSERT,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_INDEX_BASE: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_OPS: :samp:`{{MP_ARRAY array of update operations}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of primary-key field values}}`\n" -"})" -msgstr "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_UPSERT,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_INDEX_BASE: :samp:`{{MP_UINT unsigned integer}}`,\n" -" IPROTO_OPS: :samp:`{{MP_ARRAY array of update operations}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of primary-key field values}}`\n" -"})" - -msgid "" -"The IPROTO_OPS is the same as the IPROTO_TUPLE of :ref:`IPROTO_UPDATE " -"`." -msgstr "" -"IPROTO_OPS — это то же самое, что и IPROTO_TUPLE в :ref:`IPROTO_UPDATE " -"`." - -msgid "IPROTO_CALL = 0x0a" -msgstr "IPROTO_CALL = 0x0a" - -msgid "See :ref:`conn:call() `. The body is a 2-item map:" -msgstr "" -"См. :ref:`conn:call() `. Тело сообщения представляет собой " -"ассоциативный массив из 2 элементов:" - -msgid "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_CALL,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_FUNCTION_NAME: :samp:`{{MP_STR string}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}`\n" -"})" -msgstr "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_CALL,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_FUNCTION_NAME: :samp:`{{MP_STR string}}`,\n" -" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}`\n" -"})" - -msgid "" -"The response will be a list of values, similar to the :ref:`IPROTO_EVAL " -"` response." -msgstr "" -"Вернется список значений, наподобие ответа :ref:`IPROTO_EVAL `." - -msgid "IPROTO_EXECUTE = 0x0b" -msgstr "IPROTO_EXECUTE = 0x0b" - -msgid "" -"See :ref:`box.execute() `, this is only for SQL. The " -"body is a 3-item map:" -msgstr "" -"См. :ref:`box.execute() `, используется только для SQL." -" Тело сообщения представляет собой ассоциативный массив из 3 элементов:" - -msgid "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_EXECUTE,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_STMT_ID: :samp:`{{MP_INT integer}}` or IPROTO_SQL_TEXT: :samp:`{{MP_STR string}}`,\n" -" IPROTO_SQL_BIND: :samp:`{{MP_INT integer}}`,\n" -" IPROTO_OPTIONS: :samp:`{{MP_ARRAY array}}`\n" -"})" -msgstr "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_EXECUTE,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_STMT_ID: :samp:`{{MP_INT integer}}` или IPROTO_SQL_TEXT: :samp:`{{MP_STR string}}`,\n" -" IPROTO_SQL_BIND: :samp:`{{MP_INT integer}}`,\n" -" IPROTO_OPTIONS: :samp:`{{MP_ARRAY array}}`\n" -"})" - -msgid "" -"Use IPROTO_STMT_ID (0x43) and statement-id (MP_INT) if executing a prepared " -"statement, or use IPROTO_SQL_TEXT (0x40) and statement-text (MP_STR) if " -"executing an SQL string, then IPROTO_SQL_BIND (0x41) and array of parameter " -"values to match ? placeholders or :name placeholders, IPROTO_OPTIONS (0x2b) " -"and array of options (usually empty)." -msgstr "" -"При выполнении подготовленного оператора используйте IPROTO_STMT_ID (0x43) и" -" ID оператора (MP_INT), при работе со строками SQL — IPROTO_SQL_TEXT (0x40) " -"и текст оператора (MP_STR), а затем IPROTO_SQL_BIND (0x41) и массив значений" -" параметров для подстановочных знаков ``?`` или ``:name``, IPROTO_OPTIONS " -"(0x2b) и массив параметров (обычно пустой)." - -msgid "" -"For example, suppose we prepare a statement with two ? placeholders, and " -"execute with two parameters, thus: |br| :code:`n = conn:prepare([[VALUES (?," -" ?);]])` |br| :code:`conn:execute(n.stmt_id, {1,'a'})` |br| Then the body " -"will look like this:" -msgstr "" -"Например, предположим, что мы создаем подготовленный оператор с двумя " -"подстановочными знаками ? и выполняем его с двумя параметрами таким образом:" -" |br| :code:`n = conn:prepare([[VALUES (?, ?);]])` |br| " -":code:`conn:execute(n.stmt_id, {1,'a'})` |br| Тогда тело сообщения будет " -"выглядеть так:" - -msgid "" -"# \n" -"msgpack({\n" -" IPROTO_STMT_ID: 0xd7aa741b,\n" -" IPROTO_SQL_BIND: [1, 'a'],\n" -" IPROTO_OPTIONS: []\n" -"})" -msgstr "" -"# \n" -"msgpack({\n" -" IPROTO_STMT_ID: 0xd7aa741b,\n" -" IPROTO_SQL_BIND: [1, 'a'],\n" -" IPROTO_OPTIONS: []\n" -"})" - -msgid "" -"Later in :ref:`Binary protocol -- illustration ` " -"we will show actual byte codes of the IPROTO_EXECUTE message." -msgstr "" -"Далее в разделе :ref:`Примеры ` будут рассмотрены" -" байт-коды сообщения IPROTO_EXECUTE." - -msgid "" -"To call a prepared statement with named parameters from a connector pass the" -" parameters within an array of maps. A client should wrap each element into " -"a map, where the key holds a name of the parameter (with a colon) and the " -"value holds an actual value. So, to bind foo and bar to 42 and 43, a client " -"should send ``IPROTO_SQL_TEXT: <...>, IPROTO_SQL_BIND: [{\"foo\": 42}, " -"{\"bar\": 43}]``." -msgstr "" -"Чтобы вызвать подготовленный оператор с именованными параметрами из " -"коннектора, передайте параметры в массиве ассоциативных массивов. Клиент " -"должен поместить каждый элемент в ассоциативный массив, где ключ содержит " -"имя параметра (с двоеточием), а значение — фактическое значение. Так, чтобы " -"связать foo и bar с 42 и 43, клиент должен отправить ``IPROTO_SQL_TEXT: " -"<...>, IPROTO_SQL_BIND: [{\"foo\": 42}, {\"bar\": 43}]``." - -msgid "" -"If a statement has both named and non-named parameters, wrap only named ones" -" into a map. The rest of the parameters are positional and will be " -"substituted in order." -msgstr "" -"Если оператор содержит как именованные, так и неименованные параметры, " -"поместите в ассоциативный массив только именованные параметры. Остальные " -"параметры являются позиционными и будут подставляться по порядку." - -msgid "IPROTO_NOP = 0x0c" -msgstr "IPROTO_NOP = 0x0c" - -msgid "" -"There is no Lua request exactly equivalent to IPROTO_NOP. It causes the LSN " -"to be incremented. It could be sometimes used for updates where the old and " -"new values are the same, but the LSN must be increased because a data-change" -" must be recorded. The body is: nothing." -msgstr "" -"Нет такого запроса на Lua, который бы соответствовал IPROTO_NOP. IPROTO_NOP " -"приводит к увеличению LSN. Иногда константу можно использовать для " -"обновления значения, когда старое и новое значения одинаковы, но LSN нужно " -"увеличить, поскольку нужно зарегистрировать изменение данных. Тело сообщения" -" пустое." - -msgid "IPROTO_PREPARE = 0x0d" -msgstr "IPROTO_PREPARE = 0x0d" - -msgid "" -"See :ref:`box.prepare `, this is only for SQL. The body" -" is a 1-item map:" -msgstr "" -"См. :ref:`box.prepare `, используется только для SQL. " -"Тело сообщения представляет собой ассоциативный массив из 1 элемента:" - -msgid "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_PREPARE,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_STMT_ID: :samp:`{{MP_INT integer}}` or IPROTO_SQL_TEXT: :samp:`{{MP_STR string}}`\n" -"})" -msgstr "" -"# \n" -"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_PREPARE,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})\n" -"# \n" -"msgpack({\n" -" IPROTO_STMT_ID: :samp:`{{MP_INT integer}}` или IPROTO_SQL_TEXT: :samp:`{{MP_STR string}}`\n" -"})" - -msgid "" -"IPROTO_STMT_ID (0x43) and statement-id (MP_INT) if executing a prepared " -"statement or IPROTO_SQL_TEXT (0x40) and statement-text (string) if executing" -" an SQL string. Thus the IPROTO_PREPARE map item is the same as the first " -"item of the :ref:`IPROTO_EXECUTE ` body." -msgstr "" -"При выполнении подготовленного оператора используйте IPROTO_STMT_ID (0x43) и" -" ID оператора (MP_INT), при работе со строками SQL --- IPROTO_SQL_TEXT " -"(0x40) и текст оператора (string). Таким образом, элемент ассоциативного " -"массива IPROTO_PREPARE — это то же самое, что и первый элемент тела " -"сообщения :ref:`IPROTO_EXECUTE `." - -msgid "IPROTO_PING = 0x40" -msgstr "IPROTO_PING = 0x40" - -msgid "" -"See :ref:`conn:ping() `. The body will be an empty map because " -"IPROTO_PING in the header contains all the information that the server " -"instance needs." -msgstr "" -"См. :ref:`conn:ping() `. В теле сообщения будет пустой " -"ассоциативный массив, потому что IPROTO_PING в заголовке содержит всю " -"информацию, необходимую экземпляру сервера." - -msgid "" -"# \n" -"msgpack(5)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_PING,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})" -msgstr "" -"# \n" -"msgpack(5)\n" -"#
\n" -"msgpack({\n" -" IPROTO_REQUEST_TYPE: IPROTO_PING,\n" -" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" -"})" - -msgid "" -"IPROTO_JOIN = 0x41 -- for replication\n" -"IPROTO_SUBSCRIBE = 0x42 -- for replication SUBSCRIBE\n" -"IPROTO_VOTE_DEPRECATED = 0x43 -- for old style vote, superseded by IPROTO_VOTE\n" -"IPROTO_VOTE = 0x44 -- for master election\n" -"IPROTO_FETCH_SNAPSHOT = 0x45 -- for starting anonymous replication\n" -"IPROTO_REGISTER = 0x46 -- for leaving anonymous replication." -msgstr "" -"IPROTO_JOIN = 0x41 — для репликации\n" -"IPROTO_SUBSCRIBE = 0x42 — для репликации SUBSCRIBE\n" -"IPROTO_VOTE_DEPRECATED = 0x43 — для устаревшего типа голосования, взамен используется IPROTO_VOTE\n" -"IPROTO_VOTE = 0x44 — для выбора мастера\n" -"IPROTO_FETCH_SNAPSHOT = 0x45 — для начала анонимной репликации\n" -"IPROTO_REGISTER = 0x46 — для выхода из анонимной репликации" - -msgid "" -"Tarantool constants 0x41 to 0x46 (decimal 65 to 70) are for replication. " -"Connectors and clients do not need to send replication packets. See " -":ref:`Binary protocol -- replication `." -msgstr "" -"Константы Tarantool 0x41–0x46 (в десятичной системе 65-70) предназначены для" -" репликации. Коннекторы и клиенты не должны отправлять репликационные " -"пакеты. См. раздел о :ref:`репликации `." - -msgid "" -"The next two IPROTO messages are used in replication connections between " -"Tarantool nodes in :ref:`synchronous replication `. The messages " -"are not supposed to be used by any client applications in their regular " -"connections." -msgstr "" -"Следующие два сообщения IPROTO используются в соединениях репликации между " -"узлами Tarantool при :ref:`синхронной репликации `. Эти сообщения" -" не должны использоваться клиентскими приложениями при обычном соединении." msgid "IPROTO_CONFIRM = 0x28" msgstr "IPROTO_CONFIRM = 0x28" @@ -1490,12 +656,12 @@ msgstr "" "структуры." msgid "" -"Example: if this is the fifth message and the request is " +"If this is the fifth message and the request is " ":codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:insert{6}`, " "and the previous schema version was 100, a successful response will look " "like this:" msgstr "" -"Пример: если это пятое сообщение, запрос такой: " +"Если это пятое сообщение, запрос такой: " ":codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:insert{6}`, и " "предыдущая версия схемы была 100, ответ после успешного выполнения будет " "выглядеть следующим образом:" @@ -1607,12 +773,12 @@ msgstr "" "определяют шестнадцатеричные константы для кодов возврата." msgid "" -"Example: in version 2.4.0 and earlier, if this is the fifth message and the " +"In version 2.4.0 and earlier, if this is the fifth message and the " "request is to create a duplicate space with " "``conn:eval([[box.schema.space.create('_space');]])`` the unsuccessful " "response will look like this:" msgstr "" -"Пример: в версии 2.4.0 и раньше, если это пятое сообщение и отправляется " +"В версии 2.4.0 и раньше, если это пятое сообщение и отправляется " "запрос на создание дубликата спейса с помощью " "``conn:eval([[box.schema.space.create('_space');]])``, то ответ на " "невыполненный запрос будет выглядеть следующим образом:" @@ -1821,13 +987,13 @@ msgstr "" ":samp:`IPROTO_DATA:{array of tuples}` = строки результирующего набора." msgid "" -"Example: If we ask for full metadata by saying |br| " +"If we ask for full metadata by saying |br| " ":code:`conn.space._session_settings:update('sql_full_metadata', {{'=', " "'value', true}})` |br| and we select the two rows from a table named t1 that" " has columns named DD and Д, with |br| :code:`conn:execute([[SELECT dd, дд " "AS д FROM t1;]])` |br| we could get this response, in the body:" msgstr "" -"Пример: Если мы запросим полные метаданные, вызвав |br| " +"Если мы запросим полные метаданные, вызвав |br| " ":code:`conn.space._session_settings:update('sql_full_metadata', {{'=', " "'value', true}})` |br| и выберем две строки из таблицы t1, в которой есть " "столбцы DD и Д, с помощью |br| :code:`conn:execute([[SELECT dd, дд AS д FROM" @@ -1944,6 +1110,7 @@ msgid "" msgstr "" "Далее в разделе :ref:`Примеры ` будут рассмотрены" " байт-коды ответов на вышеприведенные SQL сообщения." +<<<<<<< HEAD msgid "Authentication" msgstr "Аутентификация" @@ -2098,6 +1265,7 @@ msgstr "" "`netbox_encode_auth`` в файле `net_box.c " "`_." +<<<<<<< HEAD msgid "Binary protocol -- streams" msgstr "Бинарный протокол — стримы" @@ -3052,6 +2220,8 @@ msgstr "" "81 2-й элемент Sub-Map: MP_MAP, размер 1\n" "01 MP_UINT = 1 = id (1-я часть vclock)\n" "06 MP_UINT = 6 = lsn (2-я часть vclock)" +======= +>>>>>>> Outline initial structure msgid "XLOG / SNAP" msgstr "XLOG / SNAP" @@ -3122,3 +2292,5 @@ msgid "" "section." msgstr "" "См. пример в разделе :ref:`Форматы файлов `." +======= +>>>>>>> Split most box_protocol content and add TODOs diff --git a/locale/ru/LC_MESSAGES/dev_guide/internals/file_formats.po b/locale/ru/LC_MESSAGES/dev_guide/internals/file_formats.po index 5049252ae5..6cc8a0d499 100644 --- a/locale/ru/LC_MESSAGES/dev_guide/internals/file_formats.po +++ b/locale/ru/LC_MESSAGES/dev_guide/internals/file_formats.po @@ -255,3 +255,68 @@ msgid "" "space id." msgstr "" "Во вторую очередь записи в .snap-файле упорядочены по первичному ключу." + + +msgid "XLOG / SNAP" +msgstr "XLOG / SNAP" + +msgid "" +"The header of a ``.snap`` or ``.xlog`` file looks like:" +msgstr "" +"Файлы форматов .xlog и .snap выглядят практически одинаково. Заголовок " +"выглядит так:" + +msgid "" +"\\n SNAP\\n or XLOG\\n\n" +"\\n currently 0.13\\n\n" +"Server: \\n where UUID is a 36-byte string\n" +"VClock: \\n e.g. {1: 0}\\n\n" +"\\n" +msgstr "" +"\\n SNAP\\n или XLOG\\n\n" +"\\n в данный момент 0.13\\n\n" +"Server: \\n где UUID -- это 36-байтная строка\n" +"VClock: \\n например, {1: 0}\\n\n" +"\\n" + +msgid "" +"After the file header come the data tuples. Tuples begin with a row marker " +"``0xd5ba0bab`` and the last tuple may be followed by an EOF marker " +"``0xd510aded``. Thus, between the file header and the EOF marker, there may " +"be data tuples that have this form:" +msgstr "" +"После файла заголовка идут кортежи с данными. Кортежи начинаются с маркера " +"строки ``0xd5ba0bab``, а после последнего кортежа может стоять маркер конца " +"файла ``0xd510aded``. Таким образом, между заголовком файла и маркером конца" +" файла могут быть кортежи с данными в следующем виде:" + +msgid "" +"0 3 4 17\n" +"+-------------+========+============+===========+=========+\n" +"| | | | | |\n" +"| 0xd5ba0bab | LENGTH | CRC32 PREV | CRC32 CUR | PADDING |\n" +"| | | | | |\n" +"+-------------+========+============+===========+=========+\n" +" MP_FIXEXT2 MP_INT MP_INT MP_INT ---\n" +"\n" +"+============+ +===================================+\n" +"| | | |\n" +"| HEADER | | BODY |\n" +"| | | |\n" +"+============+ +===================================+\n" +" MP_MAP MP_MAP" +msgstr "" +"0 3 4 17\n" +"+-------------+========+============+===========+=========+\n" +"| | | | | |\n" +"| 0xd5ba0bab | LENGTH | CRC32 PREV | CRC32 CUR | PADDING |\n" +"| | | | | |\n" +"+-------------+========+============+===========+=========+\n" +" MP_FIXEXT2 MP_INT MP_INT MP_INT ---\n" +"\n" +"+============+ +===================================+\n" +"| | | |\n" +"| HEADER | | BODY |\n" +"| | | |\n" +"+============+ +===================================+\n" +" MP_MAP MP_MAP" diff --git a/locale/ru/LC_MESSAGES/dev_guide/internals/iproto/authentication.po b/locale/ru/LC_MESSAGES/dev_guide/internals/iproto/authentication.po new file mode 100644 index 0000000000..b81bddffa3 --- /dev/null +++ b/locale/ru/LC_MESSAGES/dev_guide/internals/iproto/authentication.po @@ -0,0 +1,158 @@ + +msgid "Authentication" +msgstr "Аутентификация" + +msgid "Greeting message" +msgstr "Приветствие" + +msgid "" +"When a client connects to the server instance, the instance responds with a " +"128-byte text greeting message, not in MsgPack format:" +msgstr "" +"Когда клиент подключается к экземпляру сервера, тот выдает в ответе " +"128-байтовое текстовое сообщение приветствия не в формате MsgPack:" + + +msgid "For example:" +msgstr "Пример:" + +msgid "" +"The greeting contains two 64-byte lines of ASCII text. Each line ends with a" +" newline character (:code:`\\n`). If the line content is less than 64 bytes long," +" the rest of the line is filled up with symbols with an ASCII code of 0 that aren't displayed in the console." +msgstr "" +"Приветствие содержит две 64-байтные строки текста в формате ASCII. Каждая " +"строка заканчивается символом разрыва строки (:code:`\\n`). Если длина содержимого строки " +"менее 64 байтов, то оставшееся место заполняется символами с ASCII-кодом 0. " +"В консоли эти символы не отображаются." + +msgid "The first line contains the instance " +"version and protocol type. The second line contains the session salt -- " +"a base64-encoded random string, which is usually 44 bytes long." +" The salt is used in the authentication packet." +msgstr "Первая строка " +"описывает версию экземпляра и тип протокола. Вторая строка содержит соль сеанса -- " +"случайную строку в кодировке base-64, обычно длиной 44 байта. Соль используется " +"в пакете аутентификации." + +msgid "" +"Part of the greeting is a base64-encoded session salt - a random string " +"which can be used for authentication. The maximum length of an encoded salt " +"(44 bytes) is more than the amount necessary to create the authentication " +"message. An excess is reserved for future authentication schemas." +msgstr "" +"Часть приветствия представляет собой закодированное в формате base-64 " +"значение соль для сессии (случайная строка), которое можно использовать для " +"аутентификации. Максимальная длина закодированного значения соль (44 байта) " +"больше, чем размер создаваемого сообщения аутентификации. Остаток " +"предназначается для будущих схем аутентификации." + +msgid "" +"Authentication is optional -- if it is skipped, then the session user is " +"``'guest'`` (the ``'guest'`` user does not need a password)." +msgstr "" +"Аутентификация необязательна: если аутентификация не проводится, то " +"пользователем в сеансе будет ``'guest'`` (пользователю ``'guest'`` пароль не" +" нужен)." + +msgid "" +"If authentication is not skipped, then at any time an authentication packet " +"can be prepared using the greeting, the user's name and password, and `sha-1" +" `_ functions, as follows." +msgstr "" +"Если аутентификация проводится, то в любое время может быть подготовлен " +"пакет аутентификации с использованием приветствия, имени и пароля " +"пользователя и функции `sha-1 `_, как " +"показано ниже." + +msgid "" +"PREPARE SCRAMBLE:\n" +"\n" +" size_of_encoded_salt_in_greeting = 44;\n" +" size_of_salt_after_base64_decode = 32;\n" +" /* sha1() will only use the first 20 bytes */\n" +" size_of_any_sha1_digest = 20;\n" +" size_of_scramble = 20;\n" +"\n" +"prepare 'chap-sha1' scramble:\n" +"\n" +" salt = base64_decode(encoded_salt);\n" +" step_1 = sha1(password);\n" +" step_2 = sha1(step_1);\n" +" step_3 = sha1(first_20_bytes_of_salt, step_2);\n" +" scramble = xor(step_1, step_3);\n" +" return scramble;" +msgstr "" +"PREPARE SCRAMBLE:\n" +"\n" +" size_of_encoded_salt_in_greeting = 44;\n" +" size_of_salt_after_base64_decode = 32;\n" +" /* sha1() will only use the first 20 bytes */\n" +" size_of_any_sha1_digest = 20;\n" +" size_of_scramble = 20;\n" +"\n" +"prepare 'chap-sha1' scramble:\n" +"\n" +" salt = base64_decode(encoded_salt);\n" +" step_1 = sha1(password);\n" +" step_2 = sha1(step_1);\n" +" step_3 = sha1(first_20_bytes_of_salt, step_2);\n" +" scramble = xor(step_1, step_3);\n" +" return scramble;" + +msgid "The client sends an authentication packet as an IPROTO_AUTH message:" +msgstr "Клиент отправляет пакет аутентификации в виде сообщения IPROTO_AUTH:" + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_AUTH,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer, usually = 1}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_USER_NAME: :samp:`{{MP_STRING string }}`,\n" +" IPROTO_TUPLE: ['chap-sha1', :samp:`{{MP_STRING 20-byte string}}`]\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_AUTH,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer, usually = 1}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_USER_NAME: :samp:`{{MP_STRING string }}`,\n" +" IPROTO_TUPLE: ['chap-sha1', :samp:`{{MP_STRING 20-byte string}}`]\n" +"})" + +msgid "" +":code:`` holds the user name. :code:`` must be an array of 2 " +"fields: authentication mechanism (\"chap-sha1\" is the only supported " +"mechanism right now) and scramble, encrypted according to the specified " +"mechanism." +msgstr "" +":code:`` содержит имя пользователя. :code:`` должен представлять" +" собой массив из 2 полей: механизм аутентификации (на данный момент " +"поддерживается только механизм \"chap-sha1\") и сообщение, зашифрованное в " +"соответствии с указанным механизмом." + +msgid "" +"The server instance responds to an authentication packet with a standard " +"response with 0 tuples." +msgstr "" +"На пакет аутентификации экземпляр сервера отправляет стандартный ответ с 0 " +"кортежей." + +msgid "" +"To see how Tarantool handles this, look at `net_box.c " +"`_" +" function ``netbox_encode_auth``." +msgstr "" +"Чтобы понять, как Tarantool это обрабатывает, обратите внимание на функцию " +"`netbox_encode_auth`` в файле `net_box.c " +"`_." diff --git a/locale/ru/LC_MESSAGES/dev_guide/internals/iproto/replication.po b/locale/ru/LC_MESSAGES/dev_guide/internals/iproto/replication.po new file mode 100644 index 0000000000..c0e6154d9d --- /dev/null +++ b/locale/ru/LC_MESSAGES/dev_guide/internals/iproto/replication.po @@ -0,0 +1,342 @@ + +msgid "Replication" +msgstr "Репликация" + + +msgid "" +"IPROTO_JOIN = 0x41 -- for replication\n" +"IPROTO_SUBSCRIBE = 0x42 -- for replication SUBSCRIBE\n" +"IPROTO_VOTE_DEPRECATED = 0x43 -- for old style vote, superseded by IPROTO_VOTE\n" +"IPROTO_VOTE = 0x44 -- for master election\n" +"IPROTO_FETCH_SNAPSHOT = 0x45 -- for starting anonymous replication\n" +"IPROTO_REGISTER = 0x46 -- for leaving anonymous replication." +msgstr "" +"IPROTO_JOIN = 0x41 — для репликации\n" +"IPROTO_SUBSCRIBE = 0x42 — для репликации SUBSCRIBE\n" +"IPROTO_VOTE_DEPRECATED = 0x43 — для устаревшего типа голосования, взамен используется IPROTO_VOTE\n" +"IPROTO_VOTE = 0x44 — для выбора мастера\n" +"IPROTO_FETCH_SNAPSHOT = 0x45 — для начала анонимной репликации\n" +"IPROTO_REGISTER = 0x46 — для выхода из анонимной репликации" + +msgid "" +"Tarantool constants 0x41 to 0x46 (decimal 65 to 70) are for replication. " +"Connectors and clients do not need to send replication packets. See " +":ref:`Binary protocol -- replication `." +msgstr "" +"Константы Tarantool 0x41–0x46 (в десятичной системе 65-70) предназначены для" +" репликации. Коннекторы и клиенты не должны отправлять репликационные " +"пакеты. См. раздел о :ref:`репликации `." + +msgid "" +"The next two IPROTO messages are used in replication connections between " +"Tarantool nodes in :ref:`synchronous replication `. The messages " +"are not supposed to be used by any client applications in their regular " +"connections." +msgstr "" +"Следующие два сообщения IPROTO используются в соединениях репликации между " +"узлами Tarantool при :ref:`синхронной репликации `. Эти сообщения" +" не должны использоваться клиентскими приложениями при обычном соединении." + + +msgid "IPROTO_JOIN = 0x41" +msgstr "IPROTO_JOIN = 0x41" + +msgid "First you must send an initial IPROTO_JOIN request." +msgstr "Сначала нужно отправить запрос IPROTO_JOIN." + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_JOIN,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_INSTANCE_UUID: :samp:`{{uuid}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_JOIN,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_INSTANCE_UUID: :samp:`{{uuid}}`\n" +"})" + +msgid "" +"Then the instance which you want to connect to will send its last SNAP file," +" by simply creating a number of INSERTs (with additional LSN and ServerID) " +"(do not reply to this). Then that instance will send a vclock's MP_MAP and " +"close a socket." +msgstr "" +"Затем экземпляр, к которому вы хотите подключиться, отправит свой последний " +"SNAP-файл, просто создав несколько запросов типа INSERT (с дополнительными " +"LSN и ServerID) (не отвечайте на них). Затем этот экземпляр отправит MP_MAP " +"vclock и закроет сокет." + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" Response-Code-Indicator: 0,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_VCLOCK: :samp:`{{MP_INT SRV_ID, MP_INT SRV_LSN}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" Response-Code-Indicator: 0,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_VCLOCK: :samp:`{{MP_INT SRV_ID, MP_INT SRV_LSN}}`\n" +"})" + +msgid "IPROTO_SUBSCRIBE = 0x42" +msgstr "IPROTO_SUBSCRIBE = 0x42" + +msgid "Then you must send an IPROTO_SUBSCRIBE request." +msgstr "Теперь нужно отправить запрос IPROTO_SUBSCRIBE." + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_SUBSCRIBE,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_INSTANCE_UUID: :samp:`{{uuid}}`,\n" +" IPROTO_CLUSTER_UUID: :samp:`{{uuid}}`,\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_VCLOCK: :samp:`{{MP_INT SRV_ID, MP_INT SRV_LSN}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_SUBSCRIBE,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_INSTANCE_UUID: :samp:`{{uuid}}`,\n" +" IPROTO_CLUSTER_UUID: :samp:`{{uuid}}`,\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_VCLOCK: :samp:`{{MP_INT SRV_ID, MP_INT SRV_LSN}}`\n" +"})" + +msgid "" +"Then you must process every request that could come through other masters. " +"Every request between masters will have additional LSN and SERVER_ID." +msgstr "" +"Затем нужно обработать каждый запрос, который может прийти через других " +"мастеров. В каждом запросе между мастерами будут дополнительные LSN и " +"SERVER_ID." + +msgid "HEARTBEATS" +msgstr "Контрольные сигналы" + +msgid "" +"Frequently a master sends a :ref:`heartbeat ` message to a " +"replica. For example, if there is a replica with id = 2, and a timestamp " +"with a moment in 2020, a master might send this:" +msgstr "" +"Часто мастер отправляет реплике сообщение :ref:`контрольного сигнала " +"`. Например, если есть реплика с ID = 2 и метка с моментом " +"времени в 2020 году, мастер может послать такое сообщение:" + +msgid "" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: 0\n" +" IPROTO_REPLICA_ID: 2\n" +" IPROTO_TIMESTAMP: :samp:`{{Float 64 MP_DOUBLE 8-byte timestamp}}`\n" +"})" +msgstr "" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: 0\n" +" IPROTO_REPLICA_ID: 2\n" +" IPROTO_TIMESTAMP: :samp:`{{Float 64 MP_DOUBLE 8-byte timestamp}}`\n" +"})" + +msgid "and the replica might send back this:" +msgstr "и реплика может отправить в ответ следующее:" + +msgid "" +"#
\n" +"msgpack({\n" +" Response-Code-Indicator: IPROTO_OK\n" +" IPROTO_REPLICA_ID: 2\n" +" IPROTO_VCLOCK: {1, 6}\n" +"})" +msgstr "" +"#
\n" +"msgpack({\n" +" Response-Code-Indicator: IPROTO_OK\n" +" IPROTO_REPLICA_ID: 2\n" +" IPROTO_VCLOCK: {1, 6}\n" +"})" + +msgid "" +"Later in :ref:`Binary protocol -- illustration ` " +"we will show actual byte codes of the above heartbeat examples." +msgstr "" +"Далее в разделе :ref:`Примеры ` будут рассмотрены" +" байт-коды вышеприведенных сообщений контрольного сигнала." + +msgid "BALLOTS" +msgstr "Сообщения с идентификатором BALLOT" + +msgid "" +"While connecting for replication, an instance sends a request with header " +"IPROTO_VOTE (0x44). The normal response is ER_OK,and IPROTO_BALLOT (0x29). " +"The fields within IPROTO_BALLOT are map items:" +msgstr "" +"При подключении для репликации экземпляр отправляет запрос с заголовком " +"IPROTO_VOTE (0x44). Обычно ответом будет ER_OK и IPROTO_BALLOT (0x29). Поля " +"в IPROTO_BALLOT — это элементы ассоциативного массива:" + +msgid "" +"IPROTO_BALLOT_IS_RO_CFG (0x01) + MP_BOOL\n" +"IPROTO_BALLOT_VCLOCK (0x02) + vclock\n" +"IPROTO_BALLOT_GC_VCLOCK (0x03) + vclock\n" +"IPROTO_BALLOT_IS_RO (0x04) + MP_BOOL\n" +"IPROTO_BALLOT_IS_ANON = 0x05 + MP_BOOL\n" +"IPROTO_BALLOT_IS_BOOTED = 0x06 + MP_BOOL\n" +"IPROTO_BALLOT_CAN_LEAD = 0x07 + MP_BOOL" +msgstr "" + +msgid "" +"IPROTO_BALLOT_IS_RO_CFG and IPRO_BALLOT_VCLOCK and IPROTO_BALLOT_GC_VCLOCK " +"and IPROTO_BALLOT_IS_RO were added in version :doc:`2.6.1 `." +" IPROTO_BALLOT_IS_ANON was added in version :doc:`2.7.1 `. " +"IPROTO_BALLOT_IS_BOOTED was added in version 2.7.3 and 2.8.2 and 2.9.1. " +"There have been some name changes starting with version 2.7.3 and 2.8.2 and " +"2.9.1: IPROTO_BALLOT_IS_RO_CFG was formerly called IPROTO_BALLOT_IS_RO, and " +"IPROTO_BALLOT_IS_RO was formerly called IPROTO_BALLOT_IS_LOADING." +msgstr "" +"IPROTO_BALLOT_IS_RO_CFG, IPRO_BALLOT_VCLOCK, IPROTO_BALLOT_GC_VCLOCK и " +"IPROTO_BALLOT_IS_RO добавлены в версии :doc:`2.6.1 `. " +"Константа IPROTO_BALLOT_IS_ANON добавлена в версии :doc:`2.7.1 " +"`. Константа IPROTO_BALLOT_IS_BOOTED добавлена в версиях " +"2.7.3, 2.8.2 и 2.9.1. В версиях 2.7.3, 2.8.2, 2.9.1 и более поздних " +"константа IPROTO_BALLOT_IS_RO переименована в IPROTO_BALLOT_IS_RO_CFG, а " +"IPROTO_BALLOT_IS_LOADING — в IPROTO_BALLOT_IS_RO." + +msgid "" +"IPROTO_BALLOT_IS_RO_CFG corresponds to :ref:`box.cfg.read_only `." +msgstr "" +"Значение IPROTO_BALLOT_IS_RO_CFG соответствует значению " +":ref:`box.cfg.read_only `." + +msgid "" +"IPROTO_BALLOT_GC_VCLOCK can be the vclock value of the instance's oldest WAL" +" entry, which corresponds to :ref:`box.info.gc().vclock `." +msgstr "" +"IPROTO_BALLOT_GC_VCLOCK может принимать значение vclock самой старой записи " +"журнала WAL на экземпляре. Это соответствует значению " +":ref:`box.info.gc().vclock `." + +msgid "" +"IPROTO_BALLOT_IS_RO is true if the instance is not writable, which may " +"happen for a variety of reasons, such as: it was configured as " +":ref:`read_only `, or it has :ref:`orphan status " +"`, or it is a :ref:`Raft ` " +"follower." +msgstr "" +"IPROTO_BALLOT_IS_RO принимает значение ``true``, если экземпляр недоступен " +"для записи. Причины у этого могут быть разные: например, экземпляр настроен " +"как :ref:`read_only `, :ref:`имеет статус orphan " +"` или является последователем (follower) при " +":ref:`выполнении алгоритма Raft `." + +msgid "" +"IPROTO_BALLOT_IS_ANON corresponds to :ref:`box.cfg.replication_anon " +"`." +msgstr "" +"Значение IPROTO_BALLOT_IS_ANON соответствует значению " +":ref:`box.cfg.replication_anon `." + +msgid "" +"IPROTO_BALLOT_IS_BOOTED is true if the instance has finished its bootstrap " +"or recovery process." +msgstr "" +"IPROTO_BALLOT_IS_BOOTED принимает значение ``true``, если экземпляр завершил" +" инициализацию или восстановление." + +msgid "" +"IPROTO_BALLOT_CAN_LEAD is true if the :ref:`election_mode ` configuration setting is either 'candidate' or 'manual', so " +"that during the :ref:`leader election process ` " +"this instance may be preferred over instances whose configuration setting is" +" 'voter'. IPROTO_BALLOT_CAN_LEAD support was added simultaneously in version" +" :doc:`2.7.3 ` and version :doc:`2.8.2 `." +msgstr "" + +msgid "FLAGS" +msgstr "Сообщения с идентификатором FLAG" + +msgid "" +"For replication of :doc:`synchronous transactions " +"` a header may contain a key = IPROTO_FLAGS and" +" an MP_UINT value = one or more bits: IPROTO_FLAG_COMMIT or " +"IPROTO_FLAG_WAIT_SYNC or IPROTO_FLAG_WAIT_ACK." +msgstr "" +"При репликации :doc:`синхронных транзакций ` " +"заголовок может содержать ключ = IPROTO_FLAGS и значение MP_UINT = один или " +"несколько битов: IPROTO_FLAG_COMMIT, IPROTO_FLAG_WAIT_SYNC или " +"IPROTO_FLAG_WAIT_ACK." + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" # ... other header items ...,\n" +" IPROTO_FLAGS: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" # ... message for a transaction ...\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" # ... другие элементы заголовка ...,\n" +" IPROTO_FLAGS: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" # ... message for a transaction ...\n" +"})" + +msgid "" +"IPROTO_FLAG_COMMIT (0x01) will be set if this is the last message for a " +"transaction, IPROTO_FLAG_WAIT_SYNC (0x02) will be set if this is the last " +"message for a transaction which cannot be completed immediately, " +"IPROTO_FLAG_WAIT_ACK (0x04) will be set if this is the last message for a " +"synchronous transaction." +msgstr "" +"IPROTO_FLAG_COMMIT (0x01) указывает на последнее сообщение для транзакции. " +"IPROTO_FLAG_WAIT_SYNC (0x02) указывает на последнее сообщение для " +"транзакции, которую нельзя завершить немедленно. IPROTO_FLAG_WAIT_ACK (0x04)" +" указывает на последнее сообщение для синхронной транзакции." diff --git a/locale/ru/LC_MESSAGES/dev_guide/internals/iproto/requests.po b/locale/ru/LC_MESSAGES/dev_guide/internals/iproto/requests.po new file mode 100644 index 0000000000..fecaf95c56 --- /dev/null +++ b/locale/ru/LC_MESSAGES/dev_guide/internals/iproto/requests.po @@ -0,0 +1,814 @@ + +msgid "Requests" +msgstr "Запросы" + +msgid "" +"A request has a size, a :ref:`header ` that contains " +"the IPROTO key, and a body as described here." +msgstr "" +"Запрос содержит размер, :ref:`заголовок `, который " +"содержит ключ IPROTO, и тело сообщения, как описано в этом разделе." + +msgid "IPROTO_SELECT = 0x01" +msgstr "IPROTO_SELECT = 0x01" + +msgid "" +"See :ref:`space_object:select() `. The body is a 6-item " +"map." +msgstr "" +"См. :ref:`space_object:select() `. Тело сообщения " +"представляет собой ассоциативный массив из 6 элементов." + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_SELECT,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_LIMIT: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_OFFSET: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_ITERATOR: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_KEY: :samp:`{{MP_ARRAY array of key values}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_SELECT,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_LIMIT: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_OFFSET: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_ITERATOR: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_KEY: :samp:`{{MP_ARRAY array of key values}}`\n" +"})" + +msgid "Example" +msgstr "Пример" + +msgid "" +"If the id of 'tspace' is 512 and this is the fifth message, |br| " +":samp:`{conn}.`:code:`space.tspace:select({0},{iterator='GT',offset=1,limit=2})`" +" will cause:" +msgstr "" +"Если ID спейса 'tspace' = 512 и это пятое сообщение, |br| " +":samp:`{conn}.`:code:`space.tspace:select({0},{iterator='GT',offset=1,limit=2})`" +" вызовет:" + +msgid "" +"\n" +"msgpack(21)\n" +"#
\n" +"msgpack({\n" +" IPROTO_SYNC: 5,\n" +" IPROTO_REQUEST_TYPE: IPROTO_SELECT\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: 512,\n" +" IPROTO_INDEX_ID: 0,\n" +" IPROTO_ITERATOR: 6,\n" +" IPROTO_OFFSET: 1,\n" +" IPROTO_LIMIT: 2,\n" +" IPROTO_KEY: [1]\n" +"})" +msgstr "" +"\n" +"msgpack(21)\n" +"#
\n" +"msgpack({\n" +" IPROTO_SYNC: 5,\n" +" IPROTO_REQUEST_TYPE: IPROTO_SELECT\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: 512,\n" +" IPROTO_INDEX_ID: 0,\n" +" IPROTO_ITERATOR: 6,\n" +" IPROTO_OFFSET: 1,\n" +" IPROTO_LIMIT: 2,\n" +" IPROTO_KEY: [1]\n" +"})" + +msgid "" +"In the :ref:`examples `, " +"you can find actual byte codes of an IPROTO_SELECT message." +msgstr "" +"Байт-коды сообщения IPROTO_SELECT рассмотрены в разделе :ref:`Примеры `. + + +msgid "IPROTO_INSERT = 0x02" +msgstr "IPROTO_INSERT = 0x02" + +msgid "" +"See :ref:`space_object:insert() `. The body is a 2-item " +"map:" +msgstr "" +"См. :ref:`space_object:insert() `. Тело сообщения " +"представляет собой ассоциативный массив из 2 элементов:" + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_INSERT,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of field values}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_INSERT,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of field values}}`\n" +"})" + +msgid "" +"If the id of 'tspace' is 512 and this is the fifth message, |br| " +":samp:`{conn}.`:code:`space.tspace:insert{1, 'AAA'}` will cause:" +msgstr "" +"Если ID спейса 'tspace' = 512 и это пятое сообщение, |br| " +":samp:`{conn}.`:code:`space.tspace:insert{1, 'AAA'}` вызовет:" + +msgid "" +"# \n" +"msgpack(17)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_INSERT,\n" +" IPROTO_SYNC: 5\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: 512,\n" +" IPROTO_TUPLE: [1, 'AAA']\n" +"})" +msgstr "" +"# \n" +"msgpack(17)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_INSERT,\n" +" IPROTO_SYNC: 5\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: 512,\n" +" IPROTO_TUPLE: [1, 'AAA']\n" +"})" + +msgid "IPROTO_REPLACE = 0x03" +msgstr "IPROTO_REPLACE = 0x03" + +msgid "" +"See :ref:`space_object:replace() `. The body is a 2-item" +" map, the same as for IPROTO_INSERT:" +msgstr "" +"См. :ref:`space_object:replace() `. Тело сообщения " +"представляет собой ассоциативный массив из 2 элементов, как и в случае " +"IPROTO_INSERT:" + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_REPLACE,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of field values}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_REPLACE,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of field values}}`\n" +"})" + +msgid "IPROTO_UPDATE = 0x04" +msgstr "IPROTO_UPDATE = 0x04" + +msgid "See :ref:`space_object:update() `." +msgstr "См. :ref:`space_object:update() `." + +msgid "The body is usually a 4-item map:" +msgstr "" +"Тело сообщения обычно представляет собой ассоциативный массив из 4 " +"элементов:" + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_UPDATE,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_KEY: :samp:`{{MP_ARRAY array of index keys}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of update operations}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_UPDATE,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_KEY: :samp:`{{MP_ARRAY array of index keys}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of update operations}}`\n" +"})" + +msgid "" +"If the operation specifies no values, then IPROTO_TUPLE is a 2-item array: " +"|br| :samp:`[{MP_STR OPERATOR = '#', {MP_INT FIELD_NO = field number " +"starting with 1}]`. Normally field numbers start with 1." +msgstr "" +"Если в операции не указаны значения, то IPROTO_TUPLE — это массив из 2 " +"элементов: |br| :samp:`[{MP_STR OPERATOR = '#', {MP_INT FIELD_NO = номер " +"поля, начиная с 1}]`. Обычно номера полей начинаются с 1." + +msgid "" +"If the operation specifies one value, then IPROTO_TUPLE is a 3-item array: " +"|br| :samp:`[{MP_STR string OPERATOR = '+' or '-' or '^' or '^' or '|' or " +"'!' or '='}, {MP_INT FIELD_NO}, {MP_OBJECT VALUE}]`. |br|" +msgstr "" +"Если в операции задано одно значение, то IPROTO_TUPLE — это массив из трех " +"элементов: |br| :samp:`[{MP_STR string OPERATOR = '+' or '-' or '^' or '^' " +"or '|' or '!' or '='}, {MP_INT FIELD_NO}, {MP_OBJECT VALUE}]`. |br|" + +msgid "" +"Otherwise IPROTO_TUPLE is a 5-item array: |br| :samp:`[{MP_STR string " +"OPERATOR = ':'}, {MP_INT integer FIELD_NO}, {MP_INT POSITION}, {MP_INT " +"OFFSET}, {MP_STR VALUE}]`. |br|" +msgstr "" +"В остальных случаях IPROTO_TUPLE — это массив из 5 элементов: |br| " +":samp:`[{MP_STR string OPERATOR = ':'}, {MP_INT integer FIELD_NO}, {MP_INT " +"POSITION}, {MP_INT OFFSET}, {MP_STR VALUE}]`. |br|" + +msgid "" +"If the id of 'tspace' is 512 and this is the fifth message, |br| " +":samp:`{conn}.`:code:`space.tspace:update(999, {{'=', 2, 'B'}})` will cause:" +msgstr "" +"Если ID спейса 'tspace' = 512 и это пятое сообщение, br| " +":samp:`{conn}.`:code:`space.tspace:update(999, {{'=', 2, 'B'}})` вызовет:" + +msgid "" +"# \n" +"msgpack(17)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_UPDATE,\n" +" IPROTO_SYNC: 5\n" +"})\n" +"# ... the map-item IPROTO_INDEX_BASE is optional\n" +"msgpack({\n" +" IPROTO_SPACE_ID: 512,\n" +" IPROTO_INDEX_ID: 0,\n" +" IPROTO_INDEX_BASE: 1,\n" +" IPROTO_TUPLE: [['=',2,'B']],\n" +" IPROTO_KEY: [999]\n" +"})" +msgstr "" +"# \n" +"msgpack(17)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_UPDATE,\n" +" IPROTO_SYNC: 5\n" +"})\n" +"# ... the map-item IPROTO_INDEX_BASE is optional\n" +"msgpack({\n" +" IPROTO_SPACE_ID: 512,\n" +" IPROTO_INDEX_ID: 0,\n" +" IPROTO_INDEX_BASE: 1,\n" +" IPROTO_TUPLE: [['=',2,'B']],\n" +" IPROTO_KEY: [999]\n" +"})" + +msgid "" +"Later in :ref:`Binary protocol -- illustration ` " +"we will show actual byte codes of an IPROTO_UPDATE message." +msgstr "" +"Далее в разделе :ref:`Примеры ` будут рассмотрены" +" байт-коды сообщения IPROTO_UPDATE." + +msgid "IPROTO_DELETE = 0x05" +msgstr "IPROTO_DELETE = 0x05" + +msgid "" +"See :ref:`space_object:delete() `. The body is a 3-item " +"map:" +msgstr "" +"См. :ref:`space_object:delete() `. Тело сообщения " +"представляет собой ассоциативный массив из 3 элементов:" + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_DELETE,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_KEY: :samp:`{{MP_ARRAY array of key values}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_DELETE,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_INDEX_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_KEY: :samp:`{{MP_ARRAY array of key values}}`\n" +"})" + + +msgid "IPROTO_UPSERT = 0x09" +msgstr "IPROTO_UPSERT = 0x09" + +msgid "See :ref:`space_object:upsert() `." +msgstr "См. :ref:`space_object:upsert() `." + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_UPSERT,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_INDEX_BASE: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_OPS: :samp:`{{MP_ARRAY array of update operations}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of primary-key field values}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_UPSERT,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_SPACE_ID: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_INDEX_BASE: :samp:`{{MP_UINT unsigned integer}}`,\n" +" IPROTO_OPS: :samp:`{{MP_ARRAY array of update operations}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of primary-key field values}}`\n" +"})" + +msgid "" +"The IPROTO_OPS is the same as the IPROTO_TUPLE of :ref:`IPROTO_UPDATE " +"`." +msgstr "" +"IPROTO_OPS — это то же самое, что и IPROTO_TUPLE в :ref:`IPROTO_UPDATE " +"`." + + +msgid "IPROTO_CALL = 0x0a" +msgstr "IPROTO_CALL = 0x0a" + +msgid "See :ref:`conn:call() `. The body is a 2-item map:" +msgstr "" +"См. :ref:`conn:call() `. Тело сообщения представляет собой " +"ассоциативный массив из 2 элементов:" + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_CALL,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_FUNCTION_NAME: :samp:`{{MP_STR string}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_CALL,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_FUNCTION_NAME: :samp:`{{MP_STR string}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}`\n" +"})" + +msgid "" +"The response will be a list of values, similar to the :ref:`IPROTO_EVAL " +"` response." +msgstr "" +"Вернется список значений, наподобие ответа :ref:`IPROTO_EVAL `." + + +msgid "" +"The ```` has the details of the request or response. In a request, it " +"can also be absent or be an empty map. Both these states will be interpreted" +" equally. Responses will contain the ```` anyway even for an " +":ref:`IPROTO_PING ` request." +msgstr "" +"Тело сообщения ```` содержит детали запроса или ответа. В запросе оно " +"может отсутствовать или представлять собой пустой ассоциативный массив. И " +"то, и другое будет интерпретироваться одинаково. Ответы будут содержать " +"```` в любом случае, даже после запроса :ref:`IPROTO_PING " +"`." +" + +msgid "IPROTO_CALL_16 = 0x06" +msgstr "IPROTO_CALL_16 = 0x06" + +msgid "" +"See :ref:`conn:call() `. The suffix ``_16`` is a hint that " +"this is for the ``call()`` until Tarantool 1.6. It is deprecated. Use " +":ref:`IPROTO_CALL ` instead. The body is a 2-item map:" +msgstr "" +"См. :ref:`conn:call() `. ``_16`` в конце подсказывает, что " +"константа используется для ``call()`` до версии Tarantool 1.6. Эта константа" +" объявлена устаревшей. Вместо нее используйте :ref:`IPROTO_CALL " +"`. Тело сообщения представляет собой ассоциативный массив" +" из 2 элементов:" + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_CALL_16,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_FUNCTION_NAME: :samp:`{{MP_STR string}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_CALL_16,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_FUNCTION_NAME: :samp:`{{MP_STR string}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}`\n" +"})" + +msgid "The return value is an array of tuples." +msgstr "Возвращается массив кортежей." + +msgid "IPROTO_AUTH = 0x07" +msgstr "IPROTO_AUTH = 0x07" + +msgid "" +"See :ref:`authentication `. See the later section " +":ref:`Binary protocol -- authentication `." +msgstr "" +"См. раздел :ref:`Аутентификация ` в документации. См. " +"раздел об :ref:`аутентификации ` ниже." + +msgid "IPROTO_EVAL = 0x08" +msgstr "IPROTO_EVAL = 0x08" + +msgid "" +"See :ref:`conn:eval() `. Since the argument is a Lua " +"expression, this is Tarantool's way to handle non-binary with the binary " +"protocol. Any request that does not have its own code, for example " +":samp:`box.space.{space-name}:drop()`, will be handled either with " +":ref:`IPROTO_CALL ` or IPROTO_EVAL. The " +":ref:`tarantoolctl ` administrative utility makes extensive " +"use of ``eval``. The body is a 2-item map:" +msgstr "" +"См. :ref:`conn:eval() `. В качестве аргумента выступает " +"выражение на Lua — так Tarantool обрабатывает небинарный код с помощью " +"бинарного протокола. Любой запрос без собственного кода, например " +":samp:`box.space.{space-name}:drop()`, будет обработан с помощью либо " +":ref:`IPROTO_CALL `, либо IPROTO_EVAL. Административная " +"утилита :ref:`tarantoolctl ` активно использует ``eval``. Тело" +" сообщения представляет собой ассоциативный массив из 2 элементов:" + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_EVAL,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_EXPR: :samp:`{{MP_STR string}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_EVAL,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_EXPR: :samp:`{{MP_STR string}}`,\n" +" IPROTO_TUPLE: :samp:`{{MP_ARRAY array of arguments}}`\n" +"})" + +msgid "" +"If this is the fifth message, :samp:`conn:eval('return 5;')` will " +"cause:" +msgstr "" +"Если это пятое сообщение, :samp:`conn:eval('return 5;')` приведет к " +"следующему:" + +msgid "" +"# \n" +"msgpack(19)\n" +"#
\n" +"msgpack({\n" +" IPROTO_SYNC: 5\n" +" IPROTO_REQUEST_TYPE: IPROTO_EVAL\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_EXPR: 'return 5;',\n" +" IPROTO_TUPLE: []\n" +"})" +msgstr "" +"# \n" +"msgpack(19)\n" +"#
\n" +"msgpack({\n" +" IPROTO_SYNC: 5\n" +" IPROTO_REQUEST_TYPE: IPROTO_EVAL\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_EXPR: 'return 5;',\n" +" IPROTO_TUPLE: []\n" +"})" + + +msgid "IPROTO_EXECUTE = 0x0b" +msgstr "IPROTO_EXECUTE = 0x0b" + +msgid "" +"See :ref:`box.execute() `, this is only for SQL. The " +"body is a 3-item map:" +msgstr "" +"См. :ref:`box.execute() `, используется только для SQL." +" Тело сообщения представляет собой ассоциативный массив из 3 элементов:" + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_EXECUTE,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_STMT_ID: :samp:`{{MP_INT integer}}` or IPROTO_SQL_TEXT: :samp:`{{MP_STR string}}`,\n" +" IPROTO_SQL_BIND: :samp:`{{MP_INT integer}}`,\n" +" IPROTO_OPTIONS: :samp:`{{MP_ARRAY array}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_EXECUTE,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_STMT_ID: :samp:`{{MP_INT integer}}` или IPROTO_SQL_TEXT: :samp:`{{MP_STR string}}`,\n" +" IPROTO_SQL_BIND: :samp:`{{MP_INT integer}}`,\n" +" IPROTO_OPTIONS: :samp:`{{MP_ARRAY array}}`\n" +"})" + +msgid "" +"Use IPROTO_STMT_ID (0x43) and statement-id (MP_INT) if executing a prepared " +"statement, or use IPROTO_SQL_TEXT (0x40) and statement-text (MP_STR) if " +"executing an SQL string, then IPROTO_SQL_BIND (0x41) and array of parameter " +"values to match ? placeholders or :name placeholders, IPROTO_OPTIONS (0x2b) " +"and array of options (usually empty)." +msgstr "" +"При выполнении подготовленного оператора используйте IPROTO_STMT_ID (0x43) и" +" ID оператора (MP_INT), при работе со строками SQL — IPROTO_SQL_TEXT (0x40) " +"и текст оператора (MP_STR), а затем IPROTO_SQL_BIND (0x41) и массив значений" +" параметров для подстановочных знаков ``?`` или ``:name``, IPROTO_OPTIONS " +"(0x2b) и массив параметров (обычно пустой)." + +msgid "" +"For example, suppose we prepare a statement with two ? placeholders, and " +"execute with two parameters, thus: |br| :code:`n = conn:prepare([[VALUES (?," +" ?);]])` |br| :code:`conn:execute(n.stmt_id, {1,'a'})` |br| Then the body " +"will look like this:" +msgstr "" +"Например, предположим, что мы создаем подготовленный оператор с двумя " +"подстановочными знаками ? и выполняем его с двумя параметрами таким образом:" +" |br| :code:`n = conn:prepare([[VALUES (?, ?);]])` |br| " +":code:`conn:execute(n.stmt_id, {1,'a'})` |br| Тогда тело сообщения будет " +"выглядеть так:" + +msgid "" +"# \n" +"msgpack({\n" +" IPROTO_STMT_ID: 0xd7aa741b,\n" +" IPROTO_SQL_BIND: [1, 'a'],\n" +" IPROTO_OPTIONS: []\n" +"})" +msgstr "" +"# \n" +"msgpack({\n" +" IPROTO_STMT_ID: 0xd7aa741b,\n" +" IPROTO_SQL_BIND: [1, 'a'],\n" +" IPROTO_OPTIONS: []\n" +"})" + +msgid "" +"Later in :ref:`Binary protocol -- illustration ` " +"we will show actual byte codes of the IPROTO_EXECUTE message." +msgstr "" +"Далее в разделе :ref:`Примеры ` будут рассмотрены" +" байт-коды сообщения IPROTO_EXECUTE." + +msgid "" +"To call a prepared statement with named parameters from a connector pass the" +" parameters within an array of maps. A client should wrap each element into " +"a map, where the key holds a name of the parameter (with a colon) and the " +"value holds an actual value. So, to bind foo and bar to 42 and 43, a client " +"should send ``IPROTO_SQL_TEXT: <...>, IPROTO_SQL_BIND: [{\"foo\": 42}, " +"{\"bar\": 43}]``." +msgstr "" +"Чтобы вызвать подготовленный оператор с именованными параметрами из " +"коннектора, передайте параметры в массиве ассоциативных массивов. Клиент " +"должен поместить каждый элемент в ассоциативный массив, где ключ содержит " +"имя параметра (с двоеточием), а значение — фактическое значение. Так, чтобы " +"связать foo и bar с 42 и 43, клиент должен отправить ``IPROTO_SQL_TEXT: " +"<...>, IPROTO_SQL_BIND: [{\"foo\": 42}, {\"bar\": 43}]``." + +msgid "" +"If a statement has both named and non-named parameters, wrap only named ones" +" into a map. The rest of the parameters are positional and will be " +"substituted in order." +msgstr "" +"Если оператор содержит как именованные, так и неименованные параметры, " +"поместите в ассоциативный массив только именованные параметры. Остальные " +"параметры являются позиционными и будут подставляться по порядку." + +msgid "IPROTO_NOP = 0x0c" +msgstr "IPROTO_NOP = 0x0c" + +msgid "" +"There is no Lua request exactly equivalent to IPROTO_NOP. It causes the LSN " +"to be incremented. It could be sometimes used for updates where the old and " +"new values are the same, but the LSN must be increased because a data-change" +" must be recorded. The body is: nothing." +msgstr "" +"Нет такого запроса на Lua, который бы соответствовал IPROTO_NOP. IPROTO_NOP " +"приводит к увеличению LSN. Иногда константу можно использовать для " +"обновления значения, когда старое и новое значения одинаковы, но LSN нужно " +"увеличить, поскольку нужно зарегистрировать изменение данных. Тело сообщения" +" пустое." + + + +msgid "IPROTO_PREPARE = 0x0d" +msgstr "IPROTO_PREPARE = 0x0d" + +msgid "" +"See :ref:`box.prepare `, this is only for SQL. The body" +" is a 1-item map:" +msgstr "" +"См. :ref:`box.prepare `, используется только для SQL. " +"Тело сообщения представляет собой ассоциативный массив из 1 элемента:" + +msgid "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_PREPARE,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_STMT_ID: :samp:`{{MP_INT integer}}` or IPROTO_SQL_TEXT: :samp:`{{MP_STR string}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(:samp:`{{MP_UINT unsigned integer = size(
) + size()}}`)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_PREPARE,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})\n" +"# \n" +"msgpack({\n" +" IPROTO_STMT_ID: :samp:`{{MP_INT integer}}` или IPROTO_SQL_TEXT: :samp:`{{MP_STR string}}`\n" +"})" + +msgid "" +"IPROTO_STMT_ID (0x43) and statement-id (MP_INT) if executing a prepared " +"statement or IPROTO_SQL_TEXT (0x40) and statement-text (string) if executing" +" an SQL string. Thus the IPROTO_PREPARE map item is the same as the first " +"item of the :ref:`IPROTO_EXECUTE ` body." +msgstr "" +"При выполнении подготовленного оператора используйте IPROTO_STMT_ID (0x43) и" +" ID оператора (MP_INT), при работе со строками SQL --- IPROTO_SQL_TEXT " +"(0x40) и текст оператора (string). Таким образом, элемент ассоциативного " +"массива IPROTO_PREPARE — это то же самое, что и первый элемент тела " +"сообщения :ref:`IPROTO_EXECUTE `." + +msgid "IPROTO_PING = 0x40" +msgstr "IPROTO_PING = 0x40" + +msgid "" +"See :ref:`conn:ping() `. The body will be an empty map because " +"IPROTO_PING in the header contains all the information that the server " +"instance needs." +msgstr "" +"См. :ref:`conn:ping() `. В теле сообщения будет пустой " +"ассоциативный массив, потому что IPROTO_PING в заголовке содержит всю " +"информацию, необходимую экземпляру сервера." + +msgid "" +"# \n" +"msgpack(5)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_PING,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})" +msgstr "" +"# \n" +"msgpack(5)\n" +"#
\n" +"msgpack({\n" +" IPROTO_REQUEST_TYPE: IPROTO_PING,\n" +" IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`\n" +"})" diff --git a/locale/ru/LC_MESSAGES/dev_guide/internals/iproto/streams.po b/locale/ru/LC_MESSAGES/dev_guide/internals/iproto/streams.po new file mode 100644 index 0000000000..96ac605ec5 --- /dev/null +++ b/locale/ru/LC_MESSAGES/dev_guide/internals/iproto/streams.po @@ -0,0 +1,132 @@ + +msgid "Binary protocol -- streams" +msgstr "Бинарный протокол — стримы" + +msgid "" +"The :ref:`Streams and interactive transactions ` feature, which " +"was added in Tarantool version :tarantool-release:`2.10.0`, allows two" +" things: sequential processing and interleaving." +msgstr "" +":ref:`Стримы и интерактивные транзакции `, добавленные в " +"Tarantool :tarantool-release:`2.10.0`, делают возможными две " +"процедуры: последовательную обработку и чередование." + +msgid "" +"Sequential processing: With streams there is a guarantee that the server " +"instance will not handle the next request in a stream until it has completed" +" the previous one." +msgstr "" +"Последовательная обработка гарантирует, что экземпляр не будет обрабатывать " +"следующий запрос в стриме, пока не завершит работу с предыдущим." + +msgid "" +"Interleaving: For example, a series of requests can include \"begin for " +"stream #1\", \"begin for stream #2\", \"insert for stream #1\", \"insert for" +" stream #2\", \"delete for stream #1\", \"commit for stream #1\", \"rollback" +" for stream #2\"." +msgstr "" +"Чередование допускает, например, такую последовательность запросов: \"begin " +"для стрима 1\", \"begin для стрима 2\", \"insert для стрима 1\", \"insert " +"для стрима 2\", \"delete для стрима 1\", \"commit для стрима 1\", \"rollback" +" для стрима 2\"." + +msgid "" +"To make these things possible, the engine should be :ref:`vinyl ` or :ref:`memtx with mvcc `, and the" +" client is responsible for ensuring that the stream identifier, unsigned " +"integer :ref:`IPROTO_STREAM_ID `, is in the " +"request header. IPROTO_STREAM_ID can be any positive 64-bit number, and " +"should be unique for the connection. If IPROTO_STREAM_ID equals zero the " +"server instance will ignore it." +msgstr "" +"Эти процедуры возможны, если используется движок :ref:`vinyl ` или :ref:`memtx с mvcc `. При этом " +"клиент отвечает за наличие идентификатора стрима, беззнакового целого числа " +":ref:`IPROTO_STREAM_ID `, в заголовке " +"запроса. Идентификатор IPROTO_STREAM_ID должен быть положительным 64-битовым" +" числом, уникальным для соединения. Если IPROTO_STREAM_ID стрима равен нулю," +" экземпляр его проигнорирует." + +msgid "" +"For example, suppose that the client has started a stream with the " +":ref:`net.box module `" +msgstr "" +"Предположим, что клиент запустил стрим с помощью :ref:`модуля " +"net.box`." + +msgid "" +"net_box = require('net.box')\n" +"conn = net_box.connect('localhost:3302')\n" +"stream = conn:new_stream()" +msgstr "" +"net_box = require('net.box')\n" +"conn = net_box.connect('localhost:3302')\n" +"stream = conn:new_stream()" + +msgid "" +"At this point the stream object will look like a duplicate of the conn " +"object, with just one additional member: ``stream_id``. Now, using stream " +"instead of conn, the client sends two requests:" +msgstr "" +"В этот момент объект ``stream`` будет выглядеть так же, как объект ``conn``," +" но включать один дополнительный элемент: ``stream_id``. Пусть теперь " +"клиент, используя ``stream`` вместо ``conn``, отправит два запроса:" + +msgid "" +"stream.space.T:insert{1}\n" +"stream.space.T:insert{2}" +msgstr "" +"stream.space.T:insert{1}\n" +"stream.space.T:insert{2}" + +msgid "" +"The header and body of these requests will be the same as in non-stream " +":ref:`IPROTO_INSERT ` requests, except that the header " +"will contain an additional item: IPROTO_STREAM_ID=0x0a with MP_UINT=0x01. It" +" happens to equal 1 for this example because each call to conn:new_stream() " +"assigns a new number, starting with 1." +msgstr "" +"Заголовок и тело этих запросов будут такими же, как в обычных запросах " +":ref:`IPROTO_INSERT `, но заголовок будет содержать " +"дополнительный элемент ``IPROTO_STREAM_ID=0x0a``, где ``MP_UINT=0x01``. В " +"этом примере значение IPROTO_STREAM_ID равно 1, так как при вызове " +"``conn:new_stream()`` идентификатору каждого нового стрима присваивается " +"уникальное значение, начиная с 1." + +msgid "" +"The client makes stream transactions by sending, in order: IPROTO_BEGIN, the" +" transaction data-change and query requests, IPROTO_COMMIT or " +"IPROTO_ROLLBACK. Each request must contain the same IPROTO_STREAM_ID value. " +"With streaming there is no need to add :ref:`IPROTO_FLAGS ` and IPROTO_FLAG_COMMIT in the header of the last request of a " +"transaction. Rollback will be automatic if disconnect occurs before commit " +"is possible." +msgstr "" +"Клиент запускает транзакцию внутри стрима, отправляя запросы в следующем " +"порядке: IPROTO_BEGIN, запросы на изменение и получение данных транзакции, " +"затем IPROTO_COMMIT или IPROTO_ROLLBACK. Каждый запрос должен содержать " +"переменную IPROTO_STREAM_ID с одним и тем же значением. Используя стримы, не" +" нужно добавлять в заголовок последнего запроса транзакции " +":ref:`IPROTO_FLAGS ` и IPROTO_FLAG_COMMIT. Если " +"транзакция прервется до того, как можно будет выполнить коммит, она будет " +"автоматически отменена." + +msgid "" +"Thus there are now multiple ways to do transactions: with net_box and " +"stream:begin() and stream:commit() or stream:rollback() which cause " +"IPROTO_BEGIN and IPROTO_COMMIT or IPROTO_ROLLBACK with the current value of " +"stream.stream_id; with :ref:`box.begin() ` and :ref:`box.commit()" +" ` or :ref:`box.rollback() `; with SQL and " +":ref:`START TRANSACTION ` and :ref:`COMMIT " +"` or :ref:`ROLLBACK `. An application can use any " +"or all of these ways." +msgstr "" +"Таким образом, у приложения есть несколько способов выполнять транзакции. " +"Во-первых, можно использовать модуль ``net_box`` с методами " +"``stream:begin()`` и ``stream:commit()``/``stream:rollback()``, которые " +"отправляют запросы IPROTO_BEGIN и IPROTO_COMMIT/IPROTO_ROLLBACK с текущим " +"значением ``stream.stream_id``. Другой способ --- применять методы " +":ref:`box.begin() ` и :ref:`box.commit() `/:ref:`box.rollback() `. Наконец, можно пользоваться " +"инструкциями SQL :ref:`START TRANSACTION ` и " +":ref:`COMMIT `/:ref:`ROLLBACK `." diff --git a/locale/ru/LC_MESSAGES/how-to/other/iproto.po b/locale/ru/LC_MESSAGES/how-to/other/iproto.po new file mode 100644 index 0000000000..e03afa3892 --- /dev/null +++ b/locale/ru/LC_MESSAGES/how-to/other/iproto.po @@ -0,0 +1,517 @@ + +msgid "Examples" +msgstr "Примеры" + +msgid "" +"To follow the examples in this section, get a single Linux computer and " +"start three command-line shells (\"terminals\")." +msgstr "" +"Чтобы выполнить примеры, приведенные в этом разделе, запустите на компьютере" +" с Linux три командных оболочки (терминала)." + +msgid "" +"-- On terminal #1, Start monitoring port 3302 with `tcpdump " +"`_: |br|" +msgstr "" +"-- На терминале №1 запустите мониторинг порта 3302 с помощью `tcpdump " +"`_: |br|" + +msgid "sudo tcpdump -i lo 'port 3302' -X" +msgstr "sudo tcpdump -i lo 'port 3302' -X" + +msgid "On terminal #2, start a server with:" +msgstr "На терминале №2 запустите сервер так:" + +msgid "" +"box.cfg{listen=3302}\n" +"box.schema.space.create('tspace')\n" +"box.space.tspace:create_index('I')\n" +"box.space.tspace:insert{280}\n" +"box.schema.user.grant('guest','read,write,execute,create,drop','universe')" +msgstr "" +"box.cfg{listen=3302}\n" +"box.schema.space.create('tspace')\n" +"box.space.tspace:create_index('I')\n" +"box.space.tspace:insert{280}\n" +"box.schema.user.grant('guest','read,write,execute,create,drop','universe')" + +msgid "" +"On terminal #3, start another server, which will act as a client, with:" +msgstr "" +"На терминале №3 запустите ещё один сервер, который будет выступать в " +"качестве клиента, так:" + +msgid "" +"box.cfg{}\n" +"net_box = require('net.box')\n" +"conn = net_box.connect('localhost:3302')\n" +"conn.space.tspace:select(280)" +msgstr "" +"box.cfg{}\n" +"net_box = require('net.box')\n" +"conn = net_box.connect('localhost:3302')\n" +"conn.space.tspace:select(280)" + +msgid "" +"Now look at what tcpdump shows for the job connecting to 3302 -- the " +"\"request\". After the words \"length 32\" is a packet that ends with these " +"32 bytes (we have added indented comments):" +msgstr "" +"Теперь посмотрите, что tcpdump покажет для запроса на подключение к порту " +"3302. После слов «length 32» идет пакет, который заканчивается этими 32 " +"байтами (комментарии отделены отступами):" + +msgid "" +"ce 00 00 00 1b MP_UINT = decimal 27 = number of bytes after this\n" +"82 MP_MAP, size 2 (we'll call this \"Main-Map\")\n" +"01 IPROTO_SYNC (Main-Map Item#1)\n" +"04 MP_INT = 4 = number that gets incremented with each request\n" +"00 IPROTO_REQUEST_TYPE (Main-Map Item#2)\n" +"01 IPROTO_SELECT\n" +"86 MP_MAP, size 6 (we'll call this \"Select-Map\")\n" +"10 IPROTO_SPACE_ID (Select-Map Item#1)\n" +"cd 02 00 MP_UINT = decimal 512 = id of tspace (could be larger)\n" +"11 IPROTO_INDEX_ID (Select-Map Item#2)\n" +"00 MP_INT = 0 = id of index within tspace\n" +"14 IPROTO_ITERATOR (Select-Map Item#3)\n" +"00 MP_INT = 0 = Tarantool iterator_type.h constant ITER_EQ\n" +"13 IPROTO_OFFSET (Select-Map Item#4)\n" +"00 MP_INT = 0 = amount to offset\n" +"12 IPROTO_LIMIT (Select-Map Item#5)\n" +"ce ff ff ff ff MP_UINT = 4294967295 = biggest possible limit\n" +"20 IPROTO_KEY (Select-Map Item#6)\n" +"91 MP_ARRAY, size 1 (we'll call this \"Key-Array\")\n" +"cd 01 18 MP_UINT = 280 (Select-Map Item#6, Key-Array Item#1)\n" +" -- 280 is the key value that we are searching for" +msgstr "" +"ce 00 00 00 1b MP_UINT = 27, десятичное число = число байт после этого\n" +"82 MP_MAP, размер 2 (назовем это Main-Map)\n" +"01 IPROTO_SYNC (1-й элемент Main-Map)\n" +"04 MP_INT = 4 = число, которое увеличивается на 1 с каждым запросом\n" +"00 IPROTO_REQUEST_TYPE (2-й элемент Main-Map)\n" +"01 IPROTO_SELECT\n" +"86 MP_MAP, размер 6 (назовем это Select-Map)\n" +"10 IPROTO_SPACE_ID (1-й элемент Select-Map)\n" +"cd 02 00 MP_UINT = 512, десятичное число = id tspace (может быть больше)\n" +"11 IPROTO_INDEX_ID (2-й элемент Select-Map)\n" +"00 MP_INT = 0 = id индекса в tspace\n" +"14 IPROTO_ITERATOR (3-й элемент Select-Map)\n" +"00 MP_INT = 0 = константа Tarantool iterator_type.h ITER_EQ\n" +"13 IPROTO_OFFSET (4-й элемент Select-Map)\n" +"00 MP_INT = 0 = смещение\n" +"12 IPROTO_LIMIT (5-й элемент Select-Map)\n" +"ce ff ff ff ff MP_UINT = 4294967295 = наибольший возможный предел\n" +"20 IPROTO_KEY (6-й элемент Select-Map)\n" +"91 MP_ARRAY, размер 1 (назовем это Key-Array)\n" +"cd 01 18 MP_UINT = 280 (6-й элемент Select-Map, 1-й элемент Key-Array)\n" +" -- 280, ключевое значение, которое мы ищем" + +msgid "" +"Now read the source code file `net_box.c " +"`_" +" and skip to the line ``netbox_encode_select(lua_State *L)``. From the " +"comments and from simple function calls like ``mpstream_encode_uint(&stream," +" IPROTO_SPACE_ID);`` you will be able to see how net_box put together the " +"packet contents that you have just observed with tcpdump." +msgstr "" +"Теперь в файле исходного кода `net_box.c " +"`_" +" перейдите к строке ``netbox_encode_select(lua_State *L)``. Из комментариев " +"и из простых вызовов функций типа ``mpstream_encode_uint(&stream, " +"IPROTO_SPACE_ID);`` можно понять, как net_box собирает воедино содержимое " +"пакета, описанного выше с помощью tcpdump." + +msgid "" +"There are libraries for reading and writing MessagePack objects. C " +"programmers sometimes include `msgpuck.h " +"`_." +msgstr "" +"Существуют библиотеки для чтения и записи объектов в формате MessagePack. " +"Программисты на языке C иногда включают `msgpuck.h " +"`_." + +msgid "" +"Now you know how Tarantool itself makes requests with the binary protocol. " +"When in doubt about a detail, consult ``net_box.c`` -- it has routines for " +"each request. Some :ref:`connectors ` have similar " +"code." +msgstr "" +"Теперь вы знаете, как сам Tarantool выполняет запросы по бинарному " +"протоколу. Если какие-то детали остаются неясными, обратитесь к файлу " +"``net_box.c``, где описаны процедуры для каждого запроса. Некоторые " +":ref:`коннекторы ` написаны аналогично." + +msgid "" +"For an IPROTO_UPDATE example, suppose a user changes field #2 in tuple #2 in" +" space #256 to ``'BBBB'``. The body will look like this: (notice that in " +"this case there is an extra map item IPROTO_INDEX_BASE, to emphasize that " +"field numbers start with 1, which is optional and can be omitted):" +msgstr "" +"Рассмотрим пример IPROTO_UPDATE. Предположим, пользователь изменяет поле №2 " +"кортежа №2 в спейсе №256 на `'BBBB'``. Тело будет выглядеть так (обратите " +"внимание, что в этом случае дополнительный необязательный элемент " +"ассоциативного массива IPROTO_INDEX_BASE подчеркивает, что номера полей " +"начинаются с 1 — это можно опустить):" + +msgid "" +"04 IPROTO_UPDATE\n" +"85 IPROTO_MAP, size 5\n" +"10 IPROTO_SPACE_ID, Map Item#1\n" +"cd 02 00 MP_UINT 256\n" +"11 IPROTO_INDEX_ID, Map Item#2\n" +"00 MP_INT 0 = primary-key index number\n" +"15 IPROTO_INDEX_BASE, Map Item#3\n" +"01 MP_INT = 1 i.e. field numbers start at 1\n" +"21 IPROTO_TUPLE, Map Item#4\n" +"91 MP_ARRAY, size 1, for array of operations\n" +"93 MP_ARRAY, size 3\n" +"a1 3d MP_STR = OPERATOR = '='\n" +"02 MP_INT = FIELD_NO = 2\n" +"a5 42 42 42 42 42 MP_STR = VALUE = 'BBBB'\n" +"20 IPROTO_KEY, Map Item#5\n" +"91 MP_ARRAY, size 1, for array of key values\n" +"02 MP_UINT = primary-key value = 2" +msgstr "" +"04 IPROTO_UPDATE\n" +"85 IPROTO_MAP, размер 5\n" +"10 IPROTO_SPACE_ID, 1-й элемент ассоциативного массива\n" +"cd 02 00 MP_UINT 256\n" +"11 IPROTO_INDEX_ID, 2-й элемент ассоциативного массива\n" +"00 MP_INT 0 = номер индекса первичного ключа\n" +"15 IPROTO_INDEX_BASE, 3-й элемент ассоциативного массива\n" +"01 MP_INT = 1, т.е. нумерация полей начинается с 1\n" +"21 IPROTO_TUPLE, 4-й элемент ассоциативного массива\n" +"91 MP_ARRAY, размер 1, для массива операций\n" +"93 MP_ARRAY, размер 3\n" +"a1 3d MP_STR = OPERATOR = '='\n" +"02 MP_INT = FIELD_NO = 2\n" +"a5 42 42 42 42 42 MP_STR = VALUE = 'BBBB'\n" +"20 IPROTO_KEY, 5--й элемент ассоциативного массива\n" +"91 MP_ARRAY, размер 1, для массива ключей\n" +"02 MP_UINT = значение первичного ключа = 2" + +msgid "" +"Byte codes for the :ref:`IPROTO_EXECUTE ` example:" +msgstr "Пример байт-кода :ref:`IPROTO_EXECUTE `:" + +msgid "" +"0b IPROTO_EXECUTE\n" +"83 MP_MAP, size 3\n" +"43 IPROTO_STMT_ID Map Item#1\n" +"ce d7 aa 74 1b MP_UINT value of n.stmt_id\n" +"41 IPROTO_SQL_BIND Map Item#2\n" +"92 MP_ARRAY, size 2\n" +"01 MP_INT = 1 = value for first parameter\n" +"a1 61 MP_STR = 'a' = value for second parameter\n" +"2b IPROTO_OPTIONS Map Item#3\n" +"90 MP_ARRAY, size 0 (there are no options)" +msgstr "" +"0b IPROTO_EXECUTE\n" +"83 MP_MAP, размер 3\n" +"43 IPROTO_STMT_ID 1-й элемент ассоциативного массива\n" +"ce d7 aa 74 1b MP_UINT значение n.stmt_id\n" +"41 IPROTO_SQL_BIND 2-й элемент ассоциативного массива\n" +"92 MP_ARRAY, размер 2\n" +"01 MP_INT = 1 = значение первого параметра\n" +"a1 61 MP_STR = 'a' = значение второго параметра\n" +"2b IPROTO_OPTIONS 3-й элемент ассоциативного массива\n" +"90 MP_ARRAY, размер 0 (никакие опции не выбраны)" + +msgid "" +"Byte codes for the response to the " +":codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:insert{6}` " +"example:" +msgstr "" +"Пример байт-кода ответа на запрос " +":codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:insert{6}`:" + +msgid "" +"ce 00 00 00 20 MP_UINT = HEADER AND BODY SIZE\n" +"83 MP_MAP, size 3\n" +"00 Response-Code-Indicator\n" +"ce 00 00 00 00 MP_UINT = IPROTO_OK\n" +"01 IPROTO_SYNC\n" +"cf 00 00 00 00 00 00 00 53 MP_UINT = sync value\n" +"05 IPROTO_SCHEMA_VERSION\n" +"ce 00 00 00 68 MP_UINT = schema version\n" +"81 MP_MAP, size 1\n" +"30 IPROTO_DATA\n" +"dd 00 00 00 01 MP_ARRAY, size 1 (row count)\n" +"91 MP_ARRAY, size 1 (field count)\n" +"06 MP_INT = 6 = the value that was inserted" +msgstr "" +"ce 00 00 00 20 MP_UINT = размер заголовка и тела\n" +"83 MP_MAP, размер 3\n" +"00 индикатор кода ответа\n" +"ce 00 00 00 00 MP_UINT = IPROTO_OK\n" +"01 IPROTO_SYNC\n" +"cf 00 00 00 00 00 00 00 53 MP_UINT = значение синхронизации\n" +"05 IPROTO_SCHEMA_VERSION\n" +"ce 00 00 00 68 MP_UINT = версия схемы\n" +"81 MP_MAP, размер 1\n" +"30 IPROTO_DATA\n" +"dd 00 00 00 01 MP_ARRAY, размер 1 (число строк)\n" +"91 MP_ARRAY, размер 1 (число полей)\n" +"06 MP_INT = 6 = добавленное значение" + +msgid "" +"Byte codes for the response to the " +"``conn:eval([[box.schema.space.create('_space');]])`` example:" +msgstr "" +"Пример байт-кода ответа на запрос " +"``conn:eval([[box.schema.space.create('_space');]])``:" + +msgid "" +"ce 00 00 00 3b MP_UINT = HEADER AND BODY SIZE\n" +"83 MP_MAP, size 3 (i.e. 3 items in header)\n" +" 00 Response-Code-Indicator\n" +" ce 00 00 80 0a MP_UINT = hexadecimal 800a\n" +" 01 IPROTO_SYNC\n" +" cf 00 00 00 00 00 00 00 26 MP_UINT = sync value\n" +" 05 IPROTO_SCHEMA_VERSION\n" +" ce 00 00 00 78 MP_UINT = schema version value\n" +" 81 MP_MAP, size 1\n" +" 31 IPROTO_ERROR_24\n" +" db 00 00 00 1d 53 70 61 63 etc. MP_STR = \"Space '_space' already exists\"" +msgstr "" +"ce 00 00 00 3b MP_UINT = размер заголовка и тела\n" +"83 MP_MAP, размер 3 (3 элемента в заголовке)\n" +" 00 индикатор кода ответа\n" +" ce 00 00 80 0a MP_UINT = шестнадцатеричное значение 800a\n" +" 01 IPROTO_SYNC\n" +" cf 00 00 00 00 00 00 00 26 MP_UINT = значение синхронизации\n" +" 05 IPROTO_SCHEMA_VERSION\n" +" ce 00 00 00 78 MP_UINT = версия схемы \n" +" 81 MP_MAP, размер 1\n" +" 31 IPROTO_ERROR_24\n" +" db 00 00 00 1d 53 70 61 63 ... MP_STR = \"Space '_space' already exists\"" + +msgid "" +"Byte codes, if we use the same net.box connection that we used for " +":ref:`Binary protocol -- illustration ` and we " +"say |br| ``conn:execute([[CREATE TABLE t1 (dd INT PRIMARY KEY AUTOINCREMENT," +" дд STRING COLLATE \"unicode\");]])`` |br| ``conn:execute([[INSERT INTO t1 " +"VALUES (NULL, 'a'), (NULL, 'b');]])`` |br| and we watch what tcpdump " +"displays, we will see two noticeable things: (1) the CREATE statement caused" +" a schema change so the response has a new IPROTO_SCHEMA_VERSION value and " +"the body includes the new contents of some system tables (caused by requests" +" from net.box which users will not see); (2) the final bytes of the response" +" to the INSERT will be:" +msgstr "" +"Подключимся через то же соединение net.box, что приводилось в :ref:`примерах" +" `, и выполним следующее: |br| " +"``conn:execute([[CREATE TABLE t1 (dd INT PRIMARY KEY AUTOINCREMENT, дд " +"STRING COLLATE \"unicode\");]])`` |br| ``conn:execute([[INSERT INTO t1 " +"VALUES (NULL, 'a'), (NULL, 'b');]])`` |br| Результат вывода tcpdump покажет " +"два интересных момента: (1) инструкция CREATE привела к изменению схемы, так" +" что в ответе указано новое значение IPROTO_SCHEMA_VERSION. При этом тело " +"включает новое содержимое некоторых системных таблиц, полученное в " +"результате невидимых для пользователя запросов от net.box; (2) последние " +"байты ответа на INSERT будут следующими:" + +msgid "" +"81 MP_MAP, size 1\n" +"42 IPROTO_SQL_INFO\n" +"82 MP_MAP, size 2\n" +"00 Tarantool constant (not in iproto_constants.h) = SQL_INFO_ROW_COUNT\n" +"02 1 = row count\n" +"01 Tarantool constant (not in iproto_constants.h) = SQL_INFO_AUTOINCREMENT_ID\n" +"92 MP_ARRAY, size 2\n" +"01 first autoincrement number\n" +"02 second autoincrement number" +msgstr "" +"81 MP_MAP, размер 1\n" +"42 IPROTO_SQL_INFO\n" +"82 MP_MAP, размер 2\n" +"00 константа Tarantool (не из iproto_constants.h) = SQL_INFO_ROW_COUNT\n" +"02 1 = число строк\n" +"01 константа Tarantool (не из iproto_constants.h) = SQL_INFO_AUTOINCREMENT_ID\n" +"92 MP_ARRAY, размер 2\n" +"01 первое число с автоинкрементом\n" +"02 второе число с автоинкрементом" + +msgid "" +"Byte codes for the SQL SELECT example, if we ask for full metadata by saying" +" |br| :code:`conn.space._session_settings:update('sql_full_metadata', {{'='," +" 'value', true}})` |br| and we select the two rows from the table that we " +"just created |br| :code:`conn:execute([[SELECT dd, дд AS д FROM t1;]])` |br|" +" then tcpdump will show this response, after the header:" +msgstr "" +"Пример байт-кода SQL SELECT. Запросим полные метаданные, вызвав " +":code:`conn.space._session_settings:update('sql_full_metadata', {{'=', " +"'value', true}})`, и выберем две строки из только что созданной таблицы: " +":code:`conn:execute([[SELECT dd, дд AS д FROM t1;]])`. tcpdump выдаст " +"следующий ответ (после заголовка):" + +msgid "" +"82 MP_MAP, size 2 (i.e. metadata and rows)\n" +"32 IPROTO_METADATA\n" +"92 MP_ARRAY, size 2 (i.e. 2 columns)\n" +"85 MP_MAP, size 5 (i.e. 5 items for column#1)\n" +"00 a2 44 44 IPROTO_FIELD_NAME and 'DD'\n" +"01 a7 69 6e 74 65 67 65 72 IPROTO_FIELD_TYPE and 'integer'\n" +"03 c2 IPROTO_FIELD_IS_NULLABLE and false\n" +"04 c3 IPROTO_FIELD_IS_AUTOINCREMENT and true\n" +"05 c0 PROTO_FIELD_SPAN and nil\n" +"85 MP_MAP, size 5 (i.e. 5 items for column#2)\n" +"00 a2 d0 94 IPROTO_FIELD_NAME and 'Д' upper case\n" +"01 a6 73 74 72 69 6e 67 IPROTO_FIELD_TYPE and 'string'\n" +"02 a7 75 6e 69 63 6f 64 65 IPROTO_FIELD_COLL and 'unicode'\n" +"03 c3 IPROTO_FIELD_IS_NULLABLE and true\n" +"05 a4 d0 b4 d0 b4 IPROTO_FIELD_SPAN and 'дд' lower case\n" +"30 IPROTO_DATA\n" +"92 MP_ARRAY, size 2\n" +"92 MP_ARRAY, size 2\n" +"01 MP_INT = 1 i.e. contents of row#1 column#1\n" +"a1 61 MP_STR = 'a' i.e. contents of row#1 column#2\n" +"92 MP_ARRAY, size 2\n" +"02 MP_INT = 2 i.e. contents of row#2 column#1\n" +"a1 62 MP_STR = 'b' i.e. contents of row#2 column#2" +msgstr "" +"82 MP_MAP, размер 2 (метаданные и строки)\n" +"32 IPROTO_METADATA\n" +"92 MP_ARRAY, размер 2 (2 столбца)\n" +"85 MP_MAP, размер 5 (5 элементов для столбца 1)\n" +"00 a2 44 44 IPROTO_FIELD_NAME и 'DD'\n" +"01 a7 69 6e 74 65 67 65 72 IPROTO_FIELD_TYPE и 'integer'\n" +"03 c2 IPROTO_FIELD_IS_NULLABLE и false\n" +"04 c3 IPROTO_FIELD_IS_AUTOINCREMENT и true\n" +"05 c0 PROTO_FIELD_SPAN и nil\n" +"85 MP_MAP, размер 5 (5 элементов для столбца 2)\n" +"00 a2 d0 94 IPROTO_FIELD_NAME и 'Д' в верхнем регистре\n" +"01 a6 73 74 72 69 6e 67 IPROTO_FIELD_TYPE и 'string'\n" +"02 a7 75 6e 69 63 6f 64 65 IPROTO_FIELD_COLL и 'unicode'\n" +"03 c3 IPROTO_FIELD_IS_NULLABLE и true\n" +"05 a4 d0 b4 d0 b4 IPROTO_FIELD_SPAN и 'дд' в нижнем регистре\n" +"30 IPROTO_DATA\n" +"92 MP_ARRAY, размер 2\n" +"92 MP_ARRAY, размер 2\n" +"01 MP_INT = 1: содержимое строки 1, столбца 1\n" +"a1 61 MP_STR = 'a': содержимое строки 1, столбца 2\n" +"92 MP_ARRAY, размер 2\n" +"02 MP_INT = 2: содержимое строки 2, столбца 1\n" +"a1 62 MP_STR = 'b': содержимое строки 2, столбца 2" + +msgid "" +"Byte code for the SQL PREPARE example. If we said |br| " +":code:`conn:prepare([[SELECT dd, дд AS д FROM t1;]])` |br| then tcpdump " +"would show almost the same response, but there would be no IPROTO_DATA. " +"Instead, additional items will appear:" +msgstr "" +"Пример байт-кода SQL PREPARE. Если вызвать :code:`conn:prepare([[SELECT dd, " +"дд AS д FROM t1;]])`, вывод tcpdump будет почти таким же, но исчезнет " +"IPROTO_DATA. Вместо этого появятся дополнительные байты:" + +msgid "" +"34 IPROTO_BIND_COUNT\n" +"00 MP_UINT = 0\n" +"\n" +"33 IPROTO_BIND_METADATA\n" +"90 MP_ARRAY, size 0" +msgstr "" +"34 IPROTO_BIND_COUNT\n" +"00 MP_UINT = 0\n" +"\n" +"33 IPROTO_BIND_METADATA\n" +"90 MP_ARRAY, размер 0" + +msgid "" +"``MP_UINT = 0`` and ``MP_ARRAY`` has size 0 because there are no parameters " +"to bind. Full output:" +msgstr "" +"``MP_UINT = 0``. Массив ``MP_ARRAY`` имеет размер 0, поскольку параметров " +"нет. Вывод целиком:" + +msgid "" +"84 MP_MAP, size 4\n" +"43 IPROTO_STMT_ID\n" +"ce c2 3c 2c 1e MP_UINT = statement id\n" +"34 IPROTO_BIND_COUNT\n" +"00 MP_INT = 0 = number of parameters to bind\n" +"33 IPROTO_BIND_METADATA\n" +"90 MP_ARRAY, size 0 = there are no parameters to bind\n" +"32 IPROTO_METADATA\n" +"92 MP_ARRAY, size 2 (i.e. 2 columns)\n" +"85 MP_MAP, size 5 (i.e. 5 items for column#1)\n" +"00 a2 44 44 IPROTO_FIELD_NAME and 'DD'\n" +"01 a7 69 6e 74 65 67 65 72 IPROTO_FIELD_TYPE and 'integer'\n" +"03 c2 IPROTO_FIELD_IS_NULLABLE and false\n" +"04 c3 IPROTO_FIELD_IS_AUTOINCREMENT and true\n" +"05 c0 PROTO_FIELD_SPAN and nil\n" +"85 MP_MAP, size 5 (i.e. 5 items for column#2)\n" +"00 a2 d0 94 IPROTO_FIELD_NAME and 'Д' upper case\n" +"01 a6 73 74 72 69 6e 67 IPROTO_FIELD_TYPE and 'string'\n" +"02 a7 75 6e 69 63 6f 64 65 IPROTO_FIELD_COLL and 'unicode'\n" +"03 c3 IPROTO_FIELD_IS_NULLABLE and true\n" +"05 a4 d0 b4 d0 b4 IPROTO_FIELD_SPAN and 'дд' lower case" +msgstr "" +"84 MP_MAP, размер 4\n" +"43 IPROTO_STMT_ID\n" +"ce c2 3c 2c 1e MP_UINT = ID инструкции\n" +"34 IPROTO_BIND_COUNT\n" +"00 MP_INT = 0 = число привязываемых параметров\n" +"33 IPROTO_BIND_METADATA\n" +"90 MP_ARRAY, размер 0 = нет привязываемых параметров\n" +"32 IPROTO_METADATA\n" +"92 MP_ARRAY, размер 2 (2 столбца)\n" +"85 MP_MAP, размер 5 (5 элементов для столбца 1)\n" +"00 a2 44 44 IPROTO_FIELD_NAME и 'DD'\n" +"01 a7 69 6e 74 65 67 65 72 IPROTO_FIELD_TYPE и 'integer'\n" +"03 c2 IPROTO_FIELD_IS_NULLABLE и false\n" +"04 c3 IPROTO_FIELD_IS_AUTOINCREMENT и true\n" +"05 c0 PROTO_FIELD_SPAN и nil\n" +"85 MP_MAP, размер 5 (5 элементов для столбца 2)\n" +"00 a2 d0 94 IPROTO_FIELD_NAME + 'Д' в верхнем регистре\n" +"01 a6 73 74 72 69 6e 67 IPROTO_FIELD_TYPE и 'string'\n" +"02 a7 75 6e 69 63 6f 64 65 IPROTO_FIELD_COLL и 'unicode'\n" +"03 c3 IPROTO_FIELD_IS_NULLABLE и true\n" +"05 a4 d0 b4 d0 b4 IPROTO_FIELD_SPAN и 'дд' в нижнем регистре" + +msgid "Byte code for the :ref:`heartbeat ` example. The master might send this body:" +msgstr "" +"Пример байт-кода :ref:`контрольного сигнала `. Мастер может отправить следующее " +"тело:" + +msgid "" +"83 MP_MAP, size 3\n" +"00 Main-Map Item #1 IPROTO_REQUEST_TYPE\n" +"00 MP_UINT = 0\n" +"02 Main-Map Item #2 IPROTO_REPLICA_ID\n" +"02 MP_UINT = 2 = id\n" +"04 Main-Map Item #3 IPROTO_TIMESTAMP\n" +"cb MP_DOUBLE (MessagePack \"Float 64\")\n" +"41 d7 ba 06 7b 3a 03 21 8-byte timestamp" +msgstr "" +"83 MP_MAP, размер 3\n" +"00 1-й элемент Main-Map IPROTO_REQUEST_TYPE\n" +"00 MP_UINT = 0\n" +"02 2-й элемент Main-Map IPROTO_REPLICA_ID\n" +"02 MP_UINT = 2 = id\n" +"04 3-й элемент Main-Map IPROTO_TIMESTAMP\n" +"cb MP_DOUBLE (MessagePack \"Float 64\")\n" +"41 d7 ba 06 7b 3a 03 21 8-байтовая временная отметка" + +msgid "" +"Byte code for the :ref:`heartbeat ` example. The replica might send back this body" +msgstr "" +"Пример байт-кода ответа на :ref:`контрольный сигнал `. Реплика может вернуть " +"следующее тело:" + +msgid "" +"81 MP_MAP, size 1\n" +"00 Main-Map Item #1 Response-code-indicator\n" +"00 MP_UINT = 0 = IPROTO_OK\n" +"81 Main-Map Item #2, MP_MAP, size 1\n" +"26 Sub-Map Item #1 IPROTO_VCLOCK\n" +"81 Sub-Map Item #2, MP_MAP, size 1\n" +"01 MP_UINT = 1 = id (part 1 of vclock)\n" +"06 MP_UINT = 6 = lsn (part 2 of vclock)" +msgstr "" +"81 MP_MAP, размер 1\n" +"00 1-й элемент Main-Map: индикатор кода ответа\n" +"00 MP_UINT = 0 = IPROTO_OK\n" +"81 2-й элемент Main-Map: MP_MAP, размер 1 (Sub-Map)\n" +"26 1-й элемент Sub-Map: IPROTO_VCLOCK\n" +"81 2-й элемент Sub-Map: MP_MAP, размер 1\n" +"01 MP_UINT = 1 = id (1-я часть vclock)\n" +"06 MP_UINT = 6 = lsn (2-я часть vclock)"