Относительно недавно встала передо мной задача переместить файловое хранилище объемом 90 ТБ на объектное хранилище S3.
Из сложностей было то, что в рунете почти нет статей на тему миграции, а те, что есть, описывают подключение внешнего хранилища.
Мне же нужно было,чтобы S3 было именно в качестве основного хранилища.
Задача не особо сложная, но требует предельной внимательности в процессе переноса.
Предварительные условия
Nextcloud 27 версии или выше. На версиях ниже 27 версии некорректно работает MultiPart Upload, вследствие чего файл загружается, но Nextcloud не воспринимает заголовок Content-Length и в БД файл оказывается нулевого размера, а такие файлы Nextcloud даже не пытается вычитать с файлового хранилища.
СУБД: PostgreSQL. Можно и MySQL, но на маленьких объемах, в противном случае диск с БД постоянно будет забит IO, плюс на MySQL сложнее реализовать Point-In-Time Recovery, а для S3 в качестве основного хранилища это критично, так как в случае потери БД нельзя будет выполнить occ rescan, он на S3 не работает.
Далее описан весь процесс миграции. Все действия выполняются на свой страх и риск.
Выгрузка списка файлов, хранящихся на локальном хранилище
datadirectory = Директория NextCloud, в которой располагаются все загруженные файлы.
dbname = Имя базы NextCloud.
Следующей командой выгружается список пользовательских файлов
psql -qt -d {{ dbname }} -U $dbUser -c "select concat('urn:oid:', fileid, ' ', '{{ datadirectory }}', substring(id from 7), '/', path) from oc_filecache join oc_storages on storage = numeric_id where id like 'home::%' order by id;" > userdata.txt
Этой командой выгружается список метаданных (превью, аватары)
psql -qt -d {{ dbname }} -U $dbUser -c "select concat('urn:oid:', fileid, ' ', substring(id from 8), path) from oc_filecache join oc_storages on storage = numeric_id where id like 'local::%' order by id;" > metadata.txt
Если сервер БД находится на другой машине, то необходимо указать адрес сервера БД с помощью параметра -h dbHost.
Создание симлинков на файлы и метаданные
Создаем отдельную директорию и в ней запускаем скрипт, который делает симлинки на всех файлы и метаданные. Переменная path указывает на директорию, где хранятся файлы userdata.txt и metadata.txt.
#!/bin/bash
while read target source ; do
if [ -f "$source" ] ; then
ln -s "$source" "$target"
fi
done < $path/userdata.txt
while read target source ; do
if [ -f "$source" ] ;
then
ln -s "$source" "$target"
fi
done < $path/metadata.txt
Данный скрипт создаст в директории симлинки вида urn:oid:999. NextCloud сохраняет файлы в S3 именно в таком виде. Симлинки нужны для того, чтобы не копировать все файлы в отдельную директорию и соответственно, сэкономить место на диске.
Синхронизация содержимого директории с S3
Устанавливаем awscli командой apt install awscli.
В Debian и Ubuntu присутствует в репозиториях.
Конфигурируем aws командой aws configure.
При конфигурировании будут запрошены access_key и secret_key к S3.
Поскольку по дефолту aws обращается к серверам Amazon, и не воспринимает endpoint-url в конфигурационном файле, то необходимо сделать алиас в .bashrc.
Параметр —no-verify-ssl нужен, если у вас самоподписанный сертификат или невалидная цепочка сертификатов.
alias aws=’aws —endpoint-url https://s3Endpoint —no-verify-ssl’
Команду, соответственно, запускать из той директории, в которой у нас лежат симлинки.
aws s3 sync . s3://bucket-name
Вместо bucket-name указываем название вашего bucket.
После синхронизации можно глянуть содержимое командой aws s3 ls s3://bucket-name