mysql innodb_table_locks_innodb_table_locks

关于innodb_table_locks,手册中在不同的位置对它的解释如下:

Starting from MySQL 4.0.20, and 4.1.2, InnoDB honors LOCK TABLES; MySQL does not return from LOCK TABLE .. WRITE until all other threads have released all their locks to the table. In MySQL 4.0.19 and before, InnoDB ignored table locks, which allowed one to more easily simulate transactions with a combination of MyISAM and InnoDB tables. The default value is 1, which means that LOCK TABLES causes also InnoDB internally to take a table lock. In applications using AUTOCOMMIT=1, InnoDB's internal table locks can cause deadlocks. You can set innodb_table_locks=0 in my.cnf to remove that problem. This option is not

available in MySQL 5.0.

LOCK TABLES sets table locks, but it is the higher MySQL layer above the InnoDB layer that sets these locks. Beginning with MySQL 4.0.20 and 4.1.2, InnoDB is aware of table locks if innodb_table_locks=1 and AUTOCOMMIT=0, and the MySQL layer above InnoDB knows about row-level locks. Otherwise, InooDB's automatic deadlock detection cannot detect deadlocks where such table locks are involved. Also, since the higher MySQL layer does not  know about row-level locks, it is possible to get a table lock on a table where another user currently has row-level locks. However, this does not endager transaction integrity, as discussed in Section 15.11.10, “Deadlock Detection and Rollback”. See also Section 15.17, “Restrictions onInnoDB Tables”.

A new startup option named innodb_table_locks was added that causes LOCK TABLE to

also acquire InnoDB table locks. This option is enabled by default. This can cause deadlocks in applications that use AUTOCOMMIT=1 and LOCK TABLES. If you application encounters deadlocks after upgrading, you may need to add innodb_table_locks=0 to your my.cnf file.

Beginning with MySQL 4.0.20 and 4.1.2, InnoDB is aware of table locks if innodb_

table_locks=1 (1 is the default), and the MySQL layer above it knows about row-level locks. Otherwise, InnoDB cannot detect deadlocks where a table lock set by a MySQL LOCK TABLES statement or a lock set by a storage engine other than InnoDB is involved. You must resolve these situations by setting the value of the innodb_lock_wait_timeout system variable.

Before MySQL 4.0.20 or 4.1.2, the MySQL LOCK TABLES operation does not know about

InnoDB row-level locks set by completed SQL statements. This means that you can get a table

lock on a table even if there still exist transactions by other users who have row level locks on

the same table. Thus your operations on the table may have to wait if they collide with these

locks of other users. Also a deadlock is possible. However, this does not endanger transaction integrity,

because the row level locks set by InnoDB always take care of the integrity. Also, a table

lock prevents other transactions from acquiring more row level locks (in a conflicting lock

mode) on the table.

Beginning with MySQL 4.0.20 and 4.1.2, the MySQL LOCK TABLES operation acquires two

locks on each table if innodb_table_locks=1. (1 is the default.) In addition to a table lock

on the MySQL layer, it also acquires an InnoDB table lock. Older versions of MySQL do not

acquire InnoDB table locks. Beginning with MySQL 4.0.22 and 4.1.7, the old behavior can be

selected by setting innodb_table_locks=0. If no InnoDB table lock is acquired, LOCK

TABLES completes even if some records of the tables are being locked by other transactions.

All InnoDB locks held by a transaction are released when the transaction is committed or aborted.

Thus, it does not make much sense to invoke LOCK TABLES on InnoDB tables in AUTOCOMMIT=

1 mode, because the acquired InnoDB table locks would be released immediately.

• Sometimes it would be useful to lock further tables in the course of a transaction. Unfortunately,

LOCK TABLES in MySQL performs an implicit COMMIT and UNLOCK TABLES. An InnoDB

variant of LOCK TABLES has been planned that can be executed in the middle of a transaction.

1. 从mysql4.0.20和4.1.2开始,Innodb开始支持innodb_table_locks(default 1)lock tables

lock table...write会等待所有其他线程释放表上的锁

2. innodb_table_locks缺省值为1, 意味着Innodb内部可以获得表锁

3. 如果autocommit=1,Innodb的内部表锁可能会导致deadlock

可以通过设置innodb_table_locks=0来解决这个问题

4. 这个参数从mysql5.0开始不再使用,明显是个过渡方案

5. 如果4.1.2-5.0之间版本设置innodb_table_locks=0,如果由于lock tables语句或者其它存储引擎设置了lock导致dead lock,Innodb将不能自动侦测到. 这时,必须设置innodb_lock_wait_timeout变量,使deadlock超时后rollback

Innodb事务回滚相关的信息如下:

When InnoDB performs a complete rollback of a transaction, all the locks of the transaction are released. However, if just a single SQL statement is rolled back as a result of an error, some of the locks set by the SQL statement may be preserved. This is because InnoDB stores row locks in a format such it cannot know afterward which lock was set by which SQL statement.

如果正常回滚,事务加的锁全部释放;否则如果回滚语句出错,导致只有事务中的部分语句被回滚掉,那有可能部分lock没有释放.因为Innodb不知道是哪条sql语句加的row lock

如果在mysql5.0以下,4.1.2以上版本发生莫名其妙的死锁问题,建议检查一下应用程序中是不是启动了autocommit=1(session的缺省设置)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值