MySQL运维25-MySQL数据库基本监控

1、基于SHOW PROCESSLIST监控线程状态是否异常

  1. 一个线程中大多数状态对应的操作都非常快,如果一个线程停留在某状态好几秒,可能就有问题
  2. 线程的常用状态如下:
    • Sleep:线程正在等待来自客户端的新查询。
    • Query:线程正在执行查询,或者正在发送结果给客户端。
    • Locked:线程正在等待表锁。
    • Analyzing和statistics:线程正在获取存储引擎的统计数据和优化查询。
    • Copying to tmp table[on disk]:线程正在处理查询,复制数据到临时表中。如果后面有“on di sk”字样,则表明MySQL正在将内存临时表转换为磁盘临时表。
    • Sorting result:线程正在排序结果集。
    • Sending data:这个状态有多种可能,可能是内部传递数据,也可能是将结果集返回给客户端。
  3. 可以通过对SHOW PROCESSLIST的结果进行分析,获取到不同状态下线程的比例。以下是具体语句示例:
# mysql --login-path=fastlogin  -e 'SHOW PROCESSLIST\G' | grep Command: | sort | uniq -c | sort -rn
      6 Command: Sleep
      1 Command: Query
      1 Command: Binlog Dump

2、基于SELECT状态变量监控SQL运行成本

2.1、基本用法

  1. 运行如下命令,可以查看Select状态变量:
mysql> SHOW STATUS LIKE 'Select%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Select_full_join       | 0     |
| Select_full_range_join | 0     |
| Select_range           | 0     |
| Select_range_check     | 0     |
| Select_scan            | 0     |
+------------------------+-------+
5 rows in set (0.01 sec)
  1. 以下三个变量都需要注意,特别是Select_scan和Select_full_join比较高意味着查询语句有问题或者没有正确使用索引
    1. Select_full_join:记录SELECT查询时进行了FULL JOIN操作且进行了全表扫描的次数。全表扫描是指没有使用索引或者无法使用索引时,MySQL 需要扫描整个表的情况。FULL JOIN是将两个表中的所有记录进行匹配,包括那些在其中一个表中没有匹配到的记录。
    2. Select_scan:记录SELECT查询时使用了全表扫描的次数。与 Select_full_join 变量不同的是,Select_scan 记录的是所有进行全表扫描的 SELECT 查询的次数,而不仅仅是使用了 FULL JOIN 操作的查询。因此,Select_scan 变量的值可能会比 Select_full_join 变量的值更高。
    3. Select_full_range_join:记录SELECT查询时使用了范围查找(Range Search)算法进行全表扫描的次数。

2.2、基于SHOW SESSION STATUS监控特定SQL运行成本

  1. 运行SHOW SESSION STATUS可以查看当前会话的状态变量。有时我们需要单独分析一些特定查询的成本,就可以通过查看会话中的状态变量进行分析
  2. 但在监控分析前,需要先手动清除状态变量归零(FLUSH STATUS),然后再运行查询,最后重新运行SHOW SESSION STATUS,从而监控特定查询所耗费的成本。
  3. 以下示例显示了如何分析一个特定查询的成本。
mysql> FLUSH STATUS;			# 清除状态变量
mysql> SELECT SQL_NO_CACHE ... from ...    	# 运行查询语句
mysql> SHOW SESSION STATUS LIKE‘Select%’;	# 重新查询状态变量
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Select_full_join       | 0     |
| Select_full_range_join | 0     |
| Select_range           | 0     |
| Select_range_check     | 0     |
| Select_scan            | 2     |
+------------------------+-------+

3、监控存储引擎操作(Handler%)相关状态变量

  1. 如下命令将检查与存储引擎操作相关的状态变量:
mysql> SHOW SESSION STATUS LIKE 'Handler%';
+------------------------+---------+
| Variable_name     | Value |
+------------------------+---------+
| Handler_commit |     0     |
| Handler_delete    |     0     |
| Handler_discover |     0     |
| Handler_prepare |     0     |
| Handler_read_first |   1    |
| Handler_read_key | 5665 |
| Handler_read_next | 5662 
| Handler_read_prev | 0 | DESC。
| Handler_read_rnd | 200 |
| Handler_read_rnd_next | 207 |
| Handler_rollback | 0 |
| Handler_savepoint | 0 |
| Handler_savepoint_rollback | 0 |
| Handler_update | 5262 |
| Handler_write | 219 |
  1. 对以上状态变量中主要几个变量的解读:
    • Handler_read_first:索引中第一条记录被读的次数。如果本变量值较大,说明存在大量全索引扫描,需要优化
    • Handler_read_key:记录查询时从表中通过索引读取记录的次数。如果该值较高,则说明查询和表的索引是正确的。
    • Handler_read_rnd_next:记录查询时,从表中通过随机索引读取记录后,读取下一条记录的次数。通常情况下,该值高说明你的表索引不正确,或者写入的查询没有利用索引。
    • Sort_merge_passes:记录在执行排序操作时,需要进行的外部排序(External Sort)的次数。当 MySQL 需要对大量的数据进行排序时,可能会使用外部排序算法。外部排序算法将数据分为多个块,并对每个块进行排序,然后将排序后的块合并成一个有序的数据集。如果需要对合并后的数据集再次排序,则可能需要进行多次外部排序,每次排序称为一次外部排序的“归并”(Merge)操作。如果这个变量值较大,则应该考虑增加sort_buffer_size系统变量的值。

