mysql:8466
From: "江口" <"江口" <eguchi@xxxxxxxxxx>>
Date: Wed, 10 Dec 2003 14:40:19 +0900
Subject: [mysql 08466] innoDB の行排他ロックについて
はじめまして、江口と申します。よろしくお願いします。 以下の事例をご存知の方がおられましたら是非御教授頂きたく思います。 よろしくお願いします。 MySQLで大量データを持つ表に対しある処理で一部レコードを更新 しながら別の処理で他のレコードを更新することが実現可能か どうかの調査を行っており、Oracleでの開発を行った経験から 双方の処理で行の排他ロックを掛ける必要があると思っています。 しかし、以下の図の様に選択した行以外の行排他ロックを行おう としてもロック待ちが発生してしまいます。 テーブルロックがかかっているかの様です。 処理1 処理2 1 mysql> set autocommit=0; Query OK, 0 rows affected (0.00 sec) (mysql> set transaction isolation level READ COMMITTED;) 2 mysql> set autocommit=0; Query OK, 0 rows affected (0.00 sec) (mysql> set transaction isolation level READ COMMITTED;) 3 mysql> select * from tableA; +-------+------+------+ | keyno | dat1 | dat2 | +-------+------+------+ | 1 | 1 | 2 | | 2 | 1 | 2 | +-------+------+------+ 4 rows in set (0.00 sec) 4 mysql> select * from tableA where keyno = 1 for update; +-------+------+------+ | keyno | dat1 | dat2 | +-------+------+------+ | 1 | 1 | 2 | +-------+------+------+ 1 row in set (0.00 sec) 5 mysql> select * from tableA where keyno = 2 for update; ↑ここでロック解除待ちとなる。 ※set transaction isolation levelはセットしてもしなくても同じ現象が発生しま す。 解析する知識はありませんがこのときのInnoDB モニタの出力結果は 以下の様なものでした mysql> show innodb status\G *************************** 1. row *************************** Status: ===================================== 031210 10:27:42 INNODB MONITOR OUTPUT ===================================== Per second averages calculated from the last 40 seconds ---------- SEMAPHORES ---------- OS WAIT ARRAY INFO: reservation count 3, signal count 3 Mutex spin waits 0, rounds 0, OS waits 0 RW-shared spins 7, OS waits 3; RW-excl spins 1, OS waits 0 ------------ TRANSACTIONS ------------ Trx id counter 0 6922 Purge done for trx's n:o < 0 5387 undo n:o < 0 0 Total number of lock structs in row lock hash table 2 LIST OF TRANSACTIONS FOR EACH SESSION: ---TRANSACTION 0 0, not started, process no 2222, OS thread id 22541 MySQL thread id 13, query id 112 localhost rvan show innodb status ---TRANSACTION 0 6921, ACTIVE 20 sec, process no 2220, OS thread id 21516 starti ng index read mysql tables in use 1, locked 1 LOCK WAIT 2 lock struct(s), heap size 320 MySQL thread id 12, query id 102 localhost rvan Sending data select * from tableA where keyno = 2 for update ------- TRX HAS BEEN WAITING 20 SEC FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 0 page no 50 n bits 72 table DB_A/tableA index GEN_CLU ST_INDEX trx id 0 6921 lock_mode X waiting Record lock, heap no 2 RECORD: info bits 0 0: len 6; hex 000000000200; asc ..... .;; 1: ------------------ ---TRANSACTION 0 6920, ACTIVE 45 sec, process no 2218, OS thread id 20491 2 lock struct(s), heap size 320 MySQL thread id 11, query id 101 localhost rvan Trx read view will not see trx with id >= 0 6921, sees < 0 6921 -------- FILE I/O -------- I/O thread 0 state: waiting for i/o request (insert buffer thread) I/O thread 1 state: waiting for i/o request (log thread) I/O thread 2 state: waiting for i/o request (read thread) I/O thread 3 state: waiting for i/o request (write thread) Pending normal aio reads: 0, aio writes: 0, ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0 Pending flushes (fsync) log: 0; buffer pool: 0 45 OS file reads, 8 OS file writes, 8 OS fsyncs 0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s ------------------------------------- INSERT BUFFER AND ADAPTIVE HASH INDEX ------------------------------------- Ibuf for space 0: size 1, free list len 0, seg size 2, 0 inserts, 0 merged recs, 0 merges Hash table size 34679, used cells 0, node heap has 0 buffer(s) 0.00 hash searches/s, 0.00 non-hash searches/s --- LOG --- Log sequence number 0 54013 Log flushed up to 0 54013 Last checkpoint at 0 54013 0 pending log writes, 0 pending chkp writes 11 log i/o's done, 0.00 log i/o's/second ---------------------- BUFFER POOL AND MEMORY ---------------------- Total memory allocated 17490512; in additional pool allocated 668544 Buffer pool size 512 Free buffers 488 Database pages 24 Modified db pages 0 Pending reads 0 Pending writes: LRU 0, flush list 0, single page 0 Pages read 24, created 0, written 1 0.00 reads/s, 0.00 creates/s, 0.00 writes/s Buffer pool hit rate 1000 / 1000 -------------- ROW OPERATIONS -------------- 0 queries inside InnoDB, 0 queries in queue Main thread process no. 1080, id 7176, state: waiting for server activity Number of rows inserted 0, updated 0, deleted 0, read 48 0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.10 reads/s ---------------------------- END OF INNODB MONITOR OUTPUT ============================ 似たような事例がないか探したところ http://lists.mysql.com/bugs/14769 にほぼ同じ現象がありましたが、ここではこれはマニュアルに記述された予期され た振る舞いであると説明があります。 これが仕様なのか (だとしたらMySQLでは行排他ロックはどの様に実現すればよいのか?) または環境を作成する際に誤りがあったのか (構築した環境に誤りがある可能性は大いにあります。 rpmをダウンロードしてきて通常インストールしただけの状態です。 MySQLの知識はネット上の資料を読み始めて正味数日というところです。) 判断がつかずにおります。 環境は、mysqlbugの出力結果から抜粋してみましたが 以下のとおりです。(見にくいので折り返しました。) Server version 4.0.16-Max C compiler: 2.95.3 C++ compiler: 2.95.3 System: Linux 2.4.18-3 #1 Thu Apr 18 07:37:53 EDT 2002 i686 unknown gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-113) Compilation info: CC='gcc' CFLAGS='-O2 -mcpu=i486 -fno-strength-reduce' CXX='g++' CXXFLAGS='-O2 \ -mcpu=i486 -fno-strength-reduce -felide-constructors -fno-exceptions -fno-rtti \ ' LDFLAGS='' ASFLAGS='' LIBC: lrwxrwxrwx 1 root root 13 6月 19 16:38 /lib/libc.so.6 -> libc-2.2.5.so -rwxr-xr-x 2 root root 1260480 3月 6 2003 /lib/libc-2.2.5.so Configure command: ./configure '--disable-shared' '--with-mysqld-ldflags=-all-static' '--with-clien\ t-ldflags=-all-static' '--with-server-suffix=-standard' '--without-embedded-server' '--without-berk\ eley-db' '--with-innodb' '--without-vio' '--without-openssl' '--enable-assembler' '--enable-local-i\ nfile' '--with-mysqld-user=mysql' '--with-unix-socket-path=/var/lib/mysql/mysql.sock' '--prefix=/' \ '--with-extra-charsets=complex' '--exec-prefix=/usr' '--libexecdir=/usr/sbin' '--libdir=/usr/lib' '\ --sysconfdir=/etc' '--datadir=/usr/share' '--localstatedir=/var/lib/mysql' '--infodir=/usr/share/in\ fo' '--includedir=/usr/include' '--mandir=/usr/share/man' '--enable-thread-safe-client' '--with-com\ ment=Official MySQL RPM' 'CC=' 'CFLAGS=-O2 -mcpu=i486 -fno-strength-reduce' 'CXXFLAGS=-O2 -mcpu=i48\ 6 -fno-strength-reduce -felide-constructors -fno-exceptions -fno-rtti '\ 'CXX=' いずれにしても、大量データを持つ表に対しある処理で一部レコードを 更新しながら別の処理で他レコードを更新する必要がある場合どのような 方法で実現可能かご存知の方が方がおられましたら是非御教授頂きたく思います。 以上、よろしくお願いいたします。 *************************** (株)BCC ****************************** *産業システム本部第二システム部 江口 登美雄 mailto:eguchi@xxxxxxxxxx * ************* tel:092-711-5846 fax:092-711-5805 ********************** *7/22より電話番号、FAX番号が変わりました。
-> 8466 2003-12-10 14:40 ["江口" <eguchi@xxxxx] innoDB の行排他ロックについて 8467 2003-12-10 18:28 ┗[とみたまさひろ <tomm] 8468 2003-12-10 18:58 ┣["江口" <eguchi@xxxxx] 8471 2003-12-10 19:10 ┃┗["江口" <eguchi@xxxxx] 8469 2003-12-10 19:08 ┗["HIROSE, Masaaki" <h] 8472 2003-12-10 19:22 ┣["HIROSE, Masaaki" <h] 8483 2003-12-11 15:28 ┗["江口" <eguchi@xxxxx]