MySQL из командной строки - могу ли я практически использовать блокировки? - PullRequest
7 голосов
/ 25 августа 2009

Я делаю сценарий bash, который взаимодействует с базой данных MySQL с помощью программы командной строки mysql. Я хочу использовать блокировки таблиц в моем SQL. Могу ли я сделать это?

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

Причина, по которой я спрашиваю, состоит в том, что блокировки таблиц сохраняются только для сеанса, поэтому не будет ли снята блокировка, как только эта программа mysql завершит работу?

Ответы [ 4 ]

8 голосов
/ 25 августа 2009

[РЕДАКТИРОВАТЬ]

nos имел основную идею - только один раз запустите «mysql», и предоставленное nos решение должно работать, но оно оставило FIFO на диске.

nos также было правильно, что я облажался: простой "echo X >FIFO" закроет FIFO; Я вспомнил неправильно. И мои (удаленные) комментарии w.r.t. время не применяется, извините.

Тем не менее, вам не нужен FIFO, вы можете использовать межпроцессный канал. И, просматривая мои старые сценарии MySQL, некоторые работали сродни с этим, но вы не можете позволить любым командам писать в stdout (без некоторых трюков "exec").

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

Другой вариант может состоять в том, чтобы назначить файловый дескриптор FIFO, а затем запустить его в фоновом режиме. Это очень похоже на то, что делал nos , но опция "exec" не требует вложенной оболочки для запуска команд bash; следовательно, вы могли бы установить «RC» в «другие вещи»:

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

Обратите внимание, что есть несколько проблем управления:

  • В этом коде НЕТ ПРОВЕРКИ ОШИБОК из-за невозможности блокировки (или любых команд SQL в рамках "других вещей"). И это определенно нетривиально.
  • Поскольку в первом примере «другие вещи» находятся внутри подоболочки, вы не можете легко установить код возврата скрипта из этого контекста.
4 голосов
/ 25 августа 2009

Вот один способ, я уверен, что есть более простой способ, хотя ..

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 голосов
/ 12 марта 2011

Очень интересный подход, который я обнаружил, изучая эту проблему для себя, заключается в использовании команды MySQL SYSTEM. Я до сих пор не уверен, какие именно недостатки, если таковые имеются, но это, безусловно, будет работать для многих случаев:

Пример:

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

Стоит отметить, что это работает только на * nix, очевидно, , как и команда SYSTEM .

Благодарность достается Даниэлю Кадошу: http://dev.mysql.com/doc/refman/5.5/en/lock-tables.html#c10447

0 голосов
/ 14 октября 2015

Другой подход без команд mkfifo:

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

Я думаю, что ответ Амра самый простой. Однако я хотел поделиться этим, потому что кому-то еще может понадобиться немного другой ответ.

sleep 3600 приостанавливает ввод на 1 час. Вы можете найти другие команды, чтобы заставить его остановиться здесь: https://unix.stackexchange.com/questions/42901/how-to-do-nothing-forever-in-an-elegant-way

SQL lock tables запускается немедленно, затем он будет ждать таймера отключения.

...