[前][次][番号順一覧][スレッド一覧]

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]