不可能は可能です!
>しかし、リクエストを取得するために途中で MySQL から出力を取得する必要があります。誰かがこれのレシピを持っていますか?
これが私のソリューションのデモです:
#!/bin/bash
################################################################################
# Bash synchronous client-server #
# or #
# Bash parallel processes with synchronized rendezvous points #
# or #
# Bash interprocess communication with named pipes #
################################################################################
#Declare your session 'globals'
args= #command line arguments are stored here
DIR= #script's current path is stored here
#Early store your bash args before you lose them
for arg in "$@"; do
args[i]=$arg
(( i+=1 ))
done
################################################################################
## Initialize constants ##
#------------------------------------------------------------------------------#
# Explain more... #
################################################################################
function init_vars() {
#absolute path of this script
DIR=$( cd "$( dirname "$0" )" && pwd )
#global MYSQL_PASS is defined in ~/.profile
#this is the file where we store MySQL root password
if [[ ! $MYSQL_PASS ]]; then
MYSQL_PASS='.mysqlpass'
fi
#do some other stuff here...
}
################################################################################
## Rotate over passed arguments ##
#------------------------------------------------------------------------------#
#Parse array 'args' based on the logic of your command line argument syntax #
#Say, '--db <database>' denotes the processing of one database, '--db all' of #
#all databases etc. #
#Linux utilities have contradicting rules for such kind of argument processing #
#(full of crap!), i.e. see tar: tar -xvf or tar --xfv or tar xvf, mysql -p #
#<pass> or mysql -p=<pass> or mysql -p'<pass>' (???) #
################################################################################
function parse_args() {
#your logic goes here
}
################################################################################
## Opens a MySQL client session ##
#------------------------------------------------------------------------------#
# For security reasons password is kept in a file given by MYSQL_PASS. #
################################################################################
function mysql_client() {
mysql --host=127.0.0.1 --port=3306 --default-character-set=utf8 -u root -p"$( cd $DIR; cat $MYSQL_PASS )"
}
################################################################################
## A job dispatcher ##
#------------------------------------------------------------------------------#
# This thread initiates the workers and also reads intermediate results from #
# the spawned jobs. We don't want to parallelize the whole part of a job but #
# rather to put some parts to run in parallel with the dispatcher and some #
# parts in a sequential order determined by what we call rendezvous points. #
# See the diagram: A, B, C, D, E and F are events or actions during the life of#
# a program. #
# #
# dispatcher #
# | start #
# A ----------------> worker #
# | | #
# B (read blocks) C #
# | signals | #
# B (unblocks)<--------------- D (write blocks) #
# | | #
# E (1st set of results) F #
# | | #
# We can only guarantee that E comes after D or, D->E in time but E->F or F->E #
# and B->C or C->B (we don't care) #
################################################################################
function dispatcher() {
#go to the directory of this script
cd $DIR
#make a temporary directory secured in 'time & space'
TMPDIR=$( mktemp -d XXXXXXXXXX )
#catch exit of this script and delete temporary folder
trap 'cd $DIR && rm -rf "$TMPDIR"' EXIT
#move into the temporary folder
cd ${TMPDIR}
#create named pipes-global to all functions of this script
TMPSQL=mysql-$RANDOM.$RANDOM.$RANDOM.$$
TMPSCRIPT=myscript-$RANDOM.$RANDOM.$RANDOM.$$
mkfifo $TMPSQL
mkfifo $TMPSCRIPT
#exec 3<> ${DIR}/${TMPDIR}/$TMPSQL || (echo 'error'; exit 1)
#exec 4<> ${DIR}/${TMPDIR}/$TMPSCRIPT || ( echo 'error'; exit 1)
echo '===1.PARENT=== Starting background jobs...'
echo 'We can guarantee the succession only of 2->3,4 and 5->6,7 but NOT 3->4 or 6->7!'
worker &
##################################
cat $TMPSQL #make a blocking read!
##################################
echo '===4.PARENT=== ...1st query has been read'
##################################
cat $TMPSQL #make a blocking read!
##################################
echo '===7.PARENT=== ...2nd query has been read'
#don't you dare to exit!
##################################
cat $TMPSQL #make a blocking read!
##################################
}
################################################################################
## A job spawned by the dispatcher ##
#------------------------------------------------------------------------------#
################################################################################
function worker() {
echo "===2.CHILD=== Executing 1st query......writing to $TMPSQL"
#the dash symbol '-' makes tabs at the beginning of line to be
#ignored inside the here-doc but improves formation!
mysql_client <<- QUERY
\! tee $TMPSQL
use test;
select * from customers;
\! echo '===3.CHILD=== End 1st query'
#####################################
#\. $TMPSCRIPT
#####################################
QUERY
echo "===5.CHILD=== Executing 2nd query......writing to $TMPSQL"
mysql_client <<- QUERY
\! tee $TMPSQL
use test;
select * from cars;
\! echo '===6.CHILD=== End 2nd query'
#####################################
#\. $TMPSCRIPT
#####################################
QUERY
echo '===8.CHILD=== End of background jobs'
echo > $TMPSQL
}
#parse command line arguments
parse_args
#initialize variables
init_vars
#call dispatcher
dispatcher
「テスト」データベースがあると仮定すると、次の出力が表示されます。
===1.PARENT=== Starting background jobs...
We can guarantee the succession only of 2->3,4 and 5->6,7 but NOT 3->4 or 6->7!
===2.CHILD=== Executing 1st query......writing to mysql-30627.1495.5394.7533
===4.PARENT=== ...1st query has been read
id_customer firstname secondname
1 John Pincolo
2 Mark Denonto
3 Ann Curtis
4 Jeny Wirth
===3.CHILD=== End 1st query
===5.CHILD=== Executing 2nd query......writing to mysql-30627.1495.5394.7533
===7.PARENT=== ...2nd query has been read
id_car type plate date_rent date_returned
1 fiat BG-457 2012-07-18 00:00:00 2012-07-20 00:00:00
2 renault AS-1234 2012-07-20 00:00:00 2012-07-25 00:00:00
3 fiat JYB-2856 2012-06-23 00:00:00 2012-06-24 00:00:00
===6.CHILD=== End 2nd query
===8.CHILD=== End of background jobs
ご覧のとおり、2 から 5 の間には、最初のデータベースの結果セットがあります。クエリと「メイン」プログラムの間の中間結果が必要でした。
「ねえ、データベース ロックを取得したいのですが、私の「メイン」プログラムが何か他のことをしている間、フリーズという点でセッションを停止してください!」まあ、答えもあります。関数 'worker' には 2 つのコメント付きコマンドがあります。
#####################################
#\. $TMPSCRIPT
#####################################
それらを有効にすると、実行がハングします!!! それでおしまい!これで、ディスパッチャで作業を開始できます。完了したら、次のように「エコー」を送信します。
echo > $TMPSCRIPT
このコード行をワーカーに追加することで、ディスパッチャーとワーカーの両方をブロック スレッドに変換しました。これで、両方が相互にリッスンします。概略的に:
dispatcher
| start
A ----------------> worker
| |
B (read blocks) C
| signals |
B (unblocks)<--------------- D (write blocks)
| |
E (1st set of results) F
| |
| G (read blocks)
| signals |
H ----------------> G (unblocks)
| (write blocks) |
もっと興奮が必要なら、送信はどうですか
echo 'set @x=@x+1;' > $TMPSCRIPT
'@x' はユーザー定義変数です! ここには何がありますか?さて、SQL ジョブにライブ コードを「注入」しただけです。素晴らしい以上!!!
これで、データベースの LOCK を取得し、論理バックアップを作成し、mysql クライアントを停止して続行し、データベースの LOCK がまだアクティブな間、好きなことを行うことができます!
バイナリ バックアップの作成についてはどうでしょうか。(年間 2,000 ~ 10,000 米ドル節約できました。https ://shop.oracle.com を参照してください)
10 個のデータベースをロックしてバックアップを開始できます。最初に完了したデータベースはディスパッチャに確認を送信し、ディスパッチャは空になるまでリストに別のデータベースを追加します。すべてのワーカーが双方向ロックのために 2 つのロックを必要とすることだけを覚えておいてください。
3 つのディスパッチャを同時に開始することもできます。それらの名前付きパイプは空間内で一意であるため、それらの名前付きパイプの衝突に直面することは不可能だからです。
それが私の2,000ドルのアドバイスです
甘い!
(百人隊長)