Nextcloud運用
- NextcloudのExternal StorageサービスでのArray to string conversionエラーに対処
- NextcloudのDB、照合順序を変更。
- Nextcloudの切り戻し(ダウングレード)手順。
NextcloudのExternal StorageサービスでのArray to string conversionエラーに対処
エラー概要
Nextcloud 28.x以降にバージョンアップしてから、ログで以下が大量に出力され続けていました。
Array to string conversion at /var/www/html/nextcloud/lib/private/Files/Cache/Scanner.php#224
こちらの対処を行います。
エラーが出る要件
- Nextcloud 28.x以降を利用している。
- External Storageプラグインを利用している。
- このプラグインで、S3(乃至はS3互換のオンラインストレージ)をマウントしている。
- マウントしたストレージにファイルやフォルダを保存した。
詳細:Nextcloud Hub 8, copying files to an External Storage configured as primary storage isn't reliable
環境
- Ubuntu 20.04
- Nextcloud 29.0.0
- PHP 8.1
- Apache 2.4
- オンラインストレージサービスとしてwasabiを利用
解決策
上記issueに
Pretty sure this would be fixed by #43794. At least in my limited testing using the merge request as a patch: https://patch-diff.githubusercontent.com/raw/nextcloud/server/pull/43794.diff
とあったので、この通りに実施します。
さっくりとした手順
- rootに昇格します。
- パッチファイルを入手します。
- ファイルを適用します。
- Apacheを再起動します。
root昇格
sudo su -
Nextcloudはwww-dataユーザーのみアクセス可能と、厳しめのアクセス権が設定されているので、ここで昇格させます。
ディレクトリ移動
- Nextcloudのルートディレクトリに移動
cd /var/www/html/nextcloud && pwd
自分の環境に合わせます。
cd lib/private/Files/Cache
ファイルバックアップ
- Scanner.phpファイルのバックアップ
cp -pi Scanner.php /path/to/backup/directory/Scanner.php.$(date +%Y%m%d)
任意のバックアップディレクトリを指定します。
- バックアップ確認
diff -u Scanner.php /path/to/backup/directory/Scanner.php.$(date +%Y%m%d)
差分がなければバックアップは成功です。
パッチ適用
- wgetでパッチ入手
sudo -u www-data wget https://patch-diff.githubusercontent.com/raw/nextcloud/server/pull/43794.diff
- パッチ適用
sudo -u www-data patch < 43794.diff
patching file Scanner.php
と返ってくればOKです。
パッチ適用確認
- 差分確認
diff -u /path/to/backup/directory/Scanner.php.$(date +%Y%m%d) Scanner.php
- 差分結果
}
// Only update metadata that has changed
- $newData = array_diff_assoc($data, $cacheData->getData());
-
+ // i.e. get all the values in $data that are not present in the cache already
+ // NOTE: we serialize then unserialize here because array_diff_assoc() doesn't
+ // support multidimensional arrays on its own (and otherwise internally casts any
+ // embedded array elements to attempt to compare them - not only generating warnings
+ // like "Array to string conversion" but also, as a resut, overlooking real differences)
+ $newData = array_diff_assoc(
+ array_map('serialize', $data),
+ array_map('serialize', $cacheData->getData())
+ );
+ $newData = array_map('unserialize', $newData);
+
// make it known to the caller that etag has been changed and needs propagation
if (isset($newData['etag'])) {
$data['etag_changed'] = true;
- Apache再起動
systemctl restart apache2.service
既にrootに昇格しているので、sudoは不要のはずです。
- パッチファイルを削除
rm 43794.diff
エラー解消確認
- ブラウザでNextcloudサイトに管理者権限でログインします。
- 管理メニュー→ログへと進み、適用時刻以降に冒頭のログが出力されていないことを確認します。
NextcloudのDB、照合順序を変更。
NextcloudのインストールでDBを作成す際に
CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
としていました。
運用中、より正確な比較やソートが必要という判断をしたのでDBの照合順序をci(Case Insentive)ではなく、bin(Binary)に変更します。
DBを操作するため、作業前後にメンテナンスモードに入るとともに、ユーザーへの周知は徹底して行ってください。
メンテナンスモードを実行
- Nextcloudのルートディレクトリ移動
cd /var/www/html/nextcloud && pwd
自分の環境に合わせます。(筆者環境/home/www-data/nextcloud
)
- メンテナンスモード有効化
sudo -u www-data php occ maintenance:mode --on
- メンテナンスモード確認
運用中のNextcloudのURLにアクセスし、メンテナンスモードであることを確認します。
mysqldumpでバックアップを取得する
- 作業ディレクトリに移動
cd /hoge && pwd
任意のディレクトリを指定します。
- DBバックアップ作成
mysqldump -h localhost -u nextcloud -p --no-tablespaces --single-transaction nextcloud > nextcloud_backup.$(date +%Y%m%d).sql
DB名やユーザーは自分の環境に合わせます。
- DBバックアップ作成確認
ls -la nextcloud_backup.$(date +%Y%m%d).sql
ファイルがあることを確認します。
DB設定変更
- 管理者権限でMySQLにログインする
mysql -u root -p
- 対象のDBを確認する
SHOW DATABASES;
nextcloudが動いているDBであることを再確認してください。
- データベース全体の照合順序を変更する
ALTER DATABASE nextcloud COLLATE utf8mb4_bin;
- 既存のデーテーブルの照合順序を変更する
USE nextcloud;
SET @DATABASE_NAME = 'nextcloud';
DB名は自分の環境に合わせます。
SET @COLLATE = 'utf8mb4_bin';
SELECT CONCAT('ALTER TABLE ', TABLE_NAME, ' CONVERT TO CHARACTER SET utf8mb4 COLLATE ', @COLLATE, ';')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = @DATABASE_NAME
AND TABLE_TYPE = 'BASE TABLE';
- MySQLから抜ける
EXIT
メンテナンスモードの解除を実行
- Nextcloudのルートディレクトリ移動
cd /var/www/html/nextcloud && pwd
自分の環境に合わせます。(筆者環境/home/www-data/nextcloud
)
- メンテナンスモード無効化
sudo -u www-data php occ maintenance:mode --off
- メンテナンスモード確認
運用中のNextcloudのURLにアクセスし、普通にアクセスできることを確認します。
切り戻し
何か不具合があった場合の切り戻し手順です。上記、メンテナンスモードを有効化してから行ってください。
- バックアップしたDBがあることを再確認する
ls -l /hoge/nextcloud_backup.$(date +%Y%m%d).sql
バックアップを行ったディレクトリを指定します。
head -100 /hoge/nextcloud_backup.$(date +%Y%m%d).sql
ファイルがあること、平文で読めることを確認します。
- 管理者権限でMySQLにログインする
mysql -u root -p
- 対象のDBを確認する
SHOW DATABASES;
nextcloudが動いているDBであることを再確認してください。
- 不具合が発生したDBを削除する
二回ほど深呼吸して、落ち着いて作業しましょう。
DROP DATABASE nextcloud;
- DBを再作成する
CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
- MySQLから抜ける
EXIT
- DB復元
mysql -h localhost -u nextcloud -p nextcloud < /hoge/nextcloud_backup.$(date +%Y%m%d).sql
この後、メンテナンスモードを解除して、以前と同じ状態か確認します。
作業後:バックアップDBの削除
平文でSQLがサーバ上にあるのは危険な状態なので、以下の措置を執ります。
- 作業ディレクトリに移動
cd /hoge && pwd
バックアップを行ったディレクトリを指定します。
- DBバックアップ確認
ls -la nextcloud_backup.$(date +%Y%m%d).sql
ファイルがあることを確認します。
- バックアップしたDBの削除
rm nextcloud_backup.$(date +%Y%m%d).sql
- DBバックアップ削除確認
ls -la nextcloud_backup.$(date +%Y%m%d).sql
ファイルが無いことを確認します。
Nextcloudの切り戻し(ダウングレード)手順。
Nextcloud、Webからアップグレードすることはできますが下位のメジャーバージョンにダウングレードすることはできません。
アップグレードの失敗ならびにアプリの相性などで元のバージョンに戻したい場合は以下のように切り戻しを行います。
(今回の筆者のパターンは前者です)
前提
アップグレード前のnextcloudのDBを取っていること
これがなければそもそも成り立ちません。この方法で日次のバックアップを取っていました。 取っていなかった場合は別のサイトをお探しください。
nextcloud_backup.sql
等のSQLを任意のディレクトリに格納してください。
環境
- Ubuntu 24.04
- Apache2.4
- php 8.3
- MySQL 8.0.39
- Nextcloud 29.0.8
特記事項
データ格納ディレクトリを別パーティションにしています。
さっくりとした手順
- 切り戻し前のプログラムを退避させます。
- 切り戻しを行いたいプログラムをダウンロードします。
- プログラムを解凍して再配置します。
- コンフィグやアプリデータなどを再配置します。
- DBをリストアします。
- 切り戻しを確認します。
Nextcloudの退避
- プログラム退避
sudo mv /home/www-data/nextcloud /path/to/backup/directory/nextcloud.$(date +%Y%m%d)
退避前、退避先はそれぞれ自分の環境に合わせます。
- 退避確認
ls -l /path/to/backup/directory/nextcloud.$(date +%Y%m%d)
退避先にディレクトリファイル一式があることを確認します。
切り戻し対象前のプログラムをダウンロード
- 作業用ディレクトリに移動
cd /hoge && pwd
任意のディレクトリを指定します。
- wgetによるダウンロード
wget https://download.nextcloud.com/server/releases/nextcloud-29.0.8.zip
切り戻しを行う(アップグレード前)のバージョンを指定します。
- 解凍
unzip nextcloud-29.0.8.zip
- 所有者変更
sudo chown -R www-data:www-data nextcloud
Nextcloud(Webサービス)実行ユーザーに合わせます。
- Nextcloud再配置
sudo mv nextcloud /home/www-data/
元々Nextcloudが配置されていたディレクトリに再配置します。
- 再配置確認
ls -l nextcloud /home/www-data/nextcloud
ディレクトリ・ファイル一式があることを確認します。
Nextcloud復旧
- 退避させた元のNextcloudからコンフィグをコピー
sudo cp -pi /path/to/backup/directory/nextcloud.$(date +%Y%m%d)/config/config.php /home/www-data/nextcloud/config/
- 退避させた元のNextcloudからアプリ一式をコピー
sudo -u www-data cp -r /path/to/backup/directory/nextcloud.$(date +%Y%m%d)/apps/* /home/www-data/nextcloud/apps/
- 退避させた元のNextcloudからデータ一式をコピー
sudo -u www-data cp -r /path/to/backup/directory/nextcloud.$(date +%Y%m%d)/data/* /home/www-data/nextcloud/data/
※データ格納ディレクトリを別のパーティションにしている場合は不要です。ディスクサイズによってはcp -r
の代わりにmv
を用いてください。
- DBからリストア
mysql -u nextcloud -p nextcloud < /path/to/directory/nextcloud_backup.sql
-u nextcloudのDBユーザ名
、-p nextloudDB名
です。バックアップのSQLファイルは自分の環境に合わせます。
- Webサービス再起動(Apacheの場合)
sudo systemctl restart apache2.service
- Webサービス再起動(nginxの場合)
sudo systemctl restart nginx.service
切り戻し確認
- Nextcloudに管理者権限でログインします。
- バージョンが切り戻し前に戻っていることを確認します。
- 主要な機能が使えることを確認します。
切り戻し後のデータ削除(必要に応じて)
- 退避させたプログラムの削除
sudo rm -rf /path/to/backup/directory/nextcloud.$(date +%Y%m%d)
- バックアップのSQLファイルの削除
rm /path/to/directory/nextcloud_backup.sql