Home

技術系のメモと日々の雑感

シェルスクリプトの多重起動を防ぐ簡単な方法

cron で 1 分ごとに実行するスクリプトがあって、処理に時間がかかると同時に走ってしまって変になることがあった。
こういう場合、処理中はフラグ代わりのファイルを作っておいて、終わったら消すのが一般的なのかな。
自分もしばらくこれでやってたんだけど、もうちょっといい方法がないか考えてみた。
で、思いついたのが

pgrep -f `basename $0` | wc -l > /tmp/.script.check
if [ `cat /tmp/.script.check` -ne 1 ]; then
  exit
fi

という処理をシェルスクリプトの先頭に書いておく方法。
バッククオートがネストできればもう少しきれいに書けるんだけどなぁ。
単純に ps の結果を grep すればいいんじゃないかなんて思ってしまうけど、やってみると意外と難しいね。

Domain-U 側で independent_wallclock の設定

Xen の Domain-0 と Domain-U で別々に時刻を設定するためにカーネルパラメータ independent_wallclock に 1 をセットする話の続き。
この前、とある Xen 環境の Domain-0 側で設定してみたら有効にならなくて、Domain-U 側では時刻が変更できなかった。
過去にやったときはこれで何の問題もなかったんだけどな。
特殊なハード構成でもないし、あきらめようかと思いつつ、ひょっとして Domain-U 側で設定したらどうなるのかと思って試してみたら、こっちでもいけることが分かった。
ふ〜ん。
こういうパターンもあるのか〜。
Domain-0 で一括で設定できた方がうれしいんだけど、まぁしょうがないね。

OpenVZ の中の様子

この前触ったレンタルサーバが OpenVZ で組まれていた。
環境の作り方によって変わるところがあると思うけど、ざっくり特徴をメモっておく。
まず驚いたのが /boot が空だったことと dmesg で何も表示されなかったこと。
ファイルシステムが /dev/simfs ってのも初めて見た。
スワップが割り当てられてないのにもびっくりしたけど、これも OpenVZ の特徴のひとつなんだね。
立ち上がっているプロセス、というか見えてるプロセスは異常に少なかった。

# ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:00 init [3]
 6141 pts/0    R+     0:00 ps ax
22009 ?        S<s    0:00 /sbin/udevd -d
22279 ?        Ss     0:00 syslogd -m 0
23766 ?        Ss     0:00 crond
24056 ?        Ss     0:00 /usr/sbin/sshd
32393 ?        Rs     0:00 sshd: root@pts/0
32638 pts/0    Ss     0:00 -bash

ちなみに chkconfig では

# chkconfig --list | grep :on
auditd          0:off   1:off   2:on    3:off   4:on    5:on    6:off
avahi-daemon    0:off   1:off   2:off   3:off   4:on    5:on    6:off
crond           0:off   1:off   2:on    3:on    4:on    5:on    6:off
gpm             0:off   1:off   2:on    3:off   4:on    5:on    6:off
haldaemon       0:off   1:off   2:off   3:off   4:on    5:on    6:off
iptables        0:off   1:off   2:on    3:off   4:on    5:on    6:off
lm_sensors      0:off   1:off   2:on    3:off   4:on    5:on    6:off
mcstrans        0:off   1:off   2:on    3:off   4:on    5:on    6:off
messagebus      0:off   1:off   2:off   3:off   4:on    5:on    6:off
netfs           0:off   1:off   2:off   3:off   4:on    5:on    6:off
network         0:off   1:off   2:on    3:on    4:on    5:on    6:off
portmap         0:off   1:off   2:off   3:off   4:on    5:on    6:off
rawdevices      0:off   1:off   2:off   3:on    4:on    5:on    6:off
restorecond     0:off   1:off   2:on    3:off   4:on    5:on    6:off
sendmail        0:off   1:off   2:on    3:off   4:on    5:on    6:off
sshd            0:off   1:off   2:on    3:off   4:on    5:on    6:off
syslog          0:off   1:off   2:on    3:on    4:on    5:on    6:off
xfs             0:off   1:off   2:on    3:off   4:on    5:on    6:off
xinetd          0:off   1:off   2:off   3:off   4:on    5:on    6:off
yum-cron        0:off   1:off   2:off   3:on    4:on    5:on    6:off

という具合に、有効になっているサービスが色々とあった。
ifconfig を実行すると

# ifconfig
venet0    Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:127.0.0.1  P-t-P:127.0.0.1  Bcast:0.0.0.0  Mask:255.255.255.255
          UP BROADCAST POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1
          RX packets:108297 errors:0 dropped:0 overruns:0 frame:0
          TX packets:70786 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:263497592 (251.2 MiB)  TX bytes:5248128 (5.0 MiB)

venet0:0  Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:XXX.XXX.XXX.XXX  P-t-P:XXX.XXX.XXX.XXX  Bcast:XXX.XXX.XXX.XXX  Mask:255.255.255.255
          UP BROADCAST POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1

なんだか見慣れない表示。
あと、目に付くところといったら /proc の下に vz というディレクトリがあって、veinfo と vestat という仮想ファイルが作られてたぐらいか。
残念ながらこの環境は短期間で使用しなくなってしまったので使い勝手は不明。
もっとじっくり見ておけばよかったなぁ。

