2012年9月28日金曜日

HandlerSocketの不思議な動作(まだ試す予定)

手元の環境でHandlerSocketと戯れていたら不思議な状態になった。

まずはHandlerSocketのRWポートでテーブルにアクセス。

$ telnet localhost 9999
..

P       0       d1      t1      PRIMARY num,val
0       1

0       =       1       1       1
0       2       1       c4ca4238a0b923820dcc509a6f75849b

コネクション張りっ放し。

別ターミナルからmysqlクライアントに入る。

mysql> lock table t1 write;

返ってこない。

更に別ターミナルからmysqlクライアント。

mysql> select count(*) from t1;

当然返ってこない。
PROCESSLISTはこんな感じになる。


mysql> show processlist;
+----+-------------+-----------------+---------------+---------+------+-------------------------------------------+-------------------------+
| Id | User        | Host            | db            | Command | Time | State                                     | Info                    |
+----+-------------+-----------------+---------------+---------+------+-------------------------------------------+-------------------------+
|  1 | system user | connecting host | NULL          | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL                    |
|  2 | system user | connecting host | NULL          | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL                    |
|  3 | system user | connecting host | NULL          | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL                    |
|  4 | system user | connecting host | NULL          | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL                    |
|  5 | system user | connecting host | handlersocket | Connect | NULL | handlersocket: mode=wr, 1 conns, 0 active | NULL                    |
|  6 | system user | connecting host | NULL          | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL                    |
|  7 | system user | connecting host | NULL          | Connect | NULL | handlersocket: mode=rd, 0 conns, 0 active | NULL                    |
| 13 | root        | localhost       | d1            | Query   |  229 | Waiting for table metadata lock           | lock table t1 write     |
| 14 | root        | localhost       | d1            | Query   |   10 | Waiting for table metadata lock           | select count(*) from t1 |
| 15 | root        | localhost       | d1            | Query   |    0 | NULL                                      | show processlist        |
+----+-------------+-----------------+---------------+---------+------+-------------------------------------------+-------------------------+
10 rows in set (0.00 sec)


ここまでは直感的なんだけど、更に別ターミナルでHandlerSocketを叩く。

$ telnet localhost 9999
..
P       1       d1      t1      PRIMARY num,val
0       1

1       =       1       100     1       0
0       2       100     f899139df5e1059396431415e770c6dd


あれ、読める。

一番最初のHandlerSocketを叩いてるtelnetを落とす。
LOCK TABLEが待つのは変わらない。
次につないだtelnetを落としてようやくWRITEロックが取れてLOCK TABLEが返ってくる。


これ、MyISAMにばんばん書く様な環境でHandlerSocketからもばんばん参照させると、
WRITEロックが取れずにクエリが滞留しまくるとか…?

RWポートだとこうだけど、ROポートからアクセスするとどうなるんだろうって気になってきた。
あとでやる。


【2012/09/28 12:03】
ROポート(9998)でも再現する。
でもMyISAMの更新は普通に出来た。
OPTIMIZE TABLEは止まったから、メタデータをロックしようとする奴だけかな。

0 件のコメント :

コメントを投稿