完全通过 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 客户端 的相关文章

  • 基于列顺序的查询速度

    数据库中列类型的顺序对查询时间有影响吗 例如 具有混合排序 INT TEXT VARCHAR INT TEXT 的表的查询速度是否会比具有连续类型 INT INT VARCHAR TEXT TEXT 的表慢 答案是肯定的 这确实很重要 而且
  • 为 Mariadb 安装连接器 C

    所以 我想使用 Mariadb 有一个连接器 C https downloads mariadb org connector c https downloads mariadb org connector c 我该如何安装它 坦白说 它的文
  • Rails 多租户架构,限制多个租户的访问范围

    目前我们有一个单租户数据库架构 MySQL 运行着超过 100 个数据库 我们使用 Apartment gem 切换子域上的数据库连接 一切都很顺利 然而 我们现在需要创建所谓的 伞 客户端 它可以访问一组现有客户端的所有数据 我不认为这对
  • PHP 中的异步数据库/服务调用:Gearman 与 pthreads

    在我们的 LAMP 站点上 我们遇到一些服务必须多次调用数据库才能提取数据的问题 通常在 PHP 中完成此操作的方式 至少我的经验 是串行的 这显然是低效的 我们可以通过使用缓存和聚合一些查询来缓解一些低效率的问题 但在某些情况下我们仍然需
  • 使用 EXPLAIN 进行 MYSQL 存储过程调用

    如何分析和使用 EXPLAIN 来调用我的存储过程 我需要优化查询时间 但是似乎没有地方可以执行 EXPLAIN 调用 proc name 你可以试试 set profiling 1 call proc name show profiles
  • 如果文件修改日期早于 N 天

    此问题涉及在文件的修改日期早于这么多天时采取行动 我确信创建日期或访问日期会类似 但对于修改日期 如果我有 file path name to some file N 100 for example N is number of days
  • 如何使用 PHP 从 MySQL 查询中按升序对值进行排序?

    我使用以下 PHP 脚本从 MySQL 表中获取和更改数据 并将结果打印在 HTML 表中 我希望按升序对数据进行排序 utilization percentage变量 它是由创建的 total client time total avai
  • PDO fetch() 失败时会抛出异常吗?

    有没有方法PDO语句 fetch http php net manual en pdostatement fetch php如果 PDO 错误报告系统设置为抛出异常 则在失败时抛出异常 例如 如果我设置 PDO ATTR ERRMODE g
  • 选择MySql表数据放入数组中

    我尝试从 mysql 捕获数据并将它们全部放入数组中 认为 users table id name code 1 gorge 2132 2 flix ksd02 3 jasmen skaod2 sql mysql query select
  • MySQL“选择更新”行为

    根据 MySql 文档 MySql 支持多粒度锁定 MGL case 1 开放航站楼 1 连接到mysql mysql gt start transaction Query OK 0 rows affected 0 00 sec mysql
  • RMySQL fetch - 找不到继承的方法

    使用 RMySQL 我想将数据从数据库加载到 R 中的数据帧中 为此 我使用以下代码 R连接数据库 con lt dbConnect MySQL user root password password dbname prediction h
  • 如何使用 bash 脚本通过 tar 备份文件系统?

    我想备份我的 ubuntu 文件系统 我写了这个小脚本 这是非常基本的 但这是我第一次尝试 我害怕犯错误 由于需要几个小时才能完成才能看到结果 因此我认为最好向经验丰富的程序员询问我是否做错了什么 我特别感兴趣 gt 会记录输出mv或者它也
  • PMA 4.5.2.0 file_exists():open_basedir 限制生效

    从 PPA 在我的 Ubuntu 服务器上安装 phpMyAdmin 后 https launchpad net nijel archive ubuntu phpmyadmin https launchpad net nijel archi
  • Clojure MySQL 语法错误异常(“[...] 靠近 '???????????????' [...]”)

    除了建立连接之外 我在使用 clojure contrib sql 做任何事情时都遇到困难 我有一个 mysqld 在 localhost 3306 上运行 数据库名为clj db 用户 clj user localhost 和密码 clj
  • shell脚本中是否有互斥/信号量机制?

    我正在 shell 脚本中寻找互斥 信号量 并发机制 考虑以下情况 除非 a 用户不关闭共享文件 否则 b 用户应该无法打开 更新它 我只是想知道如何在 shell 脚本中实现互斥量 信号量 临界区等 在 shell 脚本中实现锁定机制 文
  • 我可以在一个查询中更新/选择表吗?

    我需要在查看页面时选择数据并更新 视图 列 有没有一种方法可以在一个查询中执行此操作 或者我是否必须使用不同的查询 如果您不想 不需要使用事务 则可以创建一个存储过程 该过程首先更新视图计数 然后选择值并将其返回给用户
  • 将儒略时间戳转换为 UNIX 中的常规时间

    我需要使用 Bash 将 UNIX 中的 Julian 时间戳转换为常规时间戳 在 Tandem OS 上 转换非常简单 例子 212186319010244541 OLSAPP SYSTST 1 gt interprettimestamp
  • 如何隐藏显示终端命令输出

    当我运行这个命令时 sudo htpasswd b home reynolds htpasswd admin admin 我正在得到输出Updating password for user admin在终端中 但我不想显示该输出 所以我在谷
  • #1045 - 用户“root”@“localhost”的访问被拒绝(使用密码:YES)

    这可能看起来多余 但我无法找到正确的解决方案 我无法使用 mysql 控制台登录 mysql 它要求输入密码 但我不知道我实际输入的内容 有办法获取密码或更改密码吗 这就是我的 config inc 的样子 当我尝试打开 phpmyadmi
  • 如何解决 MySQL innodb 在 TRUNCATE TABLE 上“等待表元数据锁”?

    在 GitLab CI 服务器中运行包含数百个应用程序单元测试的测试套件 运行 10 次测试后 不知怎的 它总是卡在等待 TRUNCATE TABLE 上的表元数据锁上 这是一个拆卸步骤 我知道SHOW ENGINE INNODB STAT

随机推荐