如何监控 MySQL 空间?

Posted

技术标签:

【中文标题】如何监控 MySQL 空间?【英文标题】:How to monitor MySQL space? 【发布时间】:2010-09-16 02:54:24 【问题描述】:

我下载了一个使用 mysql 的 Web 应用程序的 VM 映像。

我如何监控其空间消耗并知道何时必须添加额外空间?

【问题讨论】:

【参考方案1】:
du -s /var/lib/mysql/* | sort -nr

结果

34128   /var/lib/mysql/db_name1
33720   /var/lib/mysql/db_name2
29744   /var/lib/mysql/db_name3
26624   /var/lib/mysql/db_name4
16516   /var/lib/mysql/db_name5

Thsi 将按 kb 降序显示

【讨论】:

【参考方案2】:

您可以参考MONyog,它具有磁盘信息功能,可让您了解服务器级别、数据库级别和表级别的磁盘空间分析

【讨论】:

您好,这是您的第一个答案,请先检查您的答案是否已经存在,如it does。在这种情况下,最好支持该答案,而不是说完全相同的话。【参考方案3】:

我有一些很棒的大问题要分享:

运行此命令以获取存储引擎的 MySQL 总数据和索引使用情况

SELECT IFNULL(B.engine,'Total') "Storage Engine",
CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Data Size", CONCAT(LPAD(REPLACE(
FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Index Size", CONCAT(LPAD(REPLACE(
FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Table Size" FROM
(SELECT engine,SUM(data_length) DSize,SUM(index_length) ISize,
SUM(data_length+index_length) TSize FROM
information_schema.tables WHERE table_schema NOT IN
('mysql','information_schema','performance_schema') AND
engine IS NOT NULL GROUP BY engine WITH ROLLUP) B,
(SELECT 3 pw) A ORDER BY TSize;

运行此命令以按数据库获取 MySQL 数据和索引使用总量

SELECT DBName,CONCAT(LPAD(FORMAT(SDSize/POWER(1024,pw),3),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Data Size",CONCAT(LPAD(
FORMAT(SXSize/POWER(1024,pw),3),17,' '),' ',SUBSTR(' KMGTP',pw+1,1),'B') "Index Size",
CONCAT(LPAD(FORMAT(STSize/POWER(1024,pw),3),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Total Size" FROM
(SELECT IFNULL(DB,'All Databases') DBName,SUM(DSize) SDSize,SUM(XSize) SXSize,
SUM(TSize) STSize FROM (SELECT table_schema DB,data_length DSize,
index_length XSize,data_length+index_length TSize FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema')) AAA
GROUP BY DB WITH ROLLUP) AA,(SELECT 3 pw) BB ORDER BY (SDSize+SXSize);

运行此命令以获取数据库和存储引擎的总 MySQL 数据和索引使用情况

SELECT Statistic,DataSize "Data Size",IndexSize "Index Size",TableSize "Table Size"
FROM (SELECT IF(ISNULL(table_schema)=1,10,0) schema_score,
IF(ISNULL(engine)=1,10,0) engine_score,
IF(ISNULL(table_schema)=1,'ZZZZZZZZZZZZZZZZ',table_schema) schemaname,
IF(ISNULL(B.table_schema)+ISNULL(B.engine)=2,"Storage for All Databases",
IF(ISNULL(B.table_schema)+ISNULL(B.engine)=1,
CONCAT("Storage for ",B.table_schema),
CONCAT(B.engine," Tables for ",B.table_schema))) Statistic,
CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') DataSize,CONCAT(LPAD(REPLACE(
FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') IndexSize,
CONCAT(LPAD(REPLACE(FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') TableSize FROM (SELECT table_schema,engine,
SUM(data_length) DSize,SUM(index_length) ISize,
SUM(data_length+index_length) TSize FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema')
AND engine IS NOT NULL GROUP BY table_schema,engine WITH ROLLUP) B,
(SELECT 3 pw) A) AA ORDER BY schemaname,schema_score,engine_score;

警告

在每个查询中,您都会看到(SELECT 3 pw)。 pw 代表 1024 的幂来显示结果。

(SELECT 0 pw) 将以字节为单位显示报告 (SELECT 1 pw) 将以千字节为单位显示报告 (SELECT 2 pw) 将以兆字节显示报告 (SELECT 3 pw) 将以千兆字节显示报告 (SELECT 4 pw) 将以 TeraBytes 显示报告 (SELECT 5 pw) 将以 PetaBytes 显示报告(如果您运行此报告,请与我联系)

这是一个格式稍少的报表查询:

SELECT IFNULL(db,'Total') "Database",
datsum / power(1024,pw) "Data Size",
ndxsum / power(1024,pw) "Index Size",
totsum / power(1024,pw) "Total"
FROM (SELECT db,SUM(dat) datsum,SUM(ndx) ndxsum,SUM(dat+ndx) totsum
FROM (SELECT table_schema db,data_length dat,index_length ndx
FROM information_schema.tables WHERE engine IS NOT NULL
AND table_schema NOT IN ('information_schema','mysql')) AA
GROUP BY db WITH ROLLUP) A,(SELECT 1 pw) B;

相信我,我在 4 年前提出这些查询,至今仍在使用。

更新 2013-06-24 15:53 EDT

我有一些新东西。我已更改查询,因此您不必为不同的单位显示设置 pw 参数。每个单位显示都是为您计算的。

按存储引擎报告

SELECT
    IFNULL(ENGINE,'Total') "Storage Engine",
    LPAD(CONCAT(FORMAT(DAT/POWER(1024,pw1),2),' ',
    SUBSTR(units,pw1*2+1,2)),17,' ') "Data Size",
    LPAD(CONCAT(FORMAT(NDX/POWER(1024,pw2),2),' ',
    SUBSTR(units,pw2*2+1,2)),17,' ') "Index Size",
    LPAD(CONCAT(FORMAT(TBL/POWER(1024,pw3),2),' ',
    SUBSTR(units,pw3*2+1,2)),17,' ') "Total Size"
FROM
(
    SELECT ENGINE,DAT,NDX,TBL,
    IF(px>4,4,px) pw1,IF(py>4,4,py) pw2,IF(pz>4,4,pz) pw3
    FROM 
    (SELECT *,
        FLOOR(LOG(IF(DAT=0,1,DAT))/LOG(1024)) px,
        FLOOR(LOG(IF(NDX=0,1,NDX))/LOG(1024)) py,
        FLOOR(LOG(IF(TBL=0,1,TBL))/LOG(1024)) pz
        FROM
        (SELECT
            ENGINE,
            SUM(data_length) DAT,
            SUM(index_length) NDX,
            SUM(data_length+index_length) TBL
        FROM
        (
           SELECT engine,data_length,index_length FROM
           information_schema.tables WHERE table_schema NOT IN
           ('information_schema','performance_schema','mysql')
           AND ENGINE IS NOT NULL
        ) AAA GROUP BY ENGINE WITH ROLLUP
) AAA ) AA) A,(SELECT ' BKBMBGBTB' units) B;

按数据库报告

SELECT
    IFNULL(DB,'Total') "Database",
    LPAD(CONCAT(FORMAT(DAT/POWER(1024,pw1),2),' ',
    SUBSTR(units,pw1*2+1,2)),17,' ') "Data Size",
    LPAD(CONCAT(FORMAT(NDX/POWER(1024,pw2),2),' ',
    SUBSTR(units,pw2*2+1,2)),17,' ') "Index Size",
    LPAD(CONCAT(FORMAT(TBL/POWER(1024,pw3),2),' ',
    SUBSTR(units,pw3*2+1,2)),17,' ') "Total Size"
FROM
(
    SELECT DB,DAT,NDX,TBL,
    IF(px>4,4,px) pw1,IF(py>4,4,py) pw2,IF(pz>4,4,pz) pw3
    FROM 
    (SELECT *,
        FLOOR(LOG(IF(DAT=0,1,DAT))/LOG(1024)) px,
        FLOOR(LOG(IF(NDX=0,1,NDX))/LOG(1024)) py,
        FLOOR(LOG(IF(TBL=0,1,TBL))/LOG(1024)) pz
    FROM
    (SELECT
        DB,
        SUM(data_length) DAT,
        SUM(index_length) NDX,
        SUM(data_length+index_length) TBL
    FROM
    (
       SELECT table_schema DB,data_length,index_length FROM
       information_schema.tables WHERE table_schema NOT IN
       ('information_schema','performance_schema','mysql')
       AND ENGINE IS NOT NULL
    ) AAA GROUP BY DB WITH ROLLUP
) AAA) AA) A,(SELECT ' BKBMBGBTB' units) B;

按数据库/存储引擎报告

SELECT
    IF(ISNULL(DB)+ISNULL(ENGINE)=2,'Database Total',
    CONCAT(DB,' ',IFNULL(ENGINE,'Total'))) "Reported Statistic",
    LPAD(CONCAT(FORMAT(DAT/POWER(1024,pw1),2),' ',
    SUBSTR(units,pw1*2+1,2)),17,' ') "Data Size",
    LPAD(CONCAT(FORMAT(NDX/POWER(1024,pw2),2),' ',
    SUBSTR(units,pw2*2+1,2)),17,' ') "Index Size",
    LPAD(CONCAT(FORMAT(TBL/POWER(1024,pw3),2),' ',
    SUBSTR(units,pw3*2+1,2)),17,' ') "Total Size"
FROM
(
    SELECT DB,ENGINE,DAT,NDX,TBL,
    IF(px>4,4,px) pw1,IF(py>4,4,py) pw2,IF(pz>4,4,pz) pw3
    FROM 
    (SELECT *,
        FLOOR(LOG(IF(DAT=0,1,DAT))/LOG(1024)) px,
        FLOOR(LOG(IF(NDX=0,1,NDX))/LOG(1024)) py,
        FLOOR(LOG(IF(TBL=0,1,TBL))/LOG(1024)) pz
    FROM
    (SELECT
        DB,ENGINE,
        SUM(data_length) DAT,
        SUM(index_length) NDX,
        SUM(data_length+index_length) TBL
    FROM
    (
       SELECT table_schema DB,ENGINE,data_length,index_length FROM
       information_schema.tables WHERE table_schema NOT IN
       ('information_schema','performance_schema','mysql')
       AND ENGINE IS NOT NULL
    ) AAA GROUP BY DB,ENGINE WITH ROLLUP
) AAA) AA) A,(SELECT ' BKBMBGBTB' units) B;

【讨论】:

您可能应该编辑您的问题并在每行前面放置 4 个前导空格,以显示为代码。 LPAD 到 17 有什么特别的原因吗? @Bhathiya 我使用 17 因为FORMAT 函数的输出。 1万亿这个数字有13位数字。运行FORMAT(1000000000000,0) 显示1,000,000,000,000。请注意,添加了 4 个逗号。因此,我使用 17 来容纳较大的显示列旁边的小显示列,使报表具有统一的外观。您可以尝试使用 17 以外的宽度值,因为它不会影响磁盘空间计算。 我已经尝试过这样的查询,并且我正在尝试这些特定的查询,但我总是遇到它们需要很长时间才能运行的问题。有什么办法可以优化这些查询以更快地运行? @JDS 有问题。如果所有表都在 ibdata1 中,并且禁用了 innodb_file_per_table,则查询将非常快,因为轮询一个文件中的数据字典和数据/索引页面。在您的情况下,对具有 ibdata1 数据字典的表的每次访问都会导致在每个相应的 .ibd 文件上打开一个文件句柄。我有一个包含 112,000 多个表(900GB)的客户端数据库,需要 2 个小时。我有另一个拥有 41000 多个表(2.5TB)的客户端,它需要 15 秒(不是错字,我说的是 15 秒)。区别在于 innodb_file_per_table。【参考方案4】:

由于您拥有虚拟机,并且您并不真正关心空间的使用方式, 我认为最简单的方法是检查 MySQL 数据目录的大小。 默认为/var/lib/mysql。 此外,在检查数据目录大小之前清理 mysql 二进制日志(如果可能)会很好。

【讨论】:

【参考方案5】:

对于 MyISAM 表,我通常检查 /var/lib/mysql/mydatabasename/ 目录的大小。 InnoDB 表使用单体文件,因此您必须使用 SHOW TABLE STATUS。

【讨论】:

【参考方案6】:

如果只有 MySQL 可用,请使用 SHOW TABLE STATUS 命令,并查看每个表的 Data_length 列,以字节为单位。

如果您的机器上有其他可用的语言,其中任何一种语言的脚本都会定期运行 (cron),检查磁盘可用空间或数据库目录的大小,并通过电子邮件或其他方式更新您。有太多选择可以提出特定的解决方案 - 这取决于您的情况。

【讨论】:

以上是关于如何监控 MySQL 空间?的主要内容,如果未能解决你的问题,请参考以下文章

如何监控ORACLE索引使用与否

MySQL监控

MySQL监控

如何监控linux阿里云磁盘空间

zabbix监控mysql-如何使用zabbix自带的模板监控-nagios监控mysql主从

如何监控mysql表记录变化