2011. 9. 23. 17:48

[mongodb] Administration

mongodb를 관리하는 것은 간단하다.
backup에서 부터 multinode system 구축까지 다수의 관리 기능은 빠르며 단순하다.

* mongodb 시작/종료하기

명령줄로 부터 시작하기

mongodb는 mongod로 시작한다.
mongod --help를 통해 확인된다.
주로 사용되는 옵션을 다음과 같다.

--dbpath
; data directory를 지정한다. 보통 /data/db가 사용된다.
mongod process는 고유의 directory가 필요하다.
시작하면 mongod.lock 파일을 생성하여 다른 mongodb의 접근을 배제한다.

--port
; server에서 listen할 port를 지정한다. 디폴트로 27017이다.

--fork
; server process를 fork한다. daemon처럼 실행한다.

--logpath
; 로그 파일을 지정한다.

--config
; configuration 파일을 지정한다.

./mongod --port 5586 --fork --logpath mongodb.log

종료하기

SIGINT 혹은 SIGTERM signal을 전송한다.
만일 mongod의 PID가 1111이라면 kill -2 1111(SIGINT) 혹은 kill 1111(SIGTERM)한다.

혹은,
use admin
switched to db admin
db.shutdownServer();
server should be down...
과 같은 명령으로도 가능하다.

* 모니터하기

admin interface 사용

기본으로 mongod는 기본적인 http server를 listen한다.
http://localhost:28017을 통해 확인할 수 있다.

(혹시 관리페이지에서
REST is not enabled. use --rest...
와 같은 오류가 발생하면,
sudo gedit /etc/mongod.conf 해서
rest=true
를 추가하고,
sudo service mongodb restart
하면 된다.)

serverStatus

가장 기본적인 통계이다.

{ "host" : "ubuntu",
  "version" : "1.8.3",
  "process" : "mongod",
  "uptime" : 247,
  "uptimeEstimate" : 202,
  "localTime" : { "$date" : "Fri Sep 23 00:25:10 2011" },
  "globalLock" : { "totalTime" : 247596997,
    "lockTime" : 2867759,
    "ratio" : 0.01158236583943706,
    "currentQueue" : { "total" : 0,
      "readers" : 0,
      "writers" : 0 },
    "activeClients" : { "total" : 0,
      "readers" : 0,
      "writers" : 0 } },
  "mem" : { "bits" : 64,
    "resident" : 13,
    "virtual" : 3674,
    "supported" : true,
    "mapped" : 3600 },
  "connections" : { "current" : 0,
    "available" : 16000 },
  "extra_info" : { "note" : "fields vary by platform",
    "heap_usage_bytes" : 859376,
    "page_faults" : 196 },
  "indexCounters" : { "btree" : { "accesses" : 0,
      "hits" : 0,
      "misses" : 0,
      "resets" : 0,
      "missRatio" : 0 } },
  "backgroundFlushing" : { "flushes" : 4,
    "total_ms" : 1,
    "average_ms" : 0.25,
    "last_ms" : 0,
    "last_finished" : { "$date" : "Fri Sep 23 00:25:03 2011" } },
  "cursors" : { "totalOpen" : 0,
    "clientCursors_size" : 0,
    "timedOut" : 0 },
  "network" : { "bytesIn" : 0,
    "bytesOut" : 0,
    "numRequests" : 0 },
  "opcounters" : { "insert" : 0,
    "query" : 1,
    "update" : 0,
    "delete" : 0,
    "getmore" : 0,
    "command" : 0 },
  "asserts" : { "regular" : 0,
    "warning" : 0,
    "msg" : 0,
    "user" : 0,
    "rollovers" : 0 },
  "writeBacksQueued" : false }

globalLock은 server에서 write lock하는데 걸린 시간을 표기한다. (millisecond)

mem은 memory mapped된 가상 메모리 크기이다. (MB)

indexCounters는 disk를 읽어야 하는 B-Tree 검색 개수 정보 (miss)와
memory를 통한 검색 개수 정보(hits)

