完全通过 FIFO 连接到 MySQL 客户端

2024-01-19

在 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永远挂起,因此不会产生任何输出。
我发现消除INFIFO 整个任务不会挂起:

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 输入始终保持活动状态。您可以通过运行来做到这一点sleep 999999999 > fifofile在背景中。

Exemple:

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

最后我们终止sleep进程完全释放 FIFO 输入。它将发出信号mysql输入已经结束,结果会自动死亡。

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

run.sh:

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

查询生成器.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 ...;"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

完全通过 FIFO 连接到 MySQL 客户端 的相关文章

  • db:schema:load 与 db:migrate 使用 capistrano

    我有一个 Rails 应用程序 我正在将其移动到另一台服务器 我认为我应该使用 db schema load 来创建 mysql 数据库 因为这是推荐的 我的问题是我正在使用 capistrano 进行部署 并且它似乎默认为 rake db
  • Google Cloud SQL 在重新启动时卡住

    我的云 sql 实例长时间处于重新启动状态 在操作窗格中 重新启动的状态显示为待处理 并且还发生了导出 其状态仍为Running 有没有办法可以强制重新启动或取消重新启动或从常规备份中恢复数据 不 没有办法 如果您向 Google 支付高级
  • ruby 管道、IO 和 stderr 重定向

    我希望有一个 ruby 程序 一个 rake 任务 观察另一个 rake 任务的输出 输出写入器输出到 stderr 我想读一下这些行 我很难设置它 如果我有一个作家 stdout writer rb 不断打印一些东西 usr bin en
  • 并行运行 shell 脚本

    我有一个 shell 脚本 打乱大型文本文件 600 万行和 6 列 根据第一列对文件进行排序 输出 1000 个文件 所以伪代码看起来像这样 file1 sh bin bash for i in seq 1 1000 do Generat
  • 每月获取记录,但如果该月没有记录,则为零

    如果我有以下 SQL 表 Tests id type receiveDate 1 Blood 2012 01 18 2 Blood 2012 01 20 3 Blood 2012 01 18 4 Blood 2012 03 01 5 Blo
  • Bash - 在与当前终端分开的另一个终端中启动命令的新实例

    我有一个简单的 bash 脚本 test sh 设置如下 bin bash args if args 0 check capture then watch n 1 ls lag home user capture0 watch n 1 ls
  • 使用Perl/DBI/MySQL/InnoDB查找外键信息

    我想以编程方式查找 MySQL 数据库中特定 InnoDB 表的外键 我正在使用 Perl 我偶然发现 dbh gt foreign key info 我刚刚尝试使用它 但似乎有点错误 它不会返回 ON DELETE 和 ON UPDATE
  • 什么时候应该使用 C++ 而不是 SQL?

    我是一名 C 程序员 偶尔使用 MySQL 来处理数据库 但我的 SQL 知识相当有限 但我肯定愿意改变这一点 目前 我正在尝试仅使用 SQL 查询对数据库中的数据进行分析 但我准备放弃了 转而将数据导入到C 中 用C 代码进行分析 我和同
  • MySQL 错误 1172 - 结果包含多行

    在存储过程中运行查询时 我从 MySQL 收到此错误 错误代码 1172 结果包含多行 我理解错误 我正在做一个SELECT INTO var list 因此查询需要返回单行 当我使用LIMIT 1 or SELECT DISTINCT 错
  • 如何使用 mediawiki 的 api、curl 和 bash 登录?

    我对流程的理解 来自 mediawikis 登录手册https www mediawiki org wiki API 登录 https www mediawiki org wiki API Login 使用 MediaWiki 的 Web
  • 为什么 Git Bash 无法运行我的可执行文件?

    I am on git for windows https github com git for windows 吉特 巴什 我无法在命令行上运行可执行文件 Pedr Abc 07 MINGW64 c dev ls sqlite3 exe
  • MaxListenersExceededWarning:检测到可能的 EventEmitter 内存泄漏。添加了 11 条消息列表。使用emitter.setMaxListeners()来增加限制

    我知道这可能会标记为重复的解决方案 但堆栈溢出的解决方案对我不起作用 Problem node 5716 MaxListenersExceededWarning Possible EventEmitter memory leak detec
  • 如何检测Mysql/innodb中的死锁?

    我知道在 Innodb 中使用事务时不可避免地会发生死锁 并且如果应用程序代码正确处理死锁 它们是无害的 正如手册所说 只需再试一次 所以我想知道 如何检测死锁 死锁是否会发出一些特殊的 mysql 错误号 如果重要的话 我正在使用 PHP
  • SQL查询查找表的主键?

    我怎样才能找到哪一列首要的关键使用查询来创建表 这是重复的question https stackoverflow com questions 893874 mysql determine tables primary key dynami
  • MYSQL从每个类别中随机选择一条记录

    我有一个数据库Items表看起来像这样 id name category int 有几十万条记录 每个item可以是 7 种不同的之一categories 对应于categories table id category 我想要一个从每个类别
  • 在 Bash 中监控 tomcat,直到它完成部署 war 或应用程序

    怎么可能Tomcat在 bash 脚本中进行监控以检测它是否完成了战争或应用程序的部署 应用场景 Tomcat 开始于systemd Tomcat 开始于catalina sh 使用 Tomcat 管理器 Tomcat从Eclipse启动
  • 如何检查主机是否在您的known_host ssh中

    我的脚本中使用以下命令 将主机添加到 ssh 中的已知主机 VAR2 expect c spawn ssh o StrictHostKeyChecking no REMOTE HOST USER REMOTE HOST IP expect
  • mysql排序和排名语句

    我需要一些 mysql 语句的帮助 我的表 1 有 7 列 表 2 有 8 列 额外的列名为排名 我的语句应该是这样的 从表 1 中选择全部 然后按 用户数 排序 将其插入表 2 中并排名开始 1 2 3 等 table 1 usernam
  • SQL 最近日期

    我需要在 php 中获取诸如 2010 04 27 之类的日期作为字符串 并在表中找到最近的 5 个日期 表中的日期保存为日期类型 您可以使用DATEDIFF http dev mysql com doc refman 5 1 en dat
  • 在 macOS 上使用 find 时出现“非法选项”错误

    我试图列出末尾仅带有字母 R 的文件 我用了find在 macOS 终端中如下所示 find type f name R 但我收到消息说illegal option t 第一个参数find是它应该开始寻找的路径 路径 表示当前目录 find

随机推荐