Skip to content
Snippets Groups Projects
  1. Jun 16, 2021
    • Vladislav Shpilevoy's avatar
      txn: stop TXN_SIGNATURE_ABORT override · b5f0dc4d
      Vladislav Shpilevoy authored
      When txn_commit/try_async() failed before going to WAL thread,
      they installed TXN_SIGNATURE_ABORT signature meaning that the
      caller and the rollback triggers must look at the global diag.
      
      But they called txn_rollback() before doing return and calling the
      triggers, which overrode the signature with TXN_SIGNATURE_ROLLBACK
      leading to the original error loss.
      
      The patch makes TXN_SIGNATURE_ROLLBACK installed only when a real
      rollback happens (via box_txn_rollback()).
      
      This makes the original commit errors like a conflict in the
      transaction manager and OOM not lost.
      
      Besides, ERRINJ_TXN_COMMIT_ASYNC does not need its own diag_log()
      anymore. Because since this commit the applier logs the correct
      error instead of ER_WAL_IO/ER_TXN_ROLLBACK.
      
      Closes #6027
      b5f0dc4d
    • Vladislav Shpilevoy's avatar
      txn: introduce TXN_SIGNATURE_ABORT · 26a8317f
      Vladislav Shpilevoy authored
      Sometimes a transaction can fail before it goes to WAL. Then the
      signature didn't have any sign of it, as well as the journal_entry
      result (which might be not even created yet).
      
      Still if txn_commit/try_async() are called, they invoke
      on_rollback triggers. The triggers only can see
      TXN_SIGNATURE_ROLLBACK and can't distinguish it from a real
      rollback like box.rollback().
      
      Due to that some important errors like a transaction manager
      conflict or OOM are lost.
      
      The patch introduces a new error signature TXN_SIGNATURE_ABORT
      which says the transaction didn't manage to try going to WAL and
      for an error need to look at the global diag.
      
      The next patch is going to stop overriding it with
      TXN_SIGNATURE_ROLLBACK.
      
      Part of #6027
      26a8317f
    • Vladislav Shpilevoy's avatar
      wal: introduce JOURNAL_ENTRY_ERR_CASCADE · 3e1ba96e
      Vladislav Shpilevoy authored
      A transaction in WAL thread could be rolled back not only due to
      an IO error. But also if there was a cascading rollback in
      progress.
      
      The patch makes such case use a special error code turned into its
      own diag when it reaches the TX thread. Usage of ER_WAL_IO wasn't
      correct here.
      
      Part of #6027
      3e1ba96e
    • Vladislav Shpilevoy's avatar
      txn: install proper diag errors on txn fail · 043385db
      Vladislav Shpilevoy authored
      Previously all journal and txn errors were turned into ER_WAL_IO
      error code. It led to loss of the real error, which sometimes was
      absolutely not related to IO. For example, a timeout in the limbo
      for a synchronous transaction.
      
      The patch makes journal/txn errors turn into proper diags.
      
      Part of #6027
      043385db
    • Vladislav Shpilevoy's avatar
      txn: assert after WAL write that txn is not done · 1ade2611
      Vladislav Shpilevoy authored
      In the journal write trigger the transaction assumed it might be
      already rolled back and completed, hence does not need to do
      anything except free itself.
      
      But it can't happen. The only imaginable reason why a transaction
      might be rolled back before it completed its WAL write is a
      ROLLBACK entry issued after the transaction.
      
      But ROLLBACK applies its effects only after it is written. Hence
      only after all the other pending txns are written too. Therefore
      it is not possible for a transaction to get ROLLBACK before it
      finishes its own WAL write.
      
      Probably it was possible in the time when applier used to execute
      ROLLBACK before writing it to WAL. But that was fixed in
      b259e930 ("applier: process
      synchro rows after WAL write"). Can't happen now.
      
      This became easier to realize when not finished transaction
      signature got its own value TXN_SIGNATURE_UNKNOWN.
      1ade2611
    • Vladislav Shpilevoy's avatar
      journal: introduce proper error codes · 4d896f84
      Vladislav Shpilevoy authored
      Journal used to have only one error code in journal_entry.res:
      -1. It had at least 2 problems:
      
      - There was an assumption that TXN_SIGNATURE_ROLLBACK is the same
        as journal_entry error = -1;
      
      - It wasn't possible to tell if the entry tried to be written and
        failed, or it didn't try yet. Both looked as -1.
      
      The patch introduces a new error code JOURNAL_ENTRY_ERR_UNKNOWN.
      The IO error now has its own value: JOURNAL_ENTRY_ERR_IO.
      
      This helps to ensure that a not finished journal entry or a
      transaction won't try to obtain a diag error for their result.
      
      Part of #6027
      4d896f84
    • Vladislav Shpilevoy's avatar
      txn: change limbo rollback check in the trigger · 42afd169
      Vladislav Shpilevoy authored
      A transaction on rollback used to check if it was already rolled
      back inside of the limbo by looking at its signature as
      
          signature != TXN_SIGNATURE_ROLLBACK
      
      It meant the transaction is already completed.
      TXN_SIGNATURE_ROLLBACK was used as a default value of the
      signature. Therefore if it is not default, it is completed.
      
      This is going to break if normal (not synchronous) transactions
      would have more rollback codes except just TXN_SIGNATURE_ROLLBACK.
      Also treatment of TXN_SIGNATURE_ROLLBACK as a default value looks
      confusing.
      
      Next patches are going to rework the codes and render the
      assumptions above incorrect.
      
      This patch makes the transaction use a correct way to check
      whether it is in the limbo still - look at TXN_WAIT_SYNC flag. It
      is set for all txns in the limbo and is not set for all the
      others.
      
      Part of #6027
      42afd169
    • Vladislav Shpilevoy's avatar
      wal: encapsulate ER_WAL_IO · 1b0d713a
      Vladislav Shpilevoy authored
      ER_WAL_IO is set on any WAL error if it was after journal_write()
      success. It is not correct, because there can be plenty of
      reasons.
      
      In WAL it could be an actual IO error or a cascading rollback in
      progress. When used for transactions, it could be an error related
      to synchronous transactions like a timeout, or a persistent
      ROLLBACK.
      
      These errors are overridden by ER_WAL_IO. The patch encapsulates
      the diag installation for bad journal write and for transaction
      rollback.
      
      The next patches are going to introduce more error codes and use
      proper ones to install a diag.
      
      Part of #6027
      1b0d713a
    • Vladislav Shpilevoy's avatar
      diag: introduce diag_set_detailed() · b8990efd
      Vladislav Shpilevoy authored
      diag_set() uses the current file and line as built-in macros.
      In the future patches there are going to appear a couple of new
      diag_set-like helpers which also would want to preserve the
      original file and line.
      
      For that they must be macros at least partially, like diag_set(),
      and pass their own file and line. Because they are going not to be
      very trivial and won't be implemented in the header.
      
      The patch introduces diag_set_detailed() which allows to pass
      custom file and line.
      
      Needed for #6027
      b8990efd
    • Vladislav Shpilevoy's avatar
      wal: refactor wal_write_to_disk() · 348e0245
      Vladislav Shpilevoy authored
      It didn't have a single fail path. That led to some amount of code
      duplication, and it complicated future patches where the journal
      entries are going to get a proper error reason instead of default
      -1 without any details.
      
      The patch is a preparation for #6027 where it is wanted to have
      more detailed errors on journal entry/transaction fail instead
      of ER_WAL_IO for everything. Sometimes it can override a real
      error like a cascade rollback, or a transaction conflict.
      
      Part of #6027
      348e0245
    • Vladislav Shpilevoy's avatar
      journal: make journal_write() set diag on error · 7191a692
      Vladislav Shpilevoy authored
      It used to simply return -1 and set a diag only when OOM happened
      inside.
      
      The caller was forced either to ignore the result or set its own
      diag regardless of what really happened.
      
      The patch makes journal_write() set a correct diag error when it
      returns -1. The only implementation to change was
      wal_write_async(). The other implementations always return 0.
      
      Part of #6027
      7191a692
    • Vladislav Shpilevoy's avatar
      test: remove replica-applier-rollback.lua · b89c7cae
      Vladislav Shpilevoy authored
      The script name was too long. It was also used as a name for the
      unix socket file on which the replica listens. As a result, the
      test couldn't start, at least on my machine.
      
      Besides, the script was not any different from the existing
      replica.lua, except a couple of not important settings.
      
      The patch drops it and makes gh-4730-applier-rollback.test.lua use
      replica.lua. Now it can run on my machine.
      
      Done as a preparation for #6027, which is slightly related to the
      test - it is also about errors in applier and their display.
      b89c7cae
    • Vladislav Shpilevoy's avatar
      error: introduce ER_CASCADE_ROLLBACK · 81009767
      Vladislav Shpilevoy authored
      It was called ER_CHECKPOINT_ROLLBACK but was set only when there
      is a cascade rollback in WAL.
      
      The new error name is going to be used in the next patches, where
      not only checkpoint can fail due to a cascade rollback.
      
      Part of #6027
      81009767
    • mechanik20051988's avatar
      build: fix tarantool build failure on xcode 12.5 · c5ae543f
      mechanik20051988 authored
      `VERSION` files in small subproject and in tarantool are treated as C++
      standard library on a filesystem with case-insensitive names. So we have
      to delete the root of tarantool project from `include_directories` in
      tarantool CMake. Also we have to change `include_directories` in tarantool
      CMake from the root of `small` project to `include` subfolder in `small`
      project.
      Closes #6076
      c5ae543f
    • Kirill Yukhin's avatar
      small: bump new version · ec45e4cf
      Kirill Yukhin authored
      * build: fix tarantool build failure on xcode 12.5
      ec45e4cf
  2. Jun 15, 2021
    • Alexander V. Tikhonov's avatar
      github-ci: add GitHub Actions workflow for M1 · 00c6b496
      Alexander V. Tikhonov authored
      In scope of this commit new GitHub Actions workflows for testing
      Tarantool on M1 hosts are added:
      
        Release: .github/workflows/osx_arm64_11_2.yml
        Debug: .github/workflows/osx_debug_arm64_11_2.yml
      
      Since GitHub Actions uses x86_64 environment by default on M1 targets,
      'arch -arm64' prefix is specified in GitHub Actions workflow to make all
      commands in .travis.mk run in ARM64 environment.
      
      Introduced a new temporary target in .travis.mk Makefile to run only
      specific LuaJIT test suites on M1. Now it runs only the following LuaJIT
      test targets:
      * PUC-Rio-Lua-5.1-tests
      * lua-Harness-tests
      * tarantool-tests
      
      Python 3.9 is installed by default on M1 hosts, but gevent is required
      for Tarantool tests, which installation fails with the following error:
      
        Using cached gevent-21.1.2.tar.gz (5.9 MB)
        Installing build dependencies ... done
        Getting requirements to build wheel ... done
          Preparing wheel metadata ... error
          ERROR: Command errored out with exit status 1:
           command: /opt/homebrew/opt/python@3.9/bin/python3.9 /opt/homebrew/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/_in_process.py prepare_metadata_for_build_wheel /var/folders/b0/1vlv5rvn77x2rn6zbl2p4tqr0000gp/T/tmpyy59ae2p
               cwd: /private/var/folders/b0/1vlv5rvn77x2rn6zbl2p4tqr0000gp/T/pip-install-msbf7_vz/gevent_c2956687bb0d4de9bfb5f0660da759ee
          Complete output (42 lines):
            ...
            File "/private/var/folders/b0/1vlv5rvn77x2rn6zbl2p4tqr0000gp/T/pip-build-env-1lesbbxi/overlay/lib/python3.9/site-packages/cffi/api.py", line 48, in __init__
              import _cffi_backend as backend
          ImportError: dlopen(/private/var/folders/b0/1vlv5rvn77x2rn6zbl2p4tqr0000gp/T/pip-build-env-1lesbbxi/overlay/lib/python3.9/site-packages/_cffi_backend.cpython-39-darwin.so, 2): no suitable image found.  Did find:
          	/private/var/folders/b0/1vlv5rvn77x2rn6zbl2p4tqr0000gp/T/pip-build-env-1lesbbxi/overlay/lib/python3.9/site-packages/_cffi_backend.cpython-39-darwin.so: mach-o, but wrong architecture
          	/private/var/folders/b0/1vlv5rvn77x2rn6zbl2p4tqr0000gp/T/pip-build-env-1lesbbxi/overlay/lib/python3.9/site-packages/_cffi_backend.cpython-39-darwin.so: mach-o, but wrong architecture
      
      This issue is described in gevent/gevent#1721. Fortunately, gevent can
      be successfully installed via Python 3.8, hence to avoid this failure,
      python3 is pinned to the specific version (i.e. python@3.8) until the
      mentioned issue is resolved.
      
      Closes tarantool/tarantool-qa#120
      Relates to #6068
      00c6b496
    • Alexander V. Tikhonov's avatar
      github-ci: refactor OSX jobs parameters · ebd87543
      Alexander V. Tikhonov authored
      To avoid targets duplication in the later use of .travis.mk file, it was
      decided to parameterize OSX jobs and move all fine tuning manipulations
      related to these pipelines from .travis.mk to the corresponding GitHub
      Actions workflows.
      ebd87543
  3. Jun 12, 2021
  4. Jun 11, 2021
    • Vladislav Shpilevoy's avatar
      election: test join to an election-enabled cluster · 5fe44e27
      Vladislav Shpilevoy authored
      There was a bug that a new replica at join to a election-enabled
      cluster sometimes tried to register on a non-leader node which
      couldn't write to _cluster, so the join failed with ER_READONLY
      error.
      
      Now in scope of #5613 the algorithm of join-master selection is
      changed. A new node looks for writable members of the cluster to
      use a join-master. It will not choose a follower if there is a
      leader.
      
      Closes #6127
      5fe44e27
  5. Jun 10, 2021
    • Vladislav Shpilevoy's avatar
      replication: prefer to join from booted replicas · 6a14c8d6
      Vladislav Shpilevoy authored
      The algorithm of looking for an instance to join the replicaset
      from didn't take into account that some of the instances might be
      not bootstrapped but still perfectly available.
      
      As a result, a ridiculous situation could happen - an instance
      could connect to a cluster with just read-only instances, but it
      could have itself with box.cfg{read_only = false}. Then instead of
      failing or waiting it just booted a brand new cluster. And after
      that the node just started complaining about the others having a
      different replicaset UUID.
      
      The patch makes so a new instance always prefers a bootstrapped
      join-source to a non-boostrapped one, including self. In the
      situation above the new instance now terminates with an error.
      
      In future hopefully it should start a retry-loop instead.
      
      Closes #5613
      
      @TarantoolBot document
      Title: IPROTO_BALLOT rework and a new field
      
      A couple of fields in `IPROTO_BALLOT 0x29` used to have values not
      matching with their names. They are changed.
      
      * `IPROTO_BALLOT_IS_RO 0x01` used to mean "the instance has
        `box.cfg{read_only = true}`". It was renamed in the source code
        to `IPROTO_BALLOT_IS_RO_CFG`. It has the same code `0x01`, and
        the value is the same. Only the name has changed, and in the doc
        should be too.
      
      * `IPROTO_BALLOT_IS_LOADING 0x04` used to mean "the instance has
        finished `box.cfg()` and it has `read_only = true`". The name
        was wrong therefore, because even if the instance finished
        loading, the flag still was false for `read_only = true` nodes.
        Also such a value is not very suitable for any sane usage.
        The name was changed to `IPROTO_BALLOT_IS_RO`, the code stayed
        the same, and the value now is "the instance is not writable".
        The reason for being not writable can be any: the node is an
        orphan; or it has `read_only = true`; or it is a Raft follower;
        or anything else.
      
      And there is a new field.
      
      `IPROTO_BALLOT_IS_BOOTED 0x06` means the instance has finished its
      bootstrap or recovery.
      6a14c8d6
    • Vladislav Shpilevoy's avatar
      replication: use 'score' to find a join-master · 89f1f636
      Vladislav Shpilevoy authored
      The patch refactors the algorithm of finding a join-master (in
      replicaset_find_join_master()) to use scores instead of multiple
      iterations with different criteria.
      
      The original code was relatively fine as long as it had only
      one parameter to change - whether should it skip
      `box.cfg{read_only = true}` nodes.
      
      Although it was clear that it was "on the edge" of acceptable
      complexity due to a second non-configurable parameter whether a
      replica is in read-only state regardless of its config.
      
      It is going to get more complicated when the algorithm will take
      into account the third parameter whether an instance is
      bootstrapped.
      
      Then it should make decisions like "among bootstrapped nodes try
      to prefer instances not having read_only=true, and not being in
      read-only state". The easiest way to do so is to use
      scores/weights incremented according to the instance's parameters
      matching certain "good points".
      
      Part of #5613
      89f1f636
    • Vladislav Shpilevoy's avatar
      replication: introduce ballot.is_booted · f8a150c2
      Vladislav Shpilevoy authored
      The new field reports whether the instance has finished its
      bootstrap/recovery, or IOW has finished box.cfg().
      
      The new field will help in fixing #5613 so as not to try to join
      to a replicaset via non-bootstrapped instances if there are
      others.
      
      The problem is that otherwise, if all nodes are booted but
      are read-only, new instances bootstrap their own independent
      replicaset. It would be better to just fail and terminate the
      process than do such a bizarre action.
      
      Part of #5613
      f8a150c2
    • Vladislav Shpilevoy's avatar
      replication: ballot.is_loading -> is_ro · 71d2a560
      Vladislav Shpilevoy authored
      Is_loading in the ballot used to mean the following: "the instance
      did not finish its box.cfg() or has read_only = true". Which is
      quite a strange property.
      
      For instance, it was 'true' even if the instance is not really
      loading anymore but has read_only = true.
      
      The patch renames it to 'is_ro' (which existed here before, but
      also with a wrong meaning).
      
      Its behaviour is slightly changed to report the RO state of the
      instance. Not its read_only. This way it incorporates all the
      possible RO conditions. Such as not finished bootstrap, having
      read_only = true, being a Raft follower, and so on.
      
      The patch is done in scope of #5613 where the ballot is going to
      be extended and used a bit differently in the join-master search
      algorithm.
      
      Part of #5613
      71d2a560
    • Vladislav Shpilevoy's avatar
      replication: ballot.is_ro -> is_ro_cfg · e4488f47
      Vladislav Shpilevoy authored
      Rename the member to show its actual meaning. It is not the
      real RO state of the instance. Only how it is configured.
      
      It can happen that the instance is read_only = false, but still is
      in RO state due to other reasons.
      
      The patch is done in scope of #5613 where the ballot is going to
      be extended and used a bit differently in the join-master search
      algorithm.
      
      Part of #5613
      e4488f47
    • Vladislav Shpilevoy's avatar
      replication: refactor replicaset_leader() · 2daec523
      Vladislav Shpilevoy authored
      Firstly, rename it to replicaset_find_join_master(). Now, when
      there is Raft with a concept of an actual leader, the function
      name becomes confusing.
      
      Secondly, do not access ballot member in struct applier in such a
      long way - save the ballot pointer on the stack. This is going to
      become useful when in one of the next patches the ballot will be
      used more.
      
      Part of #5613
      2daec523
  6. Jun 07, 2021
    • Vladislav Shpilevoy's avatar
      raft: handle remote leader resign during WAL write · 08a836b1
      Vladislav Shpilevoy authored
      If Raft state machine sees the current leader has explicitly
      resigned from its role, it starts a new election round right away.
      
      But in the code starting a new round there was an assumption that
      there is no a volatile state. There was, in fact.
      
      The patch makes the election start code use the volatile state to
      bump the term. It should be safe, because the other nodes won't
      receive it anyway until the new term is persisted.
      
      There was an alternative - do not schedule new election until the
      current WAL write ends. It wasn't done, because would achieve the
      same (the term would be bumped and persisted) but with bigger a
      latency.
      
      Another reason is that if the leader would appear and resign
      during WAL write on another candidate, in the end of its WAL write
      the latter would see 0 leader and would think this term didn't
      have one yet. And would try to elect self now, in the current
      term. It makes little sense, because it won't win - the current
      term had already had a leader and the majority of votes is
      already taken.
      
      Closes #6129
      08a836b1
    • Mergen Imeev's avatar
      box: check STRING length when it is cast to UUID · 9fb95cfd
      Mergen Imeev authored
      After this patch, the tt_uuid_from_strl() function will check the length
      of the given string before converting it to a UUID.
      
      Follow up #5886
      9fb95cfd
    • Mergen Imeev's avatar
      sql: introduce SQL built-in function UUID() · bce6992e
      Mergen Imeev authored
      This patch introduces a new SQL built-in function UUID().
      
      Closes #5886
      
      @TarantoolBot document
      Title: SQL built-in function UUID()
      
      SQL built-in function UUID() takes zero or one argument. If no argument
      is specified, a UUID v4 is generated. If the version of the UUID to
      generate is specified as an argument, the function returns the new UUID
      of the given version. Currently only version 4 of UUID is supported.
      bce6992e
    • Mergen Imeev's avatar
      sql: introduce UUID field type · 64f9018c
      Mergen Imeev authored
      This patch introduces UUID to SQL. UUID is now available as a new field
      type.
      
      Part of #5886
      
      @TarantoolBot document
      Title: Field type UUID is now available in SQL
      
      The UUID field type is now available in SQL. This means that we can
      create spaces and indexes with UUID, use it in SELECT, UPDATE and
      DELETE. UUID can be accepted and returned by built-in functions and
      user-defined functions.
      
      According to the comparison rules, there will be no implicit casting in
      the comparison. This rule also applies to UUID values: if a value is not
      part of a SCALAR field, it cannot be compared to a value of any other
      type. If the value is in a SCALAR field, it can be compared to any other
      scalar value according to the comparison rules for a SCALAR field.
      
      In case a UUID value is used in an operation that is not a comparison,
      it can be implicitly converted to STRING or VARBINARY.
      
      If a STRING or VARBINARY value is used in an operation that is not a
      comparison, it can be implicitly converted to a UUID.
      
      UUID value can always be explicitly converted to STRING or VARBINARY.
      
      A STRING or VARBINARY value can be explicitly converted to a UUID if it
      conforms to the UUID standard.
      64f9018c
  7. Jun 03, 2021
    • Mergen Imeev's avatar
      sql: VARBINARY result for LUA functions · 2b25ca6c
      Mergen Imeev authored
      This patch allows VARBINARY to be returned for user-defined LUA
      functions. However, there are currently no values that can be
      interpreted as VARBINARY by the serializer, so the only way to get a
      VARBINARY result for user-defined LUA functions is to return a UUID or
      DECIMAL. Both types are not supported by SQL and are treated as
      VARBINARY.
      
      Closes #6024
      2b25ca6c
    • Mergen Imeev's avatar
      sql: VARBINARY result for C functions · b5a78ead
      Mergen Imeev authored
      This patch allows VARBINARY to be returned for user-defined C functions.
      There is currently no support for UUID and DECIMAL in SQL, so they are
      also treated as VARBINARY.
      
      Part of #6024
      b5a78ead
    • Nikita Pettik's avatar
      vinyl: don't eliminate insert+delete during index build · c5e18547
      Nikita Pettik authored
      In 0e37af31 an optimization eliminating INSERT+DELETE and DELETE+INSERT
      statements by the same key in write set was introduced. It is fine until
      it comes for secondary index build. While we are building secondary
      index we save current lsn, set on_replace trigger forwarding new
      requests to the secondary index and copy row-by-row tuples (to be more
      precise keys) to secondary index until lsn of tuple is less than the one
      we preserved at the start. Now, if during index build we execute request
      replacing key that hasn't been already transferred to secondary index,
      we will get missing key in secondary index since:
      a) In on_replace trigger replace is split into DELETE+INSERT and
         eliminated by mentioned optimization (the same concerns simple pair
         of DELETE+INSERT requests made in single transaction - so that they
         get into one write set);
      b) It is skipped in the main loop transferring tuples from PK to SK
         since lsn of modified tuples is greater than saved lsn.
      
      In this respect, we may get missing tuples in secondary index.
      The proposed solution is quite trivial: we are able to track that index
      is still being created (see previous commit) so we won't apply
      INSERT+DELETE annihilation if index build is not finished.
      
      Closes #6045
      c5e18547
    • Nikita Pettik's avatar
      vinyl: introduce vy_lsm_is_being_constructed() · eecd2b90
      Nikita Pettik authored
      It tells whether LSM tree is currently being constructed, or is already
      built and committed.
      
      Needed for #6045
      eecd2b90
Loading