为什么mysql里有些查询会出现locked呢

为什么mysql里有些查询会出现locked呢,第1张

MySQL的表锁定代码是不会死锁的。 MySQL使用表级锁定(而不是行级锁定或列级锁定)以达到很高的锁定速度。对于大表,表级锁定对大多数应用程序来说比行级锁定好一些,但是当然有一些缺陷。 在MySQL3.23.7和更高版本中,一个人能把行插入到MyISAM表同时其他线程正在读该表。注意,目前只有在表中内有删除的行时才工作。 表级锁定使很多线程能够同时读一个表,但是如果一个线程想要写一个表,它必须首先得到独占存取权。在更改期间,所有其他想要存取该特定表的线程将等到更改就绪。 因为数据库的更改通常被视为比SELECT更重要,更新一个表的所有语句比从一个表中检索信息的语句有更高的优先级。这应该保证更改不被“饿死”,因为一个人针对一个特定表会发出很多繁重的查询。 从MySQL 3.23.7开始,一个人可以能使用max_write_lock_count变量强制MySQL在一个表上一个特定数量的插入後发出一个SELECT。 对此一个主要的问题如下: 一个客户发出一个花很长时间运行的SELECT。 然後其他客户在一个使用的表上发出一个UPDATE;这个客户将等待直到SELECT完成。 另一个客户在同一个表上发出另一个SELECT语句;因为UPDATE比SELECT有更高的优先级,该SELECT将等待UPDATE的完成。它也将等待第一个SELECT完成! 对这个问题的一些可能的解决方案是: 试著使SELECT语句运行得更快;你可能必须创建一些摘要(summary)表做到这点。 用--low-priority-updates启动mysqld。这将给所有更新(修改)一个表的语句以比SELECT语句低的优先级。在这种情况下,在先前情形的最後的SELECT语句将在INSERT语句前执行。 你可以用LOW_PRIORITY属性给与一个特定的INSERT、UPDATE或DELETE语句较低优先级。 为max_write_lock_count指定一个低值来启动mysqld使得在一定数量的WRITE锁定後给出READ锁定。 通过使用SQL命令:SET SQL_LOW_PRIORITY_UPDATES=1,你可从一个特定线程指定所有的更改应该由用低优先级完成。见7.25 SET OPTION句法。 你可以用HIGH_PRIORITY属性指明一个特定SELECT是很重要的。见7.12 SELECT句法。 如果你有关于INSERT结合SELECT的问题,切换到使用新的MyISAM表,因为它们支持并发的SELECT和INSERT。 如果你主要混合INSERT和SELECT语句,DELAYED属性的INSERT将可能解决你的问题。见7.14 INSERT句法。 如果你有关于SELECT和DELETE的问题,LIMIT选项的DELETE可以帮助你。见7.11 DELETE句法。

当死锁发生后,通过服务端的Trace就可以将死锁信息传到日志。在SQL Server 2000时代,只能通过Trace flag 1204来开启,由于Trace flag 1204并不能提供XML死锁图,在SQL Server 2005以及之后的版本被Trace flag 1222所取代。

为了在服务端针对所有的Session开启Trace flag 1222。可以通过如代码所示。

DBCC TRACEON(1222,-1)

另一种方法是开启Profiler来捕捉,Profiler捕捉到的图示死锁信息内容就更直观了,


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/8589470.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-18
下一篇 2023-04-18

发表评论

登录后才能评论

评论列表(0条)

保存