Дисковото пространство е взискателен ресурс в днешно време. Обикновено ще искате да съхранявате данни възможно най-дълго, но това може да е проблем, ако не предприемете необходимите действия, за да предотвратите потенциален проблем с „недостиг на дисково пространство“.
В този блог ще видим как можем да открием този проблем за PostgreSQL, да го предотвратим и ако е твърде късно, някои опции, които вероятно ще ви помогнат да го поправите.
Как да идентифицираме проблеми с PostgreSQL дисковото пространство
Ако вие, за съжаление, сте в тази ситуация с липса на дисково пространство, ще можете да видите някои грешки в регистрационните файлове на базата данни на PostgreSQL:
2020-02-20 19:18:18.131 UTC [4400] LOG: could not close temporary statistics file "pg_stat_tmp/global.tmp": No space left on device
или дори във вашия системен дневник:
Feb 20 19:29:26 blog-pg1 rsyslogd: imjournal: fclose() failed for path: '/var/lib/rsyslog/imjournal.state.tmp': No space left on device [v8.24.0-41.el7_7.2 try http://www.rsyslog.com/e/2027 ]
PostgreSQL може да продължи да работи за известно време, изпълнявайки заявки само за четене, но в крайна сметка няма да успее да се опита да запише на диск, тогава ще видите нещо подобно в клиентската сесия:
WARNING: terminating connection because of crash of another server process
DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
HINT: In a moment you should be able to reconnect to the database and repeat your command.
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
След това, ако погледнете дисковото пространство, ще имате този нежелан изход...
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/pve-vm--125--disk--0 30G 30G 0 100% /
Как да предотвратим проблеми с PostgreSQL дисковото пространство
Основният начин за предотвратяване на този вид проблем е чрез наблюдение на използването на дисковото пространство и нарастването на използването на база данни или диск. За това графиката трябва да бъде удобен начин за наблюдение на увеличението на дисковото пространство:
И същото за растежа на базата данни:
Друго важно нещо за наблюдение е състоянието на репликация. Ако имате реплика и по някаква причина това спира да работи, в зависимост от конфигурацията е възможно PostgreSQL да съхранява всички WAL файлове, за да възстанови репликата, когато се върне.
Цялата тази система за наблюдение няма смисъл без система за предупреждение, която да знае когато трябва да предприемете действия:
Как да коригирам проблеми с дисковото пространство на PostgreSQL
Е, ако се сблъскате с този проблем с липсата на дисково пространство, дори когато системата за наблюдение и предупреждение е внедрена (или не), има много опции да се опитате да отстраните този проблем без загуба на данни (или по-малко колкото е възможно).
Какво консумира вашето дисково пространство?
Първата стъпка трябва да бъде определяне къде е моето дисково пространство. Най-добрата практика е да имате отделни дялове, поне един отделен дял за съхранение на вашата база данни, така че можете лесно да потвърдите дали вашата база данни или вашата система използват прекомерно дисково пространство. Друго предимство на това е минимизирането на щетите. Ако вашият основен дял е пълен, вашата база данни все още може да пише в собствения си дял без проблеми.
Използване на пространство в базата данни
Нека видим сега някои полезни команди за проверка на използването на дисковото пространство на базата данни.
Основен начин за проверка на използването на пространството на базата данни е проверката на директорията с данни във файловата система:
$ du -sh /var/lib/pgsql/11/data/
819M /var/lib/pgsql/11/data/
Или ако имате отделен дял за вашата директория с данни, можете да използвате директно df -h.
Командата на PostgreSQL “\l+” изброява базите данни, добавяйки информацията за размера:
$ postgres=# \l+
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges | Size | Tablespace
| Description
-----------+----------+-----------+---------+-------+-----------------------+---------+------------
+--------------------------------------------
postgres | postgres | SQL_ASCII | C | C | | 7965 kB | pg_default
| default administrative connection database
template0 | postgres | SQL_ASCII | C | C | =c/postgres +| 7817 kB | pg_default
| unmodifiable empty database
| | | | | postgres=CTc/postgres | |
|
template1 | postgres | SQL_ASCII | C | C | =c/postgres +| 7817 kB | pg_default
| default template for new databases
| | | | | postgres=CTc/postgres | |
|
world | postgres | SQL_ASCII | C | C | | 8629 kB | pg_default
|
(4 rows)
Използвайки pg_database_size и името на базата данни, можете да видите размера на базата данни:
postgres=# SELECT pg_database_size('world');
pg_database_size
------------------
8835743
(1 row)
И използването на pg_size_pretty, за да видите тази стойност по четим от човека начин, може да бъде дори по-добре:
postgres=# SELECT pg_size_pretty(pg_database_size('world'));
pg_size_pretty
----------------
8629 kB
(1 row)
Когато знаете къде е мястото, можете да предприемете съответното действие, за да го поправите. Имайте предвид, че само изтриването на редове не е достатъчно за възстановяване на дисковото пространство, ще трябва да стартирате VACUUM или VACUUM FULL, за да завършите задачата.
Регистрационни файлове
Най-лесният начин за възстановяване на дисково пространство е чрез изтриване на регистрационни файлове. Можете да проверите директорията на регистрационните файлове на PostgreSQL или дори системните регистрационни файлове, за да проверите дали можете да спечелите малко място оттам. Ако имате нещо подобно:
$ du -sh /var/lib/pgsql/11/data/log/
18G /var/lib/pgsql/11/data/log/
Трябва да проверите съдържанието на директорията, за да видите дали има проблем с ротацията/задържането на регистрационни файлове или нещо се случва във вашата база данни и го записвате в регистрационните файлове.
$ ls -lah /var/lib/pgsql/11/data/log/
total 18G
drwx------ 2 postgres postgres 4.0K Feb 21 00:00 .
drwx------ 21 postgres postgres 4.0K Feb 21 00:00 ..
-rw------- 1 postgres postgres 18G Feb 21 14:46 postgresql-Fri.log
-rw------- 1 postgres postgres 9.3K Feb 20 22:52 postgresql-Thu.log
-rw------- 1 postgres postgres 3.3K Feb 19 22:36 postgresql-Wed.log
Преди да изтриете регистрационните файлове, ако имате голям, добра практика е да запазите последните около 100 реда и след това да ги изтриете. Така че можете да проверите какво се случва след генериране на свободно пространство.
$ tail -100 postgresql-Fri.log > /tmp/log_temp.log
И след това:
$ cat /dev/null > /var/lib/pgsql/11/data/log/postgresql-Fri.log
Ако просто го изтриете с “rm” и регистрационният файл се използва от сървъра на PostgreSQL (или друга услуга), пространството няма да бъде освободено, така че трябва да съкратите този файл с помощта на тази котка / вместо това команда dev/null.
Това действие е само за PostgreSQL и системни регистрационни файлове. Не изтривайте съдържанието pg_wal или друг PostgreSQL файл, тъй като може да доведе до критични щети на вашата база данни.
Раздуване
При нормална PostgreSQL операция, кортежи, които са изтрити или остарели от актуализация, не се премахват физически от таблицата; те присъстват до извършване на ВАКУУМ. Така че е необходимо периодично да правите ВАКУУМ (АВТОВАКУУМ), особено в често актуализирани таблици.
Проблемът тук е, че пространството не се връща на операционната система само с VACUUM, а е достъпно само за използване в същата таблица.
VACUUM FULL пренаписва таблицата в нов дисков файл, връщайки неизползваното пространство в операционната система. За съжаление, той изисква изключително заключване на всяка таблица, докато работи.
Трябва да проверите таблиците, за да видите дали е необходим ВАКУУМЕН (ПЪЛЕН) процес.
Слотове за репликация
Ако използвате слотове за репликация и то не е активно по някаква причина:
postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots;
slot_name | slot_type | active
-----------+-----------+--------
slot1 | physical | f
(1 row)
Може да е проблем за вашето дисково пространство, тъй като то ще съхранява WAL файловете, докато не бъдат получени от всички резервни възли.
Начинът да го поправите е да възстановите репликата (ако е възможно) или да изтриете слота:
postgres=# SELECT pg_drop_replication_slot('slot1');
pg_drop_replication_slot
--------------------------
(1 row)
И така, пространството, използвано от WAL файловете, ще бъде освободено.
Заключение
Както споменахме, системите за наблюдение и предупреждение са ключът към избягването на подобни проблеми. По този начин ClusterControl може да ви помогне да поддържате системите си в работен режим, като ви изпраща аларми, когато е необходимо или дори предприема действия за възстановяване, за да поддържате клъстера ви от база данни да работи. Можете също така да разгръщате/импортирате различни технологии за бази данни и да ги мащабирате, ако е необходимо.