start

NextcloudのoccでOCP\HintExceptionが発生した

自鯖のNextcloudを23に更新し、occ db:add-missing-indicesを実行しようとしたらOCP\HintExceptionなる例外が発生した。

$ sudo -u www php /path/to/occ db:add-missing-indices
An unhandled exception has been thrown:
OCP\HintException: [0]: Memcache \OC\Memcache\APCu not available for local cache (Is the matching PHP module installed and enabled?)

occ単発で動かしても同様で、根本的に何かが悪いっぽい。

助けて~ぐーぐるせんせーってことで、ググったら公式にそれっぽいissueが上がっていた。

いわく、apc.enable_cli=1を付けて実行する必要があるとのこと。APCuを明示的に有効化する必要がある雰囲気?とりあえず言われたとおりにやってみる。

$ sudo -u www php --define apc.enable_cli=1 /path/to/nextcloud/occ db:add-missing-indices
Check indices of the share table.
(中略)
oc_properties table updated successfully.

無事動いた。

改めてNextcloudのマニュアルを見てみると、Memory cachingのAPCuのところにちゃんと書いてあった。

デフォルトではCLIからの実行時はAPCuが無効化されているそうで、明示的に有効化しなきゃならんとのこと。NextcloudのCronジョブにも影響するので、そっちの方も個別に対応するか、php.iniに先のapc.enable_cli=1を追加しておく必要がある。

なるほどなー、だから管理画面に「長期間バックグラウンドジョブが動いていないようです」メッセージが表示されてたのかー。

Special vdevが消失したプールとzpool -Fオプション

プールのメタデータを丸っと引き受けるというZFSのSpecial vdevの特性から、対応する物理デバイスの故障などでSpecial vdevが死ぬと、プールそのものが使えなくなりそうってのは容易に想像ができる。

実際どうなるか仮想マシンベースで確認してみると、やはり使えなくなった。それもzpool listの結果にプール自体が出てこなくなるという、割と重篤な扱い。プール名を指定 or プール探索でインポートしようとすると、以下のようになってインポートできない。

# zpool import -a -N
cannot import 'ztest': I/O error
        Destroy and re-create the pool from
        a backup source.

存在しないプールのインポートではcannot import 'znotexists': no such pool availableって感じなので、明らかに扱いが違う。

Special vdevが消失したプールの復旧は基本的に無理っぽい感じ。

一応man zpool-importを見てみると、(いつの間にか)プール回復に関するオプション-F, -X, -Tが追加されていた。それぞれの効果を抄訳してみた。

-F インポート不可能なプールのための回復モード。最後のわずかなトランザクションを破棄することで、プールがインポート可能状態への復帰を試みます。このオプションを使うことで、損傷を受けたすべてのプールが回復するとは限りません。成功した場合、破棄されたトランザクションに関連するデータは、回復不能なほどに失われます。プールがインポート可能またはインポート済みの場合、このオプションは無視されます。
-n 回復オプション(-F)と共に使用します。インポート不可能なプールが再びインポート可能になるかどうかを判定しますが、実際にプール回復は行いません。プール回復モードの詳細は、上記の-Fオプションをご覧ください。
-X 回復オプション(-F)と共に使用します。有効なtxgを見つけるための非常手段を取るか否かを指定します。これは、もはや一貫性が保証されていないtxgへ、プールがロールバックされることを許可します。矛盾したtxgでインポートされたプールは修復不能なチェックサムエラーを含むかもしれません。プール回復モードの詳細は、上記の-Fオプションをご覧ください。警告:このオプションはプールの健全性に対し極めて危険な可能性があり、最終手段として用いるべきです。
-T ロールバックに使用するtxgを指定します。暗黙的に-FXオプションを含みます。プール回復モードの詳細は、上記の-Xオプションをご覧ください。警告:このオプションはプールの健全性に対し極めて危険な可能性があり、最終手段として用いるべきです。

-F < -X < -Tの順で強力(危険)になる雰囲気。で、それぞれを指定して、先のSpecial vdevが無くなったプールのインポートを試みたのが以下。

