在 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);"
我的解决方案方法是使用两个 FIFO 保持 MySQL 会话在多个访问中打开,并将进程挂在后台。
建议的解决方案:
创建一对 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
Result:
这是行不通的。这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 中运行双重操作。