MYSQLを使用した「らじる☆らじる」の録音と再生 で紹介していた録音が先週の早朝(2018年1月24日午前6時過ぎ)に突然動作しなくなりました。
そのような時刻に何か設定変更をしているはずもなく、停電などによるサーバー停止なども確認できませんでした。
色々原因を探っていたところ、どうやらMYSQLのinto dumfile 文とload_file()関数が期待通りの挙動をしなくなっていたことが先日わかりました。
具体的には、
select sound into dumpfile "$file" from t_sound;
で、secure_file_priv で指定されたディレクトリにファイルを作成すると、所有者が通常とは異なるユーザ(ユーザー名:mysql)となってしまうのです。このため、作成したファイル$fileが消去も含めてアドミニストレータ権限でないとできなくなっていたのです。
同様に、load_file()関数も所有者がmysqlであるファイルでないと、NULL値となってしまっていました。
時間帯を考慮すると、おそらく自動アップデートによりレビジョンアップが行われたのだと推測できます。この動作は「ファイルはすべてのユーザーから読み取り可能」「上記の条件が満たされていないために、ファイルを読み取ることができない場合、この関数は NULL
を返します。」というload_file()関数の仕様を満たしています。しかし、私が期待していた「ゆるい」動作ではなくなってしまったということです。
MYSQLでのバイナリデータの取り扱いを更に増やしてゆこうと考えていたところだったので困っています。バイナリを使わない下記のような方法も考えてみましたが、mysqldへの負担が半端ではなかったため、現在停止させています。
登録側
#!/bin/bash mysql nhkradio << _SQL_ create table if not exists t_sound( seq int, estimate datetime, sub_seq int, sound int, INDEX(estimate) ); create table if not exists t_volume( seq int primary key auto_increment, DLdate datetime, estimate datetime, number int, fullname varchar(100), rms double, INDEX(estimate) ); _SQL_ if [ -z $num ] ; then echo "num が不明";exit;fi if [ -z "$estimate" ] ; then echo "推定時刻が空白";exit;fi if [ -z "$fullname" ] ; then echo "URL が不明";exit;fi if [ -z "$rms" ] ; then echo "音量 が不明";exit;fi if [ ! -e $num.raw ]; then echo "rawファイルがない";exit;fi seq=`\ mysql nhkradio -N << _SQL_ insert into t_volume(DLdate,estimate,number,fullname,rms) value(now(),"$estimate",$num,"$fullname",$rms); delete from t_sound where estimate <now() - interval 48 hour; delete from t_volume where estimate <now() - interval 48 hour; select last_insert_id(); _SQL_` cat $num.raw |\ od -w2 -t d2 -v -An |\ awk -v seq="$seq" -v estimate="$estimate" \ '{OFS=","}{print seq,estimate,NR,$1}' > loadfile.txt mysql nhkradio << _SQL_ load data local infile "loadfile.txt" into table t_sound fields terminated by "," (seq,estimate,sub_seq,sound); _SQL_ rm loadfile.txt
再生側
#!/bin/bash date1=`getparstr $# "$*" "date1"` date2=`getparstr $# "$*" "date2"` temp=`mktemp ./XXXX` mysql nhkradio -N << _SQL_ > $temp select sound from t_sound where "$date1"<=estimate and estimate<="$date2" order by seq,sub_seq; _SQL_ scilab -nw << _SCILAB_ fd=mopen('$temp','r'); a=mfscanf(-1,fd,'%d'); mclose(fd); y=a/(2^15); wavwrite(y, 8000, 'playback.wav'); _SCILAB_ #sox -r 8000 -c 1 -b 16 -e signed-integer playback.raw playback.wav aplay playback.wav rm $temp playback.wav