From 0baeb4cdb95020c198a40ede2c1b1cb67cca75b5 Mon Sep 17 00:00:00 2001 From: ocelot-inc <pgulutzan@ocelot.ca> Date: Thu, 21 Jan 2016 17:50:32 -0700 Subject: [PATCH] Fixes gh-1199 Atomic transactions --- doc/sphinx/book/box/box_index.rst | 38 ++++++++++++++---- doc/sphinx/book/box/box_schema.rst | 2 + doc/sphinx/book/box/box_space.rst | 25 ++++++++++-- doc/sphinx/book/box/index.rst | 16 ++++++-- doc/sphinx/book/box/limitations.rst | 20 ++++------ doc/sphinx/book/box/sophia_diff.rst | 61 +++++++++++++++++++++++++++++ 6 files changed, 135 insertions(+), 27 deletions(-) create mode 100644 doc/sphinx/book/box/sophia_diff.rst diff --git a/doc/sphinx/book/box/box_index.rst b/doc/sphinx/book/box/box_index.rst index fd7e22aa47..785e127159 100644 --- a/doc/sphinx/book/box/box_index.rst +++ b/doc/sphinx/book/box/box_index.rst @@ -30,7 +30,7 @@ API is a direct binding to corresponding methods of index objects of type * :samp:`{index_object}` = an :ref:`object reference <object-reference>`. - :rtype: string + :rtype: .. data:: parts @@ -107,15 +107,15 @@ API is a direct binding to corresponding methods of index objects of type Note: Formally the logic for TREE index searches is: |br| comparison-operator is = or >= or > or <= or < depending on iterator-type |br| for i = 1 to number-of-parts-of-search-value |br| - |nbsp| if search-value-part[i] is ``nil`` |br| - |nbsp| or search-value-part[i] <comparison-operator> index-key-part[i] is true |br| + |nbsp| if (search-value-part[i] is ``nil`` and <comparison-operator> is "=") |br| + |nbsp| or (search-value-part[i] <comparison-operator> index-key-part[i] is true) |br| |nbsp| then comparison-result[i] is true |br| if all comparison-results are true, then search-value "matches" index key. |br| - Notice how, according to this logic, regardless what the iterator type is, - a comparison is always true when a search-value-part is ``nil`` or is missing. - This behavior applies for the memtx storage engine only - (the sophia storage engine does not allow search-value-parts to be ``nil`` or missing). - This behavior of searches with nil is subject to change. + Notice how, according to this logic, regardless what the index-key-part contains, + the comparison-result for equality is always true when a search-value-part is ``nil`` + or is missing. This behavior of searches with nil is subject to change. + + Note re storage engine: sophia does not allow search-value-parts to be ``nil`` or missing. +---------------+-----------+---------------------------------------------+ | Type | Arguments | Description | @@ -130,6 +130,8 @@ API is a direct binding to corresponding methods of index objects of type | or 'REQ' | value | ``box.index.EQ``. | | | | Tuples are returned in descending order by | | | | index key. | + | | | Note re storage engine: sophia does not | + | | | REQ. | +---------------+-----------+---------------------------------------------+ | box.index.GT | search | The comparison operator is '>' (greater | | or 'GT' | value | than). | @@ -459,6 +461,8 @@ API is a direct binding to corresponding methods of index objects of type - - ['Tuple with bit value = 01', 1] ... + .. _index_min: + .. method:: min([key-value]) Find the minimum value in the specified index. @@ -477,6 +481,8 @@ API is a direct binding to corresponding methods of index objects of type Complexity Factors: Index size, Index type. + Note re storage engine: sophia does not support :codenormal:`min()`. + **Example:** .. code-block:: tarantoolsession @@ -486,6 +492,8 @@ API is a direct binding to corresponding methods of index objects of type - ['Alpha!', 55, 'This is the first tuple!'] ... + .. _index_max: + .. method:: max([key-value]) Find the maximum value in the specified index. @@ -504,6 +512,8 @@ API is a direct binding to corresponding methods of index objects of type Complexity Factors: Index size, Index type. + Note re storage engine: sophia does not support :codenormal:`max()`. + **Example:** .. code-block:: tarantoolsession @@ -513,6 +523,8 @@ API is a direct binding to corresponding methods of index objects of type - ['Gamma!', 55, 'This is the third tuple!'] ... + .. _index_random: + .. method:: random(random-value) Find a random value in the specified index. This method is useful when it's @@ -529,6 +541,8 @@ API is a direct binding to corresponding methods of index objects of type Complexity Factors: Index size, Index type. + Note re storage engine: sophia does not support :codenormal:`random()`. + **Example:** .. code-block:: tarantoolsession @@ -538,6 +552,8 @@ API is a direct binding to corresponding methods of index objects of type - ['Beta!', 66, 'This is the second tuple!'] ... + .. _index_count: + .. method:: count(key-value, options) Iterate over an index, counting the number of @@ -555,6 +571,8 @@ API is a direct binding to corresponding methods of index objects of type is only applicable for the memtx storage engine. :rtype: number + Note re storage engine: sophia does not support :codenormal:`count()`. + **Example:** .. code-block:: tarantoolsession @@ -604,6 +622,8 @@ API is a direct binding to corresponding methods of index objects of type :return: the deleted tuple. :rtype: tuple + .. _index_alter: + .. method:: alter({options}) Alter an index. @@ -620,6 +640,8 @@ API is a direct binding to corresponding methods of index objects of type the first index cannot be changed to {unique = false}, or the alter function is only applicable for the memtx storage engine. + Note re storage engine: sophia does not support :codenormal:`alter()`. + **Example:** .. code-block:: tarantoolsession diff --git a/doc/sphinx/book/box/box_schema.rst b/doc/sphinx/book/box/box_schema.rst index b36268e77a..f167140de7 100644 --- a/doc/sphinx/book/box/box_schema.rst +++ b/doc/sphinx/book/box/box_schema.rst @@ -53,6 +53,8 @@ for spaces, users, roles, and function tuples. attached to the space objects, for example :func:`space_object:drop() <space_object.drop>`. + Note re storage engine: sophia does not support temporary spaces. + ================================================= Example ================================================= diff --git a/doc/sphinx/book/box/box_space.rst b/doc/sphinx/book/box/box_space.rst index 7e9eae971c..e459100841 100644 --- a/doc/sphinx/book/box/box_space.rst +++ b/doc/sphinx/book/box/box_space.rst @@ -84,9 +84,12 @@ A list of all ``box.space`` functions follows, then comes a list of all | | types | | | +---------------+--------------------+-----------------------------+---------------------+ - Possible errors: too many parts. A type option other than TREE, or a - unique option other than unique, or a parts option with more than one - field component, is only applicable for the memtx storage engine. + Possible errors: too many parts. + + Note re storage engine: sophia supports only the TREE index type, + and supports only one index per space, + and supports only the unique = true option, + and requires that field numbers be in order starting with 1. .. code-block:: tarantoolsession @@ -110,6 +113,8 @@ A list of all ``box.space`` functions follows, then comes a list of all Possible errors: If a tuple with the same unique-key value already exists, returns :errcode:`ER_TUPLE_FOUND`. + Note re storage engine: sophia will return nil, rather than the inserted tuple. + **Example:** .. code-block:: tarantoolsession @@ -284,6 +289,8 @@ A list of all ``box.space`` functions follows, then comes a list of all **Complexity Factors:** Index size, Index type, Number of indexes accessed, WAL settings. + Note re storage engine: sophia will return nil, rather than the inserted tuple. + **Example:** .. code-block:: lua @@ -338,6 +345,8 @@ A list of all ``box.space`` functions follows, then comes a list of all **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. + Thus, in the instruction: .. code-block:: lua @@ -502,6 +511,8 @@ A list of all ``box.space`` functions follows, then comes a list of all **Complexity Factors:** Index size, Index type + Note re storage engine: sophia will return nil, rather than the deleted tuple. + **Example:** .. code-block:: tarantoolsession @@ -611,6 +622,8 @@ A list of all ``box.space`` functions follows, then comes a list of all - 2 ... + .. _space_truncate: + .. method:: truncate() Deletes all tuples. @@ -621,6 +634,8 @@ A list of all ``box.space`` functions follows, then comes a list of all :return: nil + Note re storage engine: sophia does not support :codenormal:`truncate`. + **Example:** .. code-block:: tarantoolsession @@ -714,12 +729,14 @@ A list of all ``box.space`` functions follows, then comes a list of all - 998 ... + .. _space_auto_increment: + .. method:: auto_increment{field-value [, field-value ...]} Insert a new tuple using an auto-increment primary key. The space specified by space_object must have a ``NUM`` primary key index of type ``TREE``. The primary-key field will be incremented before the insert. - This is only applicable for the memtx storage engine. + 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. diff --git a/doc/sphinx/book/box/index.rst b/doc/sphinx/book/box/index.rst index a7092bf03a..c4dde6d29c 100644 --- a/doc/sphinx/book/box/index.rst +++ b/doc/sphinx/book/box/index.rst @@ -296,6 +296,8 @@ all computer instructions until a yield, then switch to execute the instructions of a different fiber. Thus (say) the thread reads row#x for the sake of fiber#1, then writes row#y for the sake of fiber#2. +.. _yields_must_happen: + **FACT #3**: yields must happen, otherwise the transaction processor thread would stick permanently on the same fiber. There are implicit yields: every data-change operation @@ -321,6 +323,8 @@ the function holds a consistent view of the database until the UPDATE ends. For the combination “UPDATE plus SELECT†the view is not consistent, because after the UPDATE the transaction processor thread can switch to another fiber, and delete the tuple that was just updated. +Note re storage engine: sophia handles yields differently, see +:ref:`differences between memtx and sophia <sophia_diff>`. Since locks don't exist, and disk writes only involve the write-ahead log, transactions are usually fast. Also the Tarantool server may not be using @@ -581,9 +585,12 @@ The manual concentrates on memtx because it is the default and has been around longer. But sophia is a working key-value engine and will especially appeal to users who like to see data go directly to disk, so that recovery time might be shorter and database size might be larger. For architectural explanations and -benchmarks, see `sphia.org`_. On the other hand, sophia lacks some functions and +benchmarks, see `sphia.org`_ and Appendix E: :ref:`sophia <sophia>`. +On the other hand, sophia lacks some functions and options that are available with memtx. Where that is the case, the relevant -description will contain the words "only applicable for the memtx storage engine". +description will contain a note beginning with the words +"Note re storage engine: sophia". The end of this chapter has coverage +for all :ref:`the differeences between memtx and sophia <sophia_diff>`. .. _sphia.org: http://sphia.org @@ -603,5 +610,8 @@ description will contain the words "only applicable for the memtx storage engine admin atomic authentication - limitations triggers + limitations + sophia_diff + + diff --git a/doc/sphinx/book/box/limitations.rst b/doc/sphinx/book/box/limitations.rst index b6fdbceec0..a4c7de9c2d 100644 --- a/doc/sphinx/book/box/limitations.rst +++ b/doc/sphinx/book/box/limitations.rst @@ -4,11 +4,14 @@ .. _lim_fields_in_index: -**Number of fields in an index** +**Number of parts in an index** - For BITSET indexes, the maximum is 1. For TREE or HASH indexes, the maximum + For TREE or HASH indexes, the maximum is 255 (``box.schema.INDEX_PART_MAX``). For RTREE indexes, the maximum is 1 but the field is an ARRAY. + For BITSET indexes, the maximum is 1. + + Note re storage engine: sophia allows 8 parts in an index. .. _lim_indexes_in_space: @@ -77,14 +80,7 @@ .. _lim_sophia: -**Limitations which are only applicable for the sophia storage engine** - - The maximum number of indexes in a space is - always 1, that is, secondary indexes are not supported. Indexes must be - type=TREE, that is, the options type=HASH or type=RTREE or type=BITSET are - not supported. Indexes must be unique, that is, the option unique=false - is not supported. The ``alter()`` and ``count()`` and - ``min()`` and ``max()`` and ``random()`` and ``auto_increment()`` functions - are not supported. Temporary spaces are not supported. - The maximum number of fields in an index is 8. +For additional limitations which apply only to the sophia +storage engine, see section +:ref:`Differences between memtx and sophia <sophia_diff>`. diff --git a/doc/sphinx/book/box/sophia_diff.rst b/doc/sphinx/book/box/sophia_diff.rst new file mode 100644 index 0000000000..9bac36dd7f --- /dev/null +++ b/doc/sphinx/book/box/sophia_diff.rst @@ -0,0 +1,61 @@ +.. _sophia_diff: + +------------------------------------------------------------------------------- + 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 + 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". + + With memtx, the maximum number of indexes per space is 10. |br| + With sophia, the maximum is 1, that is, only primary indexes are supported. + Since primary indexes are always unique, it follows that sophia indexes must be unique. + + With memtx, the maximum number of (TREE) index-key parts is 255. |br| + With sophia, the maximum is 8. + + With memtx, the index type can be TREE or HASH or RTREE or BITSET. |br| + With sophia, the only index type is TREE. + + With memtx, field numbers for index parts may be in any order. |br| + With sophia, they must be in order, with no gaps, starting with field number 1. + + With memtx, for index searches, ``nil`` is considered to be equal to any scalar key-part. |br| + With memtx, ``nil`` or missing parts are not allowed. + + With memtx, temporary spaces are supported. |br| + With sophia, they are not. + + With memtx, the :ref:`alter() <index_alter>` and :ref:`count() <index_count>` + and :ref:`min() <index_min>` and :ref:`max() <index_max>` and + :ref:`random() <index_random>` and :ref:`auto_increment() <space_auto_increment>` + and :ref:`truncate() <space_truncate>` functions are supported. |br| + With sophia, they are not. + + With memtx, insert and replace and update will return a tuple, if successful. |br| + With sophia, insert and replace and update will return nil. + + With memtx, the REQ (reverse equality) comparison-operator is supported. |br| + With sophia, it is not. + (This is a minor matter because on a unique index EQ and REQ do the same thing.) + + It was explained :ref:`earlier <yields_must_happen>` that memtx does not "yield" on a select request, + it yields only on data-change requests. However, sophia does yield on a select + request, or on an equivalent such as get() or pairs(). This has significance + for cooperative multitasking. + + For more about sophia, see Appendix E :ref:`sophia <sophia>`. + -- GitLab