4、监控排序相关状态变量

  1. 排序出现比较多的全表扫描或者外部排序时,一般都说明SQL有问题
  2. 如下命令将监控排序相关状态变量及统计信息:
mysql> SHOW SESSION STATUS LIKE 'Sort%';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Sort_merge_passes | 0     |
| Sort_range        | 0     |
| Sort_rows         | 200     |
| Sort_scan         | 1     |
+-------------------+-------+
  1. 对以上状态变量中主要几个变量的解读:
    • Sort_rows:已经排序的行数。如果需要对大量的数据进行排序,可能会导致 Sort_rows 的值比较高。在这种情况下,可能需要优化查询语句,例如优化排序字段、限制返回的行数等。
    • Sort_scan:通过扫描表完成排序的数量。

5、监控临时表相关状态变量

  1. 出现较多临时表的操作时,一般都说明SQL有问题
  2. 如下命令将监控临时表相关状态变量及统计信息:
mysql> SHOW STATUS LIKE 'Created_tmp%';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 0     |
| Created_tmp_files       | 0     |
| Created_tmp_tables      | 5     |
+-------------------------+-------+
  1. 对以上状态变量中主要几个变量的解读:
    • Created_tmp_disk_tables:记录在执行查询操作时,需要在磁盘上创建临时表的次数。如果持续增加,那么可能是有性能问题。

6、SHOW PROFILE

  1. SHOW PROFILE可以让MySQL收集在执行语句的时候所使用的资源和耗时。需要注意的是,启用SHOW PROFILE性能分析会增加服务器的负载,因为 MySQL 必须记录查询执行过程中的所有操作。因此,应该仅在需要时启用性能分析,并在完成后禁用它,以避免对服务器性能产生不必要的影响。
  2. SHOW PROFILE功能默认是关闭的,但可以在会话级别开启这个功能。
  3. 下面的示例将使用SET profiling=1开启这个功能,并收集数据:
mysql> SHOW VARIABLES LIKE 'profiling';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| profiling     | OFF   |
+---------------+-------+
1 row in set (0.00 sec)
mysql> SET profiling = 1;               # 开启SHOW PROFILE功能
mysql> <输入查询语句>;
mysql> SHOW PROFILES;
+----------+------------+--------------------------------+
| Query_ID | Duration   | Query                          |
+----------+------------+--------------------------------+
|        1 | 0.00165600 | SHOW VARIABLES LIKE '%profil%' |
|        2 | 0.00013175 | SELECT DATABASE()              |
|        3 | 0.00319400 | show databases                 |
|        4 | 0.00017325 | show tables                    |
|        5 | 0.13584825 | select count(*) from t1        |
+----------+------------+--------------------------------+
mysql> SET profiling = 0;               # 关闭SHOW PROFILE功能

7、information_schema.tables表

  1. MySQL的information_schema库记录了各个库、表的数据量大小,可以据此统计实例的数据增长情况,以及各个库,甚至各个表的数据增长情况,研发人员通过判断表的数据量增长趋势及数据库的操作频率,大致判断应用的数据库流量的特点,从而更有针对性地进行数据库的应用优化。在实际生产环境中,我们可以定期查询INFORMATION_SCHEMA信息数据库,把收集的数据库大小插入监控数据库,在收集的信息的基础上进行空间趋势分析。
  2. 以下将mytest库的表按数据量和索引量从大到小排序:
SELECT table_schema,table_name, data_length, index_length FROM information_schema.tables WHERE table_schema='mytest' ORDER BY data_length DESC, index_length DESC;
  1. 下面的查询将检查数据库mytest下面的所有基础表的信息。
SELECT TABLE_SCHEMA,TABLE_NAME,TABLE_TYPE,ENGINE,TABLE_ROWS ,DATA_LENGTH,INDEX_LENGTH,DATA_FREE FROM information_schema.tables WHERE TABLE_SCHEMA=‘mytest' AND TABLE_TYPE='BASE TABLE';
  1. 下面的查询将统计数据库mytest的大小。
SELECT SUM(DATA_LENGTH),SUM(INDEX_LENGTH),SUM(DATA_FREE) FROM information_schema.tables WHERE TABLE_SCHEMA='mytest' AND TABLE_TYPE='BASE TABLE';

8、总结

  1. 本文总结了对MySQL的基本监控,总体思路是基于对Select%、Handler%、Sort%、Created_tmp%等变量的监控,分析全表扫描、磁盘临时表、外部排序等高成本操作是否大量存在,从而分析出当前SQL质量是否存在劣化。
  2. 可以通过对SHOW PROCESSLIST的输出结果的统计分析,监控是否存在异常状态的线程,一般线程不会停留在某一个状态超过1秒(除了SLEEP状态)。
  3. 可以通过information_schema.tables表统计库表的数据量增长趋势及操作频率,从而做有针对性的优化。
  4. 可以临时通过SHOW PROFILE进行SQL性能监控,但由于此操作对数据库性能有影响,因此只能临时开启,且必须及时关闭。

猜你喜欢

转载自blog.csdn.net/oddrock/article/details/130215571