手元の環境で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 件のコメント :
コメントを投稿