MongoDBがダウンするようになったので、v2.4.5からv3.0にアップデートした話




ある日、急にMongoDBが落ちるようになった。

ログを見る限り、「ロックファイルが残っているため立ちあげられない」という情報のみだった。




目次

ダウン原因の調査

エラーログやMuninなどの監視ツールを調査した結果、ダウンした際の共通点があった。
それは

  1. メモリを2GB以上喰った際に落ちている
  2. MongoDBのロックファイルが残っている

ということだった。

一歩前進はしたが「メモリを2GB以上使うと落ちる」といった言語仕様や症例もなく、これだけでは原因特定が困難だった。

しかし、よくよく調べていくと同一サーバで動いているMySQLもおおよそ2GBのメモリを使用している。

そして、このサーバの物理メモリは4GBだ。

MongoDBがダウンする原因の仮説

  1. メモリリークが起こり、MongoDBがロックファイルを残したままダウンする
  2. 自動復帰するために再起動するが、ロックファイルがあるため立ち上がらない

というものである。

MongoDBダウンの回避対策

MongoDBのメモリ利用量を制限することで、メモリリークを起こさないようにしてみる。

しかし、残念ながらMongoDB v2系はメモリ制限の機能が存在せず、上記のような対策をとることが出来ない。

だが諦めるのはまだ早い。
Mongo v3から新規で追加されたストレージエンジン「Wired Tiger」にはメモリを制限する機能が備わっている。

これだ!

ということで、

  1. MongoDBをv2からv3にアップデートし
  2. さらにストレージエンジンを「mmap」から「Wired Tiger」に切り替え
  3. 「Wired Tiger」でメモリ制限をする

ことでMongoDBのダウンが再現しないか検証する。

ぶっちゃけ、AWSなどのクラウド環境や、DBサーバを並列で立てられたり移行出来る場合は移行して潤沢なメモリを割り当ててやるのが一番だと思いますw

MongoDBがインストールされているサーバ環境

環境はさくらのVPSです。

メモリ4GBのHDDプランだったと思いますので、下記の感じですかね。

  • OS: CentOS 6.5
  • メモリ:4GB

どこにでもあるCentOSのVPS機です。
では、これからMongoDBアップデートの旅に出かけましょう。

MongoDBのアップデートの前準備

CentOSのビットを確認

MongoDBには32bit版と64bit版があります。

32bit版は非推奨なので、OSが64bitであれば、可能な限り64bitをインストールしたいので、OSのbitを調べます。

[root@server ~]# uname -m
x86_64

上記が「x86_64」なら64bitです。

32bitだと「i686」などが返ってきます。

MongoDBをバックアップ

mongod.confの場所を調べ、mongodbのデータパスを明確にする。

 ps aux | grep mongod
mongod   11488  8.4  4.9 877920 192672 ?       Sl   Mar05 514:23 /usr/bin/mongod -f /etc/mongod.conf

dbpathを調べる

[root@server ~]# grep dbpath /etc/mongod.conf  
dbpath=/var/lib/mongo

mongodbを停止

[root@server ~]# service mongod stop  
Stopping mongod:                                           [  OK  ]

バックアップを取得

バックアップ先のディレクトリを作る
[root@server ~]# mkdir ~/mongo_dump
作成したディレクトリにバックアップのダンプを出力
[root@server ~]# mongodump -v --dbpath /var/lib/mongo --out ~/mongo_dump/
Wed Mar  9 23:40:19.786 [tools] flushing directory /var/lib/mongo
Wed Mar  9 23:40:19.794 [tools] run command admin.$cmd { isdbgrid: 1 }
Wed Mar  9 23:40:19.794 [tools] command admin.$cmd command: { isdbgrid: 1 } ntoreturn:1 keyUpdates:0  reslen:99 0ms
Wed Mar  9 23:40:19.795 [tools] all dbs
Wed Mar  9 23:40:19.795 [tools] run command admin.$cmd { listDatabases: 1 }
Wed Mar  9 23:40:19.806 [tools] opening db:  local
Wed Mar  9 23:40:19.840 [tools] opening db:  admin
Wed Mar  9 23:40:19.859 [tools] opening db:  db1

… 中略

