mysql行锁效率_Mysql InnoDB表锁问题

在讨论问题之前,先看下面的mysql信息

mysql> show status like "%table_lock%";

+-----------------------+---------+

| Variable_name | Value |

+-----------------------+---------+

| Table_locks_immediate | 1290950 |

| Table_locks_waited | 1069 |

+-----------------------+---------+

2 rows in set (0.01 sec)

mysql版本5.0.77, 使用的存储引擎是innodb,而该引擎最主要的特点是transactional和row lock。按理说不会出现表锁才对,但是事实是出现了,并且锁的争用很严重。

查看mysql文档会发现,虽然innodb使用的的row lock,但是在处理具有auto increment字段的表的时候,会使用一种特殊的表锁——AUTO-INC。简单来说就是innodb会在内存里保存一个计数器用来记录auto_increment的值,当插入数据时,就会用一个表锁来锁住这个计数器,直到插入结束。一条一条插入问题不大,但是如果高并发插入,就会造成sql阻塞。

目前已知的解决方法有两种:

不用auto increment字段,自己维护主键生成。该方法中选择主键生成策略很重要, 要综合考虑简单和效率问题。假设使用uuid,虽然简单但是会造成该表的主键效率很低(innodb的主键是特殊的index,其他的index会引用主键,详见mysql文档)。

升级到最新的5.1版本。mysql在5.1.22版本以后提供了不同方式的auto-inc配置

innodb_autoinc_lock_mode = 0 (“traditional” lock mode)

innodb_autoinc_lock_mode = 1 (“consecutive” lock mode)

innodb_autoinc_lock_mode = 2 (“interleaved” lock mode)

PS:使用复制功能时请详细阅读文档

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2009-02-23 13:27

浏览 3515

论坛回复 / 浏览 (1 / 3982)

分类:数据库

评论

1 楼

sdh5724

2009-03-06

不错, 不过, 你要这么高的写入性能? innodb合适么

### 回答1: MySQL中的行锁是指在执行SQL语句时对某一行数据进行锁定,以防止其他会话对该行进行修改或删除。当一个会话对某一行进行更新或删除操作时,MySQL会为该行加上行级锁,直到事务提交或回滚后才会释放。 在什么情况下升级为表锁? 当多个会话同时对表中的不同行进行更新或删除操作时,行级锁可能会导致死锁问题,影响数据库性能。此时,MySQL会自动将行锁升级为表锁,以避免死锁问题的发生。因此,当出现大量并发更新或删除操作时,MySQL可能会自动升级为表锁。 此外,也可以通过手动设置锁级别来控制MySQL的锁行为。例如,可以将锁级别设置为READ COMMITTED(读取已提交),在该级别下,MySQL会对读取的数据行进行共享锁,对更新和删除的数据行进行排它锁。如果需要对整个表进行操作,可以使用表级锁或表级共享锁。 ### 回答2: 在MySQL中,行锁表锁是两种不同级别的锁机制。通常情况下,MySQL会根据需要自动升级行锁表锁。主要有以下几种情况: 1. 锁定范围超出了行级别:当事务需要锁定的行数超过了MySQL设置的阈值时,MySQL会自动将行锁升级为表锁。这样做是为了减少锁的数量,提高并发性能。 2. 不同事务涉及到的行相互冲突:如果不同的事务需要锁定同一张表中的不同行,并且它们之间有冲突,那么MySQL会将行锁升级为表锁。这个冲突可能是由于事务之间的读写操作或写入冲突引起的。 3. 显式设置表锁:在一些特定情况下,我们可能需要显式地将行锁升级为表锁。这可以通过使用LOCK TABLES语句来实现。但是,这个操作需要小心使用,因为表锁会限制其他事务的读写操作。 需要注意的是,MySQL行锁表锁是根据实际情况进行升级的,并不是所有的行锁都会自动升级为表锁。升级为表锁的条件是符合上述所述的情况。在实际应用中,我们需要根据具体的业务需求和场景,合理选择和使用行锁表锁,以提高数据库的并发性和性能。 ### 回答3: MySQL中的行锁升级为表锁是在以下情况下发生的: 1. 事务涉及到的行数量超过了innodb_locks_unsafe_for_binlog的阈值,默认值是30000。如果一个事务涉及到的行数超过了这个阈值,行锁就会自动升级为表锁。这是为了防止由于行级锁过多导致事务无法进行的情况。 2. 出现了锁等待超时。当一个事务等待锁的时间超过了设置的超时时间(innodb_lock_wait_timeout),行锁也会自动升级为表锁。这个超时时间可以在MySQL的配置文件中进行设置。 需要注意的是,行锁升级为表锁可能会导致并发性能下降。因为表级锁会导致其他事务需要等待,无法并发执行。因此,在设计数据库时,需要合理使用行级锁和表级锁。对于并发读多写少的场景,可以使用行锁来提高并发性能。对于并发写多的场景,可以考虑使用表锁来避免锁冲突。此外,可以使用合理的索引设计来减少锁竞争,提高并发性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值