backgroundFlushing은 fsync가 수행되고 걸린 시간이다.
opcount는 중요한 값으로, 주요 operation의 count를 표시한다.
asserts는 server에서 발생한 assert의 개수이다.

mongostat

serverStatus와 비슷한 정보를 매초 출력한다.
/usr/bin/mongostat을 통해 실행한다.

* 보안과 인증

관리자에게 가장 우선순위가 높은 작업이 보안이다.
mongodb는 connection별 인증을 지원한다.

인증 기초

각각의 database는 user의 개수를 가지고 있다.
만일 security가 enable이라면, 인증된 user만이 read/write할 수 있다.
인증에서 mongodb는 db를 admin처럼 다룬다.
admin database의 user는 superuser로 간주된다. 인증 이후,
admin user는 어떤 database에서도 read/write 가능하며, listDatabases 혹은 shutdown
명령도 가능해 진다.

securty가 on되기 전, 최소 하나 이상의 다른 admin user를 추가해야 한다

use admin
switched to db admin
db.addUser("root","password")
{
 "user" : "root",
 "readOnly" : false,
 "pwd" : "d60e7db4538202339acd585fa951c5aa"
}
use dbauth
switched to db dbauth
db.addUser("test_user","1234");
{
 "user" : "test_user",
 "readOnly" : false,
 "pwd" : "5d6323b8d8cb698fb2a1f4a411209d6f"
}
db.addUser("test_user_read","5678",true);
{
 "user" : "test_user_read",
 "readOnly" : true,
 "pwd" : "e8c568df8e2e62cfc977e6dba5429e78"
}

이제 sudo gedit /etc/mongodb.conf에서
#auth = true

auth = true
로 변경하고 sudo service mongodb restart하자.
혹은 mongod --auth해도 된다.

그럼 다음과 같다.

use dbauth
switched to db dbauth
db.a.find()
error: {
 "$err" : "unauthorized db:dbauth lock type:-1 client:127.0.0.1",
 "code" : 10057
}
db.auth("test_user_read", "5677")
0
db.auth("test_user_read", "5678")
1
db.a.find()
db.a.insert({"a":1})
unauthorized
db.auth("test_user", "1234")
1
db.a.insert({"a":1})
db.a.find()
{ "_id" : ObjectId("4e7c3b02b663ec8d86596a43"), "a" : 1 }
show dbs
Fri Sep 23 00:54:07 uncaught exception: listDatabases failed:{
 "assertion" : "unauthorized db:admin lock type:-1 client:127.0.0.1",
 "assertionCode" : 10057,
 "errmsg" : "db assertion failure",
 "ok" : 0
}
use admin
switched to db admin
> db.a.find()
error: {
 "$err" : "unauthorized db:admin lock type:-1 client:127.0.0.1",
 "code" : 10057
}
> db.auth("root","password")
1
> show dbs
...


인증 방법

주어진 database의 user 정보는 system.users collection에 저장된다.
{"user":username, "readOnly":true, "pwd":password hash}와 같은 구조이다.

다음은 user를 삭제하는 과정이다.

db.auth("test_user","1234");
0
use dbauth
switched to db dbauth
db.auth("test_user","1234");
1
db.system.users.remove({"user":"test_user"});
db.auth("test_user","1234");
0

다른 보안 고려사항

인증시 mongodb protocol은 encrypt되지 않는다. 만약 필요하다면, SSH tuenneling 혹은
다른 encrypt 방식을 사용해야 한다.

보통 mongodb server는 firewall 혹은 network access 뒷편에 있어야 하는것을 추천한다.
만일 mongodb server가 other world와 access된다면 --bindip를 사용할 것을 추천한다.
그것은 bound될 local ip 주소를 지정하도록 만들어주기 때문이다.
예를 들어, 동일 machine에서만 접근 가능토록 하려면 mongod --bindip localhost와 같이 한다.

* Backup과 Repair

Data file backup

mongodb는 모든 data를 data directory에 저장한다.

mongodb가 실행중일때 data directory를 copy하는 것은 안전하지 않다.
mongodb를 shutdown한 뒤 작업한다.
비록 shutdown과 copy는 효과적이고 안전하지만, 이상적이진 않다.

