数据库运行一段时间后占用空间持续上涨是很常见的现象。日志表、订单表、临时业务数据不断累积,磁盘占用慢慢升高。等到应用抛出写入失败报错,才会想起查看存储空间。各类数据库都自带查询命令,只是分散在文档中,平时很少用到。下面整理几款常用数据库空间查询方法,需要的时候直接使用。
MySQL查询依靠information_schema库。这个库不存储业务数据,专门存放元数据,记录库内所有表、行数、占用字节等信息。查询全部数据库总容量,执行SELECT table_schema, SUM(data_length + index_length)/1024/1024 AS size_mb FROM information_schema.tables GROUP BY table_schema;,结果以MB单位展示,一眼就能定位占用空间最大的数据库。data_length代表数据占用容量,index_length是索引占用空间,两者相加才是磁盘实际占用大小。很多场景下数据体积不大,但索引持续膨胀,分开查看就能定位问题。查询单库单表,增加WHERE table_schema = '库名'条件,再按data_length降序排序,就能列出体积靠前的大表。SHOW TABLE STATUS FROM 库名也可以查看表信息,返回字段更细致,包含平均行长度、碎片空间,但输出格式不适合人工快速阅读,更适合程序读取。

PostgreSQL的查询方式和MySQL不一样,依靠内置函数而非直接读取系统表。查看单个数据库大小,执行select pg_size_pretty(pg_database_size('库名'));,pg_size_pretty自动把字节转换为易读的KB、MB、GB单位。查询全部数据库容量排名,读取pg_database表的datname字段,搭配pg_database_size函数,增加ORDER BY desc排序。psql客户端有更简便的方式,直接输入l+,列表自带Size列,不用编写SQL。表级容量查询使用pg_total_relation_size('表名'),该函数统计表数据、索引、TOAST全部内容,比pg_relation_size更准确,后者仅统计主数据文件,容易低估占用。
SQL Server的sp_spaceused是经典存储过程,使用简单,执行USE 库名; EXEC sp_spaceused;,返回表格包含database_name、database_size、unallocated_space字段。批量查看所有数据库容量用sp_helpdb,会列出每个数据库数据文件与日志文件总大小。单独查看日志文件占用执行DBCC SQLPERF(LOGSPACE),排查日志撑满磁盘场景很有用,很多实例数据文件余量充足,日志文件增长至几十GB。sys.master_files属于底层系统视图,记录所有数据库数据和日志文件size,单位为8KB页,数值乘以8再除以1024换算成MB。想要精确统计每个文件的容量增长,需要读取这张视图。
Oracle架构相对复杂,引入表空间概念。数据不直接归属数据库,先存放于表空间,表空间再映射物理数据文件。空间查询分为两步,第一步查看表空间层面,读取dba_data_files视图,按tablespace_name分组,SUM(bytes)得到总容量,SUM(user_bytes)是已使用空间,两者差值就是剩余空间。dba_free_space视图可以查看表空间内空闲区块。日常巡检关注使用率,超过80%就要留意,高于90%需要准备扩容。dba_data_files中的autoextensible字段标记是否开启自动扩展,标记为YES代表开启自动扩容,并非永久无限增长,达到maxbytes上限依旧无法写入数据,不能仅凭这个字段判断存储安全。
MongoDB空间查询依靠dbStats命令,mongosh中直接执行db.stats()或者db.runCommand({dbStats: 1})。返回JSON包含几个关键字段,dataSize是原始数据大小,storageSize是磁盘占用空间,indexSize是索引体积。dataSize和storageSize数值经常不一致,后者一般更大,WiredTiger引擎压缩机制造成存储容量和原始数据存在差异。fsUsedSize和fsTotalSize代表所在文件系统整体占用情况,和数据库内部数据容量无关,查看时不要混淆。实例非正常关机后,dbStats统计结果可能存在偏差,官方推荐执行validate命令校正统计数据。
虚拟主机或者云数据库控制台一般会提供空间使用率图表,但大多只展示总容量,不会拆分数据、日志、临时文件占用比例。排查故障时还是需要命令行查看详细数据。另外这类统计操作会消耗数据库资源,大库执行全量统计耗时数秒至十几秒,尽量避开业务高峰期。磁盘层面使用df -h查看挂载点剩余容量,和数据库内部统计结果相互核对,有时候数据库内部显示有剩余空间,但文件系统已经写满,属于两类不同问题。