Wed Mar  9 23:40:21.299 dbexit: 
Wed Mar  9 23:40:21.299 [tools] shutdown: going to close listening sockets...
Wed Mar  9 23:40:21.299 [tools] shutdown: going to flush diaglog...
Wed Mar  9 23:40:21.299 [tools] shutdown: going to close sockets...
Wed Mar  9 23:40:21.299 [tools] shutdown: waiting for fs preallocator...
Wed Mar  9 23:40:21.299 [tools] shutdown: closing all files...
Wed Mar  9 23:40:21.315 [tools] closeAllFiles() finished
Wed Mar  9 23:40:21.315 [tools] shutdown: removing fs lock...
Wed Mar  9 23:40:21.330 dbexit: really exiting now

MongoDBをアンインストール

バックアップの作成が完了したので、2.x系のMongoDBをアンインストールしましょう。

アンインストールはコマンド一発です。

[root@server ~]# yum remove mongo*     
Loaded plugins: fastestmirror, security
Setting up Remove Process
No Match for argument: mongo_dump
Loading mirror speeds from cached hostfile
Could not get metalink https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=x86_64 error was
14: problem making ssl connection
 * epel: ftp.kddilabs.jp
 * rpmforge: mirror.fairway.ne.jp
10gen                                                                                                                                                                                                                                                 |  951 B     00:00     
base                                                                                                                                                                                                                                                  | 3.7 kB     00:00     
extras                                                                                                                                                                                                                                                | 3.4 kB     00:00     
"> [Errno 14] PYCURL ERROR 22 - "The requested URL returned error: 404 Not Found"
Trying other mirror.
rpmforge                                                                                                                                                                                                                                              | 1.9 kB     00:00     
updates                                                                                                                                                                                                                                               | 3.4 kB     00:00     
updates/primary_db                                                                                                                                                                                                                                    | 3.9 MB     00:00

無事アンインストールができたら、次にv3系のMongoDBをインストールしましょう。

公式サイトを参考にMongoDB v3.2をインストール

それではMongoDBをインストールしていきましょう。
インストールの手順は下記の公式マニュアルが非常に丁寧に説明してくれているので、見ながら順に実行していけば問題ないかと思います。

