MySQL统计库表大小

摘要:
统计每个数据库中每个表的大小是数据治理的最简单要求之一。本文将从抽样统计结果和准确统计结果两个方面统计MySQL中每个数据库中每个表的数据量。如果您想知道每个数据库和表的大致数据量,可以直接查询information_Schema.tables。

统计每个库每个表的大小是数据治理的其中最简单的一个要求,本文将从抽样统计结果及精确统计结果两方面来统计MySQL的每个库每个表的数据量情况。

1、统计预估数据量

mysql数据字典库information_schema里记录了统计的预估数据量(innodb引擎表不准确,MyISAM引擎表准确)及数据大小、索引大小及表碎片的大小等信息。

如果想了解每个库及表的大概数据量级,可以直接查information_schema.tables进行统计即可。例如:

SELECT  table_schema,table_name,table_rows,data_length+index_length+ data_free data_size
 FROM information_schema.`TABLES` WHERE table_schema IN ('db1','db2');

 其中data_size单位为B

 MySQL统计库表大小第1张

 如上文所述,统计信息里的数据条数及size是根据部分数据抽样统计的值,与实际大小存在差异,且表越大,差异越明显,如果想知道每张表的实际情况,需用后续的方法。

2、统计实际数据量

想要统计每张表的实际大小就得去遍历每个表算出对的记录数,通过查看表空间大小(每个表独立表空间)查看每个表的size。通过以下步骤即可达到精确统计的目的。

创建路径

创建一个工作路径,保存脚本及临时文件等

mkdir -p  /usr/local/data_size

创建统计库及表

在需要统计的数据库实例上创建统计库

SQL>  create  database bak_db;

创建统计的存储过程

SQL> use bak_db;
SQL>CREATE  PROCEDURE `p_db_size`()
BEGIN
DECLARE v_id INT;
DECLARE v_maxid INT;
DECLARE v_tbname VARCHAR(50);
DECLARE  v_dbname VARCHAR(50);
DECLARE v_sql_upd VARCHAR(200);
SET v_id =(SELECT MIN(id) FROM bak_db.tb_size);
SET v_maxid =(SELECT MAX(id) FROM bak_db.tb_size);
WHILE v_id <=v_maxid
DO
SET v_tbname = (SELECT tbname FROM  bak_db.tb_size WHERE  id=v_id);
SET v_dbname = (SELECT dbname FROM  bak_db.tb_size WHERE  id=v_id);
SET  v_sql_upd = CONCAT('update bak_db.tb_size  set tb_rows=(select count(*) from  ',v_dbname,".",v_tbname,") where id=",v_id);
    SET  @v_sql_upd := v_sql_upd;
    PREPARE stmt FROM @v_sql_upd;
    EXECUTE stmt ;
    DEALLOCATE PREPARE stmt;
    SET v_id = v_id +1;
END WHILE;
    END;

创建脚本

vim       data.sh
/*  插入如下内容*/