# zpool import -F ztest
cannot import 'ztest': I/O error
        Destroy and re-create the pool from
        a backup source.

# zpool import -FX ztest
cannot import 'ztest': one or more devices is currently unavailable

# zpool import -T ztest
invalid txg value
usage:
        import [-d dir] [-D]
        import [-o mntopts] [-o property=value] ...
            [-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] [-R root] [-F [-n]] -a
        import [-o mntopts] [-o property=value] ...
            [-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] [-R root] [-F [-n]]
            [--rewind-to-checkpoint] <pool | id> [newpool]

-Tはtxgを指定してやらないとダメな予感。usageにもmanにもそれらしいことは書いてないんだけど…実際にどんな値を指定したらいいのか皆目見当もつかない。

その後、Special vdev用の仮想ディスクを戻してみると、問題なくプールのインポートができた。ただし自動インポートはされず、手動で行う必要があるようだ。(上記の-Fとかでプールを操作したためかもしれないが未確認。)scrubで健全性に問題がないことも確認。

そんなわけでSpecial vdevの冗長性には十分気を付ける必要がありそうだ。

certbot renewでApacheがCPU 100%に張り付くでござるの巻き

SSL証明書の期限が切れた状態でcertbot renewを行うと、ApacheプロセスのCPU利用率が100%となりハング状態になるっぽい。apachectlで止めようとしても(弊鯖はご存じのとおりFreeBSDなのでservice apache24 stopだが)、応答が返ってこずkillせざるを得ないという状況。環境は以下のとおり。

  • FreeBSD 13.0-RELEASE-p4
  • Apache 2.4.51
  • certbot 1.21.0
  • certbot-apache 1.21.0
  • Python 3.8.12
  • webrootモードで運用

weekly_certbot_enableでもって週次で証明書の確認&更新が行われるはずなのに、なんで切れてるの?そもそも期限切れになったからと言って、なんでhttpdがハング状態になるの?と疑問は尽きないのだが、ひとまず脇に置いといて、この状況に陥ったらcertbot certonlyを使って手動で証明書を更新してやる。

# certbot certonly --webroot -w /path/to/document_root -d example.com

証明書更新後、certbot renewでhttpdが暴走しないことを確認する(renewが正常に終われば暴走はしてない。)

それにしても原因は何なんだろうなー。以前、同様の状況が発生した時は、apacheやモジュールの更新を行っていたのでバイナリ間の何らかの不整合くらいで流したが、たぶん今回と同じ原因だったんだろう。さらにその以前は正しく動いていたような気がしなくもない(結構期限切れをやらかしていたので確証が持てない)ので、よくわかりません。

詳しい方教えてください。


(2021-12-24 追記)

確証はないけど、証明書更新後にapache reloadをしておらず、新しい証明書がapacheに認識されてないのが原因な気がする。

FreeBSDフォーラムの投稿のように、証明書更新後のフックスクリプトでリロードしてやれば解決しそうな気がする。

/usr/local/etc/letsencrypt/renewal-hooks/deploy/reload_apache24.sh
#!/bin/sh
service `echo $0|sed -e 's/.*\/\(.*\)_\(.*\).sh/\2 \1/'`

パッと見「なんじゃこりゃ?」ってシェルスクだが、自身のファイル名をsedで切り出しservice apache24 reloadを実行するという、実に巧妙な仕組みだ。引用元のフォーラムでは、同様にdovecotやpostfixの証明書更新も行っていた。中身同じでファイル名を変えればいいだけとは、よく思いつくものだ。

FreeBSDのSambaのビルドでncurses not availableが出てた

家鯖のFreeBSDのnet/samba413をビルドしようとすると、configureでncursesが見つからんと言われてコケるようになっていた。

ncurses not available, cannot build regedit
ncurses not available, but --with-regedit was specified

ncursesってbaseに含まれてたような…なんでエラーになんの?と思いつつ、念のためdevel/ncursesを入れても効果なし。Sambaの依存パッケージじゃないし、そりゃそうだ。

