Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-38814

High rate of index_lock_upgrades due to btr_cur_need_opposite_intention() mostly returning true

    XMLWordPrintable

Details

    • Hide
      Added a variable innodb_index_shrink (default ON matching legacy behavior) to allow disabling the capability of InnoDB of shrinking a B-tree (by merging or reorganizing pages) on record-growing UPDATEs (such as NULL to not-NULL).
      The optimization (enabled via setting the option to OFF), reduces index tree latch upgrades and the contention they cause by favoring page splits in such cases, at the cost of slightly sparser pages.
      Show
      Added a variable innodb_index_shrink (default ON matching legacy behavior) to allow disabling the capability of InnoDB of shrinking a B-tree (by merging or reorganizing pages) on record-growing UPDATEs (such as NULL to not-NULL). The optimization (enabled via setting the option to OFF), reduces index tree latch upgrades and the contention they cause by favoring page splits in such cases, at the cost of slightly sparser pages.
    • Q2/2026 Server Maintenance, Q2/2026 Server Development

    Description

      While testing MDEV-34431 using HammerDB TPROC-C (Delivery mix) on a 24 vCPU Intel system (oversubscribed with 88 threads) we observed a strong correlation between ORDER_LINE updates and frequent index lock upgrades.

      As an experiment, commenting out the ORDER_LINE update in the Delivery stored procedure significantly reduced index lock upgrades and reduced rd_lock_spin sample percentage.

      Test Schema ORDER_LINE UPDATE NOPM index_lock_upgrade() rd_lock_spin samples (%)
      T1 Partitioned ON 586,990 14,369,068 6.53
      T2 Partitioned OFF 654,123 3,201,626 3.87
      T3 Unpartitioned ON 503,278 10,220,286 19.96
      T4 Unpartitioned OFF 653,284 3,103,213 8.95

      Counters were added around:
      btr_cur_need_opposite_intention()
      Entry to pessimistic_search_leaf()
      mtr_t::index_lock_upgrade()

      For both partitioned and unpartitioned schemas:

      btr_cur_need_opposite_intention() returned true for nearly all calls.
      The dominant reason was nosib=true.
      pessimistic_search_leaf() calls closely tracked the number of true returns.
      index_lock_upgrade() calls closely tracked pessimistic_search_leaf() calls.

      Example (Partitioned)

      [btr_cur_need_opposite_intention]
      calls=14018262 true=14010891
      zip=0 nosib=14010891 first=104879 last=121344 small=514079 rightmost=121344 reorg=0
       
      [index_lock_upgrade]
      calls=14018262 already_x=0 upgraded=14018262
      

      pess@table=tpcc/order_line#P#p7 index=PRIMARY tree_height=3 height=2
      pess@table=tpcc/orders index=PRIMARY tree_height=3 height=2
      pess@table=tpcc/new_order index=PRIMARY tree_height=3 height=2
      

      Example (Unpartitioned)

      [btr_cur_need_opposite_intention]
      calls=9786751 true=9780023
      zip=0 nosib=9780023 first=1 last=2849015 small=471126 rightmost=2849015 reorg=0
       
      [index_lock_upgrade]
      calls=9786751 already_x=0 upgraded=9786751
      

      pess@table=tpcc_nopart/order_line index=PRIMARY tree_height=4 height=3
      pess@table=tpcc_nopart/orders index=PRIMARY tree_height=3 height=2
      pess@table=tpcc_nopart/new_order index=PRIMARY tree_height=3 height=2
      

      This suggests that the update path is almost always escalating to pessimistic search and upgrading the index latch early in the descent (height == tree_height - 1), e.g.:

      calls=14018262 true=14010891 root=14018262 root_true=14010891 lvl0=0 lvlgt0=14018262
      

      Diagnostic experiment

      As a diagnostic experiment, btr_cur_need_opposite_intention() was modified to always return false.

      Results:
      pessimistic_search_leaf() and index_lock_upgrade() calls dropped from millions to tens.
      Unpartitioned throughput improved by ~7.5%.
      A small number of pessimistic_search_leaf() calls remained.

      [btr_cur_need_opposite_intention]
      calls=41255137 true=0
      zip=0 nosib=0 first=0 last=0 small=0 rightmost=0 reorg=0
       
      [index_lock_upgrade]
      calls=30 already_x=0 upgraded=30
      

      When btr_cur_need_opposite_intention() was modified to always return false, instance hangs were observed during schema builds loading the history table. After adding a primary key in our local test schema, the hang did not reproduce.

      Attachments

        Issue Links

          Activity

            People

              alessandro.vetere Alessandro Vetere
              Steve Shaw Steve Shaw
              Votes:
              1 Vote for this issue
              Watchers:
              10 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - 26d
                  26d
                  Remaining:
                  Remaining Estimate - 0d
                  0d
                  Logged:
                  Time Spent - 20d 0.5h Time Not Required
                  20d 0.5h

                  Git Integration

                    Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.