Uploaded image for project: 'Percona Toolkit'
  1. Percona Toolkit
  2. PT-2033

Avoid running same query concurrently from pt-stalk

Details

    • Improvement
    • Status: Done
    • High
    • Resolution: Fixed
    • None
    • 3.5.0
    • None
    • None
    • Yes
    • 16

    Description

      Release 3.0.4 implemented https://jira.percona.com/browse/PT-90 which runs:

       

      ps_prepared_statements() {
       $CMD_MYSQL $EXT_ARGV -e "SELECT t.processlist_id, pse.* \
       FROM performance_schema.prepared_statements_instances pse \
       JOIN performance_schema.threads t \
       ON (pse.OWNER_THREAD_ID=t.thread_id)\G"
      }

       

      On systems with lots of threads and prepared statements this does a fairly large scan for monitoring; From a processlist sample of a pt-stalk executed with this feature:

       

      Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       Rows_sent: 99685
      --
       Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       Rows_sent: 70740
      --
       Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       Rows_sent: 37304
      --
       Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       Rows_sent: 0
      --
       Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       Rows_sent: 136412
      --
       Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       Rows_sent: 107733
      --
       Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       Rows_sent: 73900
      --
       Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       Rows_sent: 36115
      --
       Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       Rows_sent: 1
      --
       Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       Rows_sent: 107209
      --
       Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       Rows_sent: 72646
      --
       Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       Rows_sent: 14
      --
       Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       Rows_sent: 109057
      --

       

      But the real problem is that not only was scanning in excess of 100k rows, is that it was running concurrently 4 - 5 instances of the query at a time;  From the same processlist samples, aggregated by "Info:"

       

      2021_12_15_14_14_20-processlist-sample-02
       389 Info: NULL
       4 Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       2 Info: SHOW ENGINE INNODB MUTEX
      =============================================
      2021_12_15_14_14_20-processlist-sample-03
       390 Info: NULL
       5 Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       2 Info: SHOW ENGINE INNODB MUTEX
      =============================================
      2021_12_15_14_14_20-processlist-sample-04
       392 Info: NULL
       3 Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       3 Info: SELECT SQL_NO_CACHE
      =============================================
      2021_12_15_14_14_20-processlist-sample-05
       376 Info: NULL
       3 Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
       3 Info: SELECT SQL_NO_CACHE
      =============================================
      2021_12_15_14_14_20-processlist-sample-06
       369 Info: NULL
       5 Info: SELECT SQL_NO_CACHE
       3 Info: SELECT t.processlist_id, pse.* FROM performance_schema.prepared_statements_instances pse JOIN performance_schema.threads t
      =============================================
      2021_12_15_14_14_20-processlist-sample-07
       392 Info: NULL
       5 Info: SELECT SQL_NO_CACHE
       4 Info: SELECT t.processlist_id, pse.*

       

      We can also see there a query with SQL_NO_CACHE; That query also comes from pt-stalk and is the one looking at locking:

      SELECT SQL_NO_CACHE
       CONCAT('thread ', b.trx_mysql_thread_id, ' from ', p.host) AS who_blocks,
       IF(p.command = "Sleep", p.time, 0) AS idle_in_trx,
       MAX(TIMESTAMPDIFF(SECOND, r.trx_wait_started, CURRENT_TIMESTAMP)) AS max_wait_time,
       COUNT(*) AS num_waiters
       FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS AS w
       INNER JOIN INFORMATION_SCHEMA.INNODB_TRX AS b ON b.trx_id = w.blocking_trx_id
       INNER JOIN INFORMATION_SCHEMA.INNODB_TRX AS r ON r.trx_id = w.requesting_trx_id
       LEFT JOIN INFORMATION_SCHEMA.PROCESSLIST AS p ON p.id = b.trx_mysql_thread_id
       GROUP BY who_blocks ORDER BY num_waiters DESC

       

       

      Both queries are necessary, but running them concurrently makes them excessively heavy. My original intent was to request making the prepared_statements_instances query optional, but I think it makes more sense to look at having pt-stalk only ever execute the same query sequentially, even if this means degrading sampling quality.   In other words: avoid having same query running concurrently.

      Having a single connection for each type of query should be easiest way to achieve this, and would also prevent the overhead of the dozens of connections pt-stalk does.

       

       

       

      Attachments

        Issue Links

          Activity

            People

              sveta.smirnova Sveta Smirnova
              marcos.albe Marcos Albe
              Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Smart Checklist