portsのバグを疑いしばらく放置&再試行してみたものの、一向に直る気配がない。そもそもエラーでググってもそれらしい結果が出てこないので、自分の環境の問題なのだろう。

では、どうやってシステムのncursesを直すか?

base.txzあたりでシステムを上書きすれば良さそうではあるものの、ncursesがどのtarballに含まれているのかが分からない。かといって、なんも考えずにtxz一式を展開した結果、設定ファイルなどがデフォルトに戻るのは避けたい。

そんな感じでモニョってたんだけど、たまたま目にしたFreeBSD-SA-00:68.ncursesに解決策があった。/usr/src/lib/libncursesでmake installするだけで良かったのだ。

# cd /usr/src/lib/libncurses
# make && make install

そしてSamba 4.13が無事ビルドできて一件落着。

# portmaster net/samba413

システムを飛ばしたときの復旧が不十分だったんだろうなぁ、たぶん。近いうちにbuildworldしとくか…

OpenZFSにRAIDZ Expansionのプルリクができてた

今まで気づかなかったが、2か月ほど前の6/11に、待望のRAIDZ ExpansionのプルリクがOpenZFSに立てられていた!!2018年のプリアルファコード以来目立った動きがなく、どうなっとんじゃーいって感じだったが、June 2021 FreeBSD Developer Summitでの報告の翌日、PRが作られた模様。

コードレビューは始まったばかり、というかまだ進んでない?ようでリリースはまだまだ先っぽい。OpenZFSプロジェクトの状況としては、現在は2.1リリース作業の真っただ中で、取り込まれるのはどんなに早くとも来年リリースのOpenZFS 2.2あたりと見込まれている。まぁ、かなり大きい変更なのでレビューもテストも時間がかかるだろうしね、仕方ないね。

PRの議論を見るに、拡張時の挙動である「既存データのストライプサイズは変更しない=データ/パリティ比率は変わらない」という点が、結構引っかかってるっぽい雰囲気。

RAIDZ ExpansionでRAIDZ vdevにストレージを追加した場合、vdevの物理ストライプ幅は拡張後のサイズとなる。対する論理ストライプ幅については、既存のデータは拡張前の幅、再書き込みを含む新規データは拡張後の幅となる。具体的な数値を当てはめると、HDD 5本のRAIDZ2プールをHDD 6本に拡張した場合、既存データは論理5ストライプ(データ/パリティ比=3:2)のままで、新規データは論理6ストライプ(データ/パリティ比=4:2)で記録される。データによってストライプ幅が異なること自体は、RAIDZの元からの仕様なので問題ないらしい。

一方で、この仕様のため既存RAIDZプールの使用率が高いほど、RAIDZ Expansionでのプール拡張後の実効空き容量は増えにくくなる。例えば、1TB×4のRAIDZ1プールに1TB書き込むとプール使用率は33%なのに対し、1TB×3のRAIDZ1プールに1TB書き込んだあと(この時点での使用率は66%)で1TBのHDDを追加しても使用率は66%のままとなる。既存データのデータ/パリティ比が変わらない以上、この容量オーバーヘッドは避けられない。

RAIDZ ExpansionでRAIDZプールは何度でも拡張可能だが、こんな感じゆえに、最小構成で始めて必要に応じて後からディスクを追加する、という戦略は取りにくいのは否めない。

使っていく中で既存データも新しいストライプ幅に置き換わり、このオーバーヘッドは徐々に解消されていく。このあたりの挙動は他のプロパティと一緒で、ZFSの思想っぽいというかなんというか。可及的速やかにプール容量を最大効率で増やしたい!という場合には厳しいだろうが、現実的にそんなケースがどれだけあるのだろうか?そもそもZFS的にはそんなカツカツ運用するなよって感じ?

拡張時に全データの再配置を行ってるにもかかわらず、既存データの論理ストライプ幅を変えないは、実装の簡便さと拡張中のRAIDZ1/2/3の冗長性担保が理由とのこと。

このまま無事マージされて欲しい。

  • start.txt
  • 最終更新: 2019-08-19 11:45
  • by Decomo