公式リポジトリを登録
vi /etc/yum.repos.d/mongodb-org-3.2.repo
[mongodb-org-3.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.2/x86_64/
gpgcheck=0
enabled=1
YumでMongoDBをインストール

インストールもyumコマンド一発です。
簡単になりましたね。

[root@server ~]# sudo yum install -y mongodb-org
Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
Could not get metalink https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=x86_64 error was
14: problem making ssl connection
 * epel: ftp.kddilabs.jp
 * rpmforge: mirror.fairway.ne.jp
http://www.hop5.in/yum/el6/repodata/repomd.xml: [Errno 14] PYCURL ERROR 22 - "The requested URL returned error: 404 Not Found"
Trying other mirror.
mongodb-org-3.2                                                                                                                                                                                                                                       | 2.5 kB     00:00     
mongodb-org-3.2/primary_db                                                                                                                                                                                                                            |  26 kB     00:00     
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package mongo-10gen.i686 0:2.4.5-mongodb_1 will be obsoleted
---> Package mongodb-org.x86_64 0:3.2.4-1.el6 will be obsoleting
--> Processing Dependency: mongodb-org-tools = 3.2.4 for package: mongodb-org-3.2.4-1.el6.x86_64
--> Processing Dependency: mongodb-org-shell = 3.2.4 for package: mongodb-org-3.2.4-1.el6.x86_64
--> Processing Dependency: mongodb-org-server = 3.2.4 for package: mongodb-org-3.2.4-1.el6.x86_64
--> Processing Dependency: mongodb-org-mongos = 3.2.4 for package: mongodb-org-3.2.4-1.el6.x86_64
--> Running transaction check
---> Package mongo-10gen-server.i686 0:2.4.5-mongodb_1 will be obsoleted
---> Package mongodb-org-mongos.x86_64 0:3.2.4-1.el6 will be installed
---> Package mongodb-org-server.x86_64 0:3.2.4-1.el6 will be obsoleting
---> Package mongodb-org-shell.x86_64 0:3.2.4-1.el6 will be installed
---> Package mongodb-org-tools.x86_64 0:3.2.4-1.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=============================================================================================================================================================================================================================================================================
 Package                                                                Arch                                                       Version                                                         Repository                                                           Size
=============================================================================================================================================================================================================================================================================
Installing:
 mongodb-org                                                            x86_64                                                     3.2.4-1.el6                                                     mongodb-org-3.2                                                     5.8 k
     replacing  mongo-10gen.i686 2.4.5-mongodb_1
 mongodb-org-server                                                     x86_64                                                     3.2.4-1.el6                                                     mongodb-org-3.2                                                      13 M
     replacing  mongo-10gen-server.i686 2.4.5-mongodb_1
Installing for dependencies:
 mongodb-org-mongos                                                     x86_64                                                     3.2.4-1.el6                                                     mongodb-org-3.2                                                     5.6 M
 mongodb-org-shell                                                      x86_64                                                     3.2.4-1.el6                                                     mongodb-org-3.2                                                     6.9 M
 mongodb-org-tools                                                      x86_64                                                     3.2.4-1.el6                                                     mongodb-org-3.2                                                      37 M

Transaction Summary
=============================================================================================================================================================================================================================================================================
Install       5 Package(s)

Total download size: 63 M
Downloading Packages:
(1/5): mongodb-org-3.2.4-1.el6.x86_64.rpm                                                                                                                                                                                                             | 5.8 kB     00:00     
(2/5): mongodb-org-mongos-3.2.4-1.el6.x86_64.rpm                                                                                                                                                                                                      | 5.6 MB     00:00     
(3/5): mongodb-org-server-3.2.4-1.el6.x86_64.rpm                                                                                                                                                                                                      |  13 MB     00:01     
(4/5): mongodb-org-shell-3.2.4-1.el6.x86_64.rpm                                                                                                                                                                                                       | 6.9 MB     00:00     
(5/5): mongodb-org-tools-3.2.4-1.el6.x86_64.rpm                                                                                                                                                                                                       |  37 MB     00:03     
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                                                         11 MB/s |  63 MB     00:05     
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : mongodb-org-tools-3.2.4-1.el6.x86_64                                                                                                                                                                                                                      1/7 
  Installing : mongodb-org-server-3.2.4-1.el6.x86_64                                                                                                                                                                                                                     2/7 
  Installing : mongodb-org-mongos-3.2.4-1.el6.x86_64                                                                                                                                                                                                                     3/7 
  Installing : mongodb-org-shell-3.2.4-1.el6.x86_64                                                                                                                                                                                                                      4/7 
  Installing : mongodb-org-3.2.4-1.el6.x86_64                                                                                                                                                                                                                            5/7 
  Erasing    : mongo-10gen-server-2.4.5-mongodb_1.i686                                                                                                                                                                                                                   6/7 
warning: /var/log/mongo/mongod.log saved as /var/log/mongo/mongod.log.rpmsave
  Erasing    : mongo-10gen-2.4.5-mongodb_1.i686                                                                                                                                                                                                                          7/7 
  Verifying  : mongodb-org-shell-3.2.4-1.el6.x86_64                                                                                                                                                                                                                      1/7 
  Verifying  : mongodb-org-mongos-3.2.4-1.el6.x86_64                                                                                                                                                                                                                     2/7 
  Verifying  : mongodb-org-server-3.2.4-1.el6.x86_64                                                                                                                                                                                                                     3/7 
  Verifying  : mongodb-org-tools-3.2.4-1.el6.x86_64                                                                                                                                                                                                                      4/7 
  Verifying  : mongodb-org-3.2.4-1.el6.x86_64                                                                                                                                                                                                                            5/7 
  Verifying  : mongo-10gen-server-2.4.5-mongodb_1.i686                                                                                                                                                                                                                   6/7 
  Verifying  : mongo-10gen-2.4.5-mongodb_1.i686                                                                                                                                                                                                                          7/7 

Installed:
  mongodb-org.x86_64 0:3.2.4-1.el6                                                                                                  mongodb-org-server.x86_64 0:3.2.4-1.el6                                                                                                 

Dependency Installed:
  mongodb-org-mongos.x86_64 0:3.2.4-1.el6                                                   mongodb-org-shell.x86_64 0:3.2.4-1.el6                                                   mongodb-org-tools.x86_64 0:3.2.4-1.el6                                                  

Replaced:
  mongo-10gen.i686 0:2.4.5-mongodb_1                                                                                                mongo-10gen-server.i686 0:2.4.5-mongodb_1                                                                                               

Complete!

これでインストールは完了です。
続いて設定に移っていきましょう。

MongoDBが起動出来るようにSELinuxを設定する

SELinuxに対し、MongoDBを許容するように設定します。
今回は問題となっているダウン症状が再現するかどうかのテストが目的であり、面倒だったので、SELinuxを無効化します。

必要に応じて、許容か無効化かを選択してください。

SELinuxの設定ファイルを作成する
vi /etc/selinux/config
作成したファイル内に下記を書き込む
SELINUX=disabled
無効になっているかを確認

「getenforce」コマンドでDisabledになれば無効になっています。

[root@server ~]# getenforce 
Disabled

WiredTiger用の設定ファイルを記述する

MongoDBの新たなストレージエンジンである「WiredTiger」を利用するための設定を記述します。
設定はYAML形式で記述します。

設定ファイルを作成する。

ファイル名は何でもOKです。

 vi /etc/mongod_wt.conf
設定を記述する

DBパスやその他設定は適宜変更してください。
今回、メモリを2GB以上利用して死んでいたので、サイズ制限を1GBに設定しました。

storage:
 dbPath: "/var/lib/mongo_wt"
 engine: "wiredTiger"
 directoryPerDB: true
 wiredTiger:
 engineConfig:
 cacheSizeGB: 1
 directoryForIndexes: true
 statisticsLogDelaySecs: 0
 collectionConfig:
 blockCompressor: "snappy"
 indexConfig:
 prefixCompression: true
 journal:
 enabled: true
systemLog:
 destination: file
 path: "/var/log/mongodb/mongodb_wt.log"
 logAppend: true
processManagement:
 fork: true

参考http://qiita.com/kuwa_tw/items/0a5704e9e505cffeae34

MongoDBの起動・リストア

アンインストール、インストール、設定ファイルの記述と終われば、いよいよ起動です。

起動の前に設定ファイルで定義したデータ保存ディレクトリがなければ作っておきましょう。

mkdir /var/lib/mongo_wt

設定ファイルのパスを指定して起動する

毎回起動する際の設定がめんどうならば、

  1. 設定ファイルを「/etc/mongod.conf」に作成する
  2. 「/etc/init.d/mongod」の設定ファイルパスを書き換える

のどちらかでパス指定が不要になります。

[root@server ~]# mongod -f /etc/mongod_wt.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 32733
child process started successfully, parent exiting
[root@server ~]# service mongod status
mongod (pid 32733) is running...

バックアップしていたデータファイルをリストアする

無事起動したら、バックアップしていたデータをリストアしましょう。

[root@server ~]# mongorestore -v --db db1 ~/mongo_dump/db1/
2016-03-10T00:20:41.028+0900	using write concern: w='1', j=false, fsync=false, wtimeout=0
2016-03-10T00:20:41.028+0900	building a list of collections to restore from /root/mongo_dump/db1 dir

… 中略

2016-03-10T00:20:59.229+0900	finished restoring db1.items (65950 documents)
2016-03-10T00:20:59.229+0900	done

これで起動は完了です。
大きなトラブルもなく、v2系からv3系に更新出来てよかったよかった。

そんなに世の中甘くない

バージョンアップにトラブルはつきもの。

うまく行ったと思っていたが、MongoDBのデータを読み書きするPHPスクリプトにアクセスしたら…

_人人人人人人_
> 突然の死 <
 ̄Y^Y^Y^Y^Y ̄

えっ。真っ白だよ。

PHPからMongoDBにつながらない。

そう。PHPからMongoDBにつながらないのである。
原因を確認したところ、なんと現行で動かしていたドライバ「mongo」にエラーが発生した。

PeclでインストールしたドライバがMongo v2.6までしか対応していなかったのだ。

仕方ないので、mongodb1.1をインストールすることに。

peclでインストールしたドライバがダメなら新しいやつインストールしてみよう。
そう思い、mongodb1.1をインストールしてみる。

sudo pecl install mongodb
vi /etc/php.d/mongo.so

開いたファイルの内容を

extension=mongodb.so

に変更。

よしよし。問題なくPHPドライバ「mongodb」がインストールされたので、再度確認。

_人人人人人人人人人人人人人人人人人人人人人人人人_
> Fatal Error – Class ‘MongoClient’ not found <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

よくよく中身をみると、そもそものコネクションクラスから、データのやり取りまで何から何まで変わってた。← あたりまえである。

つまり・・・当然プログラム全部書き換え!!

そんなのはお断りです。

…ということで

PHPドライバについて調べる

を参照。

mongo1.6ならmongodb v3.0に対応してるっぽい。

peclのmongoのバージョン確認

[root@server ~]# pecl list
Installed packages, channel pecl.php.net:
=========================================
Package   Version State
jsonc     1.3.9   stable
memcache  2.2.7   stable
memcached 2.2.0   stable
mongo     1.6.12  stable
mongodb   1.1.3   stable
xdebug    2.3.3   stable
xhprof    0.9.4   beta
zip       1.13.1  stable

1.6だった。

ということで…。

再度DB側でv3.2をアンインストール→v3.0をインストール。

一度やった手続きなので慣れたもの。
サービスを停止し、MongoDBをアンインストールする。
やり方自体は公式ドキュメントに懇切丁寧に書いてあったので、それをなぞる。

sudo service mongod stop
sudo yum erase $(rpm -qa | grep mongodb-org)

v3.0をインストール

vi /etc/yum.repos.d/mongodb-org-3.0.repo

リポジトリを登録。
この時、以前登録した3.2のファイルは消しておきましょう。

[mongodb-org-3.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.0/x86_64/
gpgcheck=0
enabled=1

yumでインストール実行。

sudo yum install -y mongodb-org

設定ファイルを指定し、起動。バックアップからデータのリストアを実行。

[root@server plugins]# mongod -f /etc/mongod_wt.conf
[root@server plugins]# mongorestore -v --db db1 ~/mongo_dump/db1/
2016-03-10T01:16:24.897+0900 using write concern: w='1', j=false, fsync=false, wtimeout=0

… 中略

2016-03-10T01:16:33.330+0900 finished restoring db1.items (65950 documents)
2016-03-10T01:16:33.330+0900 done

元気に稼働し始めました。

よかったよかった。

番外編:Muninの監視から外れる

muninでメモリとか監視していたが、再インストール後監視から外れていたため、再登録を行う。
調べると、muninのmongodbプラグインはインストールされているが、稼働していない状態だった。

とりあえずMuninのプラグインを単体でテストしてみる。

[root@server plugins]# cd /etc/munin/plugins
[root@server plugins]# munin-run mongo_ops 
Traceback (most recent call last):
  File "/etc/munin/plugins/mongo_ops", line 56, in <module>
    doData()
  File "/etc/munin/plugins/mongo_ops", line 33, in doData
    ss = getServerStatus()
  File "/etc/munin/plugins/mongo_ops", line 28, in getServerStatus
    raw = urllib2.urlopen(req).read()
  File "/usr/lib64/python2.6/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib64/python2.6/urllib2.py", line 391, in open
    response = self._open(req, data)
  File "/usr/lib64/python2.6/urllib2.py", line 409, in _open
    '_open', req)
  File "/usr/lib64/python2.6/urllib2.py", line 369, in _call_chain
    result = func(*args)
  File "/usr/lib64/python2.6/urllib2.py", line 1190, in http_open
    return self.do_open(httplib.HTTPConnection, req)
  File "/usr/lib64/python2.6/urllib2.py", line 1165, in do_open
    raise URLError(err)
urllib2.URLError: <urlopen error [Errno 111] Connection refused>

エラーメッセージを読むと、RESTアクセス出来てないようだ。

調べたところ、セキュリティの関係上、MongoDBはデフォルトではRESTが無効になっているようだ。

設定ファイルに下記を加筆して、再度Mongoを起動

net:
   http:
      enabled: true
      JSONPEnabled: true
      RESTInterfaceEnabled: true

これでRESTを許可したので、Muninからもアクセスが行えるようになったはずである。

再度テスト

[root@server plugins]# munin-run mongo_ops 
getmore.value 0
insert.value 0
update.value 0
command.value 0
query.value 1
delete.value 0

いけた。

munin-nodeの再起動

[root@server plugins]# service munin-node restart
Stopping Munin Node agents:                                [  OK  ]
Starting Munin Node:                                       [  OK  ]

MuninのMongoDBのトラッキングも再設定できました。

あとがき

1ヶ月以上運用した結果、いまのところ以前のようなMondoDBダウンは1度も発生していません。
仮説の通り、単純にメモリ不足によるエラーだったものと思われます。

MongoDB自体アップグレードし、性能が上がり、メモリ利用量も少なくなっているので、結果オーライだと思います。

教訓: アップグレードは慎重に。でも大切なのでしっかりやろう。そして、事前の情報収集もしっかりと。

スポンサーリンク
スポンサーリンク




スポンサーリンク




シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
スポンサーリンク