`
kavy
  • 浏览: 866176 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

mysql LOCK

 
阅读更多

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,该表可能会解锁。

分享到:
评论

相关推荐

    MySQL lock & 隔离级别

    来自一线大厂的MySQL lock 隔离级别的相关介绍,很赞,强烈推荐

    MySQL启动报错问题InnoDB:Unable to lock/ibdata1 error

    主要介绍了MySQL启动报错问题InnoDB:Unable to lock/ibdata1 error,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    go-mysql-lock:MySQL支持的锁定基元

    go-mysql-lock提供基于MySQL的锁定原语锁定名称是字符串,MySQL对64个字符的锁定名称强制使用最大长度。 用例 尽管Zookeeper和etcd等系统提供了成熟的锁定原语,但是当您拥有一个主要依赖MySQL的正常运行时间和运行...

    关于MySQL innodb_autoinc_lock_mode介绍

    下面小编就为大家带来一篇关于MySQL innodb_autoinc_lock_mode介绍。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    mysql启动提示mysql.host 不存在,启动失败的解决方法

    error 日志当中的记录: [ERROR] Fatal error: Can’t open and lock privilege tables: Table ‘mysql.host’ doesn’t exist 从发了帖子,只有人看,没有人回复,看到这种情况只能自己解决问题了,自己动手...

    MySQL: mysql is not running but lock exists 的解决方法

    but lock exists: 一个网友说可能和log文件有关,于是将log文件给移除了,再重启MySQL终于OK了找了下资料,基本上都是说: 代码如下: # chown -R mysql:mysql /var/lib/mysql # rm /var/lock/subsys/mysql # ...

    mysql Unable to lock ./ibdata1, error: 11

    NULL 博文链接:https://yizhilong28.iteye.com/blog/1154092

    MYSQL METADATA LOCK(MDL LOCK)MDL锁问题分析

    主要介绍了MYSQL METADATA LOCK(MDL LOCK)MDL锁问题分析,并通过实例给大家例句的问题处理办法,需要的朋友参考学习下。

    MySQL中文参考手册.chm

    7.22 EXPLAIN (解释)句法(得到关于SELECT的信息) 7.23 DESCRIBE (描述)句法(得到列的信息) 7.24 LOCK TABLES/UNLOCK TABLES (锁定表/解锁表)句法 7.25 SET OPTION (设置选项)句法 7.26 ...

    MYSQL

    7.24 LOCK TABLES/UNLOCK TABLES (锁定表/解锁表)句法 7.25 SET OPTION (设置选项)句法 7.26 GRANT (授权)和REVOKE (撤回)句法 7.27 CREATE INDEX (创建索引)句法 7.28 DROP INDEX (抛弃索引)...

    MySQL出现Waiting for table metadata lock的原因方法

    MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景。而且,一旦alter table TableA的操作停滞在Waiting for table metadata lock的状态,后续对TableA的任何操作(包括读)...

    MySQL DBA培训全套教程

    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....

    MySQL服务无法启动(1067)问题解决

    MySQL服务无法启动(1067)问题解决

    MySQL 5.1中文手冊

    LOCK TABLES和UNLOCK TABLES语法 13.4.6. SET TRANSACTION语法 13.4.7. XA事务 13.5. 数据库管理语句 13.5.1. 账户管理语句 13.5.2. 表维护语句 13.5.3. SET语法 13.5.4. SHOW语法 13.5.5. 其它管理语句 13.6. 复制...

    mysql锁表解表

    MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景。而且,一旦alter table TableA的操作停滞在Waiting for table metadata lock的状态,后续对TableA的任何操作(包括读)...

    MySQL中文参考手册

    * 1 MySQL的一般的信息 o 1.1 什么是MySQL? o 1.2 关于本手册 + 1.2.1 本手册中使用的约定 o 1.3 MySQL的历史 o 1.4 MySQL的主要特征 o 1.5 MySQL稳定性? o 1.6 顺应2000年 o 1.7 SQL一般信息和教程 o ...

    MySQL表结构变更你不可不知的Metadata Lock详解

    想必玩过mysql的人对Waiting for table metadata lock肯定不会陌生,一般都是进行alter操作时被堵住了,导致了我们在show processlist 时,看到线程的状态是在等metadata lock。本文会对MySQL表结构变更的Metadata ...

    mysql5.1中文手册

    MySQL论坛上的MySQL社区支持 1.8. MySQL标准的兼容性 1.8.1. MySQL遵从的标准是什么 1.8.2. 选择SQL模式 1.8.3. 在ANSI模式下运行MySQL 1.8.4. MySQL对标准SQL的扩展 1.8.5. MySQL与标准SQL的...

Global site tag (gtag.js) - Google Analytics