sqlite on nfs
調査中です。
SQLite3 bindings for CleanをLinuxで動かそうとしているのですが、そのまえに、SQLite3そのものが動作しない。
「database is locked」というメッセージを表示して、何の処理も受け付けてくれない。
- -
ファイルシステムがNFSであることが何か関係していそうな気がする。
- -
ビンゴっぽい。
同じ現象だ。
今動かしてるサービスをSolaris上のSQLiteで組んでるんだけど、DBはNFS上に置いてても普通に動いてた。
で、SolarisをLinuxにリプレースすることになったので、LinuxからNFS上のSQLiteファイルアクセスしてみたら、データベースが全く開けない。
いろいろ調べてみると、別にDBD::SQLiteのインストールに失敗したというわけではなさそうで、ローカルディスク上のSQLiteファイルならいくらでもアクセスできる。
なもんでNFS上に置いてるのが原因かと思って調べてみたら、案の定だった。
Solarisでsqlite使ったシステム。
nfs上にデータベース置いてても動作してた。
システムをLinuxにリプレース。
nfs上のデータベースにアクセスしたら、全く開けない。
ローカルディスクのデータベースなら問題なく動作する。
nfs上のデータベースが問題。
NFSパーティションにマウントされたSQLiteデータベースを処理すること は推奨されません。ロックに関してNFSは著しい問題があるので、 データベースを全くオープンすることさえできない可能性があります。ま た、成功した場合でも、ロックに関する動作は予測できない結果を生む可 能性があります。
nfsのロックには問題あり。
データベースのオープンに成功しても、動作は保証できない。
上記にあるように、複数のプロセスで同時に1つのデータベース(ファイル)を操作することは可能とのこと。但し、データベースを変更できるプロセスは瞬間的には1つだけ、という制限があるようです。しかも、NFSのような仕組みを介すると一貫性が保たれない。
sqliteにはロック機構あり。
複数プロセスから同時アクセスも可能。
nfs上のデータベースについては、一貫性が保たれない。
解決の糸口が
> SQLiteはNFS上に置けない
> 情報としてはこの辺。より正確に言うと「ファイルのロックができない場所には置けない」ですね。
SQLite を普通に使うと、同じファイルに対して各クライアントがそれぞれ直接読み書きすることになるので、ファイルのロックができない環境では排他制御ができないので使えません。
以前は「NFS ではロックはできない」のが常識だったので、NFS 上ではそもそも無理でした。
今時は NFS でもロックができる実装が増えていますが、ロックが信用できない実装もあるので、その情報のようなことになっています。逆に言うと、きちんとファイルのロックができるシステムであれば、NFS 上に SQLite のデータベースを置いても問題ありません。
(きちんとロックができるかどうかは、NFS サーバ/クライアントの実装依存です。Linux や Solaris の実装がきちんとしているのかどうかは、私は知りません ← じゃあ役に立たないじゃねーか)> LinuxからNFS上のSQLiteファイルアクセスしてみたら、データベースが全く開けない。
どのような Linux の環境でしょうか?
NFS サーバ/クライアント共に、Vine Linux 4.1, カーネル 2.6.16-0vl76.3, nfs-utils-1.0.9-0vl3, DBD-SQLite-1.13 の環境で rpc.statd (init スクリプトの名前は nfslock) が動いている状態であれば、NFS 経由で SQLite の読み書きができました。
# 正しく排他制御できるのかどうかまでは不明。
(rpc.statd が動いていない状態の場合、マウントしてファイルの読み書きはできますが、ロックができないため SQLite は使えないので注意。)あと、Solaris と Linux の NFS のロックの違いとしては、Solaris ではサーバ側だけのデーモンを使ってロックを管理していたような気がしますが、Linux の rpc.statd はサーバ/クライアント双方で動いている必要があるようです。
ローカルのcolinuxを2台立てて実験してみる
ここを参考に
サーバの設定は 2 つのステップからなります。 まず NFS の設定ファイルを編集し、 次に NFS サービスを実際に起動します。
centos5をサーバに
設定を書いた
# cat /etc/exports /home 192.168.52.9(rw)
nfs-utilsパッケージをインストール
# yum install nfs-utils Loading "fastestmirror" plugin Loading "installonlyn" plugin Setting up Install Process Setting up repositories extras 100% |=========================| 1.1 kB 00:00 updates 100% |=========================| 951 B 00:00 base 100% |=========================| 1.1 kB 00:00 addons 100% |=========================| 951 B 00:00 Loading mirror speeds from cached hostfile Reading repository metadata in from local files Parsing package install arguments Resolving Dependencies --> Populating transaction set with selected packages. Please wait. ---> Downloading header for nfs-utils to pack into transaction set. nfs-utils-1.0.9-40.el5.i3 100% |=========================| 35 kB 00:00 ---> Package nfs-utils.i386 1:1.0.9-40.el5 set to be updated --> Running transaction check --> Processing Dependency: libgssapi.so.2 for package: nfs-utils --> Processing Dependency: libnfsidmap.so.0 for package: nfs-utils --> Processing Dependency: libgssapi for package: nfs-utils --> Processing Dependency: libgssapi.so.2(libgssapi_CITI_2) for package: nfs-utils --> Processing Dependency: librpcsecgss.so.2 for package: nfs-utils --> Processing Dependency: nfs-utils-lib >= 1.0.8-2 for package: nfs-utils --> Restarting Dependency Resolution with new changes. --> Populating transaction set with selected packages. Please wait. ---> Downloading header for libgssapi to pack into transaction set. libgssapi-0.10-2.i386.rpm 100% |=========================| 4.1 kB 00:00 ---> Package libgssapi.i386 0:0.10-2 set to be updated ---> Downloading header for nfs-utils-lib to pack into transaction set. nfs-utils-lib-1.0.8-7.2.z 100% |=========================| 5.5 kB 00:00 ---> Package nfs-utils-lib.i386 0:1.0.8-7.2.z2 set to be updated --> Running transaction check Dependencies Resolved ============================================================================= Package Arch Version Repository Size ============================================================================= Installing: nfs-utils i386 1:1.0.9-40.el5 base 379 k Installing for dependencies: libgssapi i386 0.10-2 base 22 k nfs-utils-lib i386 1.0.8-7.2.z2 base 55 k Transaction Summary ============================================================================= Install 3 Package(s) Update 0 Package(s) Remove 0 Package(s) Total download size: 456 k Is this ok [y/N]: y Downloading Packages: (1/3): libgssapi-0.10-2.i 100% |=========================| 22 kB 00:00 (2/3): nfs-utils-1.0.9-40 100% |=========================| 379 kB 00:00 (3/3): nfs-utils-lib-1.0. 100% |=========================| 55 kB 00:00 Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction Installing: libgssapi ######################### [1/3] Installing: nfs-utils-lib ######################### [2/3] Installing: nfs-utils ######################### [3/3] Installed: nfs-utils.i386 1:1.0.9-40.el5 Dependency Installed: libgssapi.i386 0:0.10-2 nfs-utils-lib.i386 0:1.0.8-7.2.z2 Complete!
nfsサーバの設定はここを参考に
http://www.server-world.info/note?os=ce5&p=nfs
portmapを起動してみる
# /etc/init.d/portmap start portmap を起動中: [ OK ] # /usr/sbin/rpcinfo -p プログラム バージョン プロトコル ポート 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper
nfsを起動してみます
# /etc/init.d/nfs start NFS サービスを起動中: [ OK ] NFS デーモンを起動中: [ OK ] NFS mountd を起動中: [ OK ] RPC idmapd を起動中: [ OK ] # /usr/sbin/rpcinfo -p プログラム バージョン プロトコル ポート 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100021 1 udp 32775 nlockmgr 100021 3 udp 32775 nlockmgr 100021 4 udp 32775 nlockmgr 100003 2 udp 2049 nfs 100003 3 udp 2049 nfs 100003 4 udp 2049 nfs 100021 1 tcp 40066 nlockmgr 100021 3 tcp 40066 nlockmgr 100021 4 tcp 40066 nlockmgr 100003 2 tcp 2049 nfs 100003 3 tcp 2049 nfs 100003 4 tcp 2049 nfs 100005 1 udp 989 mountd 100005 1 tcp 992 mountd 100005 2 udp 989 mountd 100005 2 tcp 992 mountd 100005 3 udp 989 mountd 100005 3 tcp 992 mountd # ps aux | grep nfs root 6736 0.0 0.0 0 0 ? S< 20:06 0:00 [nfsd4] root 6739 0.0 0.0 0 0 ? S 20:06 0:00 [nfsd] root 6740 0.0 0.0 0 0 ? S 20:06 0:00 [nfsd] root 6741 0.0 0.0 0 0 ? S 20:06 0:00 [nfsd] root 6742 0.0 0.0 0 0 ? S 20:06 0:00 [nfsd] root 6743 0.0 0.0 0 0 ? S 20:06 0:00 [nfsd] root 6744 0.0 0.0 0 0 ? S 20:06 0:00 [nfsd] root 6745 0.0 0.0 0 0 ? S 20:06 0:00 [nfsd] root 6746 0.0 0.0 0 0 ? S 20:06 0:00 [nfsd] root 6776 0.0 0.5 4960 740 pts/0 R+ 20:07 0:00 grep nfs
nfslockを起動してみます
# /etc/init.d/nfslock start NFS statd を起動中: [ OK ]
debianをクライアントに
# cat /etc/debian_version
4.0
ここを参考に
クライアントからつないでみます
# mkdir /mnt/home # mount 192.168.52.12:/home /mnt/home mount: 192.168.52.12:/home: can't read superblock
エラーが表示されてつながりません。
NFSでは、サーバ側にもクライアント側にも、portmapが必須な模様。今回は、そのportmapがクライアントで動いていなかった(インストールされていなかった)という話。
クライアント側にもportmapが必要だそうで。
debianにportmapをインストールします。
# apt-cache search portmap portmap - The RPC portmapper # apt-get install portmap パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています... 完了 以下のパッケージが新たにインストールされます: portmap アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 80 個。 35.5kB のアーカイブを取得する必要があります。 展開後に追加で 156kB のディスク容量が消費されます。 取得:1 http://ftp2.jp.debian.org etch/main portmap 5-26 [35.5kB] 35.5kB を 0s で取得しました (51.5kB/s) Illegal character in prototype for bytes::length : _ at /home/hoge/perl/lib/5.10.0/bytes.pm line 22. Illegal character in prototype for bytes::chr : _ at /home/hoge/perl/lib/5.10.0/bytes.pm line 23. Illegal character in prototype for bytes::ord : _ at /home/hoge/perl/lib/5.10.0/bytes.pm line 24. パッケージを事前設定しています ... 未選択パッケージ portmap を選択しています。 (データベースを読み込んでいます ... 現在 26840 個のファイルとディレクトリがインストールされています。) (.../archives/portmap_5-26_i386.deb から) portmap を展開しています... portmap (5-26) を設定しています ... Illegal character in prototype for bytes::length : _ at /home/hoge/perl/lib/5.10.0/bytes.pm line 22. Illegal character in prototype for bytes::chr : _ at /home/hoge/perl/lib/5.10.0/bytes.pm line 23. Illegal character in prototype for bytes::ord : _ at /home/hoge/perl/lib/5.10.0/bytes.pm line 24. Starting portmap daemon....
あらためてmountしてみます
# mount 192.168.52.12:/home /mnt/home # df -h Filesystem サイズ 使用 残り 使用% マウント位置 /dev/cobd0 1007M 122M 835M 13% / tmpfs 62M 0 62M 0% /lib/init/rw udev 10M 28K 10M 1% /dev tmpfs 62M 0 62M 0% /dev/shm /dev/cobd4 1008M 426M 532M 45% /var /dev/cobd5 1008M 722M 235M 76% /usr /dev/cobd6 3.0G 1.9G 982M 66% /home 192.168.52.12:/home 2.0G 165M 1.8G 9% /mnt/home
あっさりmountできました。