wiki/HowtoMongoDB.md

778 lines
22 KiB
Markdown
Raw Normal View History

2017-04-14 14:34:12 +02:00
---
title: Howto MongoDB
2020-05-06 12:18:51 +02:00
categories: databases nosql
2017-04-14 14:34:12 +02:00
---
2016-12-29 11:25:39 +01:00
**CETTE DOCUMENTATION EST EN COURS DE RÉVISION....**
2016-12-29 11:25:39 +01:00
* 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.
2016-12-29 11:25:39 +01:00
## 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
2016-12-29 11:25:39 +01:00
~~~
# 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/mongodb-server-4.2.asc
# apt update && apt install mongodb-org
2016-12-29 11:25:39 +01:00
~~~
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 !
2016-12-29 11:25:39 +01:00
#### Version Debian (3.2)
2016-12-29 11:25:39 +01:00
~~~
# apt install mongodb
2016-12-29 11:25:39 +01:00
~~~
#### 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
2016-12-29 11:25:39 +01:00
~~~
# 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/mongodb-server-3.6.asc
# apt update && apt install mongodb-org
2016-12-29 11:25:39 +01:00
~~~
Tous les détails sont disponibles sur <https://docs.mongodb.com/v3.6/tutorial/install-mongodb-on-debian/>.
2016-12-29 11:25:39 +01:00
## Logrotate
2016-12-29 11:25:39 +01:00
### Paquets mongodb.org 3.6+
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
Les paquets fournis par mongodb.org n'ont pas de configuration pour logrotate !
On peut simplement ajouter cette configuration dans `/etc/logrotate.d/mongod`
2016-12-29 11:25:39 +01:00
~~~
/var/log/mongodb/mongod.log {
daily
missingok
rotate 365
dateext
compress
delaycompress
notifempty
sharedscripts
postrotate
kill -USR1 $(cat /var/lib/mongodb/mongod.lock)
endscript
}
2016-12-29 11:25:39 +01:00
~~~
Il faut aussi penser à modifier la configuration (`/etc/mongod.conf`) pour forcer le mode _reopen_ de la directive `logRotate` :
2016-12-29 11:25:39 +01:00
~~~
systemLog:
destination: file
logRotate: reopen
logAppend: true
path: /var/log/mongodb/mongod.log
2016-12-29 11:25:39 +01:00
~~~
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/>.
2016-12-29 11:25:39 +01:00
2017-08-01 15:40:29 +02:00
> **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).
2016-12-29 11:25:39 +01:00
## Configuration
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
La configuration de MongoDB se trouve dans le fichier `/etc/mongod.conf` qui est un fichier format au yaml.
Il n'y a pas d'autres fichiers de configuration
2016-12-29 11:25:39 +01:00
## Authentification
2020-05-06 12:17:30 +02:00
<https://docs.mongodb.com/manual/core/authentication/>
2016-12-29 11:25:39 +01:00
MongoDB a deux modes de fonctionnement pour l'authentification :
* Un mode sans aucune authentification
* Un mode avec authentification
2020-05-06 12:17:30 +02:00
### Mode sans aucune authentification
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
Il s'agit du mode par défaut.
2016-12-29 11:25:39 +01:00
La configuration sans authentification se fait ainsi :
~~~
2020-05-06 12:17:30 +02:00
security:
authorization: disabled
2016-12-29 11:25:39 +01:00
~~~
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
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
L'authentification avec MongoDB peut paraître surprenante à première vue. En effet chaque utilisateur est associée à une base pour l'authentification. Mais les privilèges de l'utilisateur peuvent aller au-delà de la base de données qui sert à l'authentification.
Aussi, un utilisateur, pour s'authentifier, a besoin de son login, de son mot de passe **et** du nom de sa base d'authentification.
> **Note** : Il peut donc y avoir plusieurs utilisateurs *foo* avec des privilèges différent. Ce qui les distinguera sera la base d'authentification
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
Par convention, on définiera donc un utilisateur d'administration (*mongoAdmin*) dans la base `admin`
Pour activer l'authenfication dans les réglages du service MongoDB, il faut alors passer la directive `authorization` à enabled, dans
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
security:
authorization: enabled
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
Il n'est pas forcément nécessaire de créer un compte avec un rôle administrateur avant d'activer l'authentification.
En effet, en l'absence de comptes utilisateurs, mongodb va accepter les connexions *locales* sans authentification pour permettre notamment de créer un compte.
2016-12-29 11:25:39 +01:00
~~~
$ mongo
> use admin
2020-05-06 12:17:30 +02:00
> db.createUser(
{
user: "mongoAdmin",
2021-05-02 23:56:24 +02:00
pwd: "PASSWORD",
2020-05-06 12:17:30 +02:00
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
Successfully added user: {
"user" : "mongoAdmin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
2016-12-29 11:25:39 +01:00
}
2020-05-06 12:17:30 +02:00
2016-12-29 11:25:39 +01:00
> db.system.users.find()
2020-05-06 12:17:30 +02:00
{ "_id" : "admin.mongoAdmin", "userId" : UUID("3d475ec9-b82c-4312-8ce6-399bcbe3ca7a"), "user" : "mongoAdmin", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "lO6VBPnKD0dC5TwRcCJwZg==", "storedKey" : "AUUwnA6v/8LbSEUpDU5EXQmp9sY=", "serverKey" : "DjHukfkoW0QE5Zy/5plD9FLrsu8=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "fqRp+/wrOGTyk1hiTn4RoPQr4jWVlqw79GsD4g==", "storedKey" : "/aaz0CJHlFfFDD5bSBPOBCnipn07ezx+X0pHFABeOV0=", "serverKey" : "W6BOf07RoYytpgJc4KOoTTTID7qJ1iah9Wqwub9xjgE=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
C'est seulement une fois ce premier utilisateur "mongoAdmin" créé que l'authentication est activée !!
Si aucun utilisateur n'est crée, l'authentification reste inactive.
2016-12-29 11:25:39 +01:00
On peut ensuite se connecter à la base "admin" ainsi :
~~~
2021-05-02 23:56:24 +02:00
$ mongo admin -u mongoAdmin -p PASSWORD
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
> *Note*: Si on spécifie simplement l'argument `-p`, sans valeur, mongo demandera de saisir le mot de passe. Ainsi, il ne sera pas dans votre historique shell !
2016-12-29 11:25:39 +01:00
Pour les accès aux base, les utilisateurs sont stockés dans la collection _system.users_ propre à chaque base.
2020-05-06 12:17:30 +02:00
## Utilisation
### Administration en cli
Comme pour MySQL, on peut manipuler mongo en CLI en mode interactif avec la commande `mongo`
```
2021-05-02 23:56:24 +02:00
$ mongo admin -u mongoAdmin -p PASSWORD
2020-05-06 12:17:30 +02:00
```
Ici, pour se connecter à la base locale admin. Comme la base d'authentification n'est pas spécifiée, ça sera la base à laquelle on se connecte (ici admin) qui servira pour l'authentificat
> *Note*: Pour vous connecter à une base différente de celle d'authentification, on pourra spécifier le nom de cette base avec l'argument `--authenticationDatabase XXX`
#### Créer un utilisateur
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
> use admin;
> db.createUser(
{
"user" : "myApp",
2021-05-02 23:56:24 +02:00
"pwd" : "PASSWORD",
2020-05-06 12:17:30 +02:00
roles: [
{ "role" : "dbOwner", "db" : "myApp" }
]
}
)
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
#### Supprimer un utilisateur
Supprimons l'utilisateur foo de la base admin :
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
> use admin
> db.dropUser('foo')
true
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
#### Lister tous les utilisateurs
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
> use admin
> db.system.users.find()
{ "_id" : "admin.mongoAdmin", "userId" : UUID("3d475ec9-b82c-4312-8ce6-399bcbe3ca7a"), "user" : "mongoAdmin", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "lO6VBPnKD0dC5TwRcCJwZg==", "storedKey" : "AUUwnA6v/8LbSEUpDU5EXQmp9sY=", "serverKey" : "DjHukfkoW0QE5Zy/5plD9FLrsu8=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "fqRp+/wrOGTyk1hiTn4RoPQr4jWVlqw79GsD4g==", "storedKey" : "/aaz0CJHlFfFDD5bSBPOBCnipn07ezx+X0pHFABeOV0=", "serverKey" : "W6BOf07RoYytpgJc4KOoTTTID7qJ1iah9Wqwub9xjgE=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
#### Lister les bases de données
2020-05-06 12:17:30 +02:00
~~~
> show dbs
admin 0.000GB
config 0.000GB
foo 0.000GB
local 0.000GB
~~~
2020-05-06 12:17:30 +02:00
#### Supprimer une base
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
Pour supprimer la base foo :
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
> use foo
> db.runCommand( { dropDatabase: 1 } )
{
"dropped" : "foo",
"ok" : 1
}
~~~
#### Lister les collections d'une base
~~~
> use foo
switched to db foo
> show collections
bar
baz
2016-12-29 11:25:39 +01:00
~~~
2021-08-11 12:09:07 +02:00
#### Créer une base de données
Il ny a pas de commande équivalente à `CREATE DATABASE` dans MongoBD. Une base de données est effectivement créée lorsque des données sont insérées dans la base.
Pour créer une base de données, il faut sy attacher avec la commande `use` puis y ajouter des données.
```
use math
db.constants.insert({name: "e", value: "2.7182818"})
```
Les commandes précédentes permettent dajouter un élément à une collection `constants` dans la base `math`.
2020-05-06 12:17:30 +02:00
#### Autre exemples
Voici quelques opérations de base
2016-12-29 11:25:39 +01:00
~~~
> 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
2020-05-06 12:17:30 +02:00
Il existe plusieurs stratégies possibles pour faire de la sauvegarde comme détaillée dans la documentation de mongod : <https://docs.mongodb.com/manual/core/backups/>
### Via snapshots du système de fichier
Voir <https://docs.mongodb.com/manual/tutorial/backup-with-filesystem-snapshots/>
### Via mongodump
2020-05-06 12:17:30 +02:00
`mongodump` permet de créer des sauvegardes dans des fichiers au format bson utilisables par la commande `mongorestore`
> **Important**: `mongodump` sauvegarde uniquement les documents d'une base. Cela signifie qu'après leur re-injections, il y aura une phase de reconstructions des index de la base de donnée (qui sera plus ou moins longue en fonction de la quantitée de données et des performances de la machine)
> **Note**: Si l'authentification est activée, il convient de créer un compte dédié à la sauvegarde. Il existe pour cela un rôle dédié pour les opérations de sauvegarde `backup`
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
# mkdir -p /home/backup/mongodump/
2021-05-02 23:56:24 +02:00
# mongodump --username mongoDump --password PASSWORD --authenticationDatabase admin --output /home/backup/mongodump/
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
Ainsi, mongo écrire la sauvegarde dans `/home/backup/mongodump/`, avec un dossier par base.
2020-05-06 12:17:30 +02:00
Il est possible de générer un dump compressé avec l'option `--gzip`. Lors de l'injection de la sauvegarde avec `mongorestore` il faudra alors préciser à nouveau cet argument.
2017-11-17 16:26:31 +01:00
## Restauration
2020-05-06 12:17:30 +02:00
> **Note** : Si l'authentification est activée, il existe aussi un rôle dédié pour la restoration de données : `restore`
2017-11-17 16:26:31 +01:00
~~~
cd /home/backup/mongodump/
# mongorestore --db dbname dbname
mongorestore --db admin admin
~~~
2020-05-06 12:17:30 +02:00
> **Note** : Si le dump est compressé, il faut ajouter l'option `--gzip` à la commande
2016-12-29 11:25:39 +01:00
## Réplication avec replica set
2020-05-06 12:17:30 +02:00
La réplication avec "replica set" nécessite au moins 3 machines. En effet, la selection d'un noeud primaire où se produisent les
écritures se fait au travers d'un processus d'élection. Les noeuds secondaires sont seulement utilisables en lecture.
> **Note**: Si pour du multiples raisons, on ne peut avoir que deux noeuds mongodb supportant des données. On peut alors, introduire dans le cluster, un noeud de type 'arbitre'. Celui-ci doit bien être situé sur une machine indépendante des deux autres noeuds mongodb.
il ne supportera aucune donnée dans son datadir local, mais participera a l'election du noeud primaire.
2016-12-29 11:25:39 +01:00
### En Version 3.2+
2016-12-29 11:25:39 +01:00
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/>
2020-05-06 12:17:30 +02:00
> **Attention** : Le datadir des noeuds à ajouter à un replica set doit être vierge.*
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
#### Avec keyfile & authentification
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
Créer le keyfile sur une machine et le déployer sur les autres membres du replica set
2016-12-29 11:25:39 +01:00
~~~
# 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
2020-05-06 12:17:30 +02:00
2016-12-29 11:25:39 +01:00
replication:
replSetName: rs0
~~~
2020-05-06 12:17:30 +02:00
On va alors démarrer mongodb sur la machine qui sera initialement "primaire".
C'est via celle-ci que l'on va amorcer le cluster.
2016-12-29 11:25:39 +01:00
~~~
# systemctl restart mongod
~~~
2020-05-06 12:17:30 +02:00
Se connecter pour créer un compte administrateur *mongoAdmin* avec les roles `userAdminAnyDatabase` et `clusterAdmin`
2016-12-29 11:25:39 +01:00
~~~
# mongo
> use admin
2020-05-06 12:17:30 +02:00
> db.createUser(
{
user: "mongoAdmin",
2021-05-02 23:56:24 +02:00
pwd: "PASSWORD",
2020-05-06 12:17:30 +02:00
roles: [ { role: "userAdminAnyDatabase", db: "admin" },
2021-05-02 23:56:24 +02:00
{ "role" : "clusterAdmin", "db" : "admin" } ]
2016-12-29 11:25:39 +01:00
}
)
~~~
2020-05-06 12:17:30 +02:00
On peut alors modifier la configuration pour activer l'authentification, et redémarrer le mongodb primaire.
Et démarrer tous les autres membres
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
security:
keyFile: /etc/mongod.key
authorization: enabled
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
Sur le noeud primaire, on va amorcer le cluster :
2016-12-29 11:25:39 +01:00
~~~
2021-05-02 23:56:24 +02:00
# mongo -u mongoAdmin -p PASSWORD
2016-12-29 11:25:39 +01:00
> rs.initiate()
~~~
2020-05-06 12:17:30 +02:00
On peut ensuite, ajouter les membres seconaires du cluster :
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
```
> rs.add("192.0.2.3")
```
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
Si on soutaite ajouter un membre de typer *arbitre* :
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
```
> rs.addArb("192.0.2.100")
```
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
Le Replica Set est maintenant en place.
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
#### Avec X.509
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
TODO
2016-12-29 11:25:39 +01:00
### 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 :
2016-12-29 11:25:39 +01:00
~~~
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
2016-12-29 11:25:39 +01:00
# 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 !
2020-05-06 12:17:30 +02:00
## Monitoring
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
### Créer un accès
2016-12-29 11:25:39 +01:00
2020-05-06 12:17:30 +02:00
Si l'authentification est activée, il faut alors créer un compte. On peut utiliser le role `clusterMonitor`
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
> use admin
> db.createUser(
2016-12-29 11:25:39 +01:00
{
2020-06-09 16:50:32 +02:00
user: "mmongoMonitoring",
2021-05-02 23:56:24 +02:00
pwd: "PASSWORD",
2016-12-29 11:25:39 +01:00
roles: [ "clusterMonitor" ]
}
)
~~~
2020-05-06 12:17:30 +02:00
### Munin : Plugin mongo-munin
2016-12-29 11:25:39 +01:00
<https://github.com/comerford/mongo-munin>
~~~
# git clone https://github.com/comerford/mongo-munin.git /tmp/mongo-munin
2016-12-29 11:25:39 +01:00
# 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_* .
2016-12-29 11:25:39 +01:00
# chmod -R u=rwX,g=rwX,o=rX /usr/local/share/munin/
~~~
/etc/munin/plugin-conf.d/mongo
~~~
[mongo_*]
2021-05-02 23:56:24 +02:00
env.MONGO_DB_URI mongodb://mongoMonitoring:PASSWORD@localhost:27017/admin
2016-12-29 11:25:39 +01:00
~~~
2020-05-06 12:17:30 +02:00
### NRPE : check_mongo
TODO
## FAQ
### Modifier mot de passe `mongoAdmin`
On va arrêter MongoDB et démarrer le service à la main en *background*.
```bash
systemctl stop mongod.service
sudo -u mongodb /usr/bin/mongod --config /etc/mongod.conf --noauth &
mongo
```
Dans le *shell* MongoDB:
```js
use admin;
db.createUser( { user: "mongoAdmin", pwd: "MOT_DE_PASSE", roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] } )
exit
```
Une fois sorti du *shell* MongoDB, on tue le service démarré à la main et on démarre MongoDB normalement:
```bash
kill %%
systemctl start mongod.service
```
Pour vérifier si le mot de passe fonctionne:
```bash
mongo -u mongoAdmin -p'MOT_DE_PASSE'
```