完全通过FIFO附加到MySQL客户端

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客户端实例,同时设置虚拟对象以保持管道打开并防止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中运行双重操作.

解决方法:

FIFO的问题在于,当输入数据的每个进程都终止时,它会向正在读取的进程(在本例中为mysql)发出信号,表明它是数据的结尾,因此终止.

诀窍是确保有一个进程始终保持FIFO输入处于活动状态.你可以通过运行睡眠来实现这一点999999999> fifofile在背景中.

例:

#!/bin/sh

mkfifo /tmp/sqlpipe

sleep 2147483647 > /tmp/sqlpipe &
PID=$!

mysql -B -uUSER -pPASSWORD < /tmp/sqlpipe &

# all set up, now just push the SQL queries to the pipe, exemple:
echo "INSERT INTO table VALUES (...);" > /tmp/sqlpipe
echo "INSERT INTO table VALUES (...);" > /tmp/sqlpipe
echo "INSERT INTO table VALUES (...);" > /tmp/sqlpipe
cat "mysqldump.sql" > /tmp/sqlpipe
echo "DELETE FROM table WHERE ...;" > /tmp/sqlpipe

# done! terminate pipe
kill -s SIGINT $PID
rm /tmp/sqlpipe

最后,我们终止睡眠过程以完全释放FIFO输入.它会向mysql发出输入已经结束的信号,它会自动死亡.

还有一种不需要FIFO的替代方案,但是您需要两个脚本:

run.sh:

#!/bin/sh
./querygenerator.sh | mysql -B -uUSER -pPASSWORD

querygenerator.sh:

#!/bin/sh
echo "INSERT INTO table VALUES (...);"
echo "INSERT INTO table VALUES (...);"
echo "INSERT INTO table VALUES (...);"
cat "mysqldump.sql"
echo "DELETE FROM table WHERE ...;"
上一篇:可以在c编程中将一个fifo重定向到stdout吗?


下一篇:进程间通信之数据传输--FIFO