Присоединяйтесь к клиенту MySQL полностью через FIFO
В скрипте Bash я хочу, чтобы сеансы MySQL были открыты для нескольких последовательных обращений; Распространенный способ доступа к MySQL - это открытие отдельного сеанса для каждой команды SQL или набора команд, таких как
mysql -u user -e "show tables;"
Ограничением этого метода является потеря атомарности и статусов блокировки для тех транзакций, которые должны быть двоякими: например, невозможно сохранить статус блокировки для таблицыT
на всю длину следующей двойной операции:
### Minimalistic example
data=$(mysql -e "\
lock table T write;
select col from T;
")
# ...
# parse 'data' and compute 'output' variable
# ...
mysql -e "insert into T values ($output);"
Мой подход к решению состоит в том, чтобы оставить сеанс MySQL открытым для нескольких обращений, используя два FIFO, и повесить процесс в фоновом режиме.
Предложенное решение:
Создайте пару FIFO:mkfifo IN OUT
.
Установите экземпляр MySQL-клиента на место вместе с фиктивнымwhile
держать трубы открытыми и предотвратитьSIGPIPE
сигналы:
mysql --xml --batch --raw --skip-column-names \
-h "$hostname" -u "$username" "$db" >IN <OUT &
while :; do sleep 1; done <IN >OUT &
Тогда проверьте это:
echo "show tables;" >OUT
read <IN
Результат:
Это не работает.echo
команда завершается, и bash перешагивает через нее, что означает, что MySQL получает ввод, ноread
зависает навсегда, поэтому вывод не производится.
Я обнаружил, что устранениеIN
FIFO вся задача не висит
mysql --xml --batch --raw --skip-column-names \
-h "$hostname" -u "$username" "$db" <OUT &
while :; do sleep 1; done >OUT &
echo "show tables;" >OUT # this produces the expected output
Ожидается ли такое поведение? Также мне интересно, можно ли в Bash запускать двойные операции без пользовательских домашних пивоваров.