Использовать (временное) сетевое хранилище для восстановления и обновления PSQL

Мы используем более крупную установку Discourse на VPS, которая в целом работает у нас очень хорошо. По производительности CPU и памяти у нас есть запас. Однако с дисковым пространством возникают некоторые сложности — не в повседневной работе, но, например, при обновлении Postgres (обновление с версии 13 до 15 пока отложено именно по этой причине) нам не хватает места, и мы не можем его легко расширить.

Я знаю, что существуют другие варианты обновления Postgres, но рассматриваю это скорее как общий вопрос.

Мы работаем на Hetzner, где сетевое хранилище легко доступно для временного использования.

На тестовом сервере я сейчас экспериментирую с временным решением: сначала восстановить резервную копию с рабочего сайта, а затем протестировать обновление Postgres. Пока что мне это не удалось.

Я уже пробовал использовать символические ссылки, но заметил, что это не работает, и также где-то читал, что это не рекомендуемый способ. Также я пробовал переместить общую папку /shared из /var/discourse/shared/standalone в /mnt/ext-storage/standalone и перенести туда файлы — к сожалению, без проблем не обошлось. Я даже не могу завершить сборку.

Есть ли способ, который работает для таких случаев? Я понимаю, что производительность диска значительно ниже, чем у локального, но я не планирую запускать форум на нём. Мне бы очень хотелось иметь удобный способ использовать его для определённых сценариев.

Если ваша цель — выполнить обновление максимально просто, лучше всего создать новую виртуальную машину и мигрировать на неё. Так вы избежите необходимости обновлять базу данных и получите новую операционную систему на вашей виртуальной машине, что вам, скорее всего, всё равно нужно сделать.

Следуйте руководству Перенос сайта Discourse на другой VPS с помощью rsync и не копируйте базу данных (но да, загрузку файлов, сертификаты Let’s Encrypt и сами сертификаты).

Если ваши резервные копии хранятся в S3, процесс очень прост: заморозьте старый сервер, создайте резервную копию и восстановите её на новой машине.

Если у Hetzner есть постоянный IP-адрес, который можно назначать разным серверам, вам даже не придётся менять DNS.

Вам важно убедиться, что вы можете создать новый сервер, чтобы в случае необходимости всегда иметь такую возможность. Это отличный шанс потренироваться.

На самом деле это не вариант. В любом случае, для повседневных задач места не заканчивается. К тому же у нас сейчас диск на 600 ГБ, и используется около 50%. Более крупного варианта нет — по крайней мере, у Hetzner.

Вот почему я прямо спрашивал про внешний диск.

Вы по интересам выполняли команду ./launcher cleanup app? Разве это не освободило достаточно места для выполнения обновления на месте?

Разве это должно иметь значение при пересборке? Для простого перезапуска я бы понял, но для пересборки?

Я не предлагал переходить на диск большего размера, просто купите новый сервер точно такой же, как тот. Установите Discourse и восстановите вашу базу данных.

Это очень хороший вопрос.

Да. Каждая пересборка создает новый контейнер, и каждый из них занимает место. Если вы никогда этого не делали, вы можете освободить десятки гигабайт.

Для обновления базы данных вам нужно максимально возможное свободное место. Так что да, это важно.

Наше руководство по обновлению включает инструкцию именно для вашего случая.

Мы добавили эту опцию для людей, находящихся в такой же ситуации, как и вы. Обязательно создайте резервную копию на удалённом носителе перед попыткой этого действия!

Если вы работаете на виртуальной машине, гораздо проще просто перейти на новую, и это даёт множество преимуществ. Вот несколько из них:

  • нулевой риск — если что-то пойдёт не так, у вас всё ещё будет старый сервер
  • нулевое время простоя (на старом сервере останется только режим только для чтения)
  • вы получите обновление операционной системы, которое вам, вероятно, всё равно нужно
  • вы сможете убедиться, что умеете разворачивать новый сервер на случай чрезвычайной ситуации
  • вам не потребуется повторная индексация и вакуумирование

Благодарю за совет, ребята.

Спасибо, это тот самый вариант, о котором я упоминал, что знаю о нём. Всё равно спасибо, что указали на него.