mongodump와 mongorestore

mongodump utility를 통해 모든 mongodb 분산 시스템까지 backup할 수 있다.
mongodump는 실행중인 mongodb server에 대해 query 작업을 한다. 그리고
모든 document들을 disk에 저장한다.

/usr/bin$ mongodump --help
options:
  --help                   produce help message
  -v [ --verbose ]         be more verbose (include multiple times for more
                           verbosity e.g. -vvvvv)
  -h [ --host ] arg        mongo host to connect to ( <set name>/s1,s2 for
                           sets)
  --port arg               server port. Can also use --host hostname:port
  --ipv6                   enable IPv6 support (disabled by default)
  -u [ --username ] arg    username
  -p [ --password ] arg    password
  --dbpath arg             directly access mongod database files in the given
                           path, instead of connecting to a mongod  server -
                           needs to lock the data directory, so cannot be used
                           if a mongod is currently accessing the same path
  --directoryperdb         if dbpath specified, each db is in a separate
                           directory
  -d [ --db ] arg          database to use
  -c [ --collection ] arg  collection to use (some commands)
  -o [ --out ] arg (=dump) output directory or "-" for stdout
  -q [ --query ] arg       json query
  --oplog                  Use oplog for point-in-time snapshotting
  --repair                 try to recover a crashed database

~$ /usr/bin/mongodump -d test -o backup
connected to: 127.0.0.1
DATABASE: test  to  backup/test
 test.system.indexes to backup/test/system.indexes.bson
   4 objects
 test.fs.files to backup/test/fs.files.bson
   1 objects
 test.fs.chunks to backup/test/fs.chunks.bson
   1 objects

와 같이 백업할 수 있다.

그리고 이와 유사하게 mongorestore를 사용한다.

fsync와 lock

mongodump와 mongorestore는 shutdown없이 backup할 수 있도록 한다.
이는 저장할 싯점의 변경사항은 lose할 수 있다.
fsync는 동작중일때, data directory를 복사하는 것으로, 다른 충돌 위험이 없다.

fsync는 server에게 flush를 강제로 명령하여, 대기된 disk 쓰기 작업을 진행시킨다.
그리고, server가 lock이 풀릴때까지 database를 쓰는 것을 방지하도록 lock한다.

use admin
switched to db admin
db.runCommand({"fsync":1, "lock":1});
{
 "info" : "now locked against writes, use db.$cmd.sys.unlock.findOne() to unlock",
 "ok" : 1
}

이 싯점에서, data directory는 일관성이 있다. 왜냐하면 lock되었기 때문이다.
이때 우리는 안전하게 data directory를 복사할 수 있다.
복사가 종료되었다면, 다음과 같이 unlock한다.

db.$cmd.sys.unlock.findOne();                                                                 
{ "ok" : 1, "info" : "unlock requested" }
db.currentOp();
{ "inprog" : [ ] }

slave backup

slave server 백업은 위 방법으로 적용된다.

repair

재앙이 발생했다면, backup을 찾게된다.
그러나 불행이도 backup이 없는 경우도 있을 것이다.
여하튼, mongodb는 built-in repairing 기능이 있다.

repair는 unclean shutdown뒤에 실행해야 한다.
만일, 그러하다면, 다시 시작시에 아래와 같은 메시지를 받는다.

**************
old lock file: /data/db/mongod.lock. probably means unclean shutdown
recommend removing file and running --repair
see: http://dochub.mongodb.org/core/repair for more information
*************

이런 경우에 ---repair:mongod --repair를 사용한다.

단일 database를 repair하기 위해서는,
repairDatabase를 호출한다.

use test
switched to db test
db.repairDatabase()
{ "ok" : 1 }

'Research > mongodb' 카테고리의 다른 글

[mongodb] Sharding  (0) 2011.10.06
[mongodb] Replication  (0) 2011.09.28
[mongodb] Advanced topics  (0) 2011.09.23
[mongodb] Aggregation (MapReduce)  (0) 2011.09.22
[mongodb] Indexing  (0) 2011.09.22