mysql8 翻译系列 五十三

2025-03-19  本文已影响0人  如风_dcac

10.11.2 表锁定问题

InnoDB表使用行级锁定,这样多个会话和应用程序可以同时对同一表进行读写操作,而无需相互等待或产生不一致的结果。对于这个存储引擎,应避免使用LOCK TABLES语句,因为它不会提供任何额外的保护,反而会降低并发性。自动行级锁定使这些表适用于处理最繁忙的数据库和最重要的数据,同时也简化了应用程序逻辑,因为无需对表进行加锁和解锁操作。因此,InnoDB存储引擎是MySQL的默认存储引擎。

除InnoDB外,MySQL对所有存储引擎都使用表锁定(而不是页锁定、行锁定或列锁定)。锁定操作本身的开销并不大。但是,由于在任何时刻只有一个会话可以对表进行写入操作,为了在使用这些其他存储引擎时获得最佳性能,应主要将它们用于查询频繁且很少进行插入或更新操作的表。

倾向于InnoDB的性能考量

在选择使用InnoDB还是其他存储引擎创建表时,请记住表锁定存在以下缺点:

锁定性能问题的解决方法

以下介绍一些避免或减少表锁定导致的争用的方法:

10.11.3 并发插入

MyISAM存储引擎支持并发插入,以此减少给定表上读写操作之间的争用:如果MyISAM表的数据文件中没有空洞(即中间不存在已删除的行),那么在SELECT语句从表中读取数据的同时,可以执行INSERT语句在表的末尾添加行。如果有多个INSERT语句,它们会被排队并按顺序执行,同时与SELECT语句并发执行。并发INSERT的结果可能不会立即显示出来。

concurrent_insert系统变量可用于修改并发插入的处理方式。默认情况下,该变量设置为AUTO(或1),并发插入的处理方式如上文所述。如果将concurrent_insert设置为NEVER(或0),则会禁用并发插入。如果将该变量设置为ALWAYS(或2),即使表中有已删除的行,也允许在表的末尾进行并发插入。另请参阅concurrent_insert系统变量的说明。

如果使用二进制日志,对于CREATE...SELECTINSERT...SELECT语句,并发插入会被转换为普通插入。这样做是为了确保在备份操作期间,通过应用日志能够精确地重新创建表的副本。请参见7.4.4节 “二进制日志”。此外,对于这些语句,会在被选择的表上放置读锁,从而阻止对该表的插入操作。其结果是,对该表的并发插入也必须等待。

使用LOAD DATA时,如果对满足并发插入条件(即中间不包含空闲块)的MyISAM表指定CONCURRENT,那么在执行LOAD DATA时,其他会话可以从该表检索数据。即使没有其他会话同时使用该表,使用CONCURRENT选项也会对LOAD DATA的性能产生一定影响。

如果指定HIGH_PRIORITY,若服务器是使用--low-priority-updates选项启动的,那么HIGH_PRIORITY会覆盖该选项的效果,并且也会导致不使用并发插入。

对于LOCK TABLEREAD LOCALREAD之间的区别在于,持有READ LOCAL锁时,允许不冲突的INSERT语句(即并发插入)执行。但是,如果在持有锁的同时要使用服务器外部的进程来操作数据库,则不能使用READ LOCAL锁。

上一篇 下一篇

猜你喜欢

热点阅读