Skip to content
Snippets Groups Projects
  1. Aug 17, 2021
    • Serge Petrenko's avatar
      box: allow upgrading from version 1.6 · 9d9e9289
      Serge Petrenko authored
      Direct upgrade support from pre-1.7.5 versions was removed in commit
      7d3b80e7
      (Forbid upgrade from Tarantool < 1.7.5 and refactor upgrade.lua)
      The reason for that was the mandatory space format checks introduced
      back then. With these space format checks, old schema couldn't be
      recovered on new Tarantool versions, because newer versions had
      different system space formats. So old schema couldn't be upgraded
      because it couldn't even be recovered.
      
      Actually this was rather inconvenient. One had to perform an extra
      upgrade step when upgrading from, say, 1.6 to 2.x: instead of
      performing a direct upgrade one had to do 1.6 -> 1.10 -> 2.x upgrade
      which takes twice the time.
      
      Make it possible to boot from snapshots coming from Tarantool version
      1.6.8 and above.
      
      In order to do so, introduce before_replace triggers on system spaces,
      which work during snapshot/xlog recovery. The triggers will set tuple
      formats to the ones supported by current Tarantool (2.x). This way the
      recovered data will have the correct format for a usual schema upgrade.
      
      Also add upgrade_to_1_7_5() handler, which finishes transformation of
      old schema to 1.7.5. The handler is fired together with other
      box.schema.upgrade() handlers, so there's no user-visible behaviour
      change.
      
      Side note: it would be great to use the same technique to allow booting
      from pre-1.6.8 snapshots. Unfortunately, this is not possible.
      
      Current triggers don't break the order of schema upgrades, so 1.7.1
      upgrades come before 1.7.2 and 1.7.5. This is because all the upgrades
      in these versions are replacing existing tuples and not inserting new
      ones, so the upgrades may be handled by the before_replace triggers.
      
      Upgrade to 1.6.8 requires inserting new tuples: creating sysviews, like
      _vspace, _vuser and so on. This can't be done from the before_replace
      triggers, so we would have to run triggers for 1.7.x first which would
      allow Tarantool to recover the snapshot, and then run an upgrade handler for
      1.6.8. This looks really messy.
      
      Closes #5894
      9d9e9289
    • Serge Petrenko's avatar
      lua: introduce table.equals method · 0afe1f78
      Serge Petrenko authored
      Introduce table.equals for comparing tables.
      The method respects __eq metamethod, if provided.
      
      Needed-for #5894
      
      @TarantoolBot document
      Title: lua: new method table.equals
      
      Document the new lua method table.equals
      It compares two tables deeply. For example:
      ```
      tarantool> t1 = {a=3}
      ---
      ...
      
      tarantool> t2 = {a=3}
      ---
      ...
      
      tarantool> t1 == t2
      ---
      - false
      ...
      
      tarantool> table.equals(t1, t2)
      ---
      - true
      ...
      ```
      The method respects the __eq metamethod. When both tables being compared
      have the same __eq metamethod, it's used for comparison (just like this
      is done in Lua 5.1)
      0afe1f78
    • Serge Petrenko's avatar
      replication: fix flaky election_basic test · fc3e6986
      Serge Petrenko authored
      Found the following error in our CI:
      
       Test failed! Result content mismatch:
       --- replication/election_basic.result	Fri Aug 13 13:50:26 2021
       +++ /build/usr/src/debug/tarantool-2.9.0.276/test/var/rejects/replication/election_basic.reject	Sat Aug 14 08:14:17 2021
       @@ -116,6 +116,7 @@
         | ...
        box.ctl.demote()
         | ---
       + | - error: box.ctl.demote does not support simultaneous invocations
         | ...
        --
      
      Even though box.ctl.demote() or box.ctl.promote() isn't called above the
      failing line, promote() is issued internally once the instance becomes
      the leader.
      
      Wait until previous promote is finished
      (i.e. box.info.synchro.queue.owner is set)
      fc3e6986
    • Serge Petrenko's avatar
      applier: fix upstream.lag calculations · 884e93ad
      Serge Petrenko authored
      upstream.lag is the delta between the moment when a row was written to
      master's journal and the moment when it was received by the replica.
      It's an important metric to check whether the replica has fallen too far
      behind master.
      
      Not all the rows coming from master have a valid time of creation. For
      example, RAFT system messages don't have one, and we can't assign
      correct time to them: these messages do not originate from the journal,
      and assigning current time to them would lead to jumps in upstream.lag
      results.
      
      Stop updating upstream.lag for rows which don't have creation time
      assigned.
      
      The upstream.lag calculation changes were meant to fix the flaky
      replication/errinj.test:
      
       Test failed! Result content mismatch:
       --- replication/errinj.result	Fri Aug 13 15:15:35 2021
       +++ /tmp/tnt/rejects/replication/errinj.reject	Fri Aug 13 15:40:39 2021
       @@ -310,7 +310,7 @@
        ...
        box.info.replication[1].upstream.lag < 1
        ---
       -- true
       +- false
        ...
      
      But the changes were not enough, because now the test
      may see the initial lag value (TIMEOUT_INFINITY).
      So fix the test as well by waiting until upstream.lag becomes < 1.
      884e93ad
  2. Aug 16, 2021
    • Vladimir Davydov's avatar
      net.box: allow to store user-defined fields in future object · 7ffae819
      Vladimir Davydov authored
      Before commit 954194a1 ("net.box:
      rewrite request implementation in C"), net.box future was a plain Lua
      table so that the caller could attach extra information to it. Now it
      isn't true anymore - a future is a userdata object, and it doesn't have
      indexing methods.
      
      For backward compatibility, let's add __index and __newindex fields and
      store user-defined fields in a Lua table, which is created lazily on the
      first __newindex invocation. __index falls back on the metatable methods
      if a field isn't found in the table.
      
      Follow-up #6241
      Closes #6306
      7ffae819
    • Vladimir Davydov's avatar
      net.box: do not yield in future.wait_result(0) · 7b4eb172
      Vladimir Davydov authored
      It didn't yield before commit 954194a1 ("net.box: rewrite request
      implementation in C"). It shouldn't yield now.
      
      Follow-up #6241
      7b4eb172
    • Nikita Pettik's avatar
      txm: disallow yields after DDL operation in TX · 8f4be322
      Nikita Pettik authored
      To avoid sharing (ergo phantom reads) metadata object for different
      transactions in MVCC mode, let's do following things.
      Firstly, let's set on replace trigger on all system spaces (content's change in
      system space is considered to be DDL operation) which disables yields until
      transaction is committed. The only exceptions are index build and space format
      check: during these operations yields are allowed since they may take a while
      (so without yields they block execution). Actually it is not a problem 'cause
      these two operations must be first-in-transaction: as a result transaction
      can't contain two yielding statements. So after any cache modification no
      yields take place for sure.
      Secondly, on committing transaction that provides DDL changes let's abort all
      other transaction since they may refer to obsolete schema objects. The last
      restriction may seem too strict, but it is OK as primitive workaround until
      transactional DDL is introduced. In fact we should only abort transactions that
      have read dirty (i.e. modified) objects.
      
      Closes #5998
      Closes #6140
      Workaround for #6138
      8f4be322
  3. Aug 14, 2021
    • Aleksandr Lyapunov's avatar
      txm: add one more test · d551a758
      Aleksandr Lyapunov authored
      It seem that the issue was fixes in one of previous commits.
      Just add the test. No logical changes.
      
      Closes #5801
      d551a758
    • Aleksandr Lyapunov's avatar
      txm: check memtx_tx_handle_gap_write return code · 3b59f4eb
      Aleksandr Lyapunov authored
      The return code was not checked and thus in case of memory error
      we could loose conflicts. Fix it.
      
      Follow up #6040
      3b59f4eb
    • Aleksandr Lyapunov's avatar
      txm: track duplicated tuples · 2cafa623
      Aleksandr Lyapunov authored
      There was a bug when a transaction makes a wrong statement that is
      aborted because of duplicate tuple in primary or secondary index.
      The problem is that check of existing tuple is an implicit read
      that has usual side effect.
      
      This patch tracks that kind of reads like ordinal reads.
      
      Part of #5999
      2cafa623
    • Aleksandr Lyapunov's avatar
      txm: track read instead of direct conflict in clarify · b7065d33
      Aleksandr Lyapunov authored
      After the previous patch it became possible to link read trackers
      to in-progress stories.
      
      This patch use one read tracker instead of bunch of direct
      conflicts in tuple_clarify. This is a bit accurate. Is also allows
      to avoid unnecessary conflict when a transaction reads its own
      change.
      
      Part of #5999
      b7065d33
    • Aleksandr Lyapunov's avatar
      txm: use read trackers instead of direct conflict · 32911677
      Aleksandr Lyapunov authored
      Before this patch when a transaction has performed a write to
      read gap (interval) a conflict record has beed created for the
      reader of this gaps. That is wrong since the next writer of the
      same value will not find a gap - the gap has been splitted into
      parts.
      
      This patch fixes that and create a special read tracker that was
      designed specially for further tracking of writes.
      
      This also requires writer to search for read trackers not only
      in prepared stories but also in in-progress stories too.
      
      Part of #5999
      32911677
    • Aleksandr Lyapunov's avatar
      txm: make replace in indexes less dependent · cc24a1d3
      Aleksandr Lyapunov authored
      There was a obvious bug in transactinal manager's GC.
      
      There can be stories about deleted tuples. In other word tuples
      were deleted, but their story remains for history for some time.
      That means that pointers to dirty tuples are left in indexes,
      while the stories say that that tuples are deleted.
      
      When GC comes, it must remove pointer to tuple from indexes too.
      That is simple to check - if a story is on top of chain - it must
      be in index, and if it is a story about deleted tuple - it must be
      removed from index. But also that story must be unliked from chain,
      and the next story becomes the top on chain, but (1) in turn it
      must not try to delete its tuple from index - we have already done
      it, deleting the first tuple. For this purpose we mark the next
      story with space = NULL.
      
      The problem is that setting space = NULL work for every index at
      once, while sometimes we have to hande each index independently.
      
      Fortunately the previous commit introduced in_index member of
      story's link, NULL by default. We can just leave that NULL in
      older story as a mark that is not in index. This commit makes so
      and fixes the bug.
      
      Closes #6234
      cc24a1d3
    • Aleksandr Lyapunov's avatar
      txm: store pointers to indexes in story · 914a36da
      Aleksandr Lyapunov authored
      There was a tricky problem in TX manager that could lead to a
      crash after deletion of a space.
      
      When a space is deleted, TX manager uses a special callback to
      remove dirty tuples from indexes. It is necessary for correct
      destruction of space and indexes.
      
      The problem is that actual space drop works in several steps,
      deletings secondary indexes and then deleting primary indexes.
      Each step is an independend alter. And alters are tricky.
      
      For example we had a struct space instance, namely S1, with
      two indexes I1 and I2. At the first step we have to delete the
      second index. By design, for that purpose a new instance of
      space is created, namely S2, with one empty index I3. Then the
      spaces exchanges their indexes, and S1 becomes with I3 and I2,
      and S2 owns I1. After that S1 is deleted. That is good until we
      try to make story cleanup - all the dirty tuples remain in S2.I1,
      while we try to clean empty S1.I3.
      
      The only way to fix it - story index pointer right in story to
      make sure we are cleaning the right index.
      
      Part of #6234
      Closes #6274
      914a36da
    • Egor Elchinov's avatar
      txm: fix iterators for hash index · 6571afcb
      Egor Elchinov authored
      MVCC used not to track hash index writes.
      This patch fixes this problem by transferring the readers which use
      `ITER_ALL` or `ITER_GT` iterators of hash index to read view after
      any subsequent external write to this index.
      
      Closes #6040
      6571afcb
    • Aleksandr Lyapunov's avatar
      txm: track read more carefully · 9db816b1
      Aleksandr Lyapunov authored
      The previous commit fixed a bug that caused dirty read but also
      introduced a much less significat problem - excess conflict in
      some cases.
      
      Usually if a reader reads a tuple - in its story aspecial record
      is stored. Any write that replaces or deletes that tuple can now
      cause conflict of current transaction.
      
      The problem happened when a reader tries to execute select from
      some index, but only deleted story is found there. The record is
      stored and that is good - we must know when somebody will insert
      a tuple to this place in index. But actually we need to know it
      only for the index from which the reader executed select.
      
      This patch introduces a special index mask in read tracker that is
      used in the case above to be more precise in conflict detection.
      
      Closes #6206
      9db816b1
    • Aleksandr Lyapunov's avatar
      txm: track deleted stories · dade56ac
      Aleksandr Lyapunov authored
      In order to preserve repeated reads transactional manager tracks
      read of each transactions. Generally reads can be of two types -
      those that have read a tuple or that have found nothing. The first
      are stored in tuple story, the second - in special gap and hole
      structures.
      
      The problem was that reads that found a dirty tuple that was
      invisible to this transaction (the story says that it is deleted)
      was not stored neither in story nor in gap/holes.
      
      This patch fixes that.
      
      Part of #6206
      dade56ac
    • Aleksandr Lyapunov's avatar
      txm: avoid excess conflict while reading gaps · 9d42ad47
      Aleksandr Lyapunov authored
      During iteration a memtx tree index must write gap records to TX
      manager. It is done in order to detect the further writes to that
      gaps and execute some logic preventing phantom reads.
      
      There are two cases when that gap is stores:
       * Iterator reads the next tuple, the gap is between two tuples.
       * Iterator finished reading, the gap is between the previous
      tuple and the key boundary.
      
      By a mistake these two cases were not distinguished correctly and
      that led to excess conflicts.
      
      This patch fixes it.
      
      Part of #6206
      9d42ad47
    • Aleksandr Lyapunov's avatar
      txm: simplify construction of tx_read_tracker · b6fab015
      Aleksandr Lyapunov authored
      Just add a function that allocates and initializes the structure.
      No logical changes.
      
      Part of #6206
      b6fab015
    • Aleksandr Lyapunov's avatar
      txm: split memtx_tx_track_read method into two parts · 2bf4484f
      Aleksandr Lyapunov authored
      No logical changes, only for the next commit simplification
      
      Part of #6206
      2bf4484f
    • Aleksandr Lyapunov's avatar
      txm: simplify code with check_dup_common function · eebf7ba0
      Aleksandr Lyapunov authored
      Implement check_dup_common function that calls either
      check_dup_clean or check_dup_dirty.
      
      No logical changes.
      
      Follow up #6132
      eebf7ba0
    • Aleksandr Lyapunov's avatar
      txm: rewrite and refactor mvcc code · d0bc565c
      Aleksandr Lyapunov authored
      There were several problems that was connected with broken
      pointers in tuple history. Another problems is that that code
      was quite huge and difficult to understand.
      
      This patch refactors all the code that is connected to lists of
      stories in history. A bunch of helper function was added and in
      fact these functions was carefully rewtitten:
       * memtx_tx_history_add_stmt
       * memtx_tx_history_rollback_stmt
       * memtx_tx_history_prepare_stmt
       * memtx_tx_history_commit_stmt
      
      In addition to refactoring a couple of significant changes was
      made to the logic:
       * Now del_story in statement point to story of the tuple that
      was effectively deleted by this statement.
       * Conflicts in secondary indexes (that were previously named as
      'cross coflicts' now handled transparently during statement
      preparation.
      
      Closes #6132
      Closes #6021
      d0bc565c
    • Aleksandr Lyapunov's avatar
      txm: remove redundant _story suffix from memtx_tx_story_link · b392839b
      Aleksandr Lyapunov authored
      Once there were two type of links of a story: with a clean tuple
      and with other story, that's why there was two similar functions
      that were used for linking, with differen suffic in names. After
      some refactoring the linkage with tuples was removed, so now
      a story can only be linked with another story. The time has come
      to remove meaningless suffix too.
      
      Part of #6132
      b392839b
    • Aleksandr Lyapunov's avatar
      txm: add more comments and rename a bit · ef59b082
      Aleksandr Lyapunov authored
      Part of #6132
      ef59b082
    • Nikita Pettik's avatar
      txm: link all transaction into list · 29f4e457
      Nikita Pettik authored
      We are going to abort all transaction on any DDL commit except for TX
      owning that change. So let's link all transaction into rlist.
      
      Needed for #5998
      29f4e457
    • EvgenyMekhanik's avatar
      test: move all ddl operations outside of transactions · 393330f9
      EvgenyMekhanik authored
      To fix some problems in the transaction manager we disallow
      yields after DDL operation in TX. Thus, we can't longer perform
      ddl operations in streams.
      
      Needed for #5998
      393330f9
  4. Aug 13, 2021
    • Sergey Kaplun's avatar
      lua: refactor port_lua_do_dump and encode_lua_call · 027775ff
      Sergey Kaplun authored
      The old code flow was the following:
      
      1) `struct port_lua` given to `port_lua_do_dump()` has Lua stack with
         arguments to encode to MessagePack.
      
      2) The main coroutine `tarantool_L` is used to call `encode_lua_call()`
         or `encode_lua_call_16`() via `lua_cpcall()`.
      
      3) Objects on port coroutine are encoded via `luamp_encode()` or
         `luamp_encode_call16()`.
      
      4) This encoding may raise an error on unprotected `port->L` coroutine.
         This coroutine has no protected frame on it and this call should fail
         in pure Lua.
      
      Calling anything on unprotected coroutine is not allowed in Lua [1]:
      
      | If an error happens outside any protected environment, Lua calls a
      | panic function
      
      Lua 5.1 sets protection only for specific lua_State [2] and calls a
      panic function if we raise an error on unprotected lua_State [3].
      
      Nevertheless, no panic occurs now due to two facts:
      * The first one is LuaJIT's support of C++ exception handling [4] that
        allows to raise an error in Lua and catch it in C++ or vice versa. But
        documentation still doesn't allow raising errors on unprotected
        coroutines (at least we must use try-catch block).
      * The second one is the patch made in LuaJIT to restore currently
        executed coroutine, when C function or fast function raises an
        error [5][6] (see the related issue here [7][8]).
      
      For these reasons, when an error occurs, the unwinder searches and finds
      the C-protected stack frame from the `lua_cpcall()` for `tarantool_L`
      coroutine and unwinds until that point (without aforementioned patches
      LuaJIT just calls a panic function and exits).
      
      If an error is raised, and `lua_cpcall()` returns not `LUA_OK`, then the
      error from `port->L` coroutine is converted into a Tarantool error and a
      diagnostic is set.
      
      Such auxiliary usage of `tarantool_L` is not idiomatic for Lua.
      Internal unwinder used on M1 is not such flexible, so such misuse leads
      to panic call. Also the `tarantool_L` usage is redundant. So this patch
      drops it and uses only port coroutine instead with `lua_pcall()`.
      
      Functions to encode are saved to the `LUA_REGISTRY` table to
      reduce GC pressure, like it is done for other handlers [9].
      
      [1]: https://www.lua.org/manual/5.2/manual.html#4.6
      [2]: https://www.lua.org/source/5.1/lstate.h.html#lua_State
      [3]: https://www.lua.org/source/5.1/ldo.c.html#luaD_throw
      [4]: https://luajit.org/extensions.html#exceptions
      [5]: https://github.com/tarantool/luajit/commit/ed412cd9f55fe87fd32a69c86e1732690fc5c1b0
      [6]: https://github.com/tarantool/luajit/commit/97699d9ee2467389b6aea21a098e38aff3469b5f
      [7]: https://github.com/tarantool/tarantool/issues/1516
      [8]: https://www.freelists.org/post/luajit/Issue-with-PCALL-in-21
      [9]: https://github.com/tarantool/tarantool/commit/e88c0d21ab765d4c53bed2437c49d77b3ffe4216
      
      
      
      Closes #6248
      Closes #4617
      
      Reviewed-by: default avatarVladislav Shpilevoy <v.shpilevoy@tarantool.org>
      Reviewed-by: default avatarIgor Munkin <imun@tarantool.org>
      Signed-off-by: default avatarIgor Munkin <imun@tarantool.org>
      027775ff
    • mechanik20051988's avatar
      net.box: add interactive transaction support in net.box · f9ca802a
      mechanik20051988 authored
      Implement `begin`, `commit` and `rollback` methods for stream object
      in `net.box`, which allows to begin, commit and rollback transaction
      accordingly.
      
      Closes #5860
      
      @TarantoolBot document
      Title: add interactive transaction support in net.box
      Implement `begin`, `commit` and `rollback` methods for stream object
      in `net.box`, which allows to begin, commit and rollback transaction
      accordingly. Now there are multiple ways to begin, commit and rollback
      transaction from `net.box`: using appropriate stream methods, using 'call`
      or 'eval' methods or using `execute` method with sql transaction syntax.
      User can mix these methods, for example, start transaction using
      `stream:begin()`, and commit transaction using `stream:call('box.commit')`
      or stream:execute('COMMIT').
      Simple example of using interactive transactions via iproto from net.box:
      ```lua
      stream = conn:new_stream()
      space = stream.space.test
      space_not_from_stream = conn.space.test
      
      stream:begin()
      space:replace({1})
      -- return previously inserted tuple, because request
      -- belongs to transaction.
      space:select({})
      -- empty select, because select doesn't belongs to
      -- transaction
      space_not_from_stream:select({})
      stream:call('box.commit')
      -- now transaction was commited, so all requests
      -- returns tuple.
      ```
      Different examples of using streams you can find in
      gh-5860-implement-streams-in-iproto.test.lua
      f9ca802a
    • mechanik20051988's avatar
      iproto: implement interactive transactions over iproto streams · 48c8dc18
      mechanik20051988 authored
      Implement interactive transactions over iproto streams. Each stream
      can start its own transaction, so they allows multiplexing several
      transactions over one connection. If any request fails during the
      transaction, it will not affect the other requests in the transaction.
      If disconnect occurs when there is some active transaction in stream,
      this transaction will be rollbacked, if it does not have time to commit
      before this moment.
      
      Part of #5860
      
      @TarantoolBot document
      Title: interactive transactions was implemented over iproto streams.
      The main purpose of streams is transactions via iproto. Each stream
      can start its own transaction, so they allows multiplexing several
      transactions over one connection. There are multiple ways to begin,
      commit and rollback transaction: using IPROTO_CALL and IPROTO_EVAL
      with corresponding function (box.begin, box.commit and box.rollback),
      IPROTO_EXECUTE with corresponding sql request ('TRANSACTION START',
      'COMMIT', 'ROLLBACK') and IPROTO_BEGIN, IPROTO_COMMIT, IPROTO_ROLLBACK
      accordingly. If disconnect occurs when there is some active transaction
      in stream, this transaction will be rollbacked, if it does not have time
      to commit before this moment. Add new command codes for begin, commit and
      rollback transactions: `IPROTO_BEGIN 14`, `IPROTO_COMMIT 15` and
      `IPROTO_ROLLBACK 16` accordingly.
      48c8dc18
    • mechanik20051988's avatar
      iproto: add RAFT prefix for all requests related to 'raft'. · 6c2eb11a
      mechanik20051988 authored
      Adding interactive transactions over iproto streamss requires
      adding new request types for begin, commit and rollback them.
      The type names of these new requests conflict with the existing
      names for the 'raft' requests. Adding RAFT prefix for all requests
      related to 'raft' resolves this problem.
      
      Part of #5860
      
      @TarantoolBot document
      Title: add RAFT prefix for all requests related to 'raft'.
      Rename IPROTO_PROMOTE, IPROTO_DEMOTE, IPROTO_CONFIRM and
      IPROTO_ROLLBACK to IPROTO_RAFT_PROMOTE, IPROTO_RAFT_DEMOTE,
      IPROTO_RAFT_CONFIRM and IPROTO_RAFT_ROLLBACK accordingly.
      6c2eb11a
    • mechanik20051988's avatar
      net.box: add stream support to net.box · 0084f903
      mechanik20051988 authored
      Add stream support to `net.box`. In "net.box", stream
      is an object over connection that has the same methods,
      but all requests from it sends with non-zero stream ID.
      Since there can be a lot of streams, we do not copy the
      spaces from the connection to the stream immediately when
      creating a stream, but do it only when we first access space.
      Also, when updating the schema, we update the spaces in lazy
      mode: each stream has it's own schema_version, when there is
      some access to stream space we compare stream schema_version
      and connection schema_version and if they are different update
      clear stream space cache and wrap space that is being accessed
      to stream cache.
      
      Part of #5860
      
      @TarantoolBot document
      Title: stream support was added to net.box
      In "net.box", stream is an object over connection that
      has the same methods, but all requests from it sends
      with non-zero stream ID. Stream ID is generated on the
      client automatically. Simple example of stream creation
      using net.box:
      ```lua
      stream = conn:new_stream()
      -- all connection methods are valid, but send requests
      -- with non zero stream_id.
      ```
      0084f903
    • mechanik20051988's avatar
      iproto: implement streams in iproto · 711cca10
      mechanik20051988 authored
      Implement streams in iproto. There is a hash table of streams for
      each connection. When a new request comes with a non-zero stream ID,
      we look for the stream with such ID in this table and if it does not
      exist, we create it. The request is placed in the queue of pending
      requests, and if this queue was empty at the time of its receipt, it
      is pushed to the tx thread for processing. When a request belonging to
      stream returns to the network thread after processing is completed, we
      take the next request out of the queue of pending requests and send it
      for processing to tx thread. If there is no pending requests we remove
      stream object from hash table and destroy it. Requests with zero stream
      ID are processed in the old way.
      
      Part of #5860
      
      @TarantoolBot document
      Title: streams are implemented in iproto
      A distinctive feature of streams is that all requests in them
      are processed sequentially. The execution of the next request
      in stream will not start until the previous one is completed.
      To separate requests belonging to and not belonging to streams
      we use stream ID field in binary iproto protocol: requests with
      non-zero stream ID belongs to some stream. Stream ID is unique
      within the connection and indicates which stream the request
      belongs to. For streams from different connections, the IDs may
      be the same.
      711cca10
    • mechanik20051988's avatar
      salad: fix segfault in case when mhash table allocation failure · a18741b0
      mechanik20051988 authored
      There was no check for successful memory allocation in `new` and `clear`
      functions for mhash table. And if the memory was not allocated, a null
      pointer dereference occured.
      a18741b0
    • mechanik20051988's avatar
      iproto: implement stream id in binary iproto protocol · e0bac737
      mechanik20051988 authored
      For further implementation of streams, we need to separate
      requests belonging to and not belonging to streams. For this
      purpose, the stream ID field was added to the iproto binary
      protocol. For requests that do not belong to stream, this field
      is omitted or equal to zero. For requests belonging to stream,
      we use this field to determine which stream the request belongs to.
      
      Part of #5860
      
      @TarantoolBot document
      Title: new field in binary iproto protocol
      
      Add new field to binary iproto protocol.
      `IPROTO_STREAM_ID 0x0a` determines whether a request
      belongs to a stream or not. If this field is omited
      or equal to zero this request doesn't belongs to stream.
      e0bac737
    • Vladimir Davydov's avatar
      iproto: clear request::header for client requests · 4fefb519
      Vladimir Davydov authored
      To apply a client request, we only need to know its type and body. All
      the meta information, such as LSN, TSN, or replica id, must be set by
      WAL. Currently, however, it isn't necessarily true: iproto leaves a
      request header received over iproto as is, and tx will reuse the header
      instead of allocating a new one in this case, which is needed to process
      replication requests, see txn_add_redo().
      
      Unless a client actually sets one of those meta fields, this causes no
      problems. However, if we added transaction support to the replication
      protocol, reusing the header would result in broken xlog, because
      currently, all requests received over iproto have the is_commit field
      set in xrow_header for the lack of TSN, while is_commit must only be set
      for the final statement in a transaction. One way to fix it would be
      clearing is_commit explicitly in iproto, but ignoring the whole header
      received over iproto looks more logical and error-proof.
      
      Needed for #5860
      4fefb519
    • Vladimir Davydov's avatar
      a397562e
  5. Aug 12, 2021
    • Leonid Vasiliev's avatar
      export: remove "error_unpack_unsafe" from "exports" · f2569702
      Leonid Vasiliev authored
      "error_unpack_unsafe" was removed from export in commit [1]
      and accidentally reanimated during rebase [2].
      Let's remove "error_unpack_unsafe" from "exports".
      
      1. https://github.com/tarantool/tarantool/commit/6aafa697e1ec8166df721573195711cea5ec3135
      2. https://github.com/tarantool/tarantool/commit/5ceabb378d0169dc776449e45577515114e39f12
      
      Follow-up #5932
      f2569702
    • Andrey Saranchin's avatar
      build: fix build on Linux ARM64 with CMAKE_BUILD_TYPE=Debug · 224cb68c
      Andrey Saranchin authored
      Fix build errors on arm64 with CMAKE_BUILD_TYPE=Debug.
      
      Despite doubts about the correctness of http parser, keep the principle
      of its work and unify behavior whether plain char is signed or unsigned.
      
      Closes #6143
      224cb68c
    • Serge Petrenko's avatar
      replication: fix flaky gh-3055-election-promote test · 1df99600
      Serge Petrenko authored
      Found the following error in our CI:
      
      [001] Test failed! Result content mismatch:
      [001] --- replication/gh-3055-election-promote.result	Mon Aug  2 17:52:55 2021
      [001] +++ var/rejects/replication/gh-3055-election-promote.reject	Mon Aug  9 10:29:34 2021
      [001] @@ -88,7 +88,7 @@
      [001]   | ...
      [001]  assert(not box.info.ro)
      [001]   | ---
      [001] - | - true
      [001] + | - error: assertion failed!
      [001]   | ...
      [001]  assert(box.info.election.term > term)
      [001]   | ---
      [001]
      
      The problem was the same as in recently fixed election_qsync.test
      (commit 096a0a7d): PROMOTE is written to
      WAL asynchronously, and box.ctl.promote() returns earlier than this
      happens.
      
      Fix the issue by waiting for the instance to become writeable.
      
      Follow-up #6034
      1df99600
    • Aleksandr Lyapunov's avatar
      box: implement compact mode in tuples · 74177dd8
      Aleksandr Lyapunov authored
      Tuple are designed to store (almost) any sizes of msgpack data
      and rather big count of field offsets. That requires data_offsert
      and bsize members of tuples to be rather large - 16 and 32 bits.
      
      That is good, but the problem is that in cases when the majority
      of tuples are small that price is significant.
      
      This patch introduces compact tuples: if tuple data size and its
      offset table are small - both tuple_offset and bsize are stored in
      one 16 bit integer and that saves 4 bytes per tuple.
      
      Compact tuples are used for memtx and runtime tuples. They are not
      implemented for vinyl, because in contrast to memtx vinyl stores
      engine specific fields after struct tuple and thus requires
      different approach for compact tuple.
      
      Part of #5385
      74177dd8
Loading