Skip to content
Snippets Groups Projects
  1. Jul 20, 2017
  2. Jul 19, 2017
    • Vladimir Davydov's avatar
      vinyl: use LSN from WAL instead of index_opts->lsn in vylog · 26af611f
      Vladimir Davydov authored
      An index can be dropped and then recreated with the same space/index id.
      To discriminate between different incarnations of the same index during
      recovery, we use index LSN stored in index options, as it is supposed to
      be unique. However, the uniqueness property doesn't always hold:
      
       - If two indexes are created from different fibers, they might receive
         the same LSN.
      
       - If an index is created by inserting a record into _index system space
         directly, without using the public API, as it is the case in case of
         logical backup, its LSN might conflict with the LSN of an existing
         index or a previous incarnation of the same index stored in vylog.
      
      These exceptions can result in unrecoverable errors during local
      recovery, like this one:
      
        F> can't initialize storage: Invalid VYLOG file: Duplicate index id 3
      
      Besides, storing LSN in index options is ugly, because LSN isn't a
      user-defined option - it's a part of the implementation.
      
      To fix this issues, let's use the LSN passed to Index::commitCreate,
      i.e. the actual LSN received by the row that created the index. There's
      one problem though: snapshot rows don't store LSNs. However, it doesn't
      mean we can't find the index in vylog corresponding to a snapshot row:
      we just need to look up the index by space_id/index_id instead of LSN
      and then compare the snapshot LSN with the LSN of the last index
      incarnation stored in vylog - if the latter turns out to be less, then
      we need to load the index, otherwise the index is going to be dropped
      and we need to load a dummy index. For more details, see the comment to
      vy_recovery_load_index().
      
      Another issue that needs a clarification is backward compatibility. The
      thing is the LSN written to the index options lags behind the actual LSN
      assigned to the row that created the index by 1. So to preserve backward
      compatibility, we use LSN from index options for legacy indexes that
      have it, while for indexes created after this patch we don't store LSN
      in index options (set it to 0), neither do we use it on recovery (use
      row LSN instead).
      
      Closes #2536
      26af611f
    • Vladimir Davydov's avatar
      box: generate LSNs for rows received during initial join · 7d67ec8a
      Vladimir Davydov authored
      Currently, 0 is passed to Index::commitCreate as index LSN during
      initial join. To stop using index_opts->lsn for identifying indexes in
      Vinyl, we need a unique LSN. So let's install a dummy journal to assign
      fake unique LSNs for rows received on initial join.
      
      Needed for #2536
      7d67ec8a
    • Vladimir Davydov's avatar
      box: propagate LSN to Index:commitCreate · fd99d3ab
      Vladimir Davydov authored
      So that we could use it instead of index_opts::lsn.
      
      On initial recovery pass the snapshot LSN instead as we don't store LSNs
      in memtx snapshot.
      
      Needed for #2536
      fd99d3ab
    • Vladislav Shpilevoy's avatar
    • Vladislav Shpilevoy's avatar
    • Vladislav Shpilevoy's avatar
      iproto: remove IprotoMsgGuard · 699b14e9
      Vladislav Shpilevoy authored
      699b14e9
    • Vladislav Shpilevoy's avatar
      2ab97c01
    • Vladislav Shpilevoy's avatar
      tuple: introduce tuple_arena_create · a2db8f1d
      Vladislav Shpilevoy authored
      Implement tuple_arena_create method to initialize tuple arena and
      quota. This method further will be used to initialize both
      memtx and vinyl arenas.
      
      Write a test showing the limit of vinyl statements size.
      
      Part of #2569
      a2db8f1d
    • Alexandr Lyapunov's avatar
    • Alexandr Lyapunov's avatar
      Fix memleak in iproto port, clean and optimize the code · bd04983a
      Alexandr Lyapunov authored
      Now if an error happens during the first tuple push from port to
      obuf, the port is not actually destroyed - only the first tuple is
      unreferenced.
      
      I believe that port dump must not free any data at all, then once
      a user creates a port he must take the ownership and destroy it in
      the end of usage. That would simplify the user code, especially C++.
      
      Simplify port_dump function and destroy a port in the code that
      creates the port.
      bd04983a
  3. Jul 18, 2017
  4. Jul 17, 2017
  5. Jul 14, 2017
  6. Jul 13, 2017
  7. Jul 12, 2017
    • Vladimir Davydov's avatar
      vinyl: zap include_deleted flag argument of vy_recovery_iterate · ea7af7f3
      Vladimir Davydov authored
      This flag is needed to skip records corresponding to dropped and
      incomplete runs on recovery, because given VY_LOG_CREATE_RUN the
      vy_recovery_iterate() callback can't tell if the run is used or
      going to be dropped. This flag needlessly complicates the code of
      vy_recovery_iterate(), which is supposed to simply replay all records
      recovered from the log, not try to be smart. Let's get rid of it and
      instead add a hint to vy_log_record indicating that a run created by
      VY_LOG_CREATE_RUN is going to be dropped.
      ea7af7f3
    • Vladimir Davydov's avatar
      vinyl: do not try to make index directory on truncate · 1b0aa562
      Vladimir Davydov authored
      vy_prepare_truncate_space() doesn't need to make directories for
      truncated indexes - they must already exist as the indexes were
      created. It just needs to create initial range for each of them.
      Factor out vy_index_init_range_tree() out of vy_index_create()
      and use it instead where appropriate.
      1b0aa562
    • Vladimir Davydov's avatar
      vinyl: refactor index recovery from vylog · 90fb2372
      Vladimir Davydov authored
      We have vy_recovery_lookup_index() function to look up an index in a
      recovery context by id and vy_recovery_iterate_index() to iterate over
      ranges, runs, and slices of a found index. vy_recovery_lookup_index()
      used to be a part of vy_recovery_iterate_index() and was factored out
      when index logging was moved to be called after WAL write, from
      vy_index_commit_create(), because during recovery we need to check if an
      index creation record was flushed to vylog before restart - currently we
      do it by trying to look it up in the recovery context.
      
      To stop using index lsn as vylog index id and remove lsn from index
      options, I'm planning to make the function loading an index from vylog
      advance an internal vylog counter so that the next time it is called it
      loads a newer incarnation of the same index. vy_recovery_lookup_index()
      doesn't fit this concept. So I introduce vy_recovery_load_index() that
      calls vy_recovery_lookup_index() and vy_recovery_iterate_index()
      internally and make the two functions private to vylog. To deal with
      indexes not logged due to vylog errors, I introduce a per index flag,
      vy_index->is_committed, which is set if the index record was flushed to
      vylog - the same approach is already used to handle index drop (see
      vy_index_commit_drop()).
      90fb2372
    • Roman Tsisyk's avatar
      Add comments to box_tuple_extract_key() · 6833e700
      Roman Tsisyk authored
      Closes #2535
      6833e700
    • Vladislav Shpilevoy's avatar
    • Alexandr Lyapunov's avatar
      vinyl: fix rollback of prepared TX · 87a2989b
      Alexandr Lyapunov authored
      Now if a prepared transaction is aborted, it expects to be the
      latest prepared TX in TX manager. It's not true in two cases:
      
      - The transaction failed during preparation. The TX is in partially
        prepared state and must rollback all the changes it made in mems
        but the preparation was not finished and thus the TX could not be
        considered as the latest in TX manager.
      
      - It's a cascading rollback with more than on TX. It would be
        graceful for the latest aborted TX to set the previous TX as
        the latest after the abortion. But the TX does not know the
        previous prepared TX and simply set to NULL appropriate pointer;
        when the time comes for the previous TX to be aborted it
        does not see itself as the latest.
      
      The TX must not expect itself to be the latest but must handle
      the last_prepared_tx pointer only if it is the latest.
      
      Fix it and add tests.
      
      Fix #2588 (case 1)
      Fix #2591 (case 2)
      87a2989b
  8. Jul 11, 2017
Loading