Amazon RDS - 每分钟变化的缓慢查询

Amazon RDS - Slow queries at every minute change

我们最近注意到,我们的慢速查询日志中每分钟更改一次(大约每分钟的第 0 秒)就会有更多的记录。这似乎与我们的任何 cronjobs 都无关,所以我决定使用 MySQL 8.0.23.

在新的 RDS t3.micro 实例上进行快速测试

复制步骤如下:

  1. 创建 table:

     CREATE TABLE `_test` (
       `date` datetime NOT NULL,
       `val` int NOT NULL DEFAULT '1'
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
     COMMIT;
    
  2. 进行 100'000 次插入(重要:对每一行使用一个查询,不要在一个查询中插入多行),如:

     INSERT INTO `_test` (`date`, `val`) VALUES (NOW(), '1');
     INSERT INTO `_test` (`date`, `val`) VALUES (NOW(), '1');
     INSERT INTO `_test` (`date`, `val`) VALUES (NOW(), '1');
     ...
    
  3. 运行 以下查询:

     SELECT  SUBSTRING(`date`, -2, 2) AS `second`, AVG(`count`) AS `avg`
       FROM  
         ( SELECT  `date`, COUNT(1) AS `count`
             FROM  `_test`
             GROUP BY  `date`
         ) AS `temp`
       GROUP BY  `second`
       ORDER BY  `avg` ASC
    

我的结果是:

second avg
00 20.1935
34 50.9667
01 51.1613
26 52.6667
02 52.9032
50 53.5333
20 53.6667
59 53.7188
30 53.8333
06 54.1613
36 54.1667
27 54.3333
05 54.5161
52 54.7742
04 55.0968
35 55.7000
15 55.9000
07 56.0000
38 56.0000
19 56.1000
49 56.1333
11 56.1333
29 56.1667
45 56.2000
03 56.2258

插入通常需要大约 0.02 秒(平均每秒 50-56 次插入),除了第 0 秒,插入需要 0.05 秒(平均每秒仅 20 次插入)。

并且随着 tables and/or 连接查询的更大和更复杂,延迟似乎变得更大。知道是什么导致了第 0 秒的滞后吗?

编辑:

@Rick James 的附加信息。

    CREATE TABLE `rds_history` (
     `action_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     `called_by_user` varchar(50) NOT NULL,
     `action` varchar(20) NOT NULL,
     `mysql_version` varchar(50) NOT NULL,
     `master_host` varchar(255) DEFAULT NULL,
     `master_port` int DEFAULT NULL,
     `master_user` varchar(16) DEFAULT NULL,
     `master_log_file` varchar(50) DEFAULT NULL,
     `master_log_pos` mediumtext,
     `master_ssl` tinyint(1) DEFAULT NULL,
     `master_delay` int DEFAULT NULL,
     `auto_position` tinyint(1) DEFAULT NULL,
     `master_gtid` text
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1

    CREATE TABLE `rds_replication_status` (
     `action_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     `called_by_user` varchar(50) NOT NULL,
     `action` varchar(20) NOT NULL,
     `mysql_version` varchar(50) NOT NULL,
     `master_host` varchar(255) DEFAULT NULL,
     `master_port` int DEFAULT NULL,
     `replication_log_file` text,
     `replication_stop_point` bigint DEFAULT NULL,
     `replication_gtid` text
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
rds_configuration InnoDB 10 Compact 3 5461 16384 0 0 0 NULL 08.03.21 11:19 NULL NULL latin1_swedish_ci NULL
rds_global_status_history InnoDB 10 Dynamic 0 0 16384 0 0 0 NULL 08.03.21 11:19 NULL NULL latin1_swedish_ci NULL
rds_global_status_history_old InnoDB 10 Dynamic 0 0 16384 0 0 0 NULL 08.03.21 11:19 NULL NULL latin1_swedish_ci NULL
rds_heartbeat2 InnoDB 10 Compact 0 0 16384 0 0 0 NULL 08.03.21 11:19 26.10.21 20:03 NULL latin1_swedish_ci NULL
rds_history InnoDB 10 Dynamic 1 16384 16384 0 0 0 NULL 08.03.21 11:19 NULL NULL latin1_swedish_ci NULL
rds_replication_status InnoDB 10 Dynamic 1 16384 16384 0 0 0 NULL 08.03.21 11:19 NULL NULL latin1_swedish_ci NULL
rds_sysinfo InnoDB 10 Compact 0 0 16384 0 0 0 NULL 08.03.21 11:19 NULL NULL utf8_general_ci NULL

更新:

刚刚在全新的 RDS t3.micro 实例上做了同样的测试 运行 MySQL 5.7.34(默认值:mysql-5-7 选项和参数组)。相似结果:

second avg
00 25.8286
01 44.8857
30 45.0000
22 45.8235
55 46.2857
20 46.8286
15 46.9143
51 47.1143
02 47.3714
45 47.5294
54 47.6286
25 47.6471
50 47.6571
24 47.6765
21 47.7647
10 47.7714
56 47.9714
16 48.1143
43 48.1176
47 48.1429
23 48.2353
07 48.2571
35 48.2647
57 48.3714
53 48.4571
06 48.4857
59 48.5429
05 48.8571
36 49.0588
03 49.1429
46 49.1471
52 49.1714
48 49.1714
26 49.1765
11 49.2000
31 49.2059
40 49.2059
58 49.2286
49 49.2857
39 49.2941
12 49.3429
04 49.3714
19 49.4000
34 49.4118
08 49.4286
38 49.4412
33 49.4706
17 49.5429
09 49.5714
18 49.6286
32 49.6765
27 49.8235
13 49.8286
41 49.8529
29 49.8529
37 49.8824
14 49.8857
44 50.0000
28 50.0588
42 50.0882

由于我无法在我的本地计算机和专用服务器(运行 MySQL 5.7)上复制结果,这一定是与 Amazon RDS 相关的问题,而不是MySQL版本问题。

我要求亚马逊对此进行调查并进行相同的测试,但没有回应。到目前为止,他们的支持总体上不是很有帮助。这里是否有其他拥有 AWS 账户的人能够复制并确认上述结果?我无法相信我们是唯一受此影响的人。

(还没有完整的答案。)

这些是奇怪的查询:

SELECT  count(*)
    FROM  mysql.rds_history
    WHERE  action = 'disable set master'
    GROUP BY  action_timestamp, called_by_user, action, mysql_version,
        master_host, master_port, master_user, master_log_file,
        master_log_pos, master_ssl
    ORDER BY  action_timestamp
    LIMIT  1

SELECT  count(*)
    FROM  mysql.rds_replication_status
    WHERE  master_host IS NOT NULL
      AND  master_port IS NOT NULL
    GROUP BY  action_timestamp, called_by_user, action, mysql_version,
        master_host, master_port
    ORDER BY  action_timestamp
    LIMIT  1

没有任何其他列的 COUNT(*) 加上 GROUP BYORDER BYLIMIT 的组合在我看来是胡说八道。

由于 RDS 使用块存储 (EBS),对 RDS 数据库的更改受限于您选择的存储的 IOPS。通用 SSD 存储每 GB 具有 3 IOPS,因此,例如,20 GB 的 IOPS 限制为 60。现在,如果您使用超过配置的 60 IOPS,您会在每分钟结束时(或新分钟开始时)遇到延迟。

解决方案:要么增加存储空间(注意,通用 SSD [gp2] 的吞吐量限制为最大 250 MiB/s,因此最多能够处理 1 '000 IOPS,即使您将存储增加到超过 333 GB)或选择支持更高 IOPS 的 IOPS-SSD 存储。