The total number of locks exceeds the lock table size

MySQL のスレーブでエラー出た。
show slave status を見ると Last_Error が

Error 'The total number of locks exceeds the lock table size' on query. Default database: 'hoge'. Query: 'CREATE TABLE fuga SELECT * FROM fugafuga'

となっている。
Slave_IO_Running は Yes だけど Slave_SQL_Running は No だ。
後で分かったんだけど、エラーが出ているのは2台あるスレーブのうちの1台だけだった。
ログを見たら

100817  7:33:07 [ERROR] Slave SQL: Error 'The total number of locks exceeds the lock table size' on query. Default database: 'hoge'. Query: 'CREATE TABLE fuga SELECT * FROM fugafuga', Error_code: 1206
100817  7:33:07 [Warning] Slave: The total number of locks exceeds the lock table size Error_code: 1206
100817  7:33:07 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.000038' position 616542968

と出ていたので stop slave して start slave したら、ひとまずエラーは消えた。
でも Exec_Master_Log_Pos の値が変わらず、Read_Master_Log_Pos の値がどんどん離れていく。
そしてしばらくしたら再発。
一時的なエラーかと思ったけど、そうじゃないんだね。
情報を探してみると、innodb_buffer_pool_size の値が小さいときに出ることがあるらしい。
そういえば、とある事情でこっちのスレーブだけデフォルト値(8MB)を使っていたんだった。
値を増やしたら今度は大丈夫そう。
Seconds_Behind_Master が 687765 なんて値になっていたけど、少しずつ減っていっている。
このスレーブは InnoDB 関係のパラメータを全部見直して環境を作り直す予定だったんで、まぁ起こるべくして起きたエラーといったところか。
それにしても、定期的に show slave status をチェックする仕組みを入れておいてよかった〜。

CentOS と 3ware 8006-2LP

3ware 8006-2LP でミラーを組んで CentOS 5.4 を入れる機会があったので、気づいたことなどをメモ。
ドライバは勝手に入るので特に引っかかるところはなかった。
RAID0 にしろ RAID1 にしろ、インストーラでディスクが1本に見えているのが確認できたら大丈夫だろう。
他のサイトにも書かれている通り、付属の CD に入っている 3dmd は動かなかったので、メーカのサイトから最新版をダウンロードして入れた。
ちなみに Java 版でないとうまく入らなかった。

cd /tmp
wget http://www.lsi.com/DistributionSystem/AssetDocument/3DM2_CLI-Linux-9.5.3.zip
unzip 3DM2_CLI-Linux-9.5.3.zip
tar zxvf 3DM2_CLI-Linux-x86-9.5.3.tgz
chmod 700 setupLinux_x86.bin
./setupLinux_x86.bin -console

ところで、ここまで終われば ps で /usr/sbin/3dm2 が起動していることが分かる。
リブートしてもちゃんと立ち上がってくるんで、どこから呼ばれているのかと思ったら /etc/rc.d/init.d/tdm2 だった。
888 ポートで 3dm2 のページにも無事にアクセスできたので、ここらで dmesg を眺めてみよう。
関係があるメッセージは

3ware Storage Controller device driver for Linux v1.26.03.000-2.6.18RH.
3w-xxxx: AEN: ERROR: Unit degraded: Unit #0.
scsi0 : 3ware Storage Controller
3w-xxxx: scsi0: Found a 3ware Storage Controller at 0xe400, IRQ: 193.
  Vendor: 3ware     Model: Logical Disk 0    Rev: 1.2
  Type:   Direct-Access                      ANSI SCSI revision: 00
SCSI device sda: 976769007 512-byte hdwr sectors (500106 MB)
sda: Write Protect is off
sda: Mode Sense: 00 00 00 00
SCSI device sda: drive cache: write back, no read (daft) w/ FUA
sda: sda1 sda2 sda3
sd 0:0:0:0: Attached scsi disk sda
3w-xxxx: scsi0: Command failed: status = 0xc4, flags = 0x31, unit #0.
3w-xxxx: scsi0: AEN: INFO: Rebuild started: Unit #0.

といったところかな。
片方のディスクを外してリビルドのテストをしていたので degraded って出てる。
Command failed って出てるのもそのせいなのかな。
そのままひと晩放置して翌日見たら

3w-xxxx: scsi0: AEN: ERROR: Drive error: Port #1.
3w-xxxx: scsi0: AEN: ERROR: Rebuild failed: Unit #0.

見事にリビルドが失敗してた。
後で分かったことだけど、RAID を構成して起動した直後は Initialize がかなり長い時間走っていたから、どうやらこの処理中に片方の HDD を外してしまったらしい。
念のため Initialize が完了するのをちゃんと確認してからやり直してみたら

3w-xxxx: scsi0: AEN: INFO: Rebuild started: Unit #0.
3w-xxxx: scsi0: AEN: INFO: Rebuild complete: Unit #0.
3w-xxxx: scsi0: AEN: WARNING: SMART threshold exceeded: Port #0.

無事リビルド完了。
I/O の速度が出ないことを除けば問題なさそう。