MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Lo script della shell Bash non si connette a MongoDB anche se lo stato è attivo

Il tuo script ha una serie di stranezze che probabilmente dovrebbero essere risolte indipendentemente dal problema immediato.

  • kill -0 "$$" || exit 0 è strano e probabilmente non fa nulla di utile. Immagino probabilmente non dovresti semplicemente fare nulla in questo caso, poiché lo scopo dello script sembra essere quello di installare il componente se manca, e quindi procedere nel mongodb_status= ... parte.
  • Poiché praticamente tutti i comandi qui sono privilegiati, avrebbe più senso interrompere in anticipo se l'intero script non è in esecuzione con i privilegi.

Stilisticamente, tutto ciò che assomiglia a sudo bash -c 'singlecommand' dovrebbe essere solo sudo singlecommand; ma con il refactoring proposto, non ti servono affatto.

Il problema immediato con il tuo script sembra essere che ci vuole del tempo prima che il server inizi ad ascoltare sulla porta per cui lo hai configurato. Non so abbastanza su Mongo per dirti come aspettare correttamente che ti dica quando è attivo "per davvero" ma aggiungendo un sleep è una soluzione alternativa comune (sebbene grossolana). Un altro è esaminare il file di registro, cercando l'evento in ascolto.

#!/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

Non sono del tutto soddisfatto di startit funzione - all'inizio non è riuscito perché ho provato ad aprire il file di registro quando non esisteva ancora, quindi non è riuscito perché le nuove righe nel file di registro contenevano già il messaggio di avvio dopo la sospensione di un secondo. Ora potrebbe ancora non riuscire se il file di registro viene aggiunto e i vecchi registri contengono il messaggio di avvio di una sessione precedente. Ma almeno questo dovrebbe farti iniziare nella giusta direzione, spero.

Ecco un refactoring che potrebbe sii più 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
}

Il sleep finale è un po' un atto di disperazione; sembra che ci voglia un attimo dopo aver registrato l'avvio fino a quando non è correttamente attivo e in ascolto; e/o magari aggiungere un ciclo di tentativi intorno al mongo finale comando.