Calculating disk space usage per MySQL DB

There are 3 scenarios.

  1. If you are using MyISAM, it is easiest to just look at the filesystem and use du -sh /var/lib/mysql/database.
  2. If you are using InnoDB with innodb_file_per_table set, then you can get an approximate answer using du -sh. It is approximate because there is still some data stored in the ibdata1 file, so you will be a little on the low side. This technique also works with mixed MyISAM/InnoDB (innodb_file_per_table) databases.
  3. If you are using InnoDB without innodb_file_per_table set, then you will need to look at INFORMATION_SCHEMA.

In any of the cases above, you can run the following query to get the information that you are looking for.

mysql> select table_schema, sum((data_length+index_length)/1024/1024) AS MB from information_schema.tables group by 1;
+--------------------+-----------------+
| table_schema       | MB              |
+--------------------+-----------------+
| prod               | 298025.72448921 |
| information_schema |      0.00781248 |
| maatkit            |     70.77330779 |
| mysql              |      0.66873168 |
| test               |   4752.31449127 |
+--------------------+-----------------+
5 rows in set (0.01 sec)

If you have a very large number of tables, it can be slow, as you have already discovered.


You can use this command to get information in GB:

mysql> select table_schema "DB name (table_schema)", 
sum((data_length+index_length)/1024/1024/1024) AS "DB size in GB" from 
information_schema.tables group by table_schema;
+-------------------------------------+-----------------+
| table_schema DB name (table_schema) | DB size in GB   |
+-------------------------------------+-----------------+
| prod                                |     29.72448921 |
| information_schema                  |      0.00781248 |
| miscDB                              |      0.77330779 |
| mysql                               |      0.66873168 |
| test                                |     47.31449127 |
+-------------------------------------+-----------------+
5 rows in set (0.01 sec)

Adapted the answer from Aaron Brown to provide size in GB. See Aaron Brown's answer for more details.

OR to include free/reclaimable space, use:

mysql> SELECT table_schema "database name",
sum( data_length + index_length ) / 1024 / 1024 "database size in MB",
sum( data_free )/ 1024 / 1024 "free reclaimable space in MB"
FROM information_schema.TABLES
GROUP BY table_schema; 

+--------------------+---------------+------------------------------+
| DB name            | DB size in GB | free/reclaimable space in GB |
+--------------------+---------------+------------------------------+
| prod               |          1.26 |                         0.03 |
| information_schema |         38.77 |                         3.75 |
| miscDB             |          0.00 |                         0.00 |
| mysql              |          0.00 |                         0.00 |
| test               |          0.00 |                         0.00 |
+--------------------+---------------+------------------------------+

Space can be reclaimed using OPTIMIZE TABLE command for InnoDB, MyISAM, and ARCHIVE tables.

See also How to Get True Size of MySQL Database? for more details.


In order for me to see where disk space is being used up (regardless if it's in a mysql table or not), I use my trusty "du" command. Here's an example of me finding where all the space is being eaten up from.

$ sudo du -cks /* | sort -rn
954881224   total
945218092   /mysql
5299904 /usr
1781376 /opt
1166488 /var
671628  /home
343332  /run
213400  /root
93476   /lib
30784   /boot
20652   /etc
15940   /bin
13708   /sbin
12388   /tmp
24  /mnt
16  /lost+found
4   /srv
4   /snap
4   /media
4   /lib64
0   /vmlinuz
0   /sys
0   /proc
0   /initrd.img
0   /dev

You can see that the majority of the space is being used by this folder. /mysql

That folder holds data tables. In order to see which tables are taking all the space you can proceed like this using the "human" or "-h" option. I like to do disk space management this way because sometimes you cannot even log into mysql because you don't know the password or user.

$ sudo du -chs /mysql/*
2.3M    /mysql/blacklist
18M /mysql/clientservices
2.5G    /mysql/data
4.0K    /mysql/doubleverify
137G    /mysql/ias
4.0K    /mysql/IAS
2.2G    /mysql/innodb
16K /mysql/lost+found
4.0K    /mysql/ml_centroids
16G /mysql/moat
4.0K    /mysql/test
4.0K    /mysql/tmp
4.0K    /mysql/var
282G    /mysql/verticaAdFees
4.0K    /mysql/verticaViewability
247G    /mysql/Whiteops
217G    /mysql/Whiteops_TLX
902G    total

You can see that all space is being hogged by a few tables holding many GiG's of data. Hope this helps.

Tags:

Mysql