Dołącz do klienta MySQL całkowicie za pośrednictwem FIFO
Na skrypcie Bash chcę, aby sesje MySQL były otwarte dla kilku kolejnych dostępów; powszechnym sposobem uzyskania dostępu do MySQL jest otwarcie pojedynczej sesji dla każdego polecenia SQL lub zestawu poleceń, takich jak
mysql -u user -e "show tables;"
Ograniczeniem tej metody jest utrata statusu atomowości i blokady dla tych transakcji, które muszą być dwojakie: na przykład nie jest możliwe zachowanie statusu blokady na stoleT
na całą długość następującej podwójnej operacji:
### 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);"
Moje podejście do rozwiązania polega na utrzymaniu sesji MySQL otwartej dla wielu dostępów przy użyciu dwóch FIFO i zawieszeniu procesu na tle.
Proponowane rozwiązanie:
Utwórz parę FIFO:mkfifo IN OUT
.
Ustaw instancję klienta MySQL na miejscu wraz z atrapąwhile
aby utrzymać rury otwarte i zapobiegaćSIGPIPE
sygnały:
mysql --xml --batch --raw --skip-column-names \
-h "$hostname" -u "$username" "$db" >IN <OUT &
while :; do sleep 1; done <IN >OUT &
Następnie przetestuj:
echo "show tables;" >OUT
read <IN
Wynik:
To nie działa. Theecho
komenda kończy się i przeskakuje nad nią, co oznacza, że MySQL otrzymuje dane wejściowe, aleread
zawiesza się na zawsze, więc nie ma wyjścia.
Odkryłem, że eliminujęIN
FIFO całe zadanie nie zawiesza się:
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
Czy to zachowanie jest oczekiwane? Zastanawiam się również, czy możliwe jest przeprowadzenie podwójnych operacji w Bash bez niestandardowych homebrewów.