sql >> Base de Datos >  >> NoSQL >> MongoDB

El script de shell Bash no se conecta a MongoDB incluso si el estado está activo

Su secuencia de comandos tiene una serie de rarezas que probablemente deberían corregirse independientemente del problema inmediato.

  • kill -0 "$$" || exit 0 es extraño y probablemente no hace nada útil. Supongo que supongo probablemente simplemente no debería hacer nada en este caso, ya que el propósito de la secuencia de comandos parece ser instalar el componente si falta, y luego proceder a mongodb_status= ... parte.
  • Como básicamente todos los comandos aquí son privilegiados, tendría más sentido abortar desde el principio si todo el script no se ejecuta con privilegios.

Estilísticamente, todo lo que se parece a sudo bash -c 'singlecommand' debería ser simplemente sudo singlecommand; pero con la refactorización propuesta, no los necesita en absoluto.

El problema inmediato con su secuencia de comandos parece ser que el servidor tarda un tiempo en comenzar a escuchar en el puerto para el que lo configuró. No sé lo suficiente sobre Mongo para decirte cómo esperar correctamente a que te diga cuándo está activo "de verdad" pero agregando un sleep es una solución alternativa común (aunque tosca). Otra es examinar el archivo de registro, buscando el evento de escucha.

#!/bin/bash

# Test for privileged access
test -w / ||
{ echo "$0: need to run privileged; aborting" >&2; exit 127; }

startit () {
    local log=/var/log/mongodb/mongod.log
    service mongod start
    while true; do
        test -e "$log" && break
        sleep 1
    done
    grep -q 'port: 27017' "$log" ||
    tail -0f "$log" |
    grep -q 'port: 27017'
}

if [ -f /usr/bin/mongod ]; then
    # Send diagnostic messages to standard error
    echo "$0: MongoDB is installed on your machine." >&2
else
    # Reduce eyesore
    echo "$0: MongoDB is not installed; proceed with 4.0 install" >&2
    apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 68818C72E52529D4
    echo "deb http://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" >/etc/apt/sources.list.d/mongodb-org-4.0.list
    apt update && apt upgrade -y
    apt-get install -y mongodb-org
    # not necessary or useful to do a second time
    # apt update && apt upgrade -y
    apt -y autoremove && apt clean
    mkdir -p /data/db
    systemctl enable mongod
    startit
    # service mongod restart  # is this really useful and necessary?
fi
echo "$0: database initialization" >&2

# Prefer modern command substitution syntax
mongod_status=$(systemctl is-active mongod)
echo "$mongod_status" >&2

if [[ "${mongod_status}" == "active" ]]
then
    echo "$0: MongoDB is already running." >&2
else
    echo "$0: MongoDB is not running" >&2
    rm -f /var/lib/mongodb/mongod.lock
    startit
fi

mongo <<EOF
        use fragment
        db.createCollection("fragmenthash");
EOF

No estoy del todo satisfecho con startit función:al principio falló porque traté de abrir el archivo de registro cuando aún no existía, luego falló porque las nuevas líneas en el archivo de registro ya contenían el mensaje de inicio después de la suspensión de un segundo. Ahora aún podría fallar si se agrega el archivo de registro y los registros antiguos contienen el mensaje de inicio de una sesión anterior. Pero al menos esto debería ayudarlo a comenzar en la dirección correcta, espero.

Aquí hay una refactorización que podría ser más robusto...

startit () {
    local log=/var/log/mongodb/mongod.log
    sudo -u mongodb touch "$log"
    service mongod start &
    local launcher=$!
    tail -0f "$log" |
    grep -q 'port: 27017'
    wait "$launcher"
    sleep 1
}

El sleep final es un poco un acto de desesperación; parece tomar un santiamén después de que registra el inicio hasta que está funcionando correctamente y escuchando; y/o tal vez agregar un bucle de reintento alrededor del mongo final comando.