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

INNODB_ROWS_UPDATED / n_rows_updated can become imprecise under heavy load

    XMLWordPrintable

    Details

      Description

      (We are currently in the process of adding Pomelo.EntityFramework.MySql and related benchmarks to the TechEmpower Framework Benchmarks. As part of that, I have also prepared a PR that will add MariaDB as a database to the benchmark. Preliminary locally run tests show about a 4 % increase in speed over MySQL. Feel free to join the conversation.)

      Affects all versions of MariaDB and MySQL.
      I posted a related bug report for MySQL.

      Issue:

      The INNODB_ROWS_UPDATED status variable is used by the TechEmpower Framework Benchmarks for MariaDB (and MySQL) verifying the expected UPDATE count after a benchmark run.

      The framework tests different scenarios from little to high loads (high concurrency).

      When running 10240 updates, divided into 512 concurrent calls, so 20 updates per connection, MariaDB (and MySQL) regularly only reports between 10237 and 10239 updates, even though all 10240 updates where successfully executed.

      It seems, that the srv_stats.n_rows_updated.inc(); calls increment the stats in an concurrency unsafe way:

        /** If you can't use a good index id. Increment by 1. */
        void inc() UNIV_NOTHROW { add(1); }
       
        /** If you can't use a good index id.
        @param n is the amount to increment */
        void add(Type n) UNIV_NOTHROW {
          size_t i = m_policy.offset(m_policy.get_rnd_index());
       
          ut_ad(i < UT_ARR_SIZE(m_counter));
       
          m_counter[i] += n;
        }
      

      The current workaround is to heuristically ignore the difference, if it is within an expected margin, which defeats the purpose of verifying the accuracy/health of the benchmark before running it.

      How to repeat:

      Run 10240 updates, divided in 512 (truly) concurrent connections, against any MariaDB (or MySQL) InnoDB table and check the expected INNODB_ROWS_UPDATED (and INNODB_ROWS_READ) count against the actual one. They should differ in about 4 out of 5 runs.

      Suggested fix:

      I would propose to use interlocked increment operations for inc() and interlocked add operations for add(), for a maximum in performance and counting accuracy at the same time.

        Attachments

          Activity

            People

            Assignee:
            marko Marko Mäkelä
            Reporter:
            lauxjpn Lau
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated:

                Git Integration