代码之家  ›  专栏  ›  技术社区  ›  Amandasaurus

命令行中的mysql-我实际上可以使用锁吗?

  •  7
  • Amandasaurus  · 技术社区  · 16 年前

    我正在执行一个bash脚本,该脚本使用 mysql 命令行程序。我想在SQL中使用表锁。我可以这样做吗?

    mysql -e "LOCK TABLES mytable"
    # do some bash stuff
    mysql -u "UNLOCK TABLES"
    

    我之所以问,是因为表锁只保留在会话中,所以当mysql程序完成时,锁不会被释放吗?

    4 回复  |  直到 10 年前
        1
  •  8
  •   NVRAM    16 年前

    [编辑]

    网络操作系统 有一个基本的想法——只运行一次“mysql”,所提供的解决方案应该可以工作,但是它把FIFO留在了磁盘上。

    网络操作系统 我搞砸了也是对的:一个简单的 echo X >FIFO “将关闭国际足联;我记错了。抱歉,我(删除)的意见不适用于时间安排。

    也就是说,您不需要FIFO,可以使用进程间管道。通过查看我以前的mysql脚本,有些类似于这个,但是你 不能 让任何命令写入stdout(不使用一些“exec”技巧)。

    #!/bin/bash
    (
      echo "LOCK TABLES mytable READ ;"
      echo "Doing something..." >&2
      echo "describe mytable;" 
      sleep 5
      echo "UNLOCK  tables;" 
    ) | mysql ${ARGUMENTS}
    

    另一个选项可能是将文件描述符分配给FIFO,然后让它在后台运行。这是 非常 类似于什么 网络操作系统 是的,但是“exec”选项不需要子shell来运行bash命令;因此允许您在“其他东西”中设置“rc”:

    #!/bin/bash
    # Use the PID ($$) in the FIFO and remove it on exit:
    FIFO="/tmp/mysql-pipe.$$"
    mkfifo ${FIFO} || exit $?
    RC=0
    
    # Tie FD3 to the FIFO (only for writing), then start MySQL in the u
    # background with its input from the FIFO:
    exec 3<>${FIFO}
    
    mysql ${ARGUMENTS} <${FIFO} &
    MYSQL=$!
    trap "rm -f ${FIFO};kill -1 ${MYSQL} 2>&-" 0
    
    # Now lock the table...
    echo "LOCK TABLES mytable WRITE;" >&3
    
    # ... do your other stuff here, set RC ...
    echo "DESCRIBE mytable;" >&3
    sleep 5
    RC=3
    # ...
    
    echo "UNLOCK TABLES;" >&3
    exec 3>&-
    
    # You probably wish to sleep for a bit, or wait on ${MYSQL} before you exit
    exit ${RC}
    

    请注意,存在一些控制问题:

    • 此代码没有错误检查锁定失败(或任何SQL命令 在“其他东西”中)。那就是 一定地 非平凡的。
    • 因为在第一个例子中,“其他东西”在一个子壳中,所以你不能轻易地 从该上下文设置脚本的返回代码。
        2
  •  4
  •   nos    16 年前

    这是一条路,不过我相信还有一条更容易的路……

    mkfifo /tmp/mysql-pipe
    mysql mydb </tmp/mysql-pipe &
    (
      echo "LOCK TABLES mytable READ ;" 1>&6 
      echo "Doing something "
      echo "UNLOCK  tables;" 1>&6
    ) 6> /tmp/mysql-pipe
    
        3
  •  2
  •   Amr Mostafa    14 年前

    我在为自己研究这个问题时发现的一个非常有趣的方法是使用mysql SYSTEM 命令。我仍然不确定缺点到底是什么,如果有的话,但它肯定适用于很多情况:

    例子:

    mysql <<END_HEREDOC
    LOCK TABLES mytable;
    SYSTEM /path/to/script.sh
    UNLOCK TABLES;
    END_HEREDOC
    

    值得注意的是,这只适用于*尼克斯,显然, as does the SYSTEM command .

    功劳归丹尼尔·卡多什: http://dev.mysql.com/doc/refman/5.5/en/lock-tables.html#c10447

        4
  •  0
  •   Community Mohan Dere    8 年前

    另一种方法 mkfifo 命令:

    cat <(echo "LOCK TABLES mytable;") <(sleep 3600) | mysql &
    LOCK_PID=$!
    # BASH STUFF
    kill $LOCK_PID
    

    我认为AMR的答案是最简单的。但是我想分享这个,因为其他人可能也需要一个稍微不同的答案。

    这个 sleep 3600 暂停输入1小时。您可以在此处找到使其暂停的其他命令: https://unix.stackexchange.com/questions/42901/how-to-do-nothing-forever-in-an-elegant-way

    这个 lock tables SQL立即运行,然后等待睡眠计时器。