Obliczanie wykorzystania miejsca na dysku dla MySQL DB


28

Obecnie używam information_schema.TABLES do obliczenia całkowitego wykorzystania miejsca na dysku pogrupowanego według nazwy bazy danych, ale działa on strasznie wolno. Na serwerach z setkami baz danych obliczenie może potrwać kilka minut.

Jaka jest najszybsza metoda obliczania zużycia miejsca na dysku według bazy danych? Czy powinienem tylko patrzeć na system plików? Czy istnieje metoda przyspieszenia schematu informacyjnego?

Odpowiedzi:


46

Istnieją 3 scenariusze.

  1. Jeśli używasz MyISAM, najłatwiej jest po prostu spojrzeć na system plików i korzystać z niego du -sh /var/lib/mysql/database.
  2. Jeśli używasz InnoDB z zestawem innodb_file_per_table , możesz uzyskać przybliżoną odpowiedź za pomocą du -sh. Jest to przybliżone, ponieważ w pliku ibdata1 jest jeszcze trochę danych, więc będziesz trochę rozczarowany. Ta technika działa również z mieszanymi innodb_file_per_tablebazami danych MyISAM / InnoDB ( ).
  3. Jeśli używasz InnoDB bez innodb_file_per_table set, musisz spojrzeć na INFORMACJE_SCHEMA.

W każdym z powyższych przypadków możesz uruchomić następujące zapytanie, aby uzyskać informacje, których szukasz.

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)

Jeśli masz bardzo dużą liczbę tabel, może to być powolne, jak już odkryłeś.


Widziałem gdzie indziej, że opcja 3 nie uwzględnia rozmiarów VARCHAR.
Joe

3

Możesz użyć tego polecenia, aby uzyskać informacje w 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)

Dostosowałem odpowiedź od Aarona Browna, aby podać rozmiar w GB. Więcej informacji można znaleźć w odpowiedzi Aarona Browna .

LUB, aby uwzględnić wolne / możliwe do odzyskania miejsce, użyj:

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 |
+--------------------+---------------+------------------------------+

Przestrzeń można odzyskać za pomocą polecenia OPTIMIZE TABLE dla tabel InnoDB, MyISAM i ARCHIWUM.

Zobacz także Jak uzyskać prawdziwy rozmiar bazy danych MySQL? po więcej szczegółów.


1

Aby uzyskać informacje na temat nazwy tabeli i liczby jej rekordów, można użyć poniższego zapytania,

SELECT * 
FROM information_schema.TABLES ;

Aby uzyskać informacje o bazach danych na serwerach o odpowiednim rozmiarze, można użyć poniższego zapytania,

SELECT 
TABLE_SCHEMA  AS `Database`,
SUM((data_length + index_length) / (1024 * 1024)) AS `Database_Size`
FROM information_schema.TABLES 
GROUP BY table_schema 
ORDER BY `Database_Size` DESC;

1

Aby zobaczyć, gdzie jest zajęte miejsce na dysku (niezależnie od tego, czy jest ono w tabeli mysql, czy nie), używam mojej zaufanej komendy „du”. Oto przykład mojego znalezienia, skąd pochłania się cała przestrzeń.

$ 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

Możesz zobaczyć, że większość miejsca jest zajęta przez ten folder. / mysql

Ten folder zawiera tabele danych. Aby zobaczyć, które tabele zajmują całe miejsce, możesz postępować w ten sposób, używając opcji „człowiek” lub „-h”. Lubię zarządzać miejscem na dysku w ten sposób, ponieważ czasami nie możesz nawet zalogować się do mysql, ponieważ nie znasz hasła ani użytkownika.

$ 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

Widać, że cała przestrzeń jest zajęta przez kilka tabel zawierających wiele danych GiG. Mam nadzieję że to pomoże.


0

Poszukałbym rozmiaru pliku w twoim słowniku danych. Jest natychmiastowy i dokładny.

Ostrzeżenie : Zgodnie z mechanizmem przechowywania indeksy są przechowywane w pliku głównym lub w innym pliku, nie zapomnij ich podsumować w razie potrzeby.


2
Tak, ale gdzie to jest?
Magne,

0

Wiem, że to stare, ale ktoś może uznać to za istotne.

W MySQL używam:

SELECT concat(table_schema) 'Database Name',
concat(round(SUM(data_length/power(1024,3)),2),'G') DATA,
concat(round(SUM(index_length/power(1024,3)),2),'G') 'INDEX',
concat(round(SUM(data_free/power(1024,3)),2),'G') 'DATA FREE',
concat(round(sum(data_free)/(SUM(data_length+index_length))*100,2)) '% FRAGMENTED',
concat(round(SUM(data_length+index_length)/power(1024,3),2),'G') TOTAL
FROM information_schema.TABLES
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema')
GROUP BY table_schema;

Ponieważ moją bazą danych jest InnoDB, jest to tylko oszacowanie.

Porównuję to wyjście do:

du -sch /location/of_Mysql/* | sort -hr | head -n20

Mam nadzieję, że to ci pomoże


0

Najlepszy (po zrobieniu apt-get install ncdu):

cd "/var/lib/mysql" && ncdu

aby uzyskać całkowity rozmiar baz danych MySQL w VPS.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.