Не сомневаюсь в этом — всё же хотел бы изучить возможность добавления дополнительного хранилища для задач обслуживания, если это потребуется.

Полезно хранить ваши загрузки, например в /var/discourse/shared/web_only, на сетевом хранилище. Вам нужно отредактировать файл yml, чтобы указать путь к нему, а не использовать символическую ссылку (символическая ссылка не работает, потому что контейнер не может получить доступ к месту, на которое указывает ссылка).

Затем, если вы перенесёте систему на новую виртуальную машину, вам достаточно будет просто перемонтировать это сетевое хранилище, вместо того чтобы копировать данные.

Я не рекомендую использовать сетевое хранилище для базы данных, так как это работает медленнее.

Я думаю, стоит разобрать, как именно расходуется место. Размер вашей базы данных может быть не таким уж большим, если основная часть использования приходится на загрузки, а только часть базы данных требует примерно в 3 раза больше места во время обновления.

Один из способов проверить это — сравнить размер резервной копии с загрузками и без них.

Или используйте командную строку. Вот вывод с моего довольно небольшого форума:

root@rc-debian-hel:~# free -m
               total        used        free      shared  buff/cache   available
Mem:            3813        1631         267         492        1915        1504
Swap:           4095         730        3365
root@rc-debian-hel:~# swapon 
NAME                       TYPE  SIZE   USED PRIO
/var/local/swap/swapfile.1 file 1024M 730.2M   -2
/var/local/swap/swapfile.3 file 1024M   136K   -3
/var/local/swap/swapfile.0 file 1024M     0B   -4
/var/local/swap/swapfile.2 file 1024M     0B   -5
root@rc-debian-hel:~# df -h 
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           382M  1.2M  381M   1% /run
/dev/sda1        38G   22G   14G  62% /
tmpfs           1.9G     0  1.9G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
/dev/sda15      253M  6.3M  246M   3% /boot/efi
overlay          38G   22G   14G  62% /var/lib/docker/overlay2/68abab42f48040e0dfc03d3c9fc893dfa3e7fb01ba1b2215731668339bbc3766/merged
tmpfs           382M     0  382M   0% /run/user/0

При более внимательном рассмотрении:

root@rc-debian-hel:~# du -kx / | sort -n | tail -33
767000	/var/lib/docker/overlay2/8b6ac2d69a1fa195285e61aba2876484a69fd2a19032c2f4def1c4adb02d6554/diff/home/discourse/.local/share/pnpm
767004	/var/lib/docker/overlay2/8b6ac2d69a1fa195285e61aba2876484a69fd2a19032c2f4def1c4adb02d6554/diff/home/discourse/.local/share
767020	/var/lib/docker/overlay2/8b6ac2d69a1fa195285e61aba2876484a69fd2a19032c2f4def1c4adb02d6554/diff/home/discourse/.local
795804	/var/lib/docker/overlay2/8b6ac2d69a1fa195285e61aba2876484a69fd2a19032c2f4def1c4adb02d6554/diff/home/discourse
795808	/var/lib/docker/overlay2/8b6ac2d69a1fa195285e61aba2876484a69fd2a19032c2f4def1c4adb02d6554/diff/home
833836	/var/discourse/shared/standalone/postgres_data
884648	/var/discourse/shared/standalone/uploads/default/original
978000	/usr/lib/modules
991644	/var/lib/docker/overlay2/68abab42f48040e0dfc03d3c9fc893dfa3e7fb01ba1b2215731668339bbc3766/diff
991664	/var/lib/docker/overlay2/68abab42f48040e0dfc03d3c9fc893dfa3e7fb01ba1b2215731668339bbc3766
1025164	/var/discourse/shared/standalone/uploads/default/optimized
1146528	/usr/lib/firmware
1350496	/var/lib/docker/overlay2/8b6ac2d69a1fa195285e61aba2876484a69fd2a19032c2f4def1c4adb02d6554/diff
1350512	/var/lib/docker/overlay2/8b6ac2d69a1fa195285e61aba2876484a69fd2a19032c2f4def1c4adb02d6554
1909816	/var/discourse/shared/standalone/uploads/default
1919380	/var/discourse/shared/standalone/uploads
2471968	/usr/lib
2506940	/var/log/journal/82e4cf9bff9748d090b41e6d336353eb
2515140	/var/log/journal
2592200	/var/log
3029428	/usr
3839148	/var/discourse/shared/standalone/backups/default
3839152	/var/discourse/shared/standalone/backups
4194324	/var/local/swap
4194328	/var/local
5171844	/var/lib/docker/overlay2
5217052	/var/lib/docker
5455612	/var/lib
6682972	/var/discourse/shared/standalone
6682976	/var/discourse/shared
6685716	/var/discourse
19041368	/var
23037264	/
root@rc-debian-hel:~# du -kx /var/discourse/shared/ | sort -n | tail -33
42312	/var/discourse/shared/standalone/uploads/default/original/2X/f
42448	/var/discourse/shared/standalone/uploads/default/original/2X/1
42548	/var/discourse/shared/standalone/uploads/default/original/2X/6
43380	/var/discourse/shared/standalone/uploads/default/optimized/2X/2
44148	/var/discourse/shared/standalone/uploads/default/optimized/2X/5
44340	/var/discourse/shared/standalone/uploads/default/optimized/2X/1
45240	/var/discourse/shared/standalone/uploads/default/optimized/2X/e
46648	/var/discourse/shared/standalone/uploads/default/optimized/2X/c
49516	/var/discourse/shared/standalone/uploads/default/optimized/2X/8
49772	/var/discourse/shared/standalone/uploads/default/optimized/2X/9
49932	/var/discourse/shared/standalone/log/var-log/nginx
50788	/var/discourse/shared/standalone/uploads/default/optimized/2X/0
55428	/var/discourse/shared/standalone/uploads/default/optimized/2X/d
55844	/var/discourse/shared/standalone/uploads/default/optimized/2X/f
57548	/var/discourse/shared/standalone/uploads/default/optimized/2X/6
77280	/var/discourse/shared/standalone/log/var-log
81928	/var/discourse/shared/standalone/postgres_data/pg_wal
84064	/var/discourse/shared/standalone/log
294384	/var/discourse/shared/standalone/uploads/default/optimized/1X
325068	/var/discourse/shared/standalone/uploads/default/original/1X
559576	/var/discourse/shared/standalone/uploads/default/original/2X
724684	/var/discourse/shared/standalone/postgres_data/base/16384
730776	/var/discourse/shared/standalone/uploads/default/optimized/2X
749424	/var/discourse/shared/standalone/postgres_data/base
833836	/var/discourse/shared/standalone/postgres_data
884648	/var/discourse/shared/standalone/uploads/default/original
1025164	/var/discourse/shared/standalone/uploads/default/optimized
1909816	/var/discourse/shared/standalone/uploads/default
1919380	/var/discourse/shared/standalone/uploads
3839148	/var/discourse/shared/standalone/backups/default
3839152	/var/discourse/shared/standalone/backups
6682972	/var/discourse/shared/standalone
6682976	/var/discourse/shared/

Надо было быть более точным изначально, но я не ожидал такого широкого отклика.

Наши загрузки и резервные копии хранятся в S3. Размер базы данных на рабочей системе сейчас составляет около 230 ГБ. Сжатые резервные копии, думаю, занимают около 25 ГБ.

Ух ты, это действительно одна из самых больших! При таком объёме операции с базой данных обычно действительно становятся немного сложнее.

Ого. Ты давно делал уборку пылесосом?

Нет, я думал, что autovacuum должен об этом позаботиться? Или нет?

Думаю, так и должно быть. Я не до конца понимаю, что именно его запускает. Считаю, что выполнить дополнительную процедуру не повредит и может освободить немного места. Это рекомендуется делать после обновления, если вы обновляете систему на месте. Несколько раз я видел, как она освобождала значительный объем места.

Если размер вашей базы данных составляет 230 ГБ, я бы определенно восстановил её на новом сервере. Простой, связанный с чтением и записью 230 ГБ, будет существенным.