8
votes

Mysql de la ligne de commande - Puis-je utiliser pratiquement des serrures?

Je fais un script Bash qui interagit avec une source de données MySQL à l'aide du programme de ligne de commande mysql . Je veux utiliser des serrures de table dans mon SQL. Puis-je faire cela? XXX

La raison que je demande, c'est que parce que les serrures de table ne sont conservées que pour la session, de sorte que la serrure ne serait pas libérée dès que ce programme MySQL se termine?


0 commentaires

5 Réponses :


4
votes

Voici une façon, je suis sûr qu'il y a une solution plus facile si ...

mkfifo /tmp/mysql-pipe
mysql mydb </tmp/mysql-pipe &
(
  echo "LOCK TABLES mytable READ ;" 1>&6 
  echo "Doing something "
  echo "UNLOCK  tables;" 1>&6
) 6> /tmp/mysql-pipe


1 commentaires

Cela ne fonctionnera pas comme prévu. Le écho "Tableaux de verrouillage de la myTable Lecture;" 1> & 6 n'est pas bloqué. Donc, echo "faire quelque chose" sera exécuté juste après elle, si la serrure est acquise ou non.



8
votes

[modifier] strong>

NOS STRUT> avait l'idée de base - seulement "MySQL" une fois, et la solution fournie devrait fonctionner, mais il a quitté la FIFO. sur le disque. p>

NOS STRT> a également été correct que je fuis: un simple " Echo x> FIFO code>" fermera la FIFO; Je me suis souvenu de mal. Et mes commentaires (supprimés) w.r.t. Le chronométrage ne s'applique pas, désolé. p>

Cela dit, vous n'avez pas besoin d'une FIFO, vous pouvez utiliser un tuyau inter-processus. Et regardant à travers mes anciens scripts MySQL, certains ont travaillé semblable à cela, mais vous ne pouvez pas fort> laisser des commandes écrire sur stdout (sans astuces "exécutées"). P>

#!/bin/bash
# Use the PID ($$) in the FIFO and remove it on exit:
FIFO="/tmp/mysql-pipe.$$"
mkfifo ${FIFO} || exit $?
RC=0

# Tie FD3 to the FIFO (only for writing), then start MySQL in the u
# background with its input from the FIFO:
exec 3<>${FIFO}

mysql ${ARGUMENTS} <${FIFO} &
MYSQL=$!
trap "rm -f ${FIFO};kill -1 ${MYSQL} 2>&-" 0

# Now lock the table...
echo "LOCK TABLES mytable WRITE;" >&3

# ... do your other stuff here, set RC ...
echo "DESCRIBE mytable;" >&3
sleep 5
RC=3
# ...

echo "UNLOCK TABLES;" >&3
exec 3>&-

# You probably wish to sleep for a bit, or wait on ${MYSQL} before you exit
exit ${RC}


2 commentaires

Vous auriez besoin d'un sous-vase ou d'un autre spectacle, si vous faites écho ...> $ {FIFO} MySQL quittera simplement après la commande 1. Depuis la fin de l'écriture ferme le tuyau


Vous avez absolument raison, mon script ne fonctionnera pas pendant que vous devriez (mais cela quitte la FIFO sur disque).



2
votes

Une approche très intéressante que j'ai découvert lors de la recherche de ce problème pour moi, consiste à utiliser la commande system code> de MySQL. Je ne suis toujours pas sûr de quoi sont exactement les inconvénients, le cas échéant, mais cela fonctionnera certainement pour beaucoup de cas:

Exemple: P>

mysql <<END_HEREDOC
LOCK TABLES mytable;
SYSTEM /path/to/script.sh
UNLOCK TABLES;
END_HEREDOC


0 commentaires

0
votes

Une autre approche sans le mkfifo Commandes: xxx

Je pense que la réponse d'AMR est la plus simple. Cependant, je voulais partager cela parce que quelqu'un d'autre peut également avoir besoin d'une réponse légèrement différente.

Le SLEEP 3600 pause l'entrée pendant 1 heure. Vous pouvez trouver d'autres commandes pour le faire faire une pause ici: https : //unix.stackexchange.com/questions/42901/how-a-o-nothing-forever-in-an-elefegant-way

Les tables de verrouillage SQL fonctionne immédiatement, puis il attendra la minuterie de sommeil.


0 commentaires

0
votes

Problème et limitation des réponses existantes
  • réponses par NVRAM , NOS et Xer0x P>

    Si des commandes entre Les tables de verrouillage code> et déverrouillent des tables code> sont toutes les requêtes SQL, vous devriez être bien. Dans ce cas, cependant, pourquoi ne pas simplement construire un fichier SQL unique et le tuyer à la commande mysql code>? P>

    S'il existe des commandes autres que d'émettre des requêtes SQL dans la section critique, vous pourriez avoir des problèmes. La commande code> echo code> envoie l'instruction de verrouillage sur le descripteur de fichier ne bloque pas et attendez mysql code> pour répondre. Des commandes ultérieures sont donc possibles d'être exécutées avant que le verrou soit réellement acquis. La synchronisation n'est pas garantie. P> li>

  • réponse par AMR Mostafa P>

    La commande system code> est exécutée sur le serveur MySQL. Donc, le script ou la commande à exécuter doit être présent sur le même serveur MySQL. Vous aurez besoin d'un accès terminal sur la machine / VM / conteneur qui héberge le serveur (ou au moins une moyenne pour transférer votre script sur l'hôte du serveur). système code> commande fonctionne également sur Windows à partir de MySQL 8.0.19 , mais en l'exécutant sur un serveur Windows de cours signifie que vous allez exécuter une commande Windows (par exemple, un fichier de lots ou un script PowerShell). P> li> ul>

    une solution modifiée h3>

    ci-dessous est une solution d'exemple basée sur les réponses de NVRAM et NOS, mais attend le verrouillage: P>

    # ...
    echo 'LOCK TABLES my_table WRITE;' >&10
    echo 'SELECT 1;' >&10
    if ! read -t 10 line <&11; then
        echo "Timeout reading from mysql"
    elif [[ $line == 1 ]]; then
        echo "Table lock acquired"
        # ...
    else
        echo "Unexpected output?!"
    fi
    


0 commentaires