848 lines
21 KiB
Markdown
848 lines
21 KiB
Markdown
---
|
|
title: Howto MongoDB
|
|
---
|
|
|
|
**CETTE DOCUMENTATION EST EN COURS DE RÉVISION....**
|
|
|
|
* Documentation (4.2) : <https://docs.mongodb.com/manual/>
|
|
* Référence de configuration (4.2) : <https://docs.mongodb.com/manual/reference/configuration-options/>
|
|
|
|
MongoDB est un système de base de données de type NoSQL, orienté dans la gestion de documents.
|
|
|
|
## Installation
|
|
|
|
### Debian Buster
|
|
|
|
A partir de Debian 10 (Buster), MongoDB n'est plus distribué dans les dépôts de Debian.
|
|
Il est néanmoins possible d'installé MongoDB 4.2 à partir des dépôts officiels du logiciel
|
|
|
|
> **Note**: MongoDB ne supporte Debian Buster que depuis sa version 4.2.1, pour utiliser une ancienne version de MongoDB, il est préférable d'utiliser une ancienne version de Debian comme Debian Stretch pour les versions 3.6 et 4.0
|
|
|
|
~~~
|
|
# echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/4.2 main" >> /etc/apt/sources.list.d/mongodb-org-4.2.list
|
|
# wget https://www.mongodb.org/static/pgp/server-4.2.asc -O /etc/apt/trusted.gpg.d/mongo-org-4.2.asc
|
|
# apt update && apt install mongodb-org
|
|
~~~
|
|
|
|
Tous les détails sont disponibles sur <https://docs.mongodb.com/manual/tutorial/install-mongodb-on-debian/>.
|
|
|
|
### Debian Stretch
|
|
|
|
Dans Debian Stretch, MongoDB 3.2 est distribué dans les dépôts Debian.
|
|
Il est aussi possible d'installer MongoDB 3.6+ à partir des des dépôts officiels du logiciel
|
|
|
|
> **Important**: Bien que les noms de paquets soient différents, les deux versions ne peuvent pas cohabiter ensemble sur un même système !
|
|
|
|
|
|
#### Version Debian (3.2)
|
|
|
|
~~~
|
|
# apt install mongodb
|
|
~~~
|
|
|
|
#### Version mongodb.org (3.6, 4.0 ou 4.2)
|
|
|
|
Les dépôts mongodb.org proposent les versions 3.6, 4.0 et 4.2 pour Debian Strech.
|
|
|
|
Exemple ici pour MongoDB 3.6
|
|
|
|
~~~
|
|
# echo "deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/3.6 main" >> /etc/apt/sources.list.d/mongodb-org-3.6.list
|
|
# wget https://www.mongodb.org/static/pgp/server-3.6.asc -O /etc/apt/trusted.gpg.d/mongo-org-3.6.asc
|
|
# apt update && apt install mongodb-org
|
|
~~~
|
|
|
|
Tous les détails sont disponibles sur <https://docs.mongodb.com/v3.6/tutorial/install-mongodb-on-debian/>.
|
|
|
|
|
|
## Logrotate
|
|
|
|
### Paquets mongodb.org 3.6+
|
|
|
|
Les paquets fournis par mongodb.org n'ont pas de logrotate !
|
|
On peut simplement ajouter cette configuration dans `/etc/logrotate.d/mongod`
|
|
|
|
~~~
|
|
/var/log/mongodb/mongod.log {
|
|
daily
|
|
missingok
|
|
rotate 365
|
|
dateext
|
|
compress
|
|
delaycompress
|
|
notifempty
|
|
sharedscripts
|
|
postrotate
|
|
kill -USR1 $(cat /var/lib/mongodb/mongod.lock)
|
|
endscript
|
|
}
|
|
~~~
|
|
|
|
Il faut aussi penser à modifier la configuration (`/etc/mongod.conf`) pour forcer le mode _reopen_ de la directive `logRotate` :
|
|
|
|
~~~
|
|
systemLog:
|
|
destination: file
|
|
logRotate: reopen
|
|
logAppend: true
|
|
path: /var/log/mongodb/mongod.log
|
|
~~~
|
|
|
|
Il y a tout un chapitre (pas toujours très clair) sur la maière de gérer la rotation de logs : <https://docs.mongodb.com/manual/reference/command/logRotate/>.
|
|
|
|
> **Note** : Attention, par défaut mongodb log les requêtes lentes de plus de 100ms. Ça peut générer beaucoup de logs… On pourra les modifier avec [slowOpThresholdMs](https://docs.mongodb.com/manual/reference/configuration-options/#operationProfiling.slowOpThresholdMs).
|
|
|
|
|
|
## Configuration
|
|
|
|
### 3.4
|
|
|
|
La configuration de MongoDB se trouve dans le fichier `/etc/mongod.conf` et le format a changé.
|
|
|
|
## Authentification
|
|
|
|
### 2.4
|
|
|
|
<https://docs.mongodb.com/v2.4/core/security-introduction/>
|
|
|
|
MongoDB a deux modes de fonctionnement pour l'authentification :
|
|
|
|
* Un mode sans aucune authentification
|
|
* Un mode avec authentification
|
|
|
|
Info : activer l'authentification génère des logs à chaque requête d'authentification qu'il n'est pas possible de désactiver avant la version 2.8 : voir <https://jira.mongodb.org/browse/SERVER-5952>
|
|
|
|
#### Mode sans aucune authentification
|
|
|
|
La configuration sans authentification se fait ainsi :
|
|
|
|
~~~
|
|
noauth = true
|
|
~~~
|
|
|
|
Dans ce mode, il n'y a besoin d'aucun login / mot de passe pour accéder à l'ensemble des dbs, données, etc.
|
|
Ce mode est donc assez dangereux : il faut s'assurer que seuls des programmes de confiance accèdent
|
|
au port TCP de MongoDB.
|
|
|
|
#### Mode avec authentification
|
|
|
|
ATTENTION, ce mode doit être correctement configuré (ce qui n'est pas le cas par défaut).
|
|
|
|
La configuration doit donc être ainsi :
|
|
|
|
~~~
|
|
auth = true
|
|
~~~
|
|
|
|
Mais surtout, il faut créer (au moins) un utilisateur "admin" :
|
|
|
|
~~~
|
|
$ mongo
|
|
> use admin
|
|
> db.addUser("mongoadmin", "PASS")
|
|
{
|
|
"user" : "mongoadmin",
|
|
"readOnly" : false,
|
|
"pwd" : "3882eaa67064707a7a6ae872504f310d"
|
|
}
|
|
> db.system.users.find()
|
|
{ "_id" : ObjectId("4e8e132c76a7c48c75393b81"), "user" : "mongoadmin", "readOnly" : false, "pwd" : "3882eaa67064707a7a6ae872504f310d" }
|
|
~~~
|
|
|
|
C'est seulement une fois ce premier utilisateur "admin" créé que l'authentication est activée !!
|
|
Si il n'est pas créé, l'authentification reste inactive...
|
|
|
|
On peut ensuite se connecter à la base "admin" ainsi :
|
|
|
|
~~~
|
|
$ mongo admin -u mongoadmin -p PASS
|
|
~~~
|
|
|
|
Pour les accès aux base, les utilisateurs sont stockés dans la collection _system.users_ propre à chaque base.
|
|
Ainsi pour créer un utilisateur pour une base données :
|
|
|
|
~~~
|
|
> use mydb
|
|
> db.addUser("foo","PASS");
|
|
~~~
|
|
|
|
Les utilisateurs (admin ou associés à une base de données) peuvent n'avoir qu'un accès read-only si
|
|
ils sont créés ainsi :
|
|
|
|
~~~
|
|
> db.addUser("foo","PASS",true);
|
|
~~~
|
|
|
|
Enfin, pour supprimer un utilisateur :
|
|
|
|
~~~
|
|
> use mydb
|
|
> db.removeUser("foo");
|
|
~~~
|
|
|
|
### 3.4
|
|
|
|
<https://docs.mongodb.com/manual/security/>
|
|
|
|
## Utilisation
|
|
|
|
En ligne de commande :
|
|
|
|
~~~
|
|
$ mongo
|
|
MongoDB shell version: 1.4.4
|
|
url: test
|
|
connecting to: test
|
|
type "help" for help
|
|
~~~
|
|
|
|
Voici les opérations de base :
|
|
|
|
~~~
|
|
> show dbs
|
|
admin
|
|
local
|
|
test
|
|
> use foo
|
|
switched to db foo
|
|
> show collections
|
|
> db.bar.find()
|
|
> db.bar.save( { a : 1 } )
|
|
> db.bar.save( { a : 2 } )
|
|
> show collections
|
|
bar
|
|
system.indexes
|
|
> db.bar.find()
|
|
{ "_id" : ObjectId("4e64dbf619a27977131978ad"), "a" : 1 }
|
|
{ "_id" : ObjectId("4e64dbf919a27977131978ae"), "a" : 2 }
|
|
> db.foo.find({a:1})
|
|
{ "_id" : ObjectId("4e0674a47888d8941034f4e1"), "a" : 1 }
|
|
> db.foo.find().limit(1)
|
|
{ "_id" : ObjectId("4e0674a47888d8941034f4e1"), "a" : 1 }
|
|
> exit
|
|
bye
|
|
~~~
|
|
|
|
Quelques commandes utiles :
|
|
|
|
Voir le compteur des connexions :
|
|
|
|
~~~
|
|
db.serverStatus().connections
|
|
~~~
|
|
|
|
Modifier un champ d'un objet existant :
|
|
|
|
~~~
|
|
> db.bar.save( { a : 4, b : 0 } )
|
|
> db.bar.update( { "_id" : ObjectId("4e64de8a19a27977131978b0") } , { $set : {b:1} } )
|
|
> db.bar.update( { "_id" : ObjectId("4e64de8a19a27977131978b0") } , { $unset : {b:1} } )
|
|
~~~
|
|
|
|
Voir uniquement certains champs :
|
|
|
|
~~~
|
|
> db.bar.find({a:1},{flip:1})
|
|
> db.bar.find({a:1},{flip:1,flap:1})
|
|
~~~
|
|
|
|
Voir plus d'objets (en évitant le _has more_) :
|
|
|
|
~~~
|
|
> DBQuery.shellBatchSize = 100
|
|
> db.foo.find()
|
|
~~~
|
|
|
|
Requête sur des dates :
|
|
|
|
~~~
|
|
db.foo.find( { "date": {"$gte": ISODate("2011-12-05T00:21:00Z")} } )
|
|
db.foo.find( { "date": {"$lt": ISODate("2011-12-05T04:00:00Z")} } )
|
|
db.foo.find( { "date": {"$gte": ISODate("2011-12-05T00:21:00Z"), "$lt": ISODate("2011-12-05T04:00:00Z")} } )
|
|
~~~
|
|
|
|
En PHP :
|
|
|
|
~~~
|
|
$m = new Mongo();
|
|
$db = $m->foo;
|
|
$bar = $db->bar;
|
|
$bar->insert(array("a"=>"1","a"=>"2"));
|
|
$res = $bar->find();
|
|
foreach ($res as $obj) {
|
|
echo $obj["a"] . "\n";
|
|
}
|
|
~~~
|
|
|
|
## Sauvegarde
|
|
|
|
### 2.4
|
|
|
|
<https://docs.mongodb.com/v2.4/core/backups/>
|
|
|
|
~~~
|
|
# mkdir /home/backup/mongodump
|
|
# cd /home/backup/mongodump
|
|
# mongodump
|
|
~~~
|
|
|
|
### 3.4
|
|
|
|
Il exise plus de possibilités de sauvegarde dans les versions récentes :
|
|
<https://docs.mongodb.com/manual/core/backups/>
|
|
|
|
## Restauration
|
|
|
|
~~~
|
|
cd /home/backup/mongodump/
|
|
# mongorestore --db dbname dbname
|
|
mongorestore --db admin admin
|
|
~~~
|
|
|
|
## Réplication avec replica set
|
|
|
|
La réplication avec "replica set" nécessite au moins 3 machines : en effet, il va y avoir une élection
|
|
du master vers lequel seront faites toutes les écritures.
|
|
|
|
### En Version 3.2+
|
|
|
|
Si vos mongod ne sont pas sur un LAN il est recommandé de mettre en place du TLS avec <https://docs.mongodb.com/manual/tutorial/configure-x509-member-authentication/.>
|
|
Sinon on pourra utiliser un keyfile <https://docs.mongodb.com/manual/tutorial/deploy-replica-set-with-keyfile-access-control/>
|
|
|
|
*/!\ Le datadir doit être vierge.*
|
|
|
|
#### Avec keyfile
|
|
|
|
Créer le keyfile sur une machine et déployer sur les autres le même fichier.
|
|
|
|
~~~
|
|
# openssl rand -base64 755 > /etc/mongod.key
|
|
# chmod 400 /etc/mongod.key
|
|
# chown mongodb: /etc/mongod.key
|
|
~~~
|
|
|
|
Modifier la configuration :
|
|
|
|
~~~
|
|
security:
|
|
keyFile: /etc/mongod.key
|
|
replication:
|
|
replSetName: rs0
|
|
~~~
|
|
|
|
Redémarrer les mongod.
|
|
|
|
~~~
|
|
# systemctl restart mongod
|
|
~~~
|
|
|
|
Se connecter et initialiser le RS.
|
|
|
|
|
|
~~~
|
|
# mongo
|
|
> rs.initiate(
|
|
{
|
|
_id : "rs0",
|
|
members: [
|
|
{ _id : 0, host : "mongo1.example.net:27017" },
|
|
{ _id : 1, host : "mongo2.example.net:27017" },
|
|
{ _id : 2, host : "mongo3.example.net:27017" }
|
|
]
|
|
}
|
|
)
|
|
~~~
|
|
|
|
Se connecter au master (voir avec rs.Status()) et créer un utilisateur admin et clusterAdmin.
|
|
|
|
~~~
|
|
# mongo
|
|
> use admin
|
|
use admin
|
|
db.createUser(
|
|
{
|
|
user: "myUserAdmin",
|
|
pwd: "abc123",
|
|
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
|
|
}
|
|
)
|
|
db.createUser(
|
|
{
|
|
"user" : "clusteradmin",
|
|
"pwd" : "abc123",
|
|
roles: [ { "role" : "clusterAdmin", "db" : "admin" } ]
|
|
}
|
|
)
|
|
~~~
|
|
|
|
Le Replica Set est maintenant en place.
|
|
|
|
#### Avec X.509
|
|
|
|
TODO
|
|
|
|
### En version 1.8
|
|
|
|
Soit trois machines de test avec MongoDB 1.8.2 : mongo1 (PRIMARY), mongo2 (SECONDARY), mongo3 (SECONDARY)
|
|
|
|
Activer le paramètre suivant dans /etc/mongodb.conf :
|
|
|
|
~~~
|
|
# in replica set configuration, specify the name of the replica set
|
|
replSet = foo
|
|
# Enable journaling (recommended for replica set)
|
|
journal = true
|
|
~~~
|
|
|
|
À ce stade, on ne peut rien écrire sur les serveurs :
|
|
|
|
~~~
|
|
> db.test.insert({"coin": "coin"})
|
|
not master
|
|
> rs.status()
|
|
{
|
|
"startupStatus" : 3,
|
|
"info" : "run rs.initiate(...) if not yet done for the set",
|
|
"errmsg" : "can't get local.system.replset config from self or any seed (EMPTYCONFIG)",
|
|
"ok" : 0
|
|
}
|
|
~~~
|
|
|
|
|
|
Réinitialiser les bases sur chaque machine (attention, opération destructrice !) :
|
|
|
|
~~~
|
|
/etc/init.d/mongodb stop && mv /var/lib/mongodb/* /tmp && /etc/init.d/mongodb start
|
|
~~~
|
|
|
|
### Sur mongo1 (PRIMARY)
|
|
|
|
Il faut ensuite s'assurer que :
|
|
- les machines communiquent bien au niveau réseau en TCP/27017
|
|
- que les machines n'ont pas de NAT (ou alors il faudra utiliser des DNS)
|
|
|
|
Puis on initialise la réplication via le mongo shell :
|
|
|
|
~~~
|
|
> config = {_id: 'foo' , members: [ {_id: 0, host: '1.2.3.4:27017'},{_id: 1, host: '1.2.3.5:27017'},{_id: 2, host: '1.2.3.6:27017'}]}
|
|
> rs.initiate(config);
|
|
{
|
|
"info" : "Config now saved locally. Should come online in about a minute.",
|
|
"ok" : 1
|
|
}
|
|
> rs.help()
|
|
~~~
|
|
|
|
On peut aussi le faire étape par étape
|
|
|
|
~~~
|
|
> rs.initiate()
|
|
{
|
|
"info2" : "no configuration explicitly specified -- making one",
|
|
"info" : "Config now saved locally. Should come online in about a minute.",
|
|
"ok" : 1
|
|
}
|
|
~~~
|
|
|
|
Ajout des 2 SECONDARY :
|
|
|
|
~~~
|
|
setname:PRIMARY> rs.add("mongo2")
|
|
{ "ok" : 1 }
|
|
|
|
setname:PRIMARY> rs.add("mongo3")
|
|
{ "ok" : 1 }
|
|
~~~
|
|
|
|
Consultation de l'état de la réplication sur le master :
|
|
|
|
~~~
|
|
setname:PRIMARY> rs.status()
|
|
{
|
|
"set" : "setname",
|
|
"date" : ISODate("2011-08-09T15:42:54Z"),
|
|
"myState" : 1,
|
|
"members" : [
|
|
{
|
|
"_id" : 0,
|
|
"name" : "mongo1",
|
|
"health" : 1,
|
|
"state" : 1,
|
|
"stateStr" : "PRIMARY",
|
|
"optime" : {
|
|
"t" : 1312904495000,
|
|
"i" : 1
|
|
},
|
|
"optimeDate" : ISODate("2011-08-09T15:41:35Z"),
|
|
"self" : true
|
|
},
|
|
{
|
|
"_id" : 1,
|
|
"name" : "mongo2",
|
|
"health" : 1,
|
|
"state" : 2,
|
|
"stateStr" : "SECONDARY",
|
|
"uptime" : 76,
|
|
"optime" : {
|
|
"t" : 1312904495000,
|
|
"i" : 1
|
|
},
|
|
"optimeDate" : ISODate("2011-08-09T15:41:35Z"),
|
|
"lastHeartbeat" : ISODate("2011-08-09T15:42:54Z")
|
|
},
|
|
{
|
|
"_id" : 2,
|
|
"name" : "mongo3",
|
|
"health" : 1,
|
|
"state" : 2,
|
|
"stateStr" : "SECONDARY",
|
|
"uptime" : 70,
|
|
"optime" : {
|
|
"t" : 1312904495000,
|
|
"i" : 1
|
|
},
|
|
"optimeDate" : ISODate("2011-08-09T15:41:35Z"),
|
|
"lastHeartbeat" : ISODate("2011-08-09T15:42:54Z")
|
|
}
|
|
],
|
|
"ok" : 1
|
|
}
|
|
~~~
|
|
|
|
Sur un slave :
|
|
|
|
~~~
|
|
SECONDARY> db.printReplicationInfo()
|
|
this is a slave, printing slave replication info.
|
|
source: 92.243.5.219:27017
|
|
syncedTo: Sun Jan 29 2012 22:34:07 GMT+0100 (CET)
|
|
= 5744 secs ago (1.6hrs)
|
|
source: stampzz-prod01.evolix.net:27017
|
|
syncedTo: Mon Jan 30 2012 00:09:47 GMT+0100 (CET)
|
|
= 4 secs ago (0hrs)
|
|
SECONDARY> use local
|
|
switched to db local
|
|
SECONDARY> db.oplog.rs.stats()
|
|
{
|
|
"ns" : "local.oplog.rs",
|
|
"count" : 9616448,
|
|
"size" : 1166277368,
|
|
"avgObjSize" : 121.27943373686418,
|
|
"storageSize" : 1320140800,
|
|
"numExtents" : 1,
|
|
"nindexes" : 0,
|
|
"lastExtentSize" : 1320140800,
|
|
"paddingFactor" : 1,
|
|
"flags" : 0,
|
|
"totalIndexSize" : 0,
|
|
"indexSizes" : {
|
|
|
|
},
|
|
"capped" : 1,
|
|
"max" : 2147483647,
|
|
"ok" : 1
|
|
}
|
|
~~~
|
|
|
|
Création d'un enregistrement de test :
|
|
|
|
~~~
|
|
setname:PRIMARY> db.foo.save({a:1})
|
|
setname:PRIMARY>
|
|
~~~
|
|
|
|
### Sur mongo2 ou mongo3 (SECONDARY)
|
|
|
|
Autorise le SECONDARY à traiter des requêtes :
|
|
|
|
~~~
|
|
setname:SECONDARY> rs.slaveOk()
|
|
~~~
|
|
|
|
Vérification de la présence de l'enregistrement de test :
|
|
|
|
~~~
|
|
setname:SECONDARY> db.foo.find()
|
|
{ "_id" : ObjectId("4e41558da08ccc36090745be"), "a" : 1 }
|
|
~~~
|
|
|
|
### Sortir un mongo de la réplication
|
|
|
|
Voici les étapes pour sortir un mongo de la réplication :
|
|
|
|
1. Sauvegarder (mongodump)
|
|
1. Stopper MongoDB
|
|
1. Sauvegarder les datas
|
|
1. Supprimer les fichiers local.*
|
|
1. Désactiver les replica dans la configuration
|
|
1. Relancer MongoDB
|
|
|
|
### Resynchroniser un mongo slave
|
|
|
|
En cas de soucis, il peut être nécessaire de resynchroniser complètement un serveur MongoDB
|
|
par rapport à un master. Il suffit de supprimer complètement le _dbpath_ :
|
|
|
|
~~~
|
|
# /etc/init.d/monogdb stop
|
|
# mv /var/lib/mongodb /var/lib/mongodb.old
|
|
# mkdir /var/lib/mongodb
|
|
# chown mongodb:mongodb /var/lib/mongodb
|
|
# chmod 750 /var/lib/mongodb
|
|
# /etc/init.d/monogdb start
|
|
~~~
|
|
|
|
Le serveur slave repassera en RECOVERING puis en SECONDARY :
|
|
|
|
~~~
|
|
RECOVERING> db.printReplicationInfo()
|
|
this is a slave, printing slave replication info.
|
|
source: master.example.com:27017
|
|
syncedTo: Thu Jan 01 1970 01:00:00 GMT+0100 (CET)
|
|
= 1327878874 secs ago (368855.24hrs)
|
|
source: otherslave.example.com:27017
|
|
syncedTo: Mon Jan 30 2012 00:14:09 GMT+0100 (CET)
|
|
= 25 secs ago (0.01hrs)
|
|
SECONDARY> db.printReplicationInfo()
|
|
configured oplog size: 1025.1384765625MB
|
|
log length start to end: 741secs (0.21hrs)
|
|
oplog first event time: Mon Jan 30 2012 00:14:09 GMT+0100 (CET)
|
|
oplog last event time: Mon Jan 30 2012 00:26:30 GMT+0100 (CET)
|
|
now: Mon Jan 30 2012 00:27:26 GMT+0100 (CET)
|
|
~~~
|
|
|
|
### Erreurs de synchronisation
|
|
|
|
En cas d'erreur du type :
|
|
|
|
~~~
|
|
"optimeDate" : ISODate("2012-01-29T21:34:07Z"),
|
|
"lastHeartbeat" : ISODate("2012-01-29T23:02:43Z"),
|
|
"pingMs" : 11,
|
|
"errmsg" : "syncTail: 0 assertion db/pdfile.cpp:1881, syncing: { ts: Timestamp 1327872847000|109, h: -1582883220170752094, op: \"i\", ns: \"DB_MONGODB.tmp.mr.COLL_MONGODB_396779\", o: { _id: \"#colorsplash\", value: 1.0 } }"
|
|
~~~
|
|
|
|
Côté slave, on a plus de détails :
|
|
|
|
~~~
|
|
[rsSync] replHandshake res not: 1 res: { ok: 1.0 }
|
|
[rsSync] local.oplog.rs Assertion failure !loc.isNull() db/pdfile.cpp 1881
|
|
0x57eeb6 0x589d6b 0x8a2746 0x82f486 0x821d8d 0x8231d8 0x82439a 0x824820 0xaa4560 0x7f1a33ef08ba 0x7f1a334ac02d
|
|
/usr/bin/mongod(_ZN5mongo12sayDbContextEPKc+0x96) [0x57eeb6]
|
|
/usr/bin/mongod(_ZN5mongo8assertedEPKcS1_j+0xfb) [0x589d6b]
|
|
/usr/bin/mongod() [0x8a2746]
|
|
/usr/bin/mongod(_ZN5mongo11_logOpObjRSERKNS_7BSONObjE+0x236) [0x82f486]
|
|
/usr/bin/mongod(_ZN5mongo11ReplSetImpl8syncTailEv+0xced) [0x821d8d]
|
|
/usr/bin/mongod(_ZN5mongo11ReplSetImpl11_syncThreadEv+0xc8) [0x8231d8]
|
|
/usr/bin/mongod(_ZN5mongo11ReplSetImpl10syncThreadEv+0x4a) [0x82439a]
|
|
/usr/bin/mongod(_ZN5mongo15startSyncThreadEv+0xa0) [0x824820]
|
|
/usr/bin/mongod(thread_proxy+0x80) [0xaa4560]
|
|
/lib/libpthread.so.0(+0x68ba) [0x7f1a33ef08ba]
|
|
/lib/libc.so.6(clone+0x6d) [0x7f1a334ac02d]
|
|
[rsSync] replSet syncTail: 0 assertion db/pdfile.cpp:1881, syncing: { ts: Timestamp 1327872847000|109, h: -1582883220170752094, op: "i", ns: "DB_MONGODB.tmp.mr.COLL_MONGODB_396779", o: { _id: "#colorsplash", value: 1.0 } }
|
|
~~~
|
|
|
|
Cela semble être une corruption de la base côté slave...
|
|
L'une des solutions consiste à resynchroniser complètement la base
|
|
(voir plus haut).
|
|
|
|
|
|
### Forcer à changer de master
|
|
|
|
~~~
|
|
> rs.stepDown()
|
|
~~~
|
|
|
|
/!\ à ne faire que si les slaves sont synchros sous peine
|
|
d'avoir un état rollback & ennuis...
|
|
|
|
### Etat ROLLBACK
|
|
|
|
Master devient indispo alors que les slaves n'était pas 100% synchro
|
|
|
|
<http://www.mongodb.org/display/DOCS/Replica+Sets+-+Rollbacks>
|
|
<http://dba.stackexchange.com/questions/18020/mongodb-replica-set-secondary-stuck-in-rollback-state>
|
|
<http://comerford.cc/2012/05/28/simulating-rollback-on-mongodb/>
|
|
<http://comments.gmane.org/gmane.comp.db.mongodb.user/78137>
|
|
|
|
ROLLBACK -> RECOVERY -> SECONDARY.. ou #FAIL avec Error RS102
|
|
|
|
<http://www.mongodb.org/display/DOCS/Resyncing+a+Very+Stale+Replica+Set+Member>
|
|
|
|
### replicaset lag
|
|
|
|
<http://docs.mongodb.org/manual/administration/replica-sets/#replica-set-replication-lag>
|
|
<http://metabroadcast.com/blog/mongodb-replication-lag-and-the-road-to-recovery>
|
|
|
|
|
|
## Réparer la base de données en cas de crash
|
|
|
|
Plusieurs méthodes selon cas.
|
|
|
|
1. Si la journalisation est activé, ce qui est le cas par défaut pour les version >1.9.2 et en 64 bits.
|
|
MongoDB devrait automatiquement se servir des fichiers journaux, regardez si tout se passe bien dans les logs.
|
|
Si malheureusement ce message apparaît :
|
|
|
|
~~~
|
|
old lock file: mongod.lock. probably means unclean shutdown,
|
|
but there are no journal files to recover.
|
|
~~~
|
|
|
|
Il faut vérifier que le système de fichier est OK !
|
|
|
|
1. Si la journalisation n'est pas activé.
|
|
|
|
Supprimez le verrou et démarrer mongodb avec l'option pour lancer une réparation.
|
|
|
|
~~~
|
|
rm /var/lib/mongodb/mongod.lock
|
|
mongod --dbpath /var/lib/mongodb/ --repairpath /tmp --repair
|
|
~~~
|
|
|
|
Vérifiez les droits du dbpath !
|
|
|
|
~~~
|
|
chown -R mongodb:mongodb /var/lib/mongodb
|
|
~~~
|
|
|
|
Démarrez mongodb, lancez un mongo shell et lancer une réparation de toutes les base de données.
|
|
|
|
~~~
|
|
db.repairDatabase();
|
|
~~~
|
|
|
|
## Mise à jour
|
|
|
|
### 1.8 vers 2.0
|
|
|
|
Voici la procédure pour passer en Mongo 2.0 (version sortie en sept/oct 2011) :
|
|
|
|
~~~
|
|
# aptitude update
|
|
# aptitude install mongodb-10gen
|
|
~~~
|
|
|
|
La version 2.0 active désormais par défaut la journalisation.
|
|
Vous pouvez donc remplacer dans votre configuration :
|
|
|
|
~~~
|
|
journal = true
|
|
~~~
|
|
|
|
par :
|
|
|
|
~~~
|
|
# Disables write-ahead journaling
|
|
# nojournal = true
|
|
~~~
|
|
|
|
Il faut également mettre-à-jour ses indexes ! On le fera via le mongo shell :
|
|
|
|
~~~
|
|
> use foo
|
|
> db.bar.getIndexes()
|
|
[
|
|
{
|
|
"key" : {
|
|
"_id" : 1
|
|
},
|
|
"ns" : "foo.bar",
|
|
"name" : "_id_",
|
|
"v" : 0
|
|
}
|
|
]
|
|
~~~
|
|
|
|
Le * "v" : 0 * signifie que l'index n'est pas à jour.
|
|
|
|
~~~
|
|
> db.runCommand({compact : 'bar'})
|
|
{ "ok" : 1 }
|
|
> db.bar.getIndexes()
|
|
[
|
|
{
|
|
"v" : 1,
|
|
"key" : {
|
|
"_id" : 1
|
|
},
|
|
"ns" : "foo.bar",
|
|
"name" : "_id_"
|
|
}
|
|
]
|
|
~~~
|
|
|
|
Répéter l'opération pour toutes les collections ayant des indexes !
|
|
|
|
|
|
## CAPPED
|
|
|
|
<http://www.mongodb.org/display/DOCS/Capped+Collections>
|
|
|
|
## Monitoring avec MMS
|
|
|
|
MMS (MongoDB Monitoring Service) est une service fourni gratuitement par 10gen.
|
|
*Déprécié, maintenant c'est payant et ça s'apelle MongoDB Cloud Manager*
|
|
|
|
### Installation
|
|
|
|
Créer un compte sur mms.10gen.com, créer un groupe et télécharger l'archive (qui contient déjà la clé API du groupe).
|
|
|
|
La décompresser dans un dossier (et donner les droits mongodb).
|
|
|
|
~~~
|
|
cd /opt
|
|
tar zxvf 10gen*.tar.gz
|
|
chown -R mongodb:mongodb mms-agent
|
|
~~~
|
|
|
|
Installer python-bson et python-pymongo (via backports).
|
|
|
|
/etc/apt/preferences:
|
|
|
|
~~~
|
|
Package: python-pymongo
|
|
Pin: release a=squeeze-backports
|
|
Pin-Priority: 999
|
|
~~~
|
|
|
|
Le lancer via le compte mongodb:
|
|
|
|
sudo -u mongodb nohup python /opt/mms-agent/agent.py > /var/log/mongodb/agent.log 2>&1 &
|
|
|
|
|
|
## Monitoring avec Munin
|
|
|
|
### Créer un accès
|
|
|
|
~~~
|
|
use admin
|
|
db.createUser(
|
|
{
|
|
user: "monitoring",
|
|
pwd: "XXX",
|
|
roles: [ "clusterMonitor" ]
|
|
}
|
|
)
|
|
~~~
|
|
|
|
### Plugin mongo-munin
|
|
|
|
<https://github.com/comerford/mongo-munin>
|
|
|
|
|
|
~~~
|
|
# git clone <https://github.com/comerford/mongo-munin.git> /tmp/mongo-munin
|
|
# mkdir -p /usr/local/share/munin/plugins
|
|
# cp /tmp/mongo-munin/mongo_* /usr/local/share/munin/plugins
|
|
# cd /etc/munin/plugins/
|
|
# ln -s /usr/local/share/munin/plugins/mongo_*
|
|
# chmod -R u=rwX,g=rwX,o=rX /usr/local/share/munin/
|
|
~~~
|
|
|
|
/etc/munin/plugin-conf.d/mongo
|
|
|
|
|
|
~~~
|
|
[mongo_*]
|
|
env.MONGO_DB_URI mongodb://monitoring:XXX@localhost:27017/admin
|
|
~~~
|