MongoDB: Recuperar un config server

12 Septiembre 2013 at 16:03 by Adrián Pérez

mongodbHoy me he encontrado, que tras una caída de un servidor que alojaba un config server de mi cluster MongoDB 2.2.0 (sobre un entorno Red Hat), el config server no era capaz de arrancar. Concretamente, al intentar iniciar el config server, podría ver los siguientes logs en el fichero de error:

Thu Sep 12 11:47:37 [initandlisten] dbexception during recovery: 15874 couldn't uncompress journal section
Thu Sep 12 11:47:37 [initandlisten] exception in initAndListen: 15874 couldn't uncompress journal section, terminating
Thu Sep 12 11:47:37 dbexit:
Thu Sep 12 11:47:37 [initandlisten] shutdown: going to close listening sockets...
Thu Sep 12 11:47:37 [initandlisten] shutdown: going to flush diaglog...
Thu Sep 12 11:47:37 [initandlisten] shutdown: going to close sockets...
Thu Sep 12 11:47:37 [initandlisten] shutdown: waiting for fs preallocator...
Thu Sep 12 11:47:37 [initandlisten] shutdown: lock for final commit...
Thu Sep 12 11:47:37 [initandlisten] shutdown: final commit...
Thu Sep 12 11:47:37 [initandlisten] shutdown: closing all files...
Thu Sep 12 11:47:37 [initandlisten] closeAllFiles() finished
Thu Sep 12 11:47:37 [initandlisten] shutdown: removing fs lock...
Thu Sep 12 11:47:37 dbexit: really exiting now

Al parecer, el fichero de journal se ha corrompido con la caída del server y ni si quiera es capaz de solucionarse con un "--repair". Aprovechando que mi cluster tiene 3 config servers, he pasado a parar uno de los dos config servers que aun funcionaban, para copiar los datos del dbpath al config server corrompido, con tal de recuperarlo.

El proceso ha sido el siguiente, descrito en la documentación oficial de MongoDB (v2.2):

1- Primero nos conectaremos a cualquier mongos y pararemos el balanceador:

[root@serverA]# mongo
MongoDB shell version: 2.2.0
connecting to: 127.0.0.1/test
mongos>

mongos> sh.stopBalancer()
Waiting for active hosts...
Waiting for active host serverA:27017 to recognize new settings... (ping : Thu Sep 12 2013 13:34:22 GMT+0200 (CEST))
Waiting for active host serverB:27017 to recognize new settings... (ping : Thu Sep 12 2013 13:34:22 GMT+0200 (CEST))
Waiting for active host serverC:27017 to recognize new settings... (ping : Thu Sep 12 2013 13:37:42 GMT+0200 (CEST))
Waiting for active host serverD:27017 to recognize new settings... (ping : Thu Sep 12 2013 13:34:18 GMT+0200 (CEST))
Waiting for active host serverE:27017 to recognize new settings... (ping : Thu Sep 12 2013 13:34:21 GMT+0200 (CEST))
Waiting for the balancer lock...
Waiting again for active hosts after balancer is off...

2- Podremos ejecutar la siguiente instrucción para asegurarnos de que no hay migraciones pendientes por el balanceador, ejecutando:

mongos> use config
switched to db config
mongos> while( db.locks.findOne({_id: "balancer"}).state ) {
... print("waiting..."); sleep(1000);
... }
mongos>

3- Si la instrucción anterior no devuelve nada, podremos salir del mongos, parar un config server que funcione, y continuar con el proceso:

mongos> quit()

[root@serverA]# ps -ef | grep mongo
[...]
root        3058       1  0 Mar31 ?        20:43:12 /usr/bin/mongod -f /etc/mongo/configsrv/configsrv3.conf

[root@serverA]# kill 3058

4- Una vez parado el config server, podremos pasar a renombrar la carpeta con el dbpath del config server que no funciona, y para posteriormente crear de nuevo el directorio vacío:

[root@serverISSUE]# cd /mongodata/
[root@serverISSUE]# mv config2 config2.OLD
[root@serverISSUE]# mkdir config2

5- Ahora, en el servidor con el config server que acabamos de parar (el que usaremos como origen para copiar los datos), haremos un rsync contra el directorio vacío del servidor con el config server con problemas:

[root@serverA]# rsync -e ssh -navz /mongodata/config3/ root@192.168.1.2:/mongodata/config2
[root@serverA]# rsync -e ssh -avz /mongodata/config3/ root@192.168.1.2:/mongodata/config2

NOTA: Podemos ejecutar el rsync con la opción "-n" para símplemente ver lo que copiaría el rsync, pero sin ejecutarlo. Así estaremos seguros de copiar la información que queremos.

6- Al acabar el rsync, podremos iniciar los config servers. Primero iniciaremos el que funcionaba y hemos parado para usar como origen de copia de datos, y a continuación iniciaremos el config server que estamos recuperando:

[root@serverA]# /usr/bin/mongod -f /etc/mongo/configsrv/configsrv3.conf
[root@serverISSUE]# /usr/bin/mongod -f /etc/mongo/configsrv/configsrv2.conf

7- En este momento, ya tendremos el config server recuperado y podremos volver a iniciar el balanceador:

[root@serverA]# mongo
MongoDB shell version: 2.2.0
connecting to: 127.0.0.1/test
mongos> sh.startBalancer()

Con ésto habremos recuperado nuestro config server, sin ningún downtime en nuestro cluster mongo.

Fuente:

http://docs.mongodb.org/v2.2/tutorial/manage-sharded-cluster-config-server/#sharding-config-server-replace