MySQL
提供: MoreslowlyWiki
MySQL 関係の話。
目次 |
unique index を単なる index にする
しげろ 2008年6月16日 (月) 16:01 (JST)
この件についてどこかにメモを残した気がするけど、忘れてしまったのでここにまた書いた。
参考:
show index from ...で、 Key_name (インデックス名) を確認する。
show index from テーブル名;
そして、alter table テーブル名 drop index ほげほげ とかで修正する。
alter table テーブル名 drop index インデックス名; alter table テーブル名 add index (カラム名);
テーブルが壊れたときの症状
テーブルの修復方法 (MySQL本家) も参考になる。
具体的にこんな症状が現れたとき、テーブルが壊れている可能性が高くて、そのときは REPAIR TABLE で直せるときがある。
- Error: 1062 SQLSTATE: 23000 (ER_DUP_ENTRY)
Message: '%s' は key %d において重複しています Message: Duplicate entry '%s' for key %d
これ↑見た目には、単なるキーの重複エラーだけど、そのキーで select して0件で、でも insert すると失敗するといった不思議な状態のとき、テーブルのインデックスが壊れている可能性がある。そしたら REPAIR TABLE をためしてみる。
> repair table ほげほげ; +-----------------+--------+----------+------------------------------------------+ | Table | Op | Msg_type | Msg_text | +-----------------+--------+----------+------------------------------------------+ | なにか.ほげほげ | repair | warning | Number of rows changed from 2231 to 2232 | | なにか.ほげほげ | repair | status | OK | +-----------------+--------+----------+------------------------------------------+ 2 rows in set (0.06 sec) > repair table ほげほげ; +-----------------+--------+----------+----------+ | Table | Op | Msg_type | Msg_text | +-----------------+--------+----------+----------+ | なにか.ほげほげ | repair | status | OK | +-----------------+--------+----------+----------+ 1 row in set (0.01 sec)
実行時間を制限する
MySQL Forums :: MySQL Query Browser :: Limit execution time? によると、 MySQL で実行時間の制限をかけたいなら、自分で show processlist (MySQL) して pid を調べて kill (MySQL) するしかないみたい。
Python でそんなことをするスクリプトは、この節の下のほうにある。
本当なら、SQL文を見直したり、テーブル設計を工夫したり、パフォーマンスチューニングをしたりして、現実的な実行時間に必ず収まるようにするべきだとおもう。でも、そううまくいかなかったり、絶対に制限時間内にクエリを収めなきゃいけなくて、おさまらなかったら途中で終了させてもいいときとかは、 show processlist; して pid を調べて kill するしかないかもしれない。
それでテーブルが壊れることもある。壊れたら REPAIR TABLE で直す。
import MySQLdb
import dbconf
# ここで dbconf は、ホスト名とかパスワードなどの定数の定義が書かれているモジュールとする
TIMEOUT = 10
class DB:
def __init__(self):
self.conn = MySQLdb.connect(host=dbconf.DB_HOST, user='root', passwd=dbconf.DB_ROOT_PASS, \
port=dbconf.DB_PORT, db=dbconf.DB_NAME, unix_socket=dbconf.DB_SOCK)
def getProcessList(self):
cursor = self.conn.cursor()
cursor.execute('SHOW PROCESSLIST')
r = cursor.fetchall()
cursor.close()
return r
def kill(self, pid):
cursor = self.conn.cursor()
cursor.execute('KILL %d' % (pid))
r = cursor.fetchall()
cursor.close()
self.conn.commit()
class DBMonitor:
def __init__(self):
self.pidList = []
self.db = DB()
def monitor(self):
for process in self.db.getProcessList():
pid = process[0]
user = process[1]
dbName = process[3]
command = process[4]
time = process[5]
state = process[6]
sql = process[7]
# 実行ユーザが hoge で、データベースが foo で、クエリで、
# TIMEOUT秒以上 statistics とか Locked な状態で、 "SELECT " ではじまってる
# クエリを kill してしまう!!
if user == 'hoge' and dbName == 'foo' and command == 'Query' \
and time > TIMEOUT and (state == 'statistics' or state == 'Locked') \
and len(sql) > 7 and sql[0:7].lower() == 'select ':
self.db.kill(pid)
def main():
mon = DBMonitor()
while 1:
mon.monitor()
time.sleep(TIMEOUT)
if __name__ == '__main__':
main()
カラムに BINARY 属性がついているかどうか見る
次のようにして show full columns を使う。 MySQL AB :: MySQL 4.1 リファレンスマニュアル :: 4.6.8 SHOW 構文 を参照。
show full columns from table_name ;
具体的にはこうなる。Collation のところが、 BINARY だと utf8_bin となって、そうでないと utf8_general_ci となっている。
> create table testtab ( a varchar(12) binary); > show full columns from testtab ; +-------+-------------+-----------+------+-----+---------+-------+---------------------------------+---------+ | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | +-------+-------------+-----------+------+-----+---------+-------+---------------------------------+---------+ | a | varchar(12) | utf8_bin | YES | | NULL | | select,insert,update,references | | +-------+-------------+-----------+------+-----+---------+-------+---------------------------------+---------+ > show full columns from testtab ; +-------+-------------+-----------------+------+-----+---------+-------+---------------------------------+---------+ | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | +-------+-------------+-----------------+------+-----+---------+-------+---------------------------------+---------+ | a | varchar(12) | utf8_general_ci | YES | | NULL | | select,insert,update,references | | +-------+-------------+-----------------+------+-----+---------+-------+---------------------------------+---------+