#! /bin/bash
cd /usr/local/data_size
du -s /data/mysql/mysql3306/data/db1/* |grep -v ".frm" |grep -v ".opt" >/usr/local/data_size/data_size du -s /data/mysql/mysql3306/data/db2/* |grep -v ".frm" |grep -v ".opt">>/usr/local/data_size/data_size # 后面4步是拼接成sql awk '{print "insert into bak_db.tb_size(size,tb_route)values("""$0}' /usr/local/data_size/data_size >/usr/local/data_size/data_size1 awk '{print $0";"}' /usr/local/data_size/data_size1 >/usr/local/data_size/data_size.sql sed -i "s# #,'#g" /usr/local/data_size/data_size.sql sed -i "s#;#');#g" /usr/local/data_size/data_size.sql # 创建统计表 /usr/local/mysql5.7/bin/mysql -uroot -p'Test#123456' -h 192.168.28.132 -e "drop table if exists bak_db.tb_size;CREATE TABLE IF NOT EXISTS bak_db.tb_size ( id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT ,size INT,tb_route VARCHAR(200),tbname VARCHAR(50),dbname VARCHAR(50),tb_rows INT(11));" # 导入数据 /usr/local/mysql5.7/bin/mysql -uroot -p'Test#123456' -h 192.168.28.132 -e "use bak_db;truncate table bak_db.tb_size;source /usr/local/data_size/data_size.sql;" # 生成库名及表名,当然该步骤也可以从数据字段中获取 /usr/local/mysql5.7/bin/mysql -uroot -p'Test#123456' -h 192.168.28.132 -e "use bak_db;UPDATE bak_db.tb_size SET tbname=REPLACE(SUBSTRING_INDEX(tb_route,'/',-1),'.ibd','');" /usr/local/mysql5.7/bin/mysql -uroot -p'Test#123456' -h 192.168.28.132 -e "UPDATE bak_db.tb_size SET dbname=LEFT (SUBSTRING_INDEX(tb_route,'/',-2),INSTR(SUBSTRING_INDEX(tb_route,'/',-2),'/')-1);" sleep 10 # 如果之前的步骤在主库金学习学习,则建议暂停一段时间 以免后面统计的时候无法获得表及内容,如果前面的步骤都在从库,则可以省略该步骤 echo 'start call procedure' # 调用存储过程 统计每个表的记录条数 /usr/local/mysql5.7/bin/mysql -uroot -p'Test#123456' -h 192.168.28.132 -e "use bak_db;call bak_db.p_db_size();" # 把表及数据导出 /usr/local/mysql5.7/bin/mysqldump -uroot -p'Test#123456' -h 192.168.28.132 --single-transaction bak_db tb_size >/usr/local/data_size/tb_size.sql # 将表及结果导入主库(从库相当于删除在重建了一次) /usr/local/mysql5.7/bin/mysql -uroot -p'Test#123456' -h 192.168.28.128 -e "use bak_db;source /usr/local/data_size/tb_size.sql;"

结果如下:

MySQL统计库表大小第2张

 可以看出精确值与统计信息里的值差异还是很大的,且表越大 差异越明显。

TIPS:  本文精确统计的脚本还有许多优化空间,写的比较仓促,大家可以按需自行调整,水平有限,欢迎斧正。如有问题,欢迎与我沟通。

想了解更多内容或参与技术交流可以关注微信公众号【数据库干货铺】或进技术交流群沟通。

MySQL统计库表大小第3张

免责声明:文章转载自《MySQL统计库表大小》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇关于c#的连接池(以OracleConneciton为例)死磕 java集合之WeakHashMap源码分析下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

一个神奇SQL引发的故障【转】

前几天一个客户数据库主实例告警,诊断过程中发现是由一个慢SQL导致的数据库故障,而在排查逐步深入之后却发现这个现象的不可思议。 问题描述 2016年12日09日,大概9点26分左右,一个客户的生产库主实例发出告警,告警信息如下: MySQL实例超过五分钟没有更新。这个告警信息简单解释下就是持续五分钟无法获取该实例的信息。 同时开发人员还反映,从12月09日...

Linux的PHP开发环境快速搭建

搭建的环境是LNMP: 1、安装MySQL 这个非常简单我用的是Ubuntu那么就用apt源,下载deb文件然后按照全新安装文档按顺序:a.加入apt库  b.更新apt库 c.安装 d.运行MySQL 下载: https://dev.mysql.com/downloads/repo/apt/ 文档: https://dev.mysql.com/doc/m...

使用golang理解mysql的两阶段提交

使用golang理解mysql的两阶段提交 文章源于一个问题:如果我们现在有两个mysql实例,在我们要尽量简单地完成分布式事务,怎么处理? 场景重现 比如我们现在有两个数据库,mysql3306和mysql3307。这里我们使用docker来创建这两个实例: # mysql3306创建命令 docker run -d -p 3306:3306 -v /U...

mysql命令行的一些小技巧【实用:多屏显示,格式化输出等】

1.以html格式输出结果使用mysql客户端的参数–html或者-T,则所有SQL的查询结果会自动生成为html的table代码$ mysql -u root --htmlWelcome to the MySQL monitor. Commands end with ; or g.Your MySQL connection id is 3286Serve...

SQL Server的链接服务器(MySQL、Oracle、Ms_sql、Access、SYBASE)

一、使用 Microsoft OLE DB Provider For ODBC 链接MySQL安装MySQL的ODBC驱动MyODBC1、为MySQL建立一个ODBC系统数据源,例如:选择数据库为test ,数据源名称为myDSN 2、建立链接数据库EXEC sp_addlinkedserver @server = 'MySQLTest', @srvpro...

八:SQL之DQL数据查询语言单表操作

前言:   DQL数据库查询语言是我们在开发中最常使用的SQL,这一章总结了单表操作部分的常用查询方式   主要操作有:查询所有字段、查询指定字段、查询指定记录、带IN的关键字查询,范围查询,陪查询、查询空值   带AND的多条件查询、带OR的多条件查询,关键字DISTINCT,查询结果排序,分组查询。分页查询等 准备好数据测试表  1 mysql&g...