2009-08-24 3 views
7

Je crée un script bash qui interagit avec une base de données MySQL en utilisant le programme de ligne de commande mysql. Je veux utiliser les verrous de table dans mon SQL. Puis-je faire ceci?MySQL depuis la ligne de commande - puis-je utiliser pratiquement des LOCK?

mysql -e "LOCK TABLES mytable" 
# do some bash stuff 
mysql -u "UNLOCK TABLES" 

La raison pour laquelle je demande, est parce que les verrous de table ne sont conservées que pour la session, donc ne la serrure être libérés dès que la finition du programme mysql?

+0

Le '-u' ne devrait-il pas être' -e'? –

Répondre

8

[EDIT]

nos a eu l'idée de base - ne fonctionne "mysql" une fois , et la solution ns fournie devrait fonctionner, mais elle a laissé le FIFO sur le disque.

nos était également correct que j'ai vissé: un simple "echo X >FIFO" fermera le FIFO; Je me suis souvenu à tort. Et mes commentaires (supprimés) w.r.t. le timing ne s'applique pas, désolé.

Cela dit, vous n'avez pas besoin d'une FIFO, vous pouvez utiliser un tube inter-processus. Et en regardant à travers mes anciens scripts MySQL, certains ont fonctionné comme ça, mais vous ne pouvez pas laisser des commandes écrire dans stdout (sans quelques astuces "exec").

#!/bin/bash 
(
    echo "LOCK TABLES mytable READ ;" 
    echo "Doing something..." >&2 
    echo "describe mytable;" 
    sleep 5 
    echo "UNLOCK tables;" 
) | mysql ${ARGUMENTS} 

Une autre option pourrait être d'attribuer un descripteur de fichier dans le FIFO, ont alors fonctionner en arrière-plan. C'est très similaire à ce que nos a fait, mais l'option "exec" n'exigerait pas un sous-shell pour exécuter les commandes bash; serait donc vous permettre de définir « RC » dans le « autres choses »:

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

Notez qu'il ya quelques problèmes de contrôle:

  • Ce code n'a AUCUNE ERREUR VÉRIFIER pour défaut de verrouillage (ou toutes les commandes SQL dans les "autres choses"). Et c'est certainement non-trivial.
  • Puisque dans le premier exemple, les «autres choses» sont dans un sous-shell, vous ne pouvez pas facilement définir le code de retour du script à partir de ce contexte.
+0

Vous auriez besoin d'un sous-shell ou d'une supercherie, si vous faites écho ...> $ {FIFO} mysql sortira juste après la commande 1. puisque la fin d'écriture ferme le tuyau – nos

+0

Vous avez absolument raison, mon script a gagné ' t travailler alors que le vôtre devrait (mais il laisse le FIFO sur le disque). – NVRAM

+0

Faites que "mon script original" ... – NVRAM

4

Voici une façon, je suis sûr qu'il ya un moyen 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 
2

Une approche très intéressante que j'ai trouvée en regardant ce problème est la commande SYSTEM de MySQL. Je ne suis pas encore sûr de ce que sont exactement les inconvénients, le cas échéant, mais il va certainement travailler pour un grand nombre de cas:

Exemple:

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

Il convient de noter que cela ne fonctionne que sur les * nix, évidemment, as does the SYSTEM command.

Le crédit va à Daniel Kadosh: http://dev.mysql.com/doc/refman/5.5/en/lock-tables.html#c10447

0

Une autre approche sans les mkfifo commandes:

cat <(echo "LOCK TABLES mytable;") <(sleep 3600) | mysql & 
LOCK_PID=$! 
# BASH STUFF 
kill $LOCK_PID 

Je pense que la réponse de Amr est le plus simple. Cependant, je voulais partager cela parce que quelqu'un d'autre peut aussi avoir besoin d'une réponse légèrement différente. Le sleep 3600 suspend l'entrée pendant 1 heure. Vous pouvez trouver d'autres commandes pour faire une pause ici: https://unix.stackexchange.com/questions/42901/how-to-do-nothing-forever-in-an-elegant-way

Le lock tables SQL s'exécute immédiatement, puis il attendra la minuterie de mise en veille.

Questions connexes