饱和度 - 监控MySQL的InnoDB Buffer pool 相关的指标
1. 对于 MySQL 而言,用什么指标来反映资源有多“满”呢?首先我们要关注 MySQL 所在机器的 CPU、内存、硬盘 I/O、网络流量这些基础指标
2. MySQL 本身也有一些指标来反映饱和度,比如刚才我们讲到的连接数,当前连接数(Threads_connected)除以最大连接数(max_connections) 可以得到连接数使用率
是一个需要重点监控的饱和度指标。
3. InnoDB Buffer pool 相关的指标,一个是 Buffer pool 的使用率,一个是 Buffer pool 的内存命中率。Buffer pool 是一块内存,专门用来缓存 Table、Index 相关的数据,提升查询性能。对 InnoDB 存储引擎而言,Buffer pool 是一个非常关键的设计。我们查看一下 Buffer pool 相关的指标。
MariaDB [(none)]> show global status like '%buffer%'; +---------------------------------------+--------------------------------------------------+ | Variable_name | Value | +---------------------------------------+--------------------------------------------------+ | Innodb_buffer_pool_pages_free | 1036 | | Innodb_buffer_pool_pages_total | 8191 | +---------------------------------------+--------------------------------------------------+ 19 rows in set (0.001 sec)
Innodb_buffer_pool_pages_total 表示 InnoDB Buffer pool 的页总量,页(page)是 Buffer pool 的一个分配单位,默认的 page size 是 16KiB,可以通过 show variables like "innodb_page_size" 拿到。
Innodb_buffer_pool_pages_free 是剩余页数量,通过 total 和 free 可以计算出 used
用 used 除以 total 就可以得到使用率
当然,使用率高并不是说有问题,因为 InnoDB 有 LRU 缓存清理机制,只要响应得够快,高使用率也不是问题。
Innodb_buffer_pool_read_requests 和 Innodb_buffer_pool_reads 是另外两个关键指标。read_requests 表示向 Buffer pool 发起的查询总量,如果 Buffer pool 缓存了相关数据直接返回就好,如果 Buffer pool 没有相关数据,就要穿透内存去查询硬盘了。有多少请求满足不了需要去查询硬盘呢?
看 Innodb_buffer_pool_reads 指标统计的数量。所以,reads 这个指标除以 read_requests 就得到了穿透比例,这个比例越高,性能越差,一般可以通过调整 Buffer pool 的大小来解决。
4. Prometheus的配置
# A scrape configuration containing exactly one endpoint to scrape: # Here it's Prometheus itself. scrape_configs: # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config. - job_name: "gauge_exporter" scrape_interval: 30s # 采集频率为30s抓取一次 static_configs: - targets: # 配置采集任务 - 127.0.0.1:5004
5. 自定义监控业务
[root@yld-db 0211]# cat flask_counter_gauge.py #!/usr/bin/env python # -*- coding:utf-8 -*- import pymysql from flask import Flask, Response from prometheus_client import Counter, generate_latest, CollectorRegistry, Gauge def base(cmd): if subprocess.call(cmd, shell=True): raise Exception("{} 执行失败".format(cmd)) app = Flask(__name__) registry = CollectorRegistry() counter = Counter('innodb_pool_counter', 'an example showed how to use counter', ['machine_ip'], registry=registry) gauge = Gauge('innodb_pool_gauge', 'an example showed how to use gauge', ['machine_ip'], registry=registry) @app.route('/metrics') def hello(): counter.labels('127.0.0.1').inc(1) # get Innodb_buffer_pool_pages_free conn = pymysql.connect(host="127.0.0.1",user='root',password='do1admin',port=13307) cursor = conn.cursor() cursor.execute('show global status like "Innodb_buffer_pool_pages_free";') Innodb_buffer_pool_pages_free_rows = cursor.fetchall() Innodb_buffer_pool_pages_free = Innodb_buffer_pool_pages_free_rows[0][1] print Innodb_buffer_pool_pages_free # get Innodb_buffer_pool_pages_total cursor_all = conn.cursor() cursor_all.execute('show global status like "Innodb_buffer_pool_pages_total";') Innodb_buffer_pool_pages_free_all = cursor_all.fetchall() Innodb_buffer_pool_pages_total = Innodb_buffer_pool_pages_free_all[0][1] print Innodb_buffer_pool_pages_total # get Innodb_buffer_pool_pages_free / Innodb_buffer_pool_pages_total gauge.labels('127.0.0.1').set(float(Innodb_buffer_pool_pages_free)/float(Innodb_buffer_pool_pages_total)) return Response(generate_latest(registry), mimetype='text/plain') #return Response(generate_latest(gauge), mimetype='text/plain') if __name__ == '__main__': app.run(host='0.0.0.0', port=5004) [root@yld-db 0211]#
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探
2018-02-11 用python2.7.9 写个小程序搜索某个目录下行有某关键字