MySQL官方文档 http://dev.mysql.com/doc/refman/5.1/zh/index.html
13.4.5. LOCK TABLES和UNLOCK TABLES语法
LOCK TABLES
tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}
[, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}] ...
UNLOCK TABLES
LOCK TABLES可以锁定用于当前线程的表。如果表被其它线程锁定,则造成堵塞,直到可以获取所有锁定为止。UNLOCK TABLES可以释放被当前线程保持的任何锁定。当线程发布另一个LOCK TABLES时,或当与服务器的连接被关闭时,所有由当前线程锁定的表被隐含地解锁。
表锁定只用于防止其它客户端进行不正当地读取和写入。保持锁定(即使是读取锁定)的客户端可以进行表层级的操作,比如DROP TABLE。
注意,下面是对事务表使用LOCK TABLES的说明:
· 在尝试锁定表之前,LOCK TABLES不是事务安全型的,会隐含地提交所有活性事务。同时,开始一项事务(例如,使用START TRANSACTION),会隐含地执行UNLOCK TABLES。(见13.4.3节,“会造成隐式提交的语句”。
· 对事务表(如InnoDB)使用LOCK TABLES的正确方法是,设置AUTOCOMMIT=0并且不能调用UNLOCK TABLES,直到您明确地提交事务为止。当您调用LOCK TABLES时,InnoDB会内部地取其自己的表锁定,MySQL取其自己的表锁定。InnoDB在下一个提交时释放其表锁定,但是,对于MySQL,要释放表锁定,您必须调用UNLOCK TABLES。您不应该让AUTOCOMMIT=1,因为那样的话,InnoDB会在调用LOCK TABLES之后立刻释放表锁定,并且很容易形成死锁定。注意,如果AUTOCOMMIT=1,我们根本不能获取InnoDB表锁定,这样就可以帮助旧的应用软件避免不必要的死锁定。
· ROLLBACK不会释放MySQL的非事务表锁定。
要使用LOCK TABLES,您必须拥有相关表的LOCK TABLES权限和SELECT权限。
使用LOCK TABLES的主要原因是仿效事务,或在更新表时加快速度。这将在后面进行更详细的解释。
如果一个线程获得对一个表地READ锁定,该线程(和所有其它线程)只能从该表中读取。如果一个线程获得对一个表的WRITE锁定,只有保持锁定的线程可以对表进行写入。其它的线程被阻止,直到锁定被释放时为止。
READ LOCAL和READ之间的区别是,READ LOCAL允许在锁定被保持时,执行非冲突性INSERT语句(同时插入)。但是,如果您正打算在MySQL外面操作数据库文件,同时您保持锁定,则不能使用READ LOCAL。对于InnoDB表,READ LOCAL与READ相同。
当您使用LOCK TABLES时,您必须锁定您打算在查询中使用的所有的表。虽然使用LOCK TABLES语句获得的锁定仍然有效,但是您不能访问没有被此语句锁定的任何的表。同时,您不能在一次查询中多次使用一个已锁定的表——使用别名代替,在此情况下,您必须分别获得对每个别名的锁定。
mysql> LOCK TABLE t WRITE, t AS t1 WRITE;
mysql> INSERT INTO t SELECT * FROM t;
ERROR 1100: Table 't' was not locked with LOCK TABLES
mysql> INSERT INTO t SELECT * FROM t AS t1;
如果您的查询使用一个别名引用一个表,那么您必须使用同样的别名锁定该表。如果没有指定别名,则不会锁定该表。
mysql> LOCK TABLE t READ;
mysql> SELECT * FROM t AS myalias;
ERROR 1100: Table 'myalias' was not locked with LOCK TABLES
相反的,如果您使用一个别名锁定一个表,您必须使用该别名在您的查询中引用该表。
mysql> LOCK TABLE t AS myalias READ;
mysql> SELECT * FROM t;
ERROR 1100: Table 't' was not locked with LOCK TABLES
mysql> SELECT * FROM t AS myalias;
WRITE锁定通常比READ锁定拥有更高的优先权,以确保更新被尽快地处理。这意味着,如果一个线程获得了一个READ锁定,则另一个线程会申请一个WRITE锁定,后续的READ锁定申请会等待,直到WRITE线程获得锁定并释放锁定。您可以使用LOW_PRIORITY WRITE锁定来允许其它线程在该线程正在等待WRITE锁定时获得READ锁定。只有当您确定最终将有一个时机,此时没有线程拥有READ锁定时,您才应该使用LOW_PRIORITY WRITE锁定。
LOCK TABLES按照如下方式执行:
1. 按照内部定义的顺序,对所有要被锁定的表进行分类。从用户的角度,此顺序是未经定义的。
2. 如果使用一个读取和一个写入锁定对一个表进行锁定,则把写入锁定放在读取锁定之前。
3. 一次锁定一个表,直到线程得到所有锁定为止。
该规则确保表锁定不会出现死锁定。但是,对于该规则,您需要注意其它的事情:
如果您正在对一个表使用一个LOW_PRIORITY WRITE锁定,这只意味着,MySQL等待特定的锁定,直到没有申请READ锁定的线程时为止。当线程已经获得WRITE锁定,并正在等待得到锁定表清单中的用于下一个表的锁定时,所有其它线程会等待WRITE锁定被释放。如果这成为对于应用程序的严重的问题,则您应该考虑把部分表转化为事务安全型表。
您可以安全地使用KILL来结束一个正在等待表锁定的线程。请参见13.5.5.3节,“KILL语法”。
注意,您不能使用INSERT DELAYED锁定任何您正在使用的表,因为,在这种情况下,INSERT由另一个线程执行。
通常,您不需要锁定表,因为所有的单个UPDATE语句都是原子性的;没有其它的线程可以干扰任何其它当前正在执行的SQL语句。但是,在几种情况下,锁定表会有好处:
· 如果您正在对一组MyISAM表运行许多操作,锁定您正在使用的表,可以快很多。锁定MyISAM表可以加快插入、更新或删除的速度。不利方面是,没有线程可以更新一个用READ锁定的表(包括保持锁定的表),也没有线程可以访问用WRITE锁定的表(除了保持锁定的表以外)。
有些MyISAM操作在LOCK TABLES之下更快的原因是,MySQL不会清空用于已锁定表的关键缓存,直到UNLOCK TABLE被调用为止。通常,关键缓存在每个SQL语句之后被清空。
· 如果您正在使用MySQL中的一个不支持事务的存储引擎,则如果您想要确定在SELECT和UPDATE之间没有其它线程,您必须使用LOCK TABLES。本处所示的例子要求LOCK TABLES,以便安全地执行:
· mysql> LOCK TABLES trans READ, customer WRITE;
· mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id;
· mysql> UPDATE customer
· -> SET total_value=sum_from_previous_statement
· -> WHERE customer_id=some_id;
· mysql> UNLOCK TABLES;
如果没有LOCK TABLES,有可能另一个线程会在执行SELECT和UPDATE语句之间在trans表中插入一个新行。
通过使用相对更新(UPDATE customer SET value=value+new_value)或LAST_INSERT_ID()函数,您可以在许多情况下避免使用LOCK TABLES。请参见1.8.5.3节,“事务和原子操作”。
通过使用用户层级的顾问式锁定函数GET_LOCK()和RELEASE_LOCK(),您也可以在有些情况下避免锁定表。这些锁定被保存在服务器中的一个混编表中,使用pthread_mutex_lock() 和pthread_mutex_unlock(),以加快速度。请参见12.9.4节,“其他函数”。
要了解更多有关锁定规则的说明,请参见7.3.1节,“锁定方法”。
您可以使用FLUSH TABLES WITH READ LOCK语句锁定位于所有带有读取锁定的数据库中的所有表。请参见13.5.5.2节,“FLUSH语法”。如果您有一个可以及时拍摄快照的文件系统,比如Veritas,这是获得备份的一个非常方便的方式。
注释:如果您对一个已锁定的表使用ALTER TABLE,该表可能会解锁。
- 浏览: 890910 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
zzuliuli:
很实用,一直关注
mysql的执行计划 -
rxin2009:
你好,最近在解决redis数据同步的问题,找到了tedis,但 ...
taobao/tedis的redis集群 -
zhangping2056:
楼主接下来要考虑页面静态化与细节上面的东西了
Nginx与Redis解决高并发问题 -
XieFuQ:
Tomcat的重启shell脚本 -
jovinlee:
jovinlee 写道 jov ...
Tomcat的重启shell脚本
发表评论
-
mysql-覆盖索引
2019-09-19 09:46 0思维导图-索引篇 系列思维导图源文件(数据库+架构) ... -
MySQL高性能优化规范建议
2019-09-19 09:26 0作者: 听风,原文地址: https://www.cnb ... -
事务的四种隔离级别
2019-09-19 08:50 0数据库事务的隔离级别有4种,由低到高分别为Read unco ... -
TCC 分布式事务
2019-09-11 09:30 0https://www.cnblogs.com/jajia ... -
终于明白为什么要“分库分表”了!
2019-09-11 09:28 0例如:单表中出现了,动辄百万甚至千万级别的数据。“分表分库” ... -
数据同步利器-otter的搭建使用说明
2019-09-11 09:26 0本文链接:https://blog.cs ... -
springboot+mycat数据库中间件+mysql(一主一备)主从复制
2019-09-11 09:05 0springboot+mycat数据库中 ... -
分布式数据库中间件Mycat百亿级数据存储(转)
2019-09-11 09:04 0此文转自: https://www.jiansh ... -
Mysql+Mycat实现数据库主从同步与读写分离
2019-09-11 09:03 0此文章源于 对文章中的架构扩展介绍,之前写过一篇关于M ... -
mysql主从复制
2016-09-26 10:31 613mysql主从复制(超简单) 怎么安装mysql数据库 ... -
mysql记录耗时的sql
2014-08-21 10:11 1243author:skatetime:2012/02/17mys ... -
mysql-锁表机制分析
2014-08-12 15:20 559为了给高并发情况下的 ... -
MyISAM InnoDB 区别
2014-08-12 15:18 526MyISAM 和 InnoDB 讲解 InnoDB和 ... -
MySQL行锁深入研究
2014-08-12 15:10 655做项目时由于业务逻辑的需要,必须对数据表的一行或多行加入行锁 ... -
MySQL批量数据导入Load data infile解决方案
2013-12-30 15:52 1999转自:http://www.veryphp.cn/datas ... -
mysql load
2013-12-16 18:36 0http://bugs.mysql.com/bug.php? ... -
MySQL监控所用到的常用命令
2013-12-03 16:13 566转自:http://www.easywu.com/?p=35 ... -
Mysql的存储引擎在InnoDB和MyISAM时的锁
2013-11-11 09:23 880mysql查询更新时的锁表机制分析 为了给高并发情 ... -
MySQL innoDB insert into性能优化
2013-11-10 15:58 2211起因:有一个innoDB引擎的表Table,在一个大概3000 ... -
Mysql(MyISAM)的读写互斥锁问题的解决方法
2013-11-10 15:45 966最近因为数据库读的请求增加,出现了比较严重的读写锁问题,由于 ...
相关推荐
来自一线大厂的MySQL lock 隔离级别的相关介绍,很赞,强烈推荐
标题“mysql Unable to lock ./ibdata1, error: 11”所反映的问题是MySQL数据库在运行过程中遇到了一个常见的错误,提示无法锁定数据文件`ibdata1`,错误代码11。这个错误通常与数据库的表空间管理、并发操作或者...
若MySQL lock文件导致无法启动,可删除`/var/lock/subsys/mysql`,或在`/etc/rc.local`末尾添加启动命令。 ### 安装Apache 1. 解压httpd-2.2.11.tar.gz。 2. 进入解压后的目录,配置Apache安装路径和启用模块:`./...
【MySQL启动报错问题InnoDB:Unable to lock/ibdata1 error】是一个常见的MySQL服务器启动时遇到的问题。这个问题通常表明MySQL的InnoDB存储引擎无法获取对`ibdata1`文件的锁,`ibdata1`是InnoDB用来存储数据和系统表...
MySQL的InnoDB存储引擎在处理自动递增列(auto_increment)时,会受到`innodb_autoinc_lock_mode`参数的影响。这个参数决定了在插入数据时如何管理自动递增锁,从而影响性能和数据一致性。接下来,我们将深入探讨这...
error 日志当中的记录: [ERROR] Fatal error: Can’t open and lock privilege tables: Table ‘mysql.host’ doesn’t exist 从发了帖子,只有人看,没有人回复,看到这种情况只能自己解决问题了,自己动手...
go-mysql-lock提供基于MySQL的锁定原语锁定名称是字符串,MySQL对64个字符的锁定名称强制使用最大长度。 用例 尽管Zookeeper和etcd等系统提供了成熟的锁定原语,但是当您拥有一个主要依赖MySQL的正常运行时间和运行...
在使用MySQL数据库时,有时会遇到“MySQL is not running but lock exists”的错误,这通常意味着MySQL服务虽然没有运行,但系统中还存在一个锁文件,阻止了MySQL的正常启动。以下是一些解决此问题的步骤和相关的...
### MySQL服务无法启动(1067)问题解决 #### 背景介绍 在使用MySQL数据库的过程中,可能会遇到MySQL服务无法启动的情况,并且错误提示为“1067”。这种情况通常发生在Windows操作系统上,当MySQL服务试图启动时,会...
【MySQL只读模式详解】 当收到"The MySQL server is running with the –read-only option so it cannot execute this statement"的错误信息时,这意味着MySQL服务器被配置为了只读模式,不允许执行写入操作。这种...
MySQL数据库系统是广泛应用于各种业务场景的重要组件,但有时会遇到一些故障,如在本问题中描述的“MySQL启动后随即关闭”的问题。这个问题通常是由于数据库文件损坏,特别是`ibdata1`文件,它是InnoDB存储引擎的...
7.22 EXPLAIN (解释)句法(得到关于SELECT的信息) 7.23 DESCRIBE (描述)句法(得到列的信息) 7.24 LOCK TABLES/UNLOCK TABLES (锁定表/解锁表)句法 7.25 SET OPTION (设置选项)句法 7.26 ...
7.24 LOCK TABLES/UNLOCK TABLES (锁定表/解锁表)句法 7.25 SET OPTION (设置选项)句法 7.26 GRANT (授权)和REVOKE (撤回)句法 7.27 CREATE INDEX (创建索引)句法 7.28 DROP INDEX (抛弃索引)...
MySQL Connector/J是MySQL数据库与Java应用程序之间的重要桥梁,它是一个实现了Java Database Connectivity (JDBC) API的驱动程序,使得Java开发者能够方便地在Java应用中访问MySQL数据库。标题中的"mysql-connector...
MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景。而且,一旦alter table TableA的操作停滞在Waiting for table metadata lock的状态,后续对TableA的任何操作(包括读)...
05.innodb_lock.pdf 06.innodb_trx.pdf 07.btree.pdf 08.nf.pdf 09.explain.pdf 10.join.pdf 11.subquery.pdf 12.cursor.pdf 13.optimization.pdf 14.replication_1.pdf 14.troubleshooting.pdf 15....