1. 24 Jun, 2021 2 commits
    • Marko Mäkelä's avatar
      Merge 10.5 into 10.6 · b4c9cd20
      Marko Mäkelä authored
      b4c9cd20
    • Marko Mäkelä's avatar
      MDEV-26004 Excessive wait times in buf_LRU_get_free_block() · 60ed4797
      Marko Mäkelä authored
      buf_LRU_get_free_block(): Initially wait for a single block to be
      freed, signaled by buf_pool.done_free. Only if that fails and no
      LRU eviction flushing batch is already running, we initiate a
      flushing batch that should serve all threads that are currently
      waiting in buf_LRU_get_free_block().
      
      Note: In an extreme case, this may introduce a performance regression
      at larger numbers of connections. We observed this in sysbench
      oltp_update_index with 512MiB buffer pool, 4GiB of data on fast NVMe,
      and 1000 concurrent connections, on a 20-thread CPU. The contention point
      appears to be buf_pool.mutex, and the improvement would turn into a
      regression somewhere beyond 32 concurrent connections.
      
      On slower storage, such regression was not observed; instead, the
      throughput was improving and maximum latency was reduced.
      
      The excessive waits were pointed out by Vladislav Vaintroub.
      60ed4797
  2. 23 Jun, 2021 15 commits
    • Marko Mäkelä's avatar
      Merge 10.5 into 10.6 · 101da872
      Marko Mäkelä authored
      101da872
    • Marko Mäkelä's avatar
      MDEV-25113: Introduce a page cleaner mode before 'furious flush' · 6441bc61
      Marko Mäkelä authored
      MDEV-23855 changed the way how the page cleaner is signaled by
      user threads. If a threshold is exceeded, a mini-transaction commit
      would invoke buf_flush_ahead() in order to initiate page flushing
      before all writers would eventually grind to halt in
      log_free_check(), waiting for the checkpoint age to reduce.
      
      However, buf_flush_ahead() would always initiate 'furious flushing',
      making the buf_flush_page_cleaner thread write innodb_io_capacity_max
      pages per batch, and sleeping no time between batches, until the
      limit LSN is reached. Because this could saturate the I/O subsystem,
      system throughput could significantly reduce during these
      'furious flushing' spikes.
      
      With this change, we introduce a gentler version of flush-ahead,
      which would write innodb_io_capacity_max pages per second until
      the 'soft limit' is reached.
      
      buf_flush_ahead(): Add a parameter to specify whether furious flushing
      is requested.
      
      buf_flush_async_lsn: Similar to buf_flush_sync_lsn, a limit for
      the less intrusive flushing.
      
      buf_flush_page_cleaner(): Keep working until buf_flush_async_lsn
      has been reached.
      
      log_close(): Suppress a warning message in the event that a new log
      is being created during startup, when old logs did not exist.
      Return what type of page cleaning will be needed.
      
      mtr_t::finish_write(): Also when m_log.is_small(), invoke log_close().
      Return what type of page cleaning will be needed.
      
      mtr_t::commit(): Invoke buf_flush_ahead() based on the return value of
      mtr_t::finish_write().
      6441bc61
    • Marko Mäkelä's avatar
      MDEV-25113: Make page flushing faster · 22b62eda
      Marko Mäkelä authored
      buf_page_write_complete(): Reduce the buf_pool.mutex hold time,
      and do not acquire buf_pool.flush_list_mutex at all.
      Instead, mark blocks clean by setting oldest_modification to 1.
      Dirty pages of temporary tables will be identified by the special
      value 2 instead of the previous special value 1.
      (By design of the ib_logfile0 format, actual LSN values smaller
      than 2048 are not possible.)
      
      buf_LRU_free_page(), buf_pool_t::get_oldest_modification()
      and many other functions will remove the garbage (clean blocks)
      from buf_pool.flush_list while holding buf_pool.flush_list_mutex.
      
      buf_pool_t::n_flush_LRU, buf_pool_t::n_flush_list:
      Replaced with non-atomic variables, protected by buf_pool.mutex,
      to avoid unnecessary synchronization when modifying the counts.
      
      export_vars: Remove unnecessary indirection for
      innodb_pages_created, innodb_pages_read, innodb_pages_written.
      22b62eda
    • Marko Mäkelä's avatar
      MDEV-25801: buf_flush_dirty_pages() is very slow · 8af53897
      Marko Mäkelä authored
      In commit 7cffb5f6 (MDEV-23399)
      the implementation of buf_flush_dirty_pages() was replaced with
      a slow one, which would perform excessive scans of the
      buf_pool.flush_list and make little progress.
      
      buf_flush_list(), buf_flush_LRU(): Split from buf_flush_lists().
      Vladislav Vaintroub noticed that we will not need to invoke
      log_flush_task.wait() for the LRU eviction flushing.
      
      buf_flush_list_space(): Replaces buf_flush_dirty_pages().
      This is like buf_flush_list(), but operating on a single
      tablespace at a time. Writes at most innodb_io_capacity
      pages. Returns whether some of the tablespace might remain
      in the buffer pool.
      8af53897
    • Marko Mäkelä's avatar
      MDEV-25948 Remove log_flush_task · 762bcb81
      Marko Mäkelä authored
      Vladislav Vaintroub suggested that invoking log_flush_up_to()
      for every page could perform better than invoking a log write
      between buf_pool.flush_list batches, like we started doing in
      commit 3a9a3be1 (MDEV-23855).
      This could depend on the sequence in which pages are being
      modified. The buf_pool.flush_list is ordered by
      oldest_modification, while the FIL_PAGE_LSN of the pages is
      theoretically independent of that. In the pathological case,
      we will wait for a log write before writing each individual page.
      
      It turns out that we can defer the call to log_flush_up_to()
      until just before submitting the page write. If the doublewrite
      buffer is being used, we can submit a write batch of "future" pages
      to the doublewrite buffer, and only wait for the log write right
      before we are writing an already doublewritten page.
      The next doublewrite batch will not be initiated before the last
      page write from the current batch has completed.
      
      When a future version introduces asynchronous writes if the log,
      we could initiate a write at the start of a flushing batch, to
      reduce waiting further.
      762bcb81
    • Marko Mäkelä's avatar
      MDEV-25954: Trim os_aio_wait_until_no_pending_writes() · 6dfd44c8
      Marko Mäkelä authored
      It turns out that we had some unnecessary waits for no outstanding
      write requests to exist. They were basically working around a
      bug that was fixed in MDEV-25953.
      
      On write completion callback, blocks will be marked clean.
      So, it is sufficient to consult buf_pool.flush_list to determine
      which writes have not been completed yet.
      
      On FLUSH TABLES...FOR EXPORT we must still wait for all pending
      asynchronous writes to complete, because buf_flush_file_space()
      would merely guarantee that writes will have been initiated.
      6dfd44c8
    • Marko Mäkelä's avatar
      MDEV-25062: Reduce trx_rseg_t::mutex contention · 6e12ebd4
      Marko Mäkelä authored
      redo_rseg_mutex, noredo_rseg_mutex: Remove the PERFORMANCE_SCHEMA keys.
      The rollback segment mutex will be uninstrumented.
      
      trx_sys_t: Remove pointer indirection for rseg_array, temp_rseg.
      Align each element to the cache line.
      
      trx_sys_t::rseg_id(): Replaces trx_rseg_t::id.
      
      trx_rseg_t::ref: Replaces needs_purge, trx_ref_count, skip_allocation
      in a single std::atomic<uint32_t>.
      
      trx_rseg_t::latch: Replaces trx_rseg_t::mutex.
      
      trx_rseg_t::history_size: Replaces trx_sys_t::rseg_history_len
      
      trx_sys_t::history_size_approx(): Replaces trx_sys.rseg_history_len
      in those places where the exact count does not matter. We must not
      acquire any trx_rseg_t::latch while holding index page latches, because
      normally the trx_rseg_t::latch is acquired before any page latches.
      
      trx_sys_t::history_exists(): Replaces trx_sys.rseg_history_len!=0
      with an approximation.
      
      We remove some unnecessary trx_rseg_t::latch acquisition around
      trx_undo_set_state_at_prepare() and trx_undo_set_state_at_finish().
      Those operations will only access fields that remain constant
      after trx_rseg_t::init().
      6e12ebd4
    • Marko Mäkelä's avatar
      MDEV-25967: Correctly extend deferred-recovery files · b3e87880
      Marko Mäkelä authored
      recv_sys_t::recover_deferred(): Set the file size to match the number
      of pages. Mariabackup might copy the file while it was being extended.
      b3e87880
    • Marko Mäkelä's avatar
      MDEV-25996 sux_lock::s_lock(): Assertion !have_s() failed on startup · 592a925c
      Marko Mäkelä authored
      dict_check_sys_tables(): Correctly advance the cursor position.
      This fixes a regression that was caused by
      commit 49e2c8f0 (MDEV-25743).
      592a925c
    • Marko Mäkelä's avatar
      Merge 10.5 into 10.6 · 3a566de2
      Marko Mäkelä authored
      3a566de2
    • Marko Mäkelä's avatar
      Merge 10.4 into 10.5 · 344e5990
      Marko Mäkelä authored
      344e5990
    • Marko Mäkelä's avatar
      Merge 10.3 into 10.4 · 09b03ff3
      Marko Mäkelä authored
      09b03ff3
    • Daniel Bartholomew's avatar
      bump the VERSION · 55b3a3f4
      Daniel Bartholomew authored
      55b3a3f4
    • Daniel Bartholomew's avatar
      bump the VERSION · bf2680ea
      Daniel Bartholomew authored
      bf2680ea
    • Daniel Bartholomew's avatar
      bump the VERSION · 1deb6304
      Daniel Bartholomew authored
      1deb6304
  3. 22 Jun, 2021 7 commits
    • Igor Babaev's avatar
      MDEV-25679 Wrong result selecting from simple view with LIMIT and ORDER BY · 7f24e37f
      Igor Babaev authored
      Cherry-picking only test case.
      7f24e37f
    • Marko Mäkelä's avatar
      MDEV-25950 Ignoring strange row from mysql.innodb_index_stats after DDL · 9fc67c6b
      Marko Mäkelä authored
      commit_try_rebuild(): Invoke trx_t::drop_table_statistics()
      with the correct (original) name of the table.
      This fixes a regression that was introduced in
      commit 1bd681c8 (MDEV-25506 part 3).
      9fc67c6b
    • Marko Mäkelä's avatar
      MDEV-25989 Crash (or hang) on startup after restoring backup · e1c953ef
      Marko Mäkelä authored
      If an ALTER TABLE that affected a table with FULLTEXT INDEX was
      in progress while a backup was made, InnoDB would crash or hang
      during the first startup after restoring the backup,
      while trying to drop the #sql-alter- table for the DDL operation.
      
      drop_garbage_tables_after_restore(): Invoke dict_sys.unlock()
      before invoking the FTS functions. Also, invoke purge_sys.stop_FTS()
      in debug builds to silence debug assertions. (Purge is not yet
      running at this point.)
      e1c953ef
    • Marko Mäkelä's avatar
      MDEV-25981 InnoDB upgrade fails · 35a9aaeb
      Marko Mäkelä authored
      trx_undo_mem_create_at_db_start(): Relax too strict upgrade checks
      that were introduced in
      commit e46f76c9 (MDEV-15912).
      On commit, pages will typically be set to TRX_UNDO_CACHED state.
      Having the type TRX_UNDO_INSERT in such pages is common and
      unproblematic; the type would be reset in trx_undo_reuse_cached().
      
      trx_rseg_array_init(): On failure, clean up the rollback segments
      that were initialized so far, to avoid an assertion failure later
      during shutdown.
      35a9aaeb
    • Marko Mäkelä's avatar
      Merge 10.2 into 10.3 · e07f0a2d
      Marko Mäkelä authored
      e07f0a2d
    • Marko Mäkelä's avatar
      MDEV-25982 Upgrade of MariaDB 10.1 log crashes due to missing encryption key · 19716ad5
      Marko Mäkelä authored
      init_crypt_key(): On failure, set info->key_version to
      ENCRYPTION_KEY_VERSION_INVALID.
      
      log_crypt_101_read_block(): Refuse to attempt decryption if
      info->key_version is ENCRYPTION_KEY_VERSION_INVALID.
      19716ad5
    • Igor Babaev's avatar
      MDEV-25679 Wrong result selecting from simple view with LIMIT and ORDER BY · 6e94ef41
      Igor Babaev authored
      This bug affected queries with views / derived_tables / CTEs whose
      specifications were of the form
        (SELECT ... LIMIT <n>) ORDER BY ...
      Units representing such specifications contains one SELECT_LEX structure
      for (SELECT ... LIMIT <n>) and additionally SELECT_LEX structure for
      fake_select_lex. This fact should have been taken into account in the
      function mysql_derived_fill().
      
      This patch has to be applied to 10.2 and 10.3 only.
      6e94ef41
  4. 21 Jun, 2021 16 commits