diff --git a/doc/sphinx/book/app/a_errcodes.rst b/doc/sphinx/book/app/a-errcodes.rst similarity index 100% rename from doc/sphinx/book/app/a_errcodes.rst rename to doc/sphinx/book/app/a-errcodes.rst diff --git a/doc/sphinx/book/box/internals.rst b/doc/sphinx/book/app/b-internals.rst similarity index 53% rename from doc/sphinx/book/box/internals.rst rename to doc/sphinx/book/app/b-internals.rst index 0f6198b53b0040f40941626180a340fb66800862..c104a76d03eec6ea35b890fe25f64fe7c95eacb2 100644 --- a/doc/sphinx/book/box/internals.rst +++ b/doc/sphinx/book/app/b-internals.rst @@ -1,7 +1,7 @@ .. _box-internals: ------------------------------------------------------------------------------- - Appendix B - Internals + Appendix B. Internals ------------------------------------------------------------------------------- This section is for advanced users or users who wish to @@ -60,25 +60,25 @@ in the WAL, or discarded completely. Let's clarify how this happens, using the REPLACE request as an example: 1. The server attempts to locate the original tuple by primary key. If found, a -reference to the tuple is retained for later use. + reference to the tuple is retained for later use. -2. The new tuple is validated. If for example it does not contain an -indexed field, or it has an indexed field whose type does not match the type -according to the index definition, the change is aborted. +2. The new tuple is validated. If for example it does not contain an indexed + field, or it has an indexed field whose type does not match the type + according to the index definition, the change is aborted. 3. The new tuple replaces the old tuple in all existing indexes. 4. A message is sent to WAL writer running in a separate thread, requesting that -the change be recorded in the WAL. The server switches to work on the next -request until the write is acknowledged. + the change be recorded in the WAL. The server switches to work on the next + request until the write is acknowledged. 5. On success, a confirmation is sent to the client. On failure, a rollback -procedure is begun. During the rollback procedure, the transaction processor -rolls back all changes to the database which occurred after the first failed -change, from latest to oldest, up to the first failed change. All rolled back -requests are aborted with :errcode:`ER_WAL_IO <ER_WAL_IO>` error. No new -change is applied while rollback is in progress. When the rollback procedure -is finished, the server restarts the processing pipeline. + procedure is begun. During the rollback procedure, the transaction processor + rolls back all changes to the database which occurred after the first failed + change, from latest to oldest, up to the first failed change. All rolled back + requests are aborted with :errcode:`ER_WAL_IO <ER_WAL_IO>` error. No new + change is applied while rollback is in progress. When the rollback procedure + is finished, the server restarts the processing pipeline. One advantage of the described algorithm is that complete request pipelining is achieved, even for requests on the same value of the primary key. As a result, @@ -140,45 +140,44 @@ make a checkpoint, and the snapshot operation is rolled back if anything goes wrong, so sophia's checkpoint is at least as fresh as the snapshot file.) -Step 1: Read the configuration parameters in the box.cfg{} request. -Parameters which affect recovery may include -:confval:`work_dir`, :confval:`wal_dir`, :confval:`snap_dir`, -:confval:`sophia_dir`, -:confval:`panic_on_snap_error`, and :confval:`panic_on_wal_error`. - -Step 2: Find the latest snapshot file. Use its data to reconstruct -the in-memory databases. Instruct the sophia engine to recover to -the latest checkpoint. - -There are actually two variations of the reconstruction procedure -for the memtx databases, depending whether the recovery process is "default". - -If it is default (panic_on_snap_error is true and panic_on_wal_error is true), -memtx can read data in -the snapshot with all indexes disabled. First, all tuples are read into memory. -Then, primary keys are built -in bulk, taking advantage of the fact that the data is already sorted -by primary key within each space. - -If it is not default (panic_on_snap_error is false or panic_on_wal_error is false), -Tarantool performs additional checking. -Indexes are enabled at the start, and tuples are added one by one. -This means that any unique-key constraint violations will be caught, -and any duplicates will be skipped. -Normally there will be no constraint violations or duplicates, -so these checks are only made if an error has occurred. - -Step 2: Find the WAL file that was made at the time of, or after, -the snapshot file. Read its log entries until the log-entry LSN is greater -than the LSN of the snapshot, or greater than the LSN of the sophia checkpoint. -This is the recovery process's "start position"; it matches the current -state of the engines. - -Step 3: Redo the log entries, from the start position to the end of -the WAL. The engine skips a redo instruction if it is older than -the engine's checkpoint. - -Step 4: For the memtx engine, re-create all secondary indexes. +Step 1 + Read the configuration parameters in the ``box.cfg{}`` request. + Parameters which affect recovery may include :confval:`work_dir`, + :confval:`wal_dir`, :confval:`snap_dir`, :confval:`sophia_dir`, + :confval:`panic_on_snap_error`, and :confval:`panic_on_wal_error`. + +Step 2 + Find the latest snapshot file. Use its data to reconstruct the in-memory + databases. Instruct the sophia engine to recover to the latest checkpoint. + +There are actually two variations of the reconstruction procedure for the memtx +databases, depending whether the recovery process is "default". + +If it is default (``panic_on_snap_error`` is ``true`` and ``panic_on_wal_error`` +is ``true``), memtx can read data in the snapshot with all indexes disabled. +First, all tuples are read into memory. Then, primary keys are built in bulk, +taking advantage of the fact that the data is already sorted by primary key +within each space. + +If it is not default (``panic_on_snap_error`` is ``false`` or ``panic_on_wal_error`` +is ``false``), Tarantool performs additional checking. Indexes are enabled at +the start, and tuples are added one by one. This means that any unique-key +constraint violations will be caught, and any duplicates will be skipped. +Normally there will be no constraint violations or duplicates, so these checks +are only made if an error has occurred. + +Step 2 + Find the WAL file that was made at the time of, or after, the snapshot file. + Read its log entries until the log-entry LSN is greater than the LSN of the + snapshot, or greater than the LSN of the sophia checkpoint. This is the + recovery process's "start position"; it matches the current state of the engines. + +Step 3 + Redo the log entries, from the start position to the end of the WAL. The + engine skips a redo instruction if it is older than the engine's checkpoint. + +Step 4 + For the memtx engine, re-create all secondary indexes. .. _internals-replication: @@ -186,92 +185,86 @@ Step 4: For the memtx engine, re-create all secondary indexes. Server Startup With Replication =============================== -In addition to the recovery process described above, -the server must take additional steps and precautions -if :ref:`replication <box-replication>` is enabled. - -Once again the startup procedure is initiated by the -:code:`box.cfg{}` request. One of the box.cfg parameters -may be :confval:`replication_source`. We will refer to -this server, which is starting up due to box.cfg, as the -"local" server to distinguish it from the other servers -in a cluster, which we will refer to as "distant" servers. - -*If there is no snapshot .snap file and replication_source is empty*: -then the local server -assumes it is an unreplicated "standalone" server, -or is the first server of a new replication cluster. -It will generate new UUIDs -for itself and for the cluster. The server UUID is -stored in the _cluster space; the cluster UUID is stored in -the _schema space. Since a snapshot contains all the data -in all the spaces, that means the local server's snapshot will -contain the server UUID and the cluster UUID. -Therefore, when the local server restarts on later occasions, -it will be able to recover these UUIDs when it reads the .snap file. +In addition to the recovery process described above, the server must take +additional steps and precautions if :ref:`replication <box-replication>` is +enabled. + +Once again the startup procedure is initiated by the ``box.cfg{}`` request. +One of the box.cfg parameters may be :confval:`replication_source`. We will +refer to this server, which is starting up due to box.cfg, as the "local" server +to distinguish it from the other servers in a cluster, which we will refer to as +"distant" servers. + +*If there is no snapshot .snap file and replication_source is empty*: |br| +then the local server assumes it is an unreplicated "standalone" server, or is +the first server of a new replication cluster. It will generate new UUIDs for +itself and for the cluster. The server UUID is stored in the _cluster space; the +cluster UUID is stored in the _schema space. Since a snapshot contains all the +data in all the spaces, that means the local server's snapshot will contain the +server UUID and the cluster UUID. Therefore, when the local server restarts on +later occasions, it will be able to recover these UUIDs when it reads the .snap +file. *If there is no snapshot .snap file and replication_source is not empty -and the _cluster space contains no other server UUIDs*: -then the local server assumes it is not a standalone server, -but is not yet part of a cluster. It must now join the cluster. -It will send its server UUID to the first distant server which is listed -in replication_source, which will act as a master. This is called the "join request". -When a distant server receives a join request, it will send back: |br| -(1) the distant server's cluster UUID, |br| +and the _cluster space contains no other server UUIDs*: |br| +then the local server assumes it is not a standalone server, but is not yet part +of a cluster. It must now join the cluster. It will send its server UUID to the +first distant server which is listed in replication_source, which will act as a +master. This is called the "join request". When a distant server receives a join +request, it will send back: + +(1) the distant server's cluster UUID, (2) the contents of the distant server's .snap file. |br| -When the local server receives this information, it puts the -cluster UUID in its _schema space, puts the distant server's -UUID and connection information in its _cluster space, and -makes a snapshot containing all the data sent by the distant server. -Then, if the local server has data in its WAL .xlog files, it sends that data to -the distant server. The distant server will receive this and -update its own copy of the data, and add the local server's -UUID to its _cluster space. + When the local server receives this information, it puts the cluster UUID in + its _schema space, puts the distant server's UUID and connection information + in its _cluster space, and makes a snapshot containing all the data sent by + the distant server. Then, if the local server has data in its WAL .xlog + files, it sends that data to the distant server. The distant server will + receive this and update its own copy of the data, and add the local server's + UUID to its _cluster space. *If there is no snapshot .snap file and replication_source is not empty -and the _cluster space contains other server UUIDs*: -then the local server assumes it is not a standalone server, -and is already part of a cluster. -It will send its server UUID and cluster UUID to all the distant servers -which are listed in replication_source. This is called the -"on-connect handshake". -When a distant server receives an on-connect handshake: |br| -(1) the distant server compares its own copy of the cluster UUID to -the one in the on-connect handshake. If there is no match, -then the handshake fails and the local server will display an error. |br| -(2) the distant server looks for a record of the connecting instance in -its _cluster space. If there is none, then the handshake fails. |br| -Otherwise the handshake is successful. -The distant server will read any new information from its own .snap and .xlog files, and send -the new requests to the local server. - -In the end ... the local server knows what cluster it belongs to, -the distant server knows that the local server is a member of -the cluster, and both servers have the same database contents. - -*If there is a snapshot file and replication source is not empty*: -first the local server goes through the recovery process described -in the previous section, using its own .snap and .xlog files. -Then it sends a "subscribe" request to all the other servers of the cluster. -The subscribe request contains the server vector clock. -The vector clock has a collection of pairs 'server id, lsn' for every server -in the _cluster system space. -Each distant server, upon receiving a subscribe request, will -read its .xlog files' requests and send them to the local server -if (lsn of .xlog file request) is greater than (lsn of the -vector clock in the subscribe request). -After all the other servers of the cluster have responded to -the local server's subscribe request, the server startup is complete. - -The following temporary limitations apply for version 1.6: |br| +and the _cluster space contains other server UUIDs*: |br| +then the local server assumes it is not a standalone server, and is already part +of a cluster. It will send its server UUID and cluster UUID to all the distant +servers which are listed in replication_source. This is called the "on-connect +handshake". When a distant server receives an on-connect handshake: |br| + +(1) the distant server compares its own copy of the cluster UUID to the one in + the on-connect handshake. If there is no match, then the handshake fails and + the local server will display an error. +(2) the distant server looks for a record of the connecting instance in its + _cluster space. If there is none, then the handshake fails. |br| + Otherwise the handshake is successful. The distant server will read any new + information from its own .snap and .xlog files, and send the new requests to + the local server. + +In the end ... the local server knows what cluster it belongs to, the distant +server knows that the local server is a member of the cluster, and both servers +have the same database contents. + +*If there is a snapshot file and replication source is not empty*: |br| +first the local server goes through the recovery process described in the +previous section, using its own .snap and .xlog files. Then it sends a +"subscribe" request to all the other servers of the cluster. The subscribe +request contains the server vector clock. The vector clock has a collection of +pairs 'server id, lsn' for every server in the _cluster system space. Each +distant server, upon receiving a subscribe request, will read its .xlog files' +requests and send them to the local server if (lsn of .xlog file request) is +greater than (lsn of the vector clock in the subscribe request). After all the +other servers of the cluster have responded to the local server's subscribe +request, the server startup is complete. + +The following temporary limitations apply for version 1.6: + * The URIs in replication_source should all be in the same order on all servers. -This is not mandatory but is an aid to consistency. |br| + This is not mandatory but is an aid to consistency. * The servers of a cluster should be started up at slightly different times. -This is not mandatory but prevents a situation where each server is waiting -for the other server to be ready. |br| + This is not mandatory but prevents a situation where each server is waiting + for the other server to be ready. * The maximum number of entries in the _cluster space is 32. Tuples for -out-of-date replicas are not automatically re-used, so if this 32-replica -limit is reached, users may have to reorganize the _cluster space manually. + out-of-date replicas are not automatically re-used, so if this 32-replica + limit is reached, users may have to reorganize the _cluster space manually. .. _MsgPack: https://en.wikipedia.org/wiki/MessagePack .. _doc/box-protocol.html: http://tarantool.org/doc/box-protocol.html diff --git a/doc/sphinx/book/app/c_lua_tutorial.rst b/doc/sphinx/book/app/c-lua_tutorial.rst similarity index 100% rename from doc/sphinx/book/app/c_lua_tutorial.rst rename to doc/sphinx/book/app/c-lua_tutorial.rst diff --git a/doc/sphinx/book/app/d_plugins.rst b/doc/sphinx/book/app/d-plugins.rst similarity index 99% rename from doc/sphinx/book/app/d_plugins.rst rename to doc/sphinx/book/app/d-plugins.rst index 2103ce827c6a40924628787c55b0010cb1f652d9..1553a9a02dda93d4a8c12f04dfe0b5056b2a35c9 100644 --- a/doc/sphinx/book/app/d_plugins.rst +++ b/doc/sphinx/book/app/d-plugins.rst @@ -595,7 +595,6 @@ on /usr. The PostgreSQL server is already running on the local host 127.0.0.1. .. code-block:: console - $ # Check that the include subdirectory exists $ # by looking for /usr/include/postgresql/libpq-fe-h. $ [ -f /usr/include/postgresql/libpq-fe.h ] && echo "OK" || echo "Error" diff --git a/doc/sphinx/book/app/e_sophia/i1.png b/doc/sphinx/book/app/e-sophia/i1.png similarity index 100% rename from doc/sphinx/book/app/e_sophia/i1.png rename to doc/sphinx/book/app/e-sophia/i1.png diff --git a/doc/sphinx/book/app/e_sophia/i10.png b/doc/sphinx/book/app/e-sophia/i10.png similarity index 100% rename from doc/sphinx/book/app/e_sophia/i10.png rename to doc/sphinx/book/app/e-sophia/i10.png diff --git a/doc/sphinx/book/app/e_sophia/i12.png b/doc/sphinx/book/app/e-sophia/i12.png similarity index 100% rename from doc/sphinx/book/app/e_sophia/i12.png rename to doc/sphinx/book/app/e-sophia/i12.png diff --git a/doc/sphinx/book/app/e_sophia/i13.png b/doc/sphinx/book/app/e-sophia/i13.png similarity index 100% rename from doc/sphinx/book/app/e_sophia/i13.png rename to doc/sphinx/book/app/e-sophia/i13.png diff --git a/doc/sphinx/book/app/e_sophia/i14.png b/doc/sphinx/book/app/e-sophia/i14.png similarity index 100% rename from doc/sphinx/book/app/e_sophia/i14.png rename to doc/sphinx/book/app/e-sophia/i14.png diff --git a/doc/sphinx/book/app/e_sophia/i2.png b/doc/sphinx/book/app/e-sophia/i2.png similarity index 100% rename from doc/sphinx/book/app/e_sophia/i2.png rename to doc/sphinx/book/app/e-sophia/i2.png diff --git a/doc/sphinx/book/app/e_sophia/i3.png b/doc/sphinx/book/app/e-sophia/i3.png similarity index 100% rename from doc/sphinx/book/app/e_sophia/i3.png rename to doc/sphinx/book/app/e-sophia/i3.png diff --git a/doc/sphinx/book/app/e_sophia/i4.png b/doc/sphinx/book/app/e-sophia/i4.png similarity index 100% rename from doc/sphinx/book/app/e_sophia/i4.png rename to doc/sphinx/book/app/e-sophia/i4.png diff --git a/doc/sphinx/book/app/e_sophia/i5.png b/doc/sphinx/book/app/e-sophia/i5.png similarity index 100% rename from doc/sphinx/book/app/e_sophia/i5.png rename to doc/sphinx/book/app/e-sophia/i5.png diff --git a/doc/sphinx/book/app/e_sophia/i6.png b/doc/sphinx/book/app/e-sophia/i6.png similarity index 100% rename from doc/sphinx/book/app/e_sophia/i6.png rename to doc/sphinx/book/app/e-sophia/i6.png diff --git a/doc/sphinx/book/app/e_sophia/i7.png b/doc/sphinx/book/app/e-sophia/i7.png similarity index 100% rename from doc/sphinx/book/app/e_sophia/i7.png rename to doc/sphinx/book/app/e-sophia/i7.png diff --git a/doc/sphinx/book/app/e_sophia/i8.png b/doc/sphinx/book/app/e-sophia/i8.png similarity index 100% rename from doc/sphinx/book/app/e_sophia/i8.png rename to doc/sphinx/book/app/e-sophia/i8.png diff --git a/doc/sphinx/book/app/e_sophia/i9.png b/doc/sphinx/book/app/e-sophia/i9.png similarity index 100% rename from doc/sphinx/book/app/e_sophia/i9.png rename to doc/sphinx/book/app/e-sophia/i9.png diff --git a/doc/sphinx/book/app/e_sophia/index.rst b/doc/sphinx/book/app/e-sophia/index.rst similarity index 100% rename from doc/sphinx/book/app/e_sophia/index.rst rename to doc/sphinx/book/app/e-sophia/index.rst diff --git a/doc/sphinx/book/box/authentication.rst b/doc/sphinx/book/box/authentication.rst index f739157668c58731d461b66a7c4549039e5237d6..8adeee8b3b080c86c3b1966c04987b8c3fd271ae 100644 --- a/doc/sphinx/book/box/authentication.rst +++ b/doc/sphinx/book/box/authentication.rst @@ -342,8 +342,8 @@ purposes are: .. cssclass:: highlight .. parsed-literal:: - box.session.uid() -- returns the id of the current user - box.session.user() -- returns the name of the current user + box.session.uid() -- returns the id of the current user + box.session.user() -- returns the name of the current user box.session.su(*user-name*) -- allows changing current user to 'user-name' If a user types requests directly on the Tarantool server in its interactive diff --git a/doc/sphinx/book/box/box_space.rst b/doc/sphinx/book/box/box_space.rst index 11ffb4212a0ee056810fdee5d1483987d793d008..2b6377f24365c95bce98ca6392edb16894e58832 100644 --- a/doc/sphinx/book/box/box_space.rst +++ b/doc/sphinx/book/box/box_space.rst @@ -78,7 +78,6 @@ A list of all ``box.space`` functions follows, then comes a list of all | :class:`box.space._cluster` | .(Metadata) List of clusters | +---------------------------------------------------------------------+---------------------------------+ - .. module:: box.space .. class:: space_object @@ -90,10 +89,12 @@ A list of all ``box.space`` functions follows, then comes a list of all first created index, which will be used as the primary-key index, must be unique. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`; - :codeitalic:`index_name` (type = string) = name of index, which should not be a number and - should not contain special characters; - :codeitalic:`options`. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`; + * :codeitalic:`index_name` (type = string) = name of index, which should + not be a number and should not contain special characters; + * :codeitalic:`options`. :return: index object :rtype: index_object @@ -148,8 +149,10 @@ A list of all ``box.space`` functions follows, then comes a list of all Insert a tuple into a space. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`; - :codeitalic:`tuple` (type = Lua table or tuple) = tuple to be inserted. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`; + * :codeitalic:`tuple` (type = Lua table or tuple) = tuple to be inserted. :return: the inserted tuple :rtype: tuple @@ -172,9 +175,11 @@ A list of all ``box.space`` functions follows, then comes a list of all Search for a tuple or a set of tuples in the given space. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`; - :codeitalic:`key` (type = Lua table or scalar) = key to be matched against the index - key, which may be multi-part. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`; + * :codeitalic:`key` (type = Lua table or scalar) = key to be matched + against the index key, which may be multi-part. :return: the tuples whose primary-key fields are equal to the passed field-values. If the number of passed field-values is less @@ -243,9 +248,11 @@ A list of all ``box.space`` functions follows, then comes a list of all Search for a tuple in the given space. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`; - :codeitalic:`key` (type = Lua table or scalar) = key to be matched against the index - key, which may be multi-part. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`; + * :codeitalic:`key` (type = Lua table or scalar) = key to be matched + against the index key, which may be multi-part. :return: the tuple whose index key matches :codeitalic:`key`, or null. :rtype: tuple @@ -273,7 +280,9 @@ A list of all ``box.space`` functions follows, then comes a list of all Drop a space. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`. :return: nil @@ -292,8 +301,10 @@ A list of all ``box.space`` functions follows, then comes a list of all Rename a space. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`; - :codeitalic:`space-name` (type = string) = new name for space. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`; + * :codeitalic:`space-name` (type = string) = new name for space. :return: nil @@ -319,8 +330,10 @@ A list of all ``box.space`` functions follows, then comes a list of all ``box.space...:put()`` have the same effect; the latter is sometimes used to show that the effect is the converse of ``box.space...:get()``. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`; - :codeitalic:`tuple` (type = Lua table or tuple) = tuple to be inserted. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`; + * :codeitalic:`tuple` (type = Lua table or tuple) = tuple to be inserted. :return: the inserted tuple. :rtype: tuple @@ -372,22 +385,24 @@ A list of all ``box.space`` functions follows, then comes a list of all For ``!`` and ``=`` operations the field number can be ``-1``, meaning the last field in the tuple. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`; - :codeitalic:`key` (type = Lua table or scalar) = primary-key field values, must be passed as a Lua - table if key is multi-part; - :codeitalic:`{operator, field_no, value}` (type = table): a group of arguments for each - operation, indicating what the operation is, what field the - operation will apply to, and what value will be applied. The - field number can be negative, meaning the position from the - end of tuple (#tuple + negative field number + 1). + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`; + * :codeitalic:`key` (type = Lua table or scalar) = primary-key field + values, must be passed as a Lua table if key is multi-part; + * :codeitalic:`{operator, field_no, value}` (type = table): a group of + arguments for each operation, indicating what the operation is, what + field the operation will apply to, and what value will be applied. The + field number can be negative, meaning the position from the end of + tuple (#tuple + negative field number + 1). :return: the updated tuple. :rtype: tuple Possible errors: it is illegal to modify a primary-key field. - **Complexity Factors:** Index size, Index type, number of indexes accessed, WAL - settings. + **Complexity Factors:** Index size, Index type, number of indexes + accessed, WAL settings. Note re storage engine: sophia will return nil, rather than the updated tuple. @@ -397,11 +412,11 @@ A list of all ``box.space`` functions follows, then comes a list of all s:update(44, {{'+', 1, 55 }, {'=', 3, 'x'}}) - the primary-key value is ``44``, the operators are ``'+'`` and ``'='`` meaning - *add a value to a field and then assign a value to a field*, the first - affected field is field ``1`` and the value which will be added to it is - ``55``, the second affected field is field ``3`` and the value which will be - assigned to it is ``'x'``. + the primary-key value is ``44``, the operators are ``'+'`` and ``'='`` + meaning *add a value to a field and then assign a value to a field*, the + first affected field is field ``1`` and the value which will be added to + it is ``55``, the second affected field is field ``3`` and the value + which will be assigned to it is ``'x'``. **Example:** @@ -519,15 +534,16 @@ A list of all ``box.space`` functions follows, then comes a list of all error checks before returning -- this is a design feature which enhances throughput but requires more caution on the part of the user. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`; - :samp:`{tuple_value}` (type = Lua table or scalar) = - field values, must be passed as a Lua - table if tuple_value contains more than one field; - :codeitalic:`{operator, field_no, value}` (type = Lua table) = a group of arguments for each - operation, indicating what the operation is, what field the - operation will apply to, and what value will be applied. The - field number can be negative, meaning the position from the - end of tuple (#tuple + negative field number + 1). + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`; + * :samp:`{tuple_value}` (type = Lua table or scalar) = field values, + must be passed as a Lua table if tuple_value contains more than one field; + * :codeitalic:`{operator, field_no, value}` (type = Lua table) = a group + of arguments for each operation, indicating what the operation is, + what field the operation will apply to, and what value will be applied. + The field number can be negative, meaning the position from the end of + tuple (#tuple + negative field number + 1). :return: null. @@ -546,9 +562,11 @@ A list of all ``box.space`` functions follows, then comes a list of all Delete a tuple identified by a primary key. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`; - :codeitalic:`key` (type = Lua table or scalar) = key to be matched against the index - key, which may be multi-part. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>` + * :codeitalic:`key` (type = Lua table or scalar) = key to be matched + against the index key, which may be multi-part. :return: the deleted tuple :rtype: tuple @@ -581,7 +599,9 @@ A list of all ``box.space`` functions follows, then comes a list of all ``box.space.tester:insert{0}`` and ``box.space[800]:insert{0}`` are equivalent requests. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`. **Example:** @@ -597,7 +617,9 @@ A list of all ``box.space`` functions follows, then comes a list of all Whether or not this space is enabled. The value is ``false`` if the space has no index. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`. .. _space-object-field-count: @@ -617,7 +639,9 @@ A list of all ``box.space`` functions follows, then comes a list of all The default value is ``0``, which means there is no required field count. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`. **Example:** @@ -634,7 +658,9 @@ A list of all ``box.space`` functions follows, then comes a list of all :mod:`box.index` with methods to search tuples and iterate over them in predefined order. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`. :rtype: table @@ -674,7 +700,9 @@ A list of all ``box.space`` functions follows, then comes a list of all .. method:: len() - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`. :return: Number of tuples in the space. @@ -693,7 +721,9 @@ A list of all ``box.space`` functions follows, then comes a list of all Deletes all tuples. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`. **Complexity Factors:** Index size, Index type, Number of tuples accessed. @@ -722,8 +752,11 @@ A list of all ``box.space`` functions follows, then comes a list of all value set to ``1``. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`; - :codeitalic:`field-value(s)` (type = Lua table or scalar) = values which must match the primary key. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`; + * :codeitalic:`field-value(s)` (type = Lua table or scalar) = values + which must match the primary key. :return: the new counter value :rtype: number @@ -760,8 +793,11 @@ A list of all ``box.space`` functions follows, then comes a list of all ``field-value(s)``, a new one is not inserted. If the counter value drops to zero, the tuple is deleted. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`; - :codeitalic:`field-value(s)` (type = Lua table or scalar) = values which must match the primary key. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`; + * :codeitalic:`field-value(s)` (type = Lua table or scalar) = values + which must match the primary key. :return: the new counter value :rtype: number @@ -803,8 +839,11 @@ A list of all ``box.space`` functions follows, then comes a list of all primary-key field will be incremented before the insert. Note re storage engine: sophia does not support auto_increment. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`; - :codeitalic:`field-value(s)` (type = Lua table or scalar) = tuple's fields, other than the primary-key field. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`; + * :codeitalic:`field-value(s)` (type = Lua table or scalar) = tuple's + fields, other than the primary-key field. :return: the inserted tuple. :rtype: tuple @@ -831,7 +870,9 @@ A list of all ``box.space`` functions follows, then comes a list of all A helper function to prepare for iterating over all tuples in a space. - Parameters: :samp:`{space_object}` = an :ref:`object reference <object-reference>`. + Parameters: + + * :samp:`{space_object}` = an :ref:`object reference <object-reference>`. :return: function which can be used in a for/end loop. Within the loop, a value is returned for each iteration. :rtype: function, tuple diff --git a/doc/sphinx/book/box/index.rst b/doc/sphinx/book/box/index.rst index 78cf16997756a6b9a9c8c1e66ce7af222ffa0a29..f3a3371987aa3c5540ffc647c086de34cf132f27 100644 --- a/doc/sphinx/book/box/index.rst +++ b/doc/sphinx/book/box/index.rst @@ -470,110 +470,131 @@ The simple index-creation operation which has been illustrated before is: |br| By default, this creates a unique "tree" index on the first field of all tuples (often called "Field#1"), which is assumed to be numeric. -These variations exist: |br| +These variations exist: + (1) A indexed field may be a string rather than a number. |br| -:codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:create_index('index-name',{parts={1,'STR'}})` |br| -For an ordinary index, the two possible data types are 'NUM' -= numeric = any positive integer, or 'STR' ='string' = any -series of bytes. Numbers are ordered -according to their point on the number line -- so 2345 is -greater than 500 -- while strings are ordered according to the -encoding of the first byte then the encoding of the second -byte then the encoding of the third byte and so on -- so -'2345' is less than '500'. |br| + :codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:create_index('index-name',{parts = {1, 'STR'}})` |br| + For an ordinary index, the two possible data types are 'NUM' = numeric = any + positive integer, or 'STR' ='string' = any series of bytes. Numbers are + ordered according to their point on the number line -- so 2345 is greater + than 500 -- while strings are ordered according to the encoding of the first + byte then the encoding of the second byte then the encoding of the third + byte and so on -- so '2345' is less than '500'. (2) There may be more than one field. |br| -:codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:create_index('index-name',{parts={3,'NUM',2,'STR'}})` |br| -For an ordinary index, the maximum number of parts is 255. -The specification of each part consists of a field number -and a type. |br| + :codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:create_index('index-name', {parts = {3, 'NUM', 2, 'STR'}})` |br| + For an ordinary index, the maximum number of parts is 255. The specification + of each part consists of a field number and a type. |br| (3) The index does not have to be unique. |br| -:codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:create_index('index-name',{unique=false})` |br| -The first index of a tuple set must be unique, but -other indexes ("secondary" indexes) may be non-unique. |br| + :codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:create_index('index-name', {unique = false})` |br| + The first index of a tuple set must be unique, but other indexes ("secondary" + indexes) may be non-unique. |br| (4) The index does not have to be a tree. |br| -:codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:create_index('index-name',{type='hash'})` |br| -The two ordinary index types are 'tree' which is the default, -and 'hash' which must be unique and which may be faster or -smaller. The third type is 'bitset' which is not unique and -which works best for combinations of binary values. -The fourth type is 'rtree' which is not unique and -which, instead of 'STR' or 'NUM' values, works with arrays. - -The existence of indexes does not affect the syntax of -data-change requests, but does cause select requests to -have more variety. + :codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:create_index('index-name', {type = 'hash'})` |br| + The two ordinary index types are 'tree' which is the default, and 'hash' + which must be unique and which may be faster or smaller. The third type is + 'bitset' which is not unique and which works best for combinations of binary + values. The fourth type is 'rtree' which is not unique and which, instead of + 'STR' or 'NUM' values, works with arrays. + +The existence of indexes does not affect the syntax of data-change requests, but +does cause select requests to have more variety. The simple select request which has been illustrated before is: |br| -:codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:select(value)` |br| -By default, this looks for a single tuple -via the first index. Since the first index is always unique, -the maximum number of returned tuples will be: one. - -These variations exist. |br| -(1) The search can use comparisons other than equality. |br| -:codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:select('value',{iterator='GT'})` |br| -The comparison operators are LT LE EQ REQ GE GT for -"less than" "less than or equal" "equal" "reversed -equal" "greater than -or equal" "greater than" respectively. -Comparisons make sense if and only if the index type -is 'tree'. -This type of search may return more than one tuple; -if so, the tuples will be in descending order by key -when the comparison operator is LT or LE or REQ, -otherwise in ascending order. -Note re storage engines: sophia does not allow REQ. |br| +:samp:`box.space.{space-name}:select(value)` |br| +By default, this looks for a single tuple via the first index. Since the first +index is always unique, the maximum number of returned tuples will be: one. + +These variations exist: + +(1) The search can use comparisons other than equality. + :codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:select('value', {iterator='GT'})` + The comparison operators are: + + * ``LT`` - "less than" + * ``LE`` - "less than or equal" + * ``EQ`` - "equal" + * ``REQ`` - "reversed equal" + * ``GE`` - "greater than or equal" + * ``GT`` - "greater than" + + Comparisons make sense if and only if the index type is 'tree'. This type of + search may return more than one tuple; if so, the tuples will be in + descending order by key when the comparison operator is ``LT`` or ``LE`` + or ``REQ``, otherwise in ascending order. |br| + Note re storage engines: sophia does not allow ``REQ``. (2) The search can use a secondary index. |br| -:codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`.index.`:codeitalic:`index-name`:codenormal:`:select('value')` |br| -For a primary-key search, it is optional to specify -and index name. For a secondary-key search, it is -mandatory. |br| -(3) The search may be for some or all key parts. |br| -Suppose an index has two parts: {1,'NUM', 2, 'STR'}}. -Suppose the space has three tuples: {1,'A'},{1,'B'},{2,''}. -The search can be for all fields, using a table for the value: |br| -:codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:select({1,'A'})` |br| -or the search can be for one field, using a table or a scalar: |br| -:codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:select(1)` |br| -... in the second case, the result will be two tuples: -{1,'A'} and {1,'B'}. It's even possible to specify zero -fields, causing all three tuples to be returned. -Note re storage engines: sophia requires that all fields, or none, be specified. - -(1) BITSET example |br| -:codenormal:`box.schema.space.create('bitset_example')` |br| -:codenormal:`box.space.bitset_example:create_index('primary')` |br| -:codenormal:`box.space.bitset_example:create_index('bitset',{unique=false,type='BITSET', parts={2,'NUM'}})` |br| -:codenormal:`box.space.bitset_example:insert{1,1}` |br| -:codenormal:`box.space.bitset_example:insert{2,4}` |br| -:codenormal:`box.space.bitset_example:insert{3,7}` |br| -:codenormal:`box.space.bitset_example:insert{4,3}` |br| -:codenormal:`box.space.bitset_example.index.bitset:select(2, {iterator='BITS_ANY_SET'})` |br| -The result will be: |br| -:codenormal:`---` |br| -:codenormal:`- - [3, 7]` |br| -|nbsp| |nbsp| :codenormal:`- [4, 3]` |br| -:codenormal:`...` |br| -because (7 AND 2) is not equal to 0, and (3 AND 2) is not equal to 0. -Searches on BITSET indexes can be for BITS_ANY_SET, BITS_ALL_SET, -BITS_ALL_NOT_SET, EQ, or ALL. - -(2) RTREE example |br| -:codenormal:`box.schema.space.create('rtree_example')` |br| -:codenormal:`box.space.rtree_example:create_index('primary')` |br| -:codenormal:`box.space.rtree_example:create_index('rtree',{unique=false,type='RTREE', parts={2,'ARRAY'}})` |br| -:codenormal:`box.space.rtree_example:insert{1, {3, 5, 9, 10}}` |br| -:codenormal:`box.space.rtree_example:insert{2, {10, 11}}` |br| -:codenormal:`box.space.rtree_example.index.rtree:select({4, 7, 5, 9}, {iterator = 'GT'})` |br| -The result will be: -:codenormal:`---` |br| -:codenormal:`- - [1, [3, 5, 9, 10]]` |br| -:codenormal:`...` |br| -because a rectangle whose corners are at coordinates -4,7,5,9 is entirely within a rectangle whose corners -are at coordinates 3,5,9,10. Searches on RTREE indexes -can be for GT, GE, LT, LE, OVERLAPS, or NEIGHBOR. - + :samp:`box.space.{space-name}.index.{index-name}:select('value')` |br| + For a primary-key search, it is optional to specify and index name. For a + secondary-key search, it is mandatory. +(3) The search may be for some or all key parts. Suppose an index has two parts: + ``{1,'NUM', 2, 'STR'}``. Suppose the space has three tuples: ``{1, 'A'}``, + ``{1, 'B'}``, ``{2, ''}``. The search can be for all fields, using a table + for the value: + :codenormal:`box.space.`:codeitalic:`space-name`:codenormal:`:select({1, 'A'})` + or the search can be for one field, using a table or a scalar: + :samp:`box.space.{space-name}:select(1)` |br| + in the second case, the result will be two tuples: {1, 'A'} and {1, 'B'}. + It's even possible to specify zero fields, causing all three tuples to be + returned. |br| + Note re storage engines: sophia requires that all fields, or none, be specified. + +(1) BITSET example: + + .. code-block:: lua + + box.schema.space.create('bitset_example') + box.space.bitset_example:create_index('primary') + box.space.bitset_example:create_index('bitset', { + unique = false, + type = 'BITSET', + parts = {2, 'NUM'} + }) + box.space.bitset_example:insert{1, 1} + box.space.bitset_example:insert{2, 4} + box.space.bitset_example:insert{3, 7} + box.space.bitset_example:insert{4, 3} + box.space.bitset_example.index.bitset:select(2, {iterator = 'BITS_ANY_SET'}) + + The result will be: + + .. code-block:: yaml + + --- + - - [3, 7] + - [4, 3] + ... + + because (7 AND 2) is not equal to 0, and (3 AND 2) is not equal to 0. + Searches on BITSET indexes can be for ``BITS_ANY_SET``, ``BITS_ALL_SET``, + ``BITS_ALL_NOT_SET``, ``EQ``, or ``ALL``. + +(2) RTREE example: + + .. code-block:: lua + + box.schema.space.create('rtree_example') + box.space.rtree_example:create_index('primary') + box.space.rtree_example:create_index('rtree', { + unique = false, + type = 'RTREE', + parts = {2, 'ARRAY'} + }) + box.space.rtree_example:insert{1, {3, 5, 9, 10}} + box.space.rtree_example:insert{2, {10, 11}} + box.space.rtree_example.index.rtree:select({4, 7, 5, 9}, {iterator = 'GT'}) + + The result will be: + + .. code-block:: yaml + + --- + - - [1, [3, 5, 9, 10]] + ... + + because a rectangle whose corners are at coordinates 4,7,5,9 is entirely + within a rectangle whose corners are at coordinates 3,5,9,10. Searches on + RTREE indexes can be for ``GT``, ``GE``, ``LT``, ``LE``, ``OVERLAPS``, or + ``NEIGHBOR``. .. _box-library: @@ -600,8 +621,8 @@ introspection (inspecting contents of spaces, accessing server configuration). .. container:: table - **Complexity Factors that may affect data - manipulation functions in the box library** + **Complexity Factors that may affect data manipulation functions in the box + library** .. rst-class:: left-align-column-1 .. rst-class:: left-align-column-2 diff --git a/doc/sphinx/book/box/sophia_diff.rst b/doc/sphinx/book/box/sophia_diff.rst index 6196bec097ebbe5fbdd9842764c5a7427c2fa5a8..c083e56f35c50f8c205105a386fcb1761ff6b6f1 100644 --- a/doc/sphinx/book/box/sophia_diff.rst +++ b/doc/sphinx/book/box/sophia_diff.rst @@ -4,21 +4,21 @@ Differences between memtx and sophia storage engines ------------------------------------------------------------------------------- - The primary difference between memtx and sophia is that - memtx is an "in-memory" engine while sophia is an "on-disk" - engine. An in-memory storage engine is generally faster, - and the memtx engine is justifiably the default for Tarantool, - but there are two situations where an on-disk engine such as + The primary difference between memtx and sophia is that memtx is an + "in-memory" engine while sophia is an "on-disk" engine. An in-memory storage + engine is generally faster, and the memtx engine is justifiably the default + for Tarantool, but there are two situations where an on-disk engine such as sophia would be preferable: - (1) when the database is larger than the available memory and - adding more memory is not a realistic option; - (2) when the server frequently goes down due to errors - or a simple desire to save power -- bringing the server - back up and restoring a memtx database into memory takes time. - - Here are behavior differences which affect programmers. - All of these differences have been noted elsewhere in - sentences that begin with the words "Note re storage engine: sophia". + + (1) when the database is larger than the available memory and adding more + memory is not a realistic option; + (2) when the server frequently goes down due to errors or a simple desire to + save power -- bringing the server back up and restoring a memtx database + into memory takes time. + + Here are behavior differences which affect programmers. All of these + differences have been noted elsewhere in sentences that begin with the words + "Note re storage engine: sophia". With memtx, the maximum number of indexes per space is 128. |br| With sophia, the maximum is 1, that is, only primary indexes are supported. diff --git a/doc/sphinx/book/box/triggers.rst b/doc/sphinx/book/box/triggers.rst index 2c993cc07d598b9218ef7607c3b64d34a7da5e22..b2d6e6678f209836d7d45e41ddbc6365dcbb0881 100644 --- a/doc/sphinx/book/box/triggers.rst +++ b/doc/sphinx/book/box/triggers.rst @@ -130,11 +130,13 @@ Here is what might appear in the log file in a typical installation: Define a trigger for execution during authentication. The on_auth trigger function is invoked in these circumstances: - (1) The :func:`console.connect` function includes an authentication check for all users except 'guest'; - for this case the on_auth trigger function is invoked after the on_connect trigger function, - if and only if the connection has succeeded so far. - (2) The binary protocol has a separate :ref:`authentication packet <iproto-authentication>` -- - for this case, connection and authentication are considered to be separate steps. + (1) The :func:`console.connect` function includes an authentication check + for all users except 'guest'; for this case the on_auth trigger function + is invoked after the on_connect trigger function, if and only if the + connection has succeeded so far. + (2) The binary protocol has a separate + :ref:`authentication packet <iproto-authentication>` -- for this case, + connection and authentication are considered to be separate steps. Unlike other trigger types, on_auth trigger functions are invoked `before` the event. Therefore a trigger function like :code:`function auth_function () v = box.session.user(); end` @@ -250,16 +252,13 @@ each trigger by replacing with ``nil``. Getting a list of triggers =========================================================== -The code :code:`on_connect()` -- with no arguments -- -returns a table of all connect-trigger functions; -:code:`on_auth()` returns all authentication-trigger functions; -:code:`on_disconnect()` returns all disconnect-trigger functions; -:code:`on_replace()` returns all replace-trigger functions. -In the following example a user finds that there are -three functions associated with :code:`on_connect` -triggers, and executes the third function, which happens to -contain the line "print('function #3')". -Then it deletes the third trigger. +The code :code:`on_connect()` -- with no arguments -- returns a table of all +connect-trigger functions; :code:`on_auth()` returns all authentication-trigger +functions; :code:`on_disconnect()` returns all disconnect-trigger functions; +:code:`on_replace()` returns all replace-trigger functions. In the following +example a user finds that there are three functions associated with +:code:`on_connect` triggers, and executes the third function, which happens to +contain the line "print('function #3')". Then it deletes the third trigger. .. code-block:: tarantoolsession diff --git a/doc/sphinx/book/configuration/cfg-replication.rst b/doc/sphinx/book/configuration/cfg-replication.rst index bba953e1d77ea9005fb13b14c1e58d5cbbb6e8c8..159c251704e1bb3133eec512d4a48d72cf6b97b2 100644 --- a/doc/sphinx/book/configuration/cfg-replication.rst +++ b/doc/sphinx/book/configuration/cfg-replication.rst @@ -6,8 +6,8 @@ Resource Identifier), for example :samp:`{konstantin}:{secret_password}@{tarantool.org}:{3301}`. If there is more than one replication source in a cluster, specify an - array of URIs, for example |br| - :codenormal:`box.cfg{replication_source = {`:codeitalic:`uri#1,uri#2`:codenormal:`}}` |br| + array of URIs, for example: |br| + :codenormal:`box.cfg{replication_source = {`:codeitalic:`uri#1, uri#2`:codenormal:`}}` |br| If one of the URIs is "self" -- that is, if one of the URIs is for the same server that :codenormal:`box.cfg{}` is being executed on -- diff --git a/doc/sphinx/book/connectors/__php.rst b/doc/sphinx/book/connectors/__php.rst index f0106c12656a77cf82b509513bba3c2aabfb3309..42ac6bd8d6ff0499ba0cc836538dff77f6fd04c1 100644 --- a/doc/sphinx/book/connectors/__php.rst +++ b/doc/sphinx/book/connectors/__php.rst @@ -28,11 +28,13 @@ line like :code:`extension=./tarantool.so`, or if PHP is started with the option Here is a complete PHP program that inserts [99999,'BB'] into a space named 'examples' via the PHP API. Before trying to run, check that the server is listening and that -:code:`examples` exists, as :ref:`described earlier <connector-setting>`. To run, paste the code into a file named -example.php and say :code:`php -d extension=~/tarantool-php/modules/tarantool.so example.php`. The program will open a socket connection with -the tarantool server at localhost:3301, then send an INSERT request, then — if all is -well — print "Insert succeeded". If the tuple already exists, the program will print -“Duplicate key exists in unique index 'primary' in space 'examples'â€. +:code:`examples` exists, as :ref:`described earlier <connector-setting>`. To run, +paste the code into a file named example.php and say +:code:`php -d extension=~/tarantool-php/modules/tarantool.so example.php`. The +program will open a socket connection with the tarantool server at localhost:3301, +then send an INSERT request, then — if all is well — print "Insert succeeded". +If the tuple already exists, the program will print “Duplicate key exists in +unique index 'primary' in space 'examples'â€. .. code-block:: php diff --git a/doc/sphinx/book/connectors/__results.rst b/doc/sphinx/book/connectors/__results.rst index dda74abb5a19f8f2a6d055693627478ff6cc64fe..e7268912cb8fc4a5a8b2443607c247907ae75983 100644 --- a/doc/sphinx/book/connectors/__results.rst +++ b/doc/sphinx/book/connectors/__results.rst @@ -4,92 +4,88 @@ ===================================================================== -For all Connectors, calling a function -via Tarantool causes a return in MsgPack format. -If the function is called using the connector's API, -some conversions may occur. -All scalar values are returned as tuples -(with a MsgPack type-identifier followed by a -value); all non-scalar values are returned as -a group of tuples (with a MsgPack array-identifier -followed by the scalar values). -If the function is called via the binary protocol -command layer -- "eval" -- rather than via the connector's API, -no conversions occur. +For all Connectors, calling a function via Tarantool causes a return in MsgPack +format. If the function is called using the connector's API, some conversions +may occur. All scalar values are returned as tuples (with a MsgPack +type-identifier followed by a value); all non-scalar values are returned as a +group of tuples (with a MsgPack array-identifier followed by the scalar values). +If the function is called via the binary protocol command layer -- "eval" -- +rather than via the connector's API, no conversions occur. -In the following example, a Lua function will be created. -Since it will be accessed externally by a 'guest' user, -a :codenormal:`grant` of an execute privilege will be necessary. -The function returns an empty array, a scalar string, -two booleans, and a short integer. The values are -the ones described in the msgpack section in the table -:ref:`Common Types and MsgPack Encodings <common-types-and-msgpack-encodings>`. +In the following example, a Lua function will be created. Since it will be +accessed externally by a 'guest' user, a `grant`` of an execute privilege will +be necessary. The function returns an empty array, a scalar string, two booleans, +and a short integer. The values are the ones described in the msgpack section in +the table :ref:`Common Types and MsgPack Encodings <common-types-and-msgpack-encodings>`. -:codenormal:`tarantool>` :codebold:`box.cfg{listen=3301}` |br| -:codenormal:`2016-03-03 18:45:52.802 [27381] main/101/interactive I> ready to accept requests` |br| -:codenormal:`---` |br| -:codenormal:`...` |br| -:codenormal:`tarantool>` :codebold:`function f() return {},'a',false,true,127; end` |br| -:codenormal:`---` |br| -:codenormal:`...` |br| -:codenormal:`tarantool>` :codebold:`box.schema.func.create('f')` |br| -:codenormal:`---` |br| -:codenormal:`...` |br| -:codenormal:`tarantool>` :codebold:`box.schema.user.grant('guest','execute','function','f')` |br| -:codenormal:`---` |br| -:codenormal:`...` +.. code-block:: tarantoolsession -Here is a C program which calls the function. -Although C is being used for the example, -the result would be precisely the same if the calling -program was written in Perl, PHP, Python, Go, or Java. + tarantool> box.cfg{listen = 3301} + 2016-03-03 18:45:52.802 [27381] main/101/interactive I> ready to accept requests + --- + ... + tarantool> function f() return {}, 'a', false, true, 127; end + --- + ... + tarantool> box.schema.func.create('f') + --- + ... + tarantool> box.schema.user.grant('guest', 'execute', 'function', 'f') + --- + ... + +Here is a C program which calls the function. Although C is being used for the +example, the result would be precisely the same if the calling program was +written in Perl, PHP, Python, Go, or Java. .. code-block:: c - #include <stdio.h>` |br| - #include <stdlib.h>` |br| - #include <tarantool/tarantool.h>` |br| - #include <tarantool/tnt_net.h>` |br| - #include <tarantool/tnt_opt.h>` |br| - void main() {` |br| - struct tnt_stream *tnt = tnt_net(NULL); /* SETUP */` - tnt_set(tnt, TNT_OPT_URI, "localhost:3301");` - if (tnt_connect(tnt) < 0) { /* CONNECT */` - printf("Connection refused\n");` - exit(-1);` - } - struct tnt_stream *tuple = tnt_object(NULL); /* MAKE REQUEST */ - struct tnt_stream *arg; arg = tnt_object(NULL); - tnt_object_add_array(arg, 0); - struct tnt_request *req1 = tnt_request_call(NULL); /* CALL function f() */ - tnt_request_set_funcz(req1, "f"); - tnt_request_set_tuple(req1, arg); - uint64_t sync1 = tnt_request_compile(tnt, req1); - tnt_flush(tnt); /* SEND REQUEST */ - struct tnt_reply reply; tnt_reply_init(&reply); /* GET REPLY */ - tnt->read_reply(tnt, &reply); - ` if (reply.code != 0) { - printf("Call failed %lu.\n", reply.code); - exit(-1); - } - const unsigned char *p= (unsigned char*)reply.data;/* PRINT REPLY */ - while (p < (unsigned char *) reply.data_end) - { - printf("%x ", *p); - ++p; - } - printf("\n"); - tnt_close(tnt); /* TEARDOWN */ - tnt_stream_free(tuple); - tnt_stream_free(tnt); - } + #include <stdio.h> + #include <stdlib.h> + #include <tarantool/tarantool.h> + #include <tarantool/tnt_net.h> + #include <tarantool/tnt_opt.h> + + void main() { + struct tnt_stream *tnt = tnt_net(NULL); /* SETUP */` + tnt_set(tnt, TNT_OPT_URI, "localhost:3301"); + if (tnt_connect(tnt) < 0) { /* CONNECT */` + printf("Connection refused\n"); + exit(-1); + } + struct tnt_stream *tuple = tnt_object(NULL); /* MAKE REQUEST */ + struct tnt_stream *arg; arg = tnt_object(NULL); + tnt_object_add_array(arg, 0); + struct tnt_request *req1 = tnt_request_call(NULL); /* CALL function f() */ + tnt_request_set_funcz(req1, "f"); + tnt_request_set_tuple(req1, arg); + uint64_t sync1 = tnt_request_compile(tnt, req1); + tnt_flush(tnt); /* SEND REQUEST */ + struct tnt_reply reply; tnt_reply_init(&reply); /* GET REPLY */ + tnt->read_reply(tnt, &reply); + if (reply.code != 0) { + printf("Call failed %lu.\n", reply.code); + exit(-1); + } + const unsigned char *p = (unsigned char*)reply.data; /* PRINT REPLY */ + while (p < (unsigned char *) reply.data_end) { + printf("%x ", *p); + ++p; + } + printf("\n"); + tnt_close(tnt); /* TEARDOWN */ + tnt_stream_free(tuple); + tnt_stream_free(tnt); + } + +When this program is executed, it will print: + +.. code-block:: none + + dd 0 0 0 5 90 91 a1 61 91 c2 91 c3 91 7f -When this program is executed, it will print: |br| -:codenormal:`dd 0 0 0 5 90 91 a1 61 91 c2 91 c3 91 7f` |br| -The first five bytes -- :codenormal:`dd 0 0 0 5` -- are the -msgpack encoding for "32-bit array header with -value 5" (see the msgpack Specification_ page). -The rest are as described in the -Common Types and MsgPack Encodings table. +The first five bytes -- ``dd 0 0 0 5`` -- are the msgpack encoding for "32-bit +array header with value 5" (see the msgpack Specification_ page). The rest are +as described in the Common Types and MsgPack Encodings table. .. _Specification: http://github.com/msgpack/msgpack/blob/master/spec.md diff --git a/doc/sphinx/book/index.rst b/doc/sphinx/book/index.rst index 435b3d3eb78fe98e898037633bb57b6fbeb82258..063968476134b60eb7c4262d6e9946b9fe2fed4f 100644 --- a/doc/sphinx/book/index.rst +++ b/doc/sphinx/book/index.rst @@ -14,8 +14,8 @@ configuration/index administration connectors/index - app/a_errcodes - box/internals - app/c_lua_tutorial - app/d_plugins - app/e_sophia/index + app/a-errcodes + app/b-internals + app/c-lua_tutorial + app/d-plugins + app/e-sophia/index diff --git a/doc/sphinx/book/replication/index.rst b/doc/sphinx/book/replication/index.rst index de0abfa775868153ec00f73c9abff51d24ed0fd2..18daf8d9559ccd13561b20e74b532cbe99b5778e 100644 --- a/doc/sphinx/book/replication/index.rst +++ b/doc/sphinx/book/replication/index.rst @@ -228,69 +228,75 @@ servers will end up with different contents. All the "What If?" Questions ===================================================================== - -Q: What if there are more than two servers with master-master? |br| -A: On each server, specify the :confval:`replication_source` for all the -others. For example, server #3 would have a request: |br| -:codenormal:`box.cfg{` |br| -|nbsp| |nbsp| |nbsp| :codenormal:`replication_source = {`:codeitalic:`uri#1, uri#2`:codenormal:`}` |br| -:codenormal:`}` - -Q: What if a server should be taken out of the cluster? |br| -A: Run ``box.cfg{}`` again specifying a blank replication source: |br| -``box.cfg{replication_source=''}`` - -Q: What if a server leaves the cluster? |br| -A: The other servers carry on. If the wayward server rejoins, it will -receive all the updates that the other servers made while it was away. - -Q: What if two servers both change the same tuple? |br| -A: The last changer wins. For example, suppose that server#1 changes the -tuple, then server#2 changes the tuple. In that case server#2's change -overrides whatever server#1 did. In order to keep track of who came last, -Tarantool implements a `vector clock`_. - -Q: What if two servers both insert the same tuple? |br| -A: If a master tries to insert a tuple which a replica has inserted -already, this is an example of a severe error. Replication stops. -It will have to be restarted manually. - -Q: What if a master disappears and the replica must take over? |br| -A: A message will appear on the replica stating that the connection is -lost. The replica must now become independent, which can be done by -saying ``box.cfg{replication_source=''}``. - -Q: What if it's necessary to know what cluster a server is in? |br| -A: The identification of the cluster is a UUID which is generated when the -first master starts for the first time. This UUID is stored in a tuple -of the :data:`box.space._schema` system space. So to see it, say: -``box.space._schema:select{'cluster'}`` - -Q: What if it's necessary to know what other servers belong in the cluster? |br| -A: The universal identification of a server is a UUID in ``box.info.server.uuid``. -The ordinal identification of a server within a cluster is a number in ``box.info.server.id``. -To see all the servers in the cluster, say: -``box.space._cluster:select{}``. This will return a table with all -{server.id, server.uuid} tuples for every server that has ever joined -the cluster. - -Q: What if one of the server's files is corrupted or deleted? |br| -A: Stop the server, destroy all the database files (the ones with extension -"snap" or "xlog" or ".inprogress"), restart the server, and catch up -with the master by contacting it again (just say -``box.cfg{...replication_source=...}``). - -Q: What if replication causes security concerns? |br| -A: Prevent unauthorized replication sources by associating a password with -every user that has access privileges for the relevant spaces, and every -user that has a replication :ref:`role <rep-role>`. That way, -the :ref:`URI` for the :confval:`replication_source` parameter will -always have to have the long form |br| -``replication_source='username:password@host:port'`` - -Q: What if advanced users want to understand better how it all works? |br| -A: See the description of server startup with replication in the -:ref:`Internals <internals-replication>` appendix. +.. container:: faq + + :Q: What if there are more than two servers with master-master? + :A: On each server, specify the :confval:`replication_source` for all the + others. For example, server #3 would have a request: + + .. cssclass:: highlight + .. parsed-literal:: + + box.cfg{ + replication_source = { *uri#1*, *uri#2* } + } + + + :Q: What if a server should be taken out of the cluster? + :A: Run ``box.cfg{}`` again specifying a blank replication source: |br| + ``box.cfg{replication_source=''}`` + + :Q: What if a server leaves the cluster? + :A: The other servers carry on. If the wayward server rejoins, it will + receive all the updates that the other servers made while it was away. + + :Q: What if two servers both change the same tuple? + :A: The last changer wins. For example, suppose that server#1 changes the + tuple, then server#2 changes the tuple. In that case server#2's change + overrides whatever server#1 did. In order to keep track of who came last, + Tarantool implements a `vector clock`_. + + :Q: What if two servers both insert the same tuple? + :A: If a master tries to insert a tuple which a replica has inserted + already, this is an example of a severe error. Replication stops. + It will have to be restarted manually. + + :Q: What if a master disappears and the replica must take over? + :A: A message will appear on the replica stating that the connection is + lost. The replica must now become independent, which can be done by + saying ``box.cfg{replication_source=''}``. + + :Q: What if it's necessary to know what cluster a server is in? + :A: The identification of the cluster is a UUID which is generated when the + first master starts for the first time. This UUID is stored in a tuple + of the :data:`box.space._schema` system space. So to see it, say: + ``box.space._schema:select{'cluster'}`` + + :Q: What if it's necessary to know what other servers belong in the cluster? + :A: The universal identification of a server is a UUID in ``box.info.server.uuid``. + The ordinal identification of a server within a cluster is a number in + ``box.info.server.id``. To see all the servers in the cluster, say: + ``box.space._cluster:select{}``. This will return a table with all + {server.id, server.uuid} tuples for every server that has ever joined + the cluster. + + :Q: What if one of the server's files is corrupted or deleted? + :A: Stop the server, destroy all the database files (the ones with extension + "snap" or "xlog" or ".inprogress"), restart the server, and catch up + with the master by contacting it again (just say + ``box.cfg{...replication_source=...}``). + + :Q: What if replication causes security concerns? + :A: Prevent unauthorized replication sources by associating a password with + every user that has access privileges for the relevant spaces, and every + user that has a replication :ref:`role <rep-role>`. That way, the + :ref:`URI` for the :confval:`replication_source` parameter will always + have to have the long form |br| + ``replication_source='username:password@host:port'`` + + :Q: What if advanced users want to understand better how it all works? + :A: See the description of server startup with replication in the + :ref:`Internals <internals-replication>` appendix. .. _vector clock: https://en.wikipedia.org/wiki/Vector_clock diff --git a/doc/sphinx/faq.rst b/doc/sphinx/faq.rst index 1c360b6084bdd11c3a8c2ffd089e01ac5d0e445c..6f571762897a7db7c6e4e36c6b3f9ba0ddee4c33 100644 --- a/doc/sphinx/faq.rst +++ b/doc/sphinx/faq.rst @@ -1,17 +1,13 @@ -:title: FAQ's -:slug: faq -:save_as: doc/faq.html -:template: documentation_rst - ------------------------------------------------------------------------------- FAQ ------------------------------------------------------------------------------- + .. container:: faq :Q: Why Tarantool? :A: Tarantool is the latest generation of a family of in-memory data servers developed for web applications. It is the result of practical experience - and trials within Mail.Ru since development began in 2008. + and trials within Mail.Ru since development began in 2008. :Q: Why Lua? :A: Lua is a lightweight, fast, extensible multi-paradigm language. Lua also happens @@ -24,7 +20,7 @@ :A: Tarantool provides a rich database feature set (HASH, TREE, RTREE, BITSET indexes, secondary indexes, composite indexes, transactions, triggers, asynchronous replication) in a flexible environment of a Lua interpreter. - + These two properties make it possible to be a fast, atomic and reliable in-memory data server which handles non-trivial application-specific logic. The advantage over traditional SQL servers is in performance: low-overhead, lock-free architecture @@ -32,27 +28,23 @@ comparable hardware. The advantage over NoSQL alternatives is in flexibility: Lua allows flexible processing of data stored in a compact, denormalized format. - :Q: What are your development plans? :A: We continuously improve server performance. On the feature front, automatic sharding and bsync (bidirectional file synchronization) and a subset of SQL are the major goals for 2016. We have an open roadmap to which we encourage anyone to add feature requests. - :Q: Who is developing Tarantool? :A: There is an engineering team employed by Mail.Ru -- check out our commit logs on github.com/tarantool. The development is fully open. Most of the connectors' authors, and the maintainers for different distributions, come from the wider community. - :Q: How serious is Mail.Ru about Tarantool? :A: Tarantool is an open source project, distributed under a BSD license, so it does not depend on any one sponsor. However, it is an integral part of the Mail.Ru backbone, so it gets a lot of support from Mail.Ru. - :Q: Are there problems associated with being an in-memory server? :A: The principal storage engine is designed for RAM plus persistent storage. It is immune to data loss because there is a write-ahead log. @@ -62,5 +54,3 @@ requests without difficulty. However, for databases which are much larger than the available RAM space, Tarantool has a second storage engine that is only limited by the available disk space. - - diff --git a/doc/sphinx/reference/crypto.rst b/doc/sphinx/reference/crypto.rst index 2beca6b85f705b3087b4f8229d32c514dd6eb6ed..3f04a924c714c1d1f0eafc06e0383d469db1575c 100644 --- a/doc/sphinx/reference/crypto.rst +++ b/doc/sphinx/reference/crypto.rst @@ -6,58 +6,96 @@ .. module:: crypto -"Crypto" is short for "Cryptography", which generally refers to -the production of a digest value from a function (usually a -`Cryptographic hash function`_), applied against a string. -Tarantool's crypto package supports -ten types of cryptographic hash functions (AES_, DES_, DSS_, MD4_, MD5_, MDC2_, RIPEMD_, SHA-0_, SHA-1_, SHA-2_). -Some of the crypto functionality is also present in the :ref:`digest` package. -The functions in crypto are: - -:codebold:`crypto.cipher.`:codeitalic:`{aes128|aes192|aes256|des}.{cbc|cfg|ecb|ofb}.{encrypt|decrypt}` (:codeitalic:`string`, :codeitalic:`key` :codenormal:`[,`:codeitalic:`initialization vector`:codenormal:`])` |br| -Pass or return a cipher derived from the string, key, and (optionally, sometimes) initialization vector. -The four choices :codenormal:`aes128|aes192|aes256|des` indicate whether the algorithm will be aes-128 (with -192-bit binary strings using AES), aes-192 (with 192-bit binary strings using AES), aes-256 (with -256-bit binary strings using AES), or des (with 56-bit binary strings using DES, though DES is not recommended). |br| -Examples; |br| -:codenormal:`crypto.cipher.aes192.cbc.encrypt('string', 'key', 'initialization')` |br| -:codenormal:`crypto.cipher.aes256.ecb.decrypt('string', 'key')` |br| - - -:codebold:`crypto.digest.`:codeitalic:`{dss|dss1|md4|md5|mdc2|ripemd160|sha|sha1|sha224|sha256|sha384|sha512}`:codenormal:`(`:codeitalic:`string`:codenormal:`)` |br| -Pass or return a digest derived from the string. -The twelve choices :codenormal:`dss|dss1|md4|md5|mdc2|ripemd160|sha|sha1|sha224|sha256|sha384|sha512` -indicate whether the algorithm will be dss (using DSS), dss (using DSS-1), md4 (with 128-bit -binary strings using MD4), md5 (with 128-bit binary strings using MD5), mdc2 (using MDC2), -sha (with 160-bit binary strings using SHA-0), sha-1 (with 160-bit binary strings using SHA-1), -sha-224 (with 224-bit binary strings using SHA-2), sha-256 (with 256-bit binary strings using SHA_2), -sha-384 (with 384-bit binary strings using SHA_2), or sha-512 (with 512-bit binary strings using SHA-2). |br| -Examples: |br| -:codenormal:`crypto.digest.md4('string')` |br| -:codenormal:`crypto.digest.sha512('string')` |br| +"Crypto" is short for "Cryptography", which generally refers to the production +of a digest value from a function (usually a `Cryptographic hash function`_), +applied against a string. Tarantool's crypto package supports ten types of +cryptographic hash functions (AES_, DES_, DSS_, MD4_, MD5_, MDC2_, RIPEMD_, +SHA-0_, SHA-1_, SHA-2_). Some of the crypto functionality is also present in the +:ref:`digest` package. The functions in crypto are: + +.. cssclass:: highlight +.. parsed-literal:: + + -- aes-128 (with 192-bit binary strings using AES) + crypto.cypher.aes128. *{cbc|cfg|ecb|pfb}*.encrypt(*string*, *key*, *init-vector*) + crypto.cypher.aes128. *{cbc|cfg|ecb|pfb}*.decrypt(*string*, *key*) + -- aes-192 (with 192-bit binary strings using AES) + crypto.cypher.aes192. *{cbc|cfg|ecb|pfb}*.encrypt(*string*, *key*, *init-vector*) + crypto.cypher.aes192. *{cbc|cfg|ecb|pfb}*.encrypt(*string*, *key*) + -- aes-256 (with 256-bit binary strings using AES) + crypto.cypher.aes256. *{cbc|cfg|ecb|pfb}*.encrypt(*string*, *key*, *init-vector*) + crypto.cypher.aes256. *{cbc|cfg|ecb|pfb}*.decrypt(*string*, *key*) + -- des (with 56-bit binary strings using DES, though DES is not recommended) + crypto.cypher.des. *{cbc|cfg|ecb|pfb}*.decrypt(*string*, *key*, *init-vector*) + crypto.cypher.des. *{cbc|cfg|ecb|pfb}*.decrypt(*string*, *key*) + +Pass or return a cipher derived from the string, key, and (optionally, sometimes) +initialization vector. + +Examples: + +.. code-block:: lua + + crypto.cipher.aes192.cbc.encrypt('string', 'key', 'initialization') + crypto.cipher.aes256.ecb.decrypt('string', 'key') + +Functions in digest are: + +.. cssclass:: highlight +.. parsed-literal:: + + -- dss (using DSS) + crypto.digest.dss(*string*) + -- dss (using DSS-1) + crypto.digest.dss1(*string*) + -- md4 (with 128-bit binary strings using MD4) + crypto.digest.md4(*string*) + -- md5 (with 128-bit binary strings using MD5) + crypto.digest.md5(*string*) + -- mdc2 (using MDC2) + crypto.digest.mdc2(*string*) + -- + crypto.digest.ripemd160(*string*) + -- sha (with 160-bit binary strings using SHA-0) + crypto.digest.sha(*string*) + -- sha-1 (with 160-bit binary strings using SHA-1) + crypto.digest.sha1(*string*) + -- sha-224 (with 224-bit binary strings using SHA-2) + crypto.digest.sha224(*string*) + -- sha-256 (with 256-bit binary strings using SHA_2) + crypto.digest.sha256(*string*) + -- sha-384 (with 384-bit binary strings using SHA_2) + crypto.digest.sha384(*string*) + -- sha-512 (with 512-bit binary strings using SHA-2) + crypto.digest.sha512(*string*) + +Examples: + +.. code-block:: lua + + crypto.digest.md4('string') + crypto.digest.sha512('string') ========================================= Incremental methods in the crypto package ========================================= - Suppose that a digest is done for a string 'A', - then a new part 'B' is appended to the string, - then a new digest is required. - The new digest could be recomputed for the whole string 'AB', - but it is faster to take what was computed - before for 'A' and apply changes based on the new part 'B'. - This is called multi-step or "incremental" digesting, - which Tarantool supports for all crypto functions ... +Suppose that a digest is done for a string 'A', then a new part 'B' is +appended to the string, then a new digest is required. The new digest could +be recomputed for the whole string 'AB', but it is faster to take what was +computed before for 'A' and apply changes based on the new part 'B'. This is +called multi-step or "incremental" digesting, which Tarantool supports for +all crypto functions.. - .. code-block:: lua +.. code-block:: lua crypto = require('crypto') -- print aes-192 digest of 'AB', with one step, then incrementally print(crypto.cipher.aes192.cbc.encrypt('AB', 'key')) c = crypto.cipher.aes192.cbc.encrypt.new() - c: init() + c:init() c:update('A', 'key') c:update('B', 'key') print(c:result()) @@ -76,19 +114,20 @@ Incremental methods in the crypto package Getting the same results from digest and crypto packages ======================================================== -The following functions are equivalent. -For example, the digest function and the +The following functions are equivalent. For example, the digest function and the crypto function x will both produce the same result. -:codenormal:`crypto.cipher.aes256.cbc.encrypt('string', 'key') == digest.aes256cbc.encrypt('string', 'key')` |br| -:codenormal:`crypto.digest.md4('string') == digest.md4('string')` |br| -:codenormal:`crypto.digest.md5('string') == digest.md5('string')` |br| -:codenormal:`crypto.digest.sha('string') == digest.sha('string')` |br| -:codenormal:`crypto.digest.sha1('string') == digest.sha1('string')` |br| -:codenormal:`crypto.digest.sha224('string') == digest.sha224('string')` |br| -:codenormal:`crypto.digest.sha256('string') == digest.sha256('string')` |br| -:codenormal:`crypto.digest.sha384('string') == digest.sha384('string')` |br| -:codenormal:`crypto.digest.sha512('string') == digest.sha512('string')` |br| +.. code-block:: lua + + crypto.cipher.aes256.cbc.encrypt('string', 'key') == digest.aes256cbc.encrypt('string', 'key') + crypto.digest.md4('string') == digest.md4('string') + crypto.digest.md5('string') == digest.md5('string') + crypto.digest.sha('string') == digest.sha('string') + crypto.digest.sha1('string') == digest.sha1('string') + crypto.digest.sha224('string') == digest.sha224('string') + crypto.digest.sha256('string') == digest.sha256('string') + crypto.digest.sha384('string') == digest.sha384('string') + crypto.digest.sha512('string') == digest.sha512('string') .. _AES: https://en.wikipedia.org/wiki/Advanced_Encryption_Standard .. _DES: https://en.wikipedia.org/wiki/Data_Encryption_Standard @@ -102,4 +141,3 @@ crypto function x will both produce the same result. .. _RIPEMD: http://homes.esat.kuleuven.be/~bosselae/ripemd160.html .. _Cryptographic hash function: https://en.wikipedia.org/wiki/Cryptographic_hash_function .. _Consistent Hashing: https://en.wikipedia.org/wiki/Consistent_hashing - diff --git a/doc/sphinx/reference/digest.rst b/doc/sphinx/reference/digest.rst index 40353598303910c09f3c3c8465390b33debc8ac6..075f34de502a7ca0201ec4aa33b3f1834927af08 100644 --- a/doc/sphinx/reference/digest.rst +++ b/doc/sphinx/reference/digest.rst @@ -6,120 +6,133 @@ .. module:: digest -A "digest" is a value which is returned by a function (usually a -`Cryptographic hash function`_), applied against a string. -Tarantool's digest package supports -five types of cryptographic hash functions (AES_, MD4_, MD5_, SHA-0_, SHA-1_, SHA-2_) -as well as a checksum function (CRC32_), two functions for base64_, and two -non-cryptographic hash functions (guava_, murmur_). -Some of the digest functionality is also present in the :ref:`crypto <crypto>` package. -The functions in digest are: +A "digest" is a value which is returned by a function (usually a `Cryptographic +hash function`_), applied against a string. Tarantool's digest package supports +five types of cryptographic hash functions (AES_, MD4_, MD5_, SHA-0_, SHA-1_, +SHA-2_) as well as a checksum function (CRC32_), two functions for base64_, and +two non-cryptographic hash functions (guava_, murmur_). Some of the digest +functionality is also present in the :ref:`crypto <crypto>` package. The +functions in digest are: -:codebold:`digest.aes256cbc.encrypt(`:codeitalic:`string`, :codeitalic:`key`) |br| -Returns 256-bit binary string = digest made with AES. +.. module:: digest + +.. function:: md4(string) + md4_hex(string) + + Returns 128-bit binary string = digest made with MD4. + + Returns 32-byte string = hexadecimal of a digest calculated with md4. + +.. function:: md5(string) + md5_hex(string) + + Returns 128-bit binary string = digest made with MD5. + + Returns 32-byte string = hexadecimal of a digest calculated with md5. + +.. function:: sha(string) + sha_hex(string) + + Returns 160-bit binary string = digest made with SHA-0. Not recommended. -:codebold:`digest.md4(`:codeitalic:`string`) |br| -Returns 128-bit binary string = digest made with MD4. |br| + Returns 40-byte string = hexadecimal of a digest calculated with sha. -:codebold:`digest.md4_hex(`:codeitalic:`string`) |br| -Returns 32-byte string = hexadecimal of a digest calculated with md4. +.. function:: sha1(string) + sha1_hex(string) -:codebold:`digest.md5(`:codeitalic:`string`) |br| -Returns 128-bit binary string = digest made with MD5. + Returns 160-bit binary string = digest made with SHA-1. -:codebold:`digest.md5_hex(`:codeitalic:`string`) |br| -Returns 32-byte string = hexadecimal of a digest calculated with md5. + Returns 40-byte string = hexadecimal of a digest calculated with sha1. -:codebold:`digest.sha(`:codeitalic:`string`) |br| -Returns 160-bit binary string = digest made with SHA-0. Not recommended. +.. function:: sha224(string) + sha224_hex(string) -:codebold:`digest.sha_hex(`:codeitalic:`string`) |br| -Returns 40-byte string = hexadecimal of a digest calculated with sha. + Returns 224-bit binary string = digest made with SHA-2. -:codebold:`digest.sha1(`:codeitalic:`string`) |br| -Returns 160-bit binary string = digest made with SHA-1. + Returns 56-byte string = hexadecimal of a digest calculated with sha224. -:codebold:`digest.sha1_hex(`:codeitalic:`string`) |br| -Returns 40-byte string = hexadecimal of a digest calculated with sha1. +.. function:: sha256(string) + sha256_hex(string) -:codebold:`digest.sha224(`:codeitalic:`string`) |br| -Returns 224-bit binary string = digest made with SHA-2. + Returns 256-bit binary string = digest made with SHA-2. -:codebold:`digest.sha224_hex(`:codeitalic:`string`) |br| -Returns 56-byte string = hexadecimal of a digest calculated with sha224. + Returns 64-byte string = hexadecimal of a digest calculated with sha256. -:codebold:`digest.sha256(`:codeitalic:`string`) |br| -Returns 256-bit binary string = digest made with SHA-2. +.. function:: sha384(string) + sha384_hex(string) -:codebold:`digest.sha256_hex(`:codeitalic:`string`) |br| -Returns 64-byte string = hexadecimal of a digest calculated with sha256. + Returns 384-bit binary string = digest made with SHA-2. -:codebold:`digest.sha384(`:codeitalic:`string`) |br| -Returns 384-bit binary string = digest made with SHA-2. + Returns 96-byte string = hexadecimal of a digest calculated with sha384. -:codebold:`digest.sha384_hex(`:codeitalic:`string`) |br| -Returns 96-byte string = hexadecimal of a digest calculated with sha384. +.. function:: sha512(string) + sha512_hex(string) -:codebold:`digest.sha512(`:codeitalic:`string`) |br| -Returns 512-bit binary tring = digest made with SHA-2. + Returns 512-bit binary tring = digest made with SHA-2. -:codebold:`digest.sha512_hex(`:codeitalic:`string`) |br| -Returns 128-byte string = hexadecimal of a digest calculated with sha512. + Returns 128-byte string = hexadecimal of a digest calculated with sha512. -:codebold:`digest.base64_encode(`:codeitalic:`string`) |br| -Returns base64 encoding from a regular string. +.. function:: base64_encode(string) + base64_decode(string) -:codebold:`digest.base64_decode(`:codeitalic:`string`) |br| -Returns a regular string from a base64 encoding. + Returns base64 encoding from a regular string. -:codebold:`digest.urandom(`:codeitalic:`integer`) |br| -Returns array of random bytes with length = integer. + Returns a regular string from a base64 encoding. -:codebold:`digest.crc32(`:codeitalic:`string`) |br| -Returns 32-bit checksum made with CRC32. +.. function:: urandom(string) - The crc32 and crc32_update functions use the `CRC-32C (Castagnoli)`_ polynomial - value: 0x11EDC6F41 / 4812730177. If it is necessary to be - compatible with other checksum functions in other - programming languages, ensure that the other functions use - the same polynomial value. |br| For example, in Python, - install the crcmod package and say: + Returns array of random bytes with length = integer. + +.. function:: crc32(string) + + Returns 32-bit checksum made with CRC32. + + The crc32 and crc32_update functions use the `CRC-32C (Castagnoli)`_ + polynomial value: 0x11EDC6F41 / 4812730177. If it is necessary to be + compatible with other checksum functions in other programming languages, + ensure that the other functions use the same polynomial value. |br| + For example, in Python, install the crcmod package and say: .. code-block:: pycon - >>> import crcmod - >>> fun = crcmod.mkCrcFun('4812730177') - >>> fun('string') - 3304160206L + >>> import crcmod + >>> fun = crcmod.mkCrcFun('4812730177') + >>> fun('string') + 3304160206L .. _CRC-32C (Castagnoli): https://en.wikipedia.org/wiki/Cyclic_redundancy_check#Standards_and_common_use -:codebold:`digest.crc32.new()` |br| -Initiates incremental crc32. -See :ref:`incremental methods <incremental-digests>` notes. +.. function:: digest.crc32.new() + + Initiates incremental crc32. + See :ref:`incremental methods <incremental-digests>` notes. .. _digest-guava: -:codebold:`digest.guava(`:codeitalic:`integer, integer`) |br| -Returns a number made with consistent hash. +.. function:: guaava(integer, integer) + + Returns a number made with consistent hash. + + The guava function uses the `Consistent Hashing`_ algorithm of the Google + guava library. The first parameter should be a hash code; the second + parameter should be the number of buckets; the returned value will be an + integer between 0 and the number of buckets. For example, + + .. code-block:: tarantoolsession + + tarantool> digest.guava(10863919174838991, 11) + --- + - 8 + ... - The guava function uses the `Consistent Hashing`_ algorithm of - the Google guava library. The first parameter should be a - hash code; the second parameter should be the number of - buckets; the returned value will be an integer between 0 - and the number of buckets. For example, +.. function:: murmur(string) - :codenormal:`tarantool>` :codebold:`digest.guava(10863919174838991, 11)` |br| - :codenormal:`---` |br| - :codenormal:`- 8` |br| - :codenormal:`...` |br| + Returns 32-bit binary string = digest made with MurmurHash. -:codebold:`digest.murmur(`:codeitalic:`string`) |br| -Returns 32-bit binary string = digest made with MurmurHash. +.. function:: digest.murmur.new([seed]) -:codebold:`digest.murmur.new([`:codeitalic:`seed`]) |br| -Initiates incremental MurmurHash. -See :ref:`incremental methods <incremental-digests>` notes. + Initiates incremental MurmurHash. + See :ref:`incremental methods <incremental-digests>` notes. .. _incremental-digests: @@ -127,16 +140,13 @@ See :ref:`incremental methods <incremental-digests>` notes. Incremental methods in the digest package ========================================= - Suppose that a digest is done for a string 'A', - then a new part 'B' is appended to the string, - then a new digest is required. - The new digest could be recomputed for the whole string 'AB', - but it is faster to take what was computed - before for 'A' and apply changes based on the new part 'B'. - This is called multi-step or "incremental" digesting, - which Tarantool supports with crc32 and with murmur ... +Suppose that a digest is done for a string 'A', then a new part 'B' is appended +to the string, then a new digest is required. The new digest could be recomputed +for the whole string 'AB', but it is faster to take what was computed before for +'A' and apply changes based on the new part 'B'. This is called multi-step or +"incremental" digesting, which Tarantool supports with crc32 and with murmur.. - .. code-block:: lua +.. code-block:: lua digest = require('digest') @@ -162,38 +172,41 @@ In the following example, the user creates two functions, ``password_insert()`` which inserts a SHA-1_ digest of the word "**^S^e^c^ret Wordpass**" into a tuple set, and ``password_check()`` which requires input of a password. - :codenormal:`tarantool>` :codebold:`digest = require('digest')` |br| - :codenormal:`---` |br| - :codenormal:`...` |br| - :codenormal:`tarantool>` :codebold:`function password_insert()` |br| - |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| :codenormal:`>` :codebold:`box.space.tester:insert{12345, digest.sha1('^S^e^c^ret Wordpass')}` |br| - |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| :codenormal:`>` :codebold:`return 'OK'` |br| - |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| :codenormal:`>` :codebold:`end` |br| - :codenormal:`---` |br| - :codenormal:`...` |br| - :codenormal:`tarantool>` :codebold:`function password_check(password)` |br| - |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| :codenormal:`>` |nbsp| :codebold:`local t` |br| - |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| :codenormal:`>` |nbsp| :codebold:`local t = box.space.tester:select{12345}` |br| - |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| :codenormal:`>` |nbsp| :codebold:`if digest.sha1(password) == t[2] then` |br| - |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| :codenormal:`>` |nbsp| |nbsp| |nbsp| :codebold:`print('Password is valid')` |br| - |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| :codenormal:`>` |nbsp| :codebold:`else` |br| - |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| :codenormal:`>` |nbsp| |nbsp| |nbsp| :codebold:`print('Password is not valid')` |br| - |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| :codenormal:`>` |nbsp| :codebold:`end` |br| - |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| :codenormal:`>` :codebold:`end` |br| - :codenormal:`---` |br| - :codenormal:`...` |br| - :codenormal:`tarantool>` :codebold:`password_insert()` |br| - :codenormal:`---` |br| - :codenormal:`- 'OK'` |br| - :codenormal:`...` |br| - -If a later user calls the ``password_check()`` function and enters -the wrong password, the result is an error. - - :codenormal:`tarantool>` :codebold:`password_check('Secret Password')` |br| - :codenormal:`Password is not valid` |br| - :codenormal:`---` |br| - :codenormal:`...` |br| +.. code-block:: tarantoolsession + + tarantool> digest = require('digest') + --- + ... + tarantool> function password_insert() + > box.space.tester:insert{12345, digest.sha1('^S^e^c^ret Wordpass')} + > return 'OK' + > end + --- + ... + tarantool> function password_checkt(password) + > local t = box.space.tester:select{12345} + > if digest.sha1(password) == t[2] then + > return 'Password is valid' + > else + > return 'Password is not valid' + > end + > end + --- + ... + tarantool> password_insert() + --- + - 'OK' + ... + +If a later user calls the ``password_check()`` function and enters the wrong +password, the result is an error. + +.. code-block:: tarantoolsession + + tarantool> password_check('Secret Password') + --- + - 'Password is not valid' + ... .. _AES: https://en.wikipedia.org/wiki/Advanced_Encryption_Standard .. _SHA-0: https://en.wikipedia.org/wiki/Sha-0 diff --git a/doc/sphinx/reference/expirationd.rst b/doc/sphinx/reference/expirationd.rst index cd4ba8c82c909fce8c375c1c2c018ed8b3958498..a953c4101e2baaf73a5e99d14c302e6fb573e788 100644 --- a/doc/sphinx/reference/expirationd.rst +++ b/doc/sphinx/reference/expirationd.rst @@ -16,8 +16,8 @@ highlight the matters that will be enhanced by studying the full source later. ... Whenever one hears "daemon" in Tarantool, one should suspect it's being done -with :doc:`fiber`. The program is making a fiber and turning control over to it so -it runs occasionally, goes to sleep, then comes back for more. +with :doc:`fiber`. The program is making a fiber and turning control over to it +so it runs occasionally, goes to sleep, then comes back for more. .. code-block:: lua @@ -44,15 +44,13 @@ process the tuple as an expired tuple. box.space[space_id]:delete(key) end -Ultimately the tuple-expiry process leads to ``default_tuple_drop()`` -which does a "delete" of a tuple from its original space. -First the fun :ref:`fun <package-fun>` package is used, -specifically fun.map_. -Remembering that :codenormal:`index[0]` is always the space's primary key, -and :codenormal:`index[0].parts[`:codeitalic:`N`:codenormal:`].fieldno` -is always the field number for key part :codeitalic:`N`, -fun.map() is creating a table from the primary-key values of the tuple. -The result of fun.map() is passed to :func:`space_object:delete() <space_object.delete>`. +Ultimately the tuple-expiry process leads to ``default_tuple_drop()`` which does +a "delete" of a tuple from its original space. First the fun :ref:`fun <package-fun>` +package is used, specifically fun.map_. Remembering that :codenormal:`index[0]` +is always the space's primary key, and :samp:`index[0].parts[{N}].fieldno` is +always the field number for key part :samp:`{N}`, ``fun.map()`` is creating a +table from the primary-key values of the tuple. The result of ``fun.map()`` is +passed to :func:`space_object:delete() <space_object.delete>`. .. code-block:: lua @@ -63,73 +61,67 @@ At this point, if the above explanation is worthwhile, it's clear that ``expirationd.lua`` starts a background routine (fiber) which iterates through all the tuples in a space, sleeps cooperatively so that other fibers can operate at the same time, and - whenever it finds a tuple that has expired -- deletes it from this space. Now the -"``expirationd_run_task()``" function can be used -in a test which creates sample data, lets the -daemon run for a while, and prints results. +- deletes it from this space. Now the "``expirationd_run_task()``" function can +be used in a test which creates sample data, lets the daemon run for a while, +and prints results. -For those who like to see things run, here are the exact steps to get -expirationd through the test. +For those who like to see things run, here are the exact steps to get expirationd through the test. -1. Get ``expirationd.lua``. There are standard ways - it is after all part - of a `standard rock <https://luarocks.org/modules/rtsisyk/expirationd>`_ - but for this purpose just copy the contents of - expirationd.lua_ to a default directory. +1. Get ``expirationd.lua``. There are standard ways - it is after all part of a + `standard rock <https://luarocks.org/modules/rtsisyk/expirationd>`_ - but + for this purpose just copy the contents of expirationd.lua_ to a default + directory. 2. Start the Tarantool server as described before. 3. Execute these requests: .. code-block:: lua - fiber = require('fiber') - expd = require('expirationd') - box.cfg{} - e = box.schema.space.create('expirationd_test') - e:create_index('primary', {type = 'hash', parts = {1, 'NUM'}}) - e:replace{1, fiber.time() + 3} - e:replace{2, fiber.time() + 30} - function is_tuple_expired(args, tuple) - if (tuple[2] < fiber.time()) then return true end - return false - end - expd.run_task('expirationd_test', e.id, is_tuple_expired) - retval = {} - fiber.sleep(2) - expd.task_stats() - fiber.sleep(2) - expd.task_stats() - expd.kill_task('expirationd_test') - e:drop() - os.exit() - -The database-specific requests (``cfg``, -:ref:`space.create <schema-space-create>`, -:func:`create_index <space_object.create_index>`) -should already be familiar. - -The function which will be supplied to expirationd is -:codenormal:`is_tuple_expired`, which is saying -"if the second field of the tuple is less than the -:ref:`current time <fiber-time>` , then return true, otherwise return false". - -The key for getting the rock rolling is -``expd = require('expirationd')``. The "``require``" function is what reads in -the program; it will appear in many later examples in this manual, when it's -necessary to get a package that's not part of the Tarantool kernel. After the -Lua variable expd has been assigned the value of the expirationd package, it's -possible to invoke the package's ``run_task()`` function. - -After :ref:`sleeping <fiber-sleep>` for two seconds, when the task has had time to do its iterations through the spaces, -``expd.task_stats()`` will print out a report showing how many tuples have expired -- -"expired_count: 0". -After sleeping for two more seconds, ``expd.task_stats()`` will print out a report showing -how many tuples have expired -- -"expired_count: 1". -This shows that the is_tuple_expired() function eventually returned "true" -for one of the tuples, because its timestamp field was more than -three seconds old. - -Of course, expirationd can be customized to do different things -by passing different parameters, which will be evident after looking in more detail -at the source code. + fiber = require('fiber') + expd = require('expirationd') + box.cfg{} + e = box.schema.space.create('expirationd_test') + e:create_index('primary', {type = 'hash', parts = {1, 'NUM'}}) + e:replace{1, fiber.time() + 3} + e:replace{2, fiber.time() + 30} + function is_tuple_expired(args, tuple) + if (tuple[2] < fiber.time()) then return true end + return false + end + expd.run_task('expirationd_test', e.id, is_tuple_expired) + retval = {} + fiber.sleep(2) + expd.task_stats() + fiber.sleep(2) + expd.task_stats() + expd.kill_task('expirationd_test') + e:drop() + os.exit() + +The database-specific requests (``cfg``, :ref:`space.create <schema-space-create>`, +:func:`create_index <space_object.create_index>`) should already be familiar. + +The function which will be supplied to expirationd is ``is_tuple_expired``, +which is saying "if the second field of the tuple is less than the +:ref:`current time <fiber-time>`, then return true, otherwise return false". + +The key for getting the rock rolling is ``expd = require('expirationd')``. The +"``require``" function is what reads in the program; it will appear in many +later examples in this manual, when it's necessary to get a package that's not +part of the Tarantool kernel. After the Lua variable expd has been assigned the +value of the expirationd package, it's possible to invoke the package's +``run_task()`` function. + +After :ref:`sleeping <fiber-sleep>` for two seconds, when the task has had time +to do its iterations through the spaces, ``expd.task_stats()`` will print out a +report showing how many tuples have expired -- "expired_count: 0". After sleeping +for two more seconds, ``expd.task_stats()`` will print out a report showing +how many tuples have expired -- "expired_count: 1". This shows that the +is_tuple_expired() function eventually returned "true" for one of the tuples, +because its timestamp field was more than three seconds old. + +Of course, expirationd can be customized to do different things by passing +different parameters, which will be evident after looking in more detail at the +source code. .. _rock: http://rocks.tarantool.org/ .. _expirationd.lua: https://github.com/tarantool/expirationd/blob/master/expirationd.lua diff --git a/doc/sphinx/reference/fiber-ipc.rst b/doc/sphinx/reference/fiber-ipc.rst index fb714f72ebfa3133c2049c269d986fada114e5f0..32ff8083c596be0f4e133f8c3375214969a198b2 100644 --- a/doc/sphinx/reference/fiber-ipc.rst +++ b/doc/sphinx/reference/fiber-ipc.rst @@ -3,15 +3,14 @@ ------------------------------------------------------------------------------- The ``fiber-ipc`` package allows sending and receiving messages between -different processes. The words "different processes" in this context -mean different connections, different sessions, or different fibers. - -Call ``fiber.channel()`` to allocate space and get a channel object, -which will be called channel for examples in this section. Call the -other ``fiber-ipc`` routines, via channel, to send messages, receive -messages, or check ipc status. Message exchange is synchronous. The -channel is garbage collected when no one is using it, as with any -other Lua object. Use object-oriented syntax, for example +different processes. The words "different processes" in this context mean +different connections, different sessions, or different fibers. + +Call ``fiber.channel()`` to allocate space and get a channel object, which will +be called channel for examples in this section. Call the other ``fiber-ipc`` +routines, via channel, to send messages, receive messages, or check ipc status. +Message exchange is synchronous. The channel is garbage collected when no one is +using it, as with any other Lua object. Use object-oriented syntax, for example ``channel:put(message)`` rather than ``fiber.channel.put(message)``. .. module:: fiber diff --git a/doc/sphinx/reference/fiber.rst b/doc/sphinx/reference/fiber.rst index 2197bebbfa1707e2f7579ea669f47abae5b67ba7..3ce61484354284141e8764f67980bafabe654de6 100644 --- a/doc/sphinx/reference/fiber.rst +++ b/doc/sphinx/reference/fiber.rst @@ -312,7 +312,7 @@ can be reused when another fiber is created. See also :data:`box.session.storage <box.session.storage>`. **Example:** - + .. code-block:: tarantoolsession tarantool> fiber = require('fiber') @@ -453,4 +453,3 @@ the status is dead because the cancel worked. # 102 . dead . gvar= 421 --- ... - diff --git a/doc/sphinx/reference/fun.rst b/doc/sphinx/reference/fun.rst index 0784973167ef2a03eeeee8d04181b37c7a8895ea..b3a53734aa86194a5caecb4204159e6486d10ef7 100644 --- a/doc/sphinx/reference/fun.rst +++ b/doc/sphinx/reference/fun.rst @@ -29,7 +29,7 @@ For example: tarantool> fun = require('fun') --- ... - tarantool> for _k, a in fun_range(3) do + tarantool> for _k, a in fun.range(3) do > print(a) > end 1 diff --git a/doc/sphinx/reference/msgpack.rst b/doc/sphinx/reference/msgpack.rst index 48598dd6a42b0ae21f92cc373c19888bf3ec43b0..8a3c0471ddee72c27e30158b02067180780baf4d 100644 --- a/doc/sphinx/reference/msgpack.rst +++ b/doc/sphinx/reference/msgpack.rst @@ -74,12 +74,8 @@ array and as a map, then displays each result in hexadecimal. end msgpack = require('msgpack') - m1 = msgpack.encode(setmetatable({'A', 'B'}, { - __serialize = "seq" - })) - m2 = msgpack.encode(setmetatable({'A', 'B'}, { - __serialize = "map" - })) + m1 = msgpack.encode(setmetatable({'A', 'B'}, { __serialize = "seq" })) + m2 = msgpack.encode(setmetatable({'A', 'B'}, { __serialize = "map" })) print('array encoding: ', hexdump(m1)) print('map encoding: ', hexdump(m2)) diff --git a/doc/sphinx/reference/socket.rst b/doc/sphinx/reference/socket.rst index db571d1ffd2f96c43d35d866210aee32e7d4d748..4c9a9bf1b31221aabdc74f8ba9d14a85b161084e 100644 --- a/doc/sphinx/reference/socket.rst +++ b/doc/sphinx/reference/socket.rst @@ -27,8 +27,8 @@ are ``errno``, ``error``. | Purposes | Names | +================+===============================================================+ | setup | :ref:`socket() <socket-socket>` | - +----------------+---------------------------------------------------------------+ - | "" | :func:`socket.tcp_connect() <socket.tcp_connect>` | + | +---------------------------------------------------------------+ + | | :func:`socket.tcp_connect() <socket.tcp_connect>` | +----------------+---------------------------------------------------------------+ | "" | :func:`socket.tcp_server() <socket.tcp_server>` | +----------------+---------------------------------------------------------------+ diff --git a/doc/sphinx/reference/tdb.rst b/doc/sphinx/reference/tdb.rst index e0490b892d8e8ad62d7645865742b0278236b890..1ba6e5f9d381f9c2dba3e373c34f7d0c22e5ed79 100644 --- a/doc/sphinx/reference/tdb.rst +++ b/doc/sphinx/reference/tdb.rst @@ -2,129 +2,142 @@ Package `tdb` ------------------------------------------------------------------------------- -The Tarantool Debugger (abbreviation = tdb) can be used -with any Lua program. The operational features include: -setting breakpoints, examining variables, going forward -one line at a time, backtracing, and showing information -about fibers. The display features include: using different -colors for different situations, including line numbers, -and adding hints. - -It is not supplied as part of the Tarantool repository; -it must be installed separately. Here is the usual way: |br| -:codebold:`git clone --recursive https://github.com/Sulverus/tdb` |br| -:codebold:`cd tdb` |br| -:codebold:`make` |br| -:codebold:`sudo make install prefix=/usr/share/tarantool/` - -To initiate tdb within a Lua program and set a breakpoint, -edit the program to include these lines: |br| -:codenormal:`tdb = require('tdb')` |br| -:codenormal:`tdb.start()` - -To start the debugging session, execute the Lua program. -Execution will stop at the breakpoint, and it will be -possible to enter debugging commands. +The Tarantool Debugger (abbreviation = tdb) can be used with any Lua program. +The operational features include: setting breakpoints, examining variables, +going forward one line at a time, backtracing, and showing information about +fibers. The display features include: using different colors for different +situations, including line numbers, and adding hints. + +It is not supplied as part of the Tarantool repository; it must be installed +separately. Here is the usual way: + +.. code-block:: bash + + git clone --recursive https://github.com/Sulverus/tdb + cd tdb + make + sudo make install prefix=/usr/share/tarantool/ + +To initiate tdb within a Lua program and set a breakpoint, edit the program to +include these lines: + +.. code-block:: lua + + tdb = require('tdb') + tdb.start() + +To start the debugging session, execute the Lua program. Execution will stop at +the breakpoint, and it will be possible to enter debugging commands. ================================================= Debugger Commands ================================================= -:codebold:`bt` -- Backtrace -- show the stack -(in red), with program/function names and line numbers -of whatever has been invoked to reach the current line. +:codebold:`bt` + Backtrace -- show the stack (in red), with program/function names and line + numbers of whatever has been invoked to reach the current line. -:codebold:`c` -- Continue till next breakpoint -or till program ends. +:codebold:`c` + Continue till next breakpoint or till program ends. -:codebold:`e` -- Enter evaluation mode. When -the program is in evaluation mode, one can execute -certain Lua statements that would be valid in the context. -This is particularly useful for displaying -the values of the program's variables. -Other debugger commands will not work until one -exits evaluation mode by typing :codebold:`-e`. +:codebold:`e` + Enter evaluation mode. When the program is in evaluation mode, one can + execute certain Lua statements that would be valid in the context. This is + particularly useful for displaying the values of the program's variables. + Other debugger commands will not work until one exits evaluation mode by + typing :codebold:`-e`. -:codebold:`-e` -- Exit evaluation mode. +:codebold:`-e` + Exit evaluation mode. -:codebold:`f` -- Display the fiber id, the -program name, and the percentage of memory used, -as a table. +:codebold:`f` + Display the fiber id, the program name, and the percentage of memory used, + as a table. -:codebold:`n` -- Go to the next line, skipping over -any function calls. +:codebold:`n` + Go to the next line, skipping over any function calls. -:codebold:`globals` -- Display names of variables -or functions which are defined as global. +:codebold:`globals` + Display names of variables or functions which are defined as global. -:codebold:`h` -- Display a list of debugger commands. +:codebold:`h` + Display a list of debugger commands. -:codebold:`locals` -- Display names and values of -variables, for example the control variables of a -Lua "for" statement. +:codebold:`locals` + Display names and values of variables, for example the control variables of + a Lua "for" statement. -:codebold:`q` -- Quit immediately. +:codebold:`q` + Quit immediately. ================================================= Example Session ================================================= -Put the following program in a default directory and call it -"example.lua": +Put the following program in a default directory and call it "example.lua": - :codenormal:`tdb = require('tdb')` |br| - :codenormal:`tdb.start()` |br| - :codenormal:`i = 1` |br| - :codenormal:`j = 'a' .. i` |br| - :codenormal:`print('end of program')` +.. code-block:: lua -Now start Tarantool, using example.lua as the -initialization file: |br| -:codebold:`tarantool example.lua` + tdb = require('tdb') + tdb.start() + i = 1 + j = 'a' .. i + print('end of program') -The screen should now look like this: |br| -:codenormal:`$` :codebold:`tarantool example.lua` |br| -:codeblue:`(TDB)` |nbsp| :codegreen:`Tarantool debugger v.0.0.3. Type h for help` |br| -:codenormal:`example.lua` |br| -:codeblue:`(TDB)` |nbsp| :codegreen:`[example.lua]` |br| -:codeblue:`(TDB)` |nbsp| :codenormal:`3: i = 1` |br| -:codeblue:`(TDB)>` |br| +Now start Tarantool, using example.lua as the initialization file -Debugger prompts are blue, debugger hints and information -are green, and the current line -- line 3 of example.lua -- -is the default color. Now enter six debugger commands: |br| -:codebold:`n` |br| -:codebold:`n` |br| -:codebold:`e` |br| -:codebold:`j` |br| -:codebold:`-e` |br| -:codebold:`q` |br| -... These commands mean "go to next line", "go to next line", -"enter evaluation mode", "display j", "exit evaluation mode", -"quit". The screen should now look like this: |br| - -:codenormal:`$` :codebold:`tarantool example.lua` |br| -:codeblue:`(TDB)` |nbsp| :codegreen:`Tarantool debugger v.0.0.3. Type h for help` |br| -:codenormal:`example.lua` |br| -:codeblue:`(TDB)` |nbsp| :codegreen:`[example.lua]` |br| -:codeblue:`(TDB)` |nbsp| :codenormal:`3: i = 1` |br| -:codeblue:`(TDB)>`:codenormal:`n` |br| -:codeblue:`(TDB)` |nbsp| :codenormal:`4: j = 'a' .. i` |br| -:codeblue:`(TDB)>`:codenormal:`n` |br| -:codeblue:`(TDB)` |nbsp| :codenormal:`5: print('end of program')` |br| -:codeblue:`(TDB)>`:codenormal:`e` |br| -:codeblue:`(TDB)` |nbsp| :codegreen:`Eval mode ON` |br| -:codeblue:`(TDB)>`:codenormal:`j` |br| -:codenormal:`j` |nbsp| |nbsp| |nbsp| |nbsp| |nbsp| :codenormal:`a1` |br| -:codeblue:`(TDB)>`:codenormal:`-e` |br| -:codeblue:`(TDB)` |nbsp| :codegreen:`Eval mode OFF` |br| -:codeblue:`(TDB)>`:codenormal:`q` |br| +.. cssclass:: highlight +.. parsed-literal:: -Another debugger example can be found here_. + $ :codebold:`tarantool example.lua` +The screen should now look like this: -.. _here: https://github.com/sulverus/tdb +.. cssclass:: highlight +.. parsed-literal:: + $ :codebold:`tarantool example.lua` + :codeblue:`(TDB)` :codegreen:`Tarantool debugger v.0.0.3. Type h for help` + example.lua + :codeblue:`(TDB)` :codegreen:`[example.lua]` + :codeblue:`(TDB)` :codenormal:`3: i = 1` + :codeblue:`(TDB)>` +Debugger prompts are blue, debugger hints and information +are green, and the current line -- line 3 of example.lua -- +is the default color. Now enter six debugger commands: + +.. code-block:: lua + + n -- go to next line + n -- go to next line + e -- enter evaluation mode + j -- display j + -e -- exit evaluation mode + q -- quit + +The screen should now look like this: + +.. cssclass:: highlight +.. parsed-literal:: + + $ :codebold:`tarantool example.lua` + :codeblue:`(TDB)` :codegreen:`Tarantool debugger v.0.0.3. Type h for help` + example.lua + :codeblue:`(TDB)` :codegreen:`[example.lua]` + :codeblue:`(TDB)` :codenormal:`3: i = 1` + :codeblue:`(TDB)>` n + :codeblue:`(TDB)` :codenormal:`4: j = 'a' .. i` + :codeblue:`(TDB)>` n + :codeblue:`(TDB)` :codenormal:`5: print('end of program')` + :codeblue:`(TDB)>` e + :codeblue:`(TDB)` :codegreen:`Eval mode ON` + :codeblue:`(TDB)>` j + j a1 + :codeblue:`(TDB)>` -e + :codeblue:`(TDB)` :codegreen:`Eval mode OFF` + :codeblue:`(TDB)>` q +Another debugger example can be found here_. +.. _here: https://github.com/sulverus/tdb