如何对MySQL数据库表进行锁定

WHERE

相关文章: 如何进行MySQL数据库表的故障检测 如何修复MySQL数据库表 锁定表的方法 防止客户机的请求互相干扰或者与维护程序相互干扰的方法主要有多种。如果你关闭数据库,就可以保证和myisamchk和isamchk之间没有交互作用。但是停止的运

mysql查看锁表_mysql查看锁表命令mysql查看锁表_mysql查看锁表命令


mysql查看锁表_mysql查看锁表命令


另:

相关文章:

mysql>FLUSH TABLES;

如何进行MySQL数据库表的故障检测

如何修复MySQL数据库表

锁定表的方法

防止客户机的请求互相干扰或者与维护程序相互干扰的方法主要有多种。如果你关闭数据库,就可以保证和myisamchk和isamchk之间没有交互作用。但是停止的运行并不是一个好注意,因为这样做会使得没有故障的数据库和表也不可用。本节主要讨论的过程,是避免和myisamchk或isamchk之间的交互作用。实现这种功能的方法是对表进行锁定。

1.内部锁定

内部锁定可以避免客户机的请求相互干扰——例如,避免客户机的SELECT查询被另一个客户机的UPDATE查询所干扰。也可以利用内部锁定机制防止在利用myisamchk或isamchk检查或修复表时对表的访问。

语法:

锁定表:LOCK TABLES tbl_name {READ | WRITE},[ tbl_name {READ | WRITE},?]

解锁表:UNLOCK TABLES

如果一个线程获得在一个表上的一个READ锁,该线程(和所有其他线程)只能从表中读。如果一个线程获得一个表上的一个WRITE锁,那么只有持锁的线程READ或WRITE表,其他线程被阻止。

每个线程等待(没有超时)直到它获得它请求的所有锁。

WRITE锁通常比READ锁有更高的优先级,以确保更改尽快被处理。这意味着,如果一个线程获得READ锁,并且然后另外一个线程请求一个WRITE锁, 随后的READ锁请求将等待直到WRITE线程得到了锁并且释放了它。

显然对于检查,你只需要获得读锁。再者钟情跨下,只能读取表,但不能修改它,因此他也允许其它客户机读取表。对于修复,你必须获得些所以防止任何客户机在你对表进行作时修改它。

2.外部锁定

还可以使用外部锁定(文件级锁)来防止其它程序在使用表时修改文件。通常,在表的检查作中将外部锁定与myisamchk或isamchk作合使用。但是,外部锁定在某些系统中是禁用的,因为他不能可靠的进行工作。对运行myisamchk或isamchk所选择的过程取决于是否能使用外部锁定。如果不使用,则必修使用内部锁定协议。

◆ 如果skip_locking为off,则外部锁定有效您可以继续并运行人和一个实用程序来检查表。和实用程序将合作对表进行访问。但是,运行任何一个实用程序之前,应该使用mysqladmin flush-tables。为了修复表,应该使用表的修复锁定协议。

◆ 如果skip_locaking为on,则禁用外部锁定,所以在myisamchk或isamchk检查修复表示并不知道,关闭。如果坚持是保持开启状态,月确保在您使用此表示没有客户机来访问它。必须使用卡的锁定协议告诉是该表不被其他客户机访问。

检查表的锁定协议

本节只介绍如果使用表的内部锁定。对于检查表的锁定协议,此过程只针对表的检查,不针对表的修复。

1.调用mysql发布下列语句:

mysql>LOCK TABLE tbl_name READ;

该锁防止其它客户机在检查时写入该表和修改该表。FLUSH语句导致关闭表的文件,它将刷新仍在告诉缓存中的任何为写入的改变。

2.执行检查过程

$myisamchk tbl_name

$ isamchk tbl_name

3.释放表锁

mysql>UNLOCK TABLES;

如果myisamchk或isamchk指出发现该表的问题,将需要执行表的修复。

修复表的锁定协议

这里只介绍如果使用表的内部锁定。修复表的锁定过程类似于检查表的锁定过程,但有两个区别。,你必须得到写锁而非读锁。由于你需要修改表,因此根本不允许客户机对其进行访问。第二,必须在执行修复之后发布FLUSH TABLE语句,因为myisamchk和isamchk建立的新的索引文件,除非再次刷新改表的高速缓存,否则不会注意到这个改变。本例同样适合优化表的过程。

1.调用mysql发布下列语句:

mysql>LOCK TABLE tbl_name WRITE;

2.做数据表的拷贝,然后运行myisamchk和isamchk:

$cp tbl_name. /some/other/dir

$myisamchk --recover tbl_name

$ isamchk --recover tbl_name

--recover选项只是针对安装而设置的。这些特殊选项的选择将取决与你执行修复的类型。

3.再次刷新高速缓存,并释放表锁:

mysql>UNLOCK TABLES;

mysql update会锁表吗

锁的分类

对WRITE,MyS其它的线程被阻止,直到锁定被释放时为止。QL使用的表锁定方法原理如下:

对与read lock 和 write lock个人说明:

如果在表上没有锁,在它上面放一个写锁。

否则,把锁定请求放在写锁定队列中。

对READ,MySQL使用的锁定方法原理如下:

如果在表上没有写锁定,把一个读锁定放在它上面。

否则,把锁请求放在读锁定队列中。

当一个锁定被释放时,锁定可被写锁定队列中的线程得到,然后是读锁定队列中的线程。

这意味着,如果你在一个表上有许多更新,SELECT语句将等待直到没有更多的更新。

mysql数据库中,我用lock锁表后提示错误.劳驾帮忙看一下

这个完全取决于表采用的是什么存储引擎。

在 MySQL 中,如果你显式的执行锁定语句(LOCK Tables ...)

那么你必须一次锁定在解锁之前需要访问的所有表,

全局锁的定型使用场景,做全库逻辑备份。在Read Committed隔离级别下不能对锁住的表进行删,改作.(需要等待锁释放才能作...)也就是把整个库每个表都Select出来,然后存成文本。而且,如果你以读锁定方式锁定的表,则不能对该表进行写作,也就是说,你使用什么方式进行的锁定,就只能进行什么方式的作

甚至如果你在 Query 语句中使用了别名,那么在之前的锁定中也必须使用别名

mysql 锁表会出现什么情况

LOCK TABLES为当前线程锁定表。UNLOCK TABLES释放被当前线程持有的任何锁。当线程发出另外一个LOCK TABLES时,或当的连接被关闭时,当前线程锁定的所有表自动被解锁。

白话解说如下:

System.out.println("异常" + e.getMessage());

简单说,就是lock

table,不让别人动

锁分共享锁和排它锁。

共享锁时,别人能读,不能改变量表数据

排它锁时,别人既不能读,也不能改表数据

根据以上特点,应该就知道何时使用锁了。不想让别人变更数lock)据,对自己产生影响,就加锁。一定要在不用之后,进行锁释放,不然,应用系统会一直因为读取数据而报错。

好处就是,保证数据的原子性,完整性,一致性。

只有加锁者释放了锁,别人才能改变数据。

如何给mysql表上锁

id

希望一下内容对你有所帮助

lock)

锁定读SELECT ... FOR UPDATE和SELECT ... LOCK IN SHARE MODE

由两种表的锁定方法:

LOCK TABLES和UNLOCK TABLES语法

LOCK TABLES

tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}

UNLOCK TABLES

LOCK TABLES可以锁定用于当前线程的表。如果表被其它线程锁定,则造成堵塞,直到可以获取所有锁定为止。UNLOCK TABLES可以释放被当前线程保持的任何锁定。当线程发布另一个LOCK TABLES时,或当与的连接被关闭时,所有由当前线程锁定的表被隐含地解锁。

mysql中的锁都有哪些(mysql锁类型)

同时,您不能在一次查询中多次使用一个已锁定的表——使用别名代替,

MySQL中有哪些锁?

数据库中锁的设计初衷处理并发问题,作为多用户共享资源,当出现并发访问的时候,数据库需要合理控制资源访问规则。锁就是实现这些访问规则中的重要数据。

全3. 特别提示:有关MyISAM和InnoDB引擎的别和在工作中如何选择,在前面已经详细讲解过了,这里就不在讲了。局锁

全局锁,就是对整个数据库实例加锁,MySQL提供了一个加全局读锁的方法,命令是:

Flushtableswithreadlock(FTWRL)

当需要整个库只读状态的时候,可以使用这个命令,之后其他线程的:数据更新语句(增删改),数据定义语句(建表,修改表结构)和更新事务的提交语句将会被阻塞。

全局锁的使用场景

如何整个库都只读,会有什么问题?如果你在主库上备份,那么在备份期间都不能执行更想,业务就基本上停摆。如果在从库上备份,那么备份期间从库不能执行主库同步过来的binlog,会导致从延迟。既然要全库只读,为什么不使用setglobalreadonly=true的方式呢?

readonly方式也可以让全库进入只读状态,但我还是会建议你用FTWRL方式,主要有两个原因:

一是,在有些系统中,readonly的值会被用来做其他逻辑,比如用来判断一个库是主库还是备库。因此,修改global变量的方式影响面更大,我不建议你使用。二是,在异常处理机制上有异。如果执行FTWRL命令之后由于客户端发生异常断开,那么MySQL会自动释放这个全局锁,整个库回到可以正常更新的状态。而将整个库设置为readonly之后,如果客户端发生异常,则数据库就会一直保持readonly状态,这样会导致整个库长时间处于不可写状态,风险较高表级别锁

MySQL里面表级别的锁有两种:一种是表锁,一种是元数据锁(metadatalok,MDL)。表锁的语法是:

与FTWRL类似,可以使用unlocktables主动释放锁,也可以在客户端断开的时候自动释放。需要注意的是,locktables语法除了会限制别的线程的读写外,也限定了本线程接下来的作对象。

什么作会加MDL锁?

读锁之间不互斥,因此可以有多个线程同时对一张表增删改查。读写之间、写锁之间是互斥的,用来保证变更表结构作的安全性,如果有两个线程要同时给一个表加字段,其中一个要等另外一个执行完才能执行。更改表结构要注意哪些?

给一个表加字段,或者修改字段,或者加索引,需要扫描全表的数据。在对大表作的时候,你肯定会特别小心,以免对线上服务造成影响。而实际上,即使是小表,作不慎也会出问题,导致整个库的线程爆满。

举个例子

我们来看一下下面的作序列,设表t是一个小表。

image

sessionA先启动,这时候会对表t加一个MDL读锁。由于sessionB需要的也是MDL读锁,因此可以正常执行。sessionC会被blocked,是因为sessionA的MDL读锁还没有释放,而sessionC需要MDL写锁,因此只能被阻塞,读写锁互斥。如果只有sessionC自己被阻塞还没什么关系,但是之后所有要在表t上新申请MDL读锁的请求也会被sessionC阻塞。前面我们说了,所有对表的增删改查作都需要先申请MDL读锁,就都被锁住,等于这个表现在完全不可读写了。

如果某个表上的查询语句频繁,而且客户端有重试机制,也就是说超时后会再起一个新session再请求的话,这个库的线程很快就会爆满。事务中的M缺点就是,增加了系统开销,有可能产生锁等待,造成数据库运行异常。这都是不正常的使用锁带来的问题。DL锁,在语句执行开始时申请,但是语句结束后并不会马上释放,而会等到整个事务提交后再释放。

怎么解决这个更改表结构问题

比较理想的机制是,在altertable语句里面设定等待时间,如果在这个指定的等待时间里面能够拿到MDL写锁,拿不到也不要阻塞后面的业务语句,先放弃。ALTERTABLEtbl_nameNOWAITaddcolumn...ALTERTABLEtbl_nameWAITNaddcolumn...

ja程序中如何实现对mysql数据库中表的锁定

$mysql _oot _p db_name

方法1:用mysql命令锁住表.

MySQL 定义了四种隔离级别,指定事务中哪些数据改变其他事务可见、哪些数据该表其他事务不可见。低级别的隔离级别可以支持更高的并发处理,同时占用的系统资源更少

String sql = "lock tables aa1 write";

// 或String sql = "lock tables aa1 read";

// 如果想锁多个表 lock tables aa1 read ,aa2 write , .....

String sql1 = "select from aa1 ";

String sql2 = "unlock tables";

try {

this.pstmt1 = conn.prepareStatement(sql1);

this.pstmt2 = conn.prepareStatement(sql2);

pstmt1.executeQuery();

pstmt2.executeQuery();

} catch (Exception e) {

}}对于read lock 和 write lock说明:

1.如果一个线程获得一个表的READ锁定,该线程(和所有其它线程)只能从该表中读取。

如果一个线程获得一个表的WRITE锁定,只有保持锁定的线程可以对表进行写入。

2.当您使用LOCK TABLES时,您必须锁定您打算在查询中使用的所有的表。

虽然使用LOCKTABLES语句获得的锁定仍然有效,但是您不能访问没有被此语句锁定的任何的表。

在此情况下,您必须分别获得对每个别名的锁定。

1.read lock 和 write lock 是线程级(表级别).

2.在同一个会话中加了read lock锁. 只能对这个表进行读作.对这个表以外的任何表都无法进行增、删、改、查的作.

但是在不同会话中,只能对加了read lock的表进行读作.但可以对read lock以外的表进行增、删、改、查的作.

3.在同一个会话中加了write lock锁.只能对这个表进行读、写作.对这个表以外的任何表都无法进行增、删、改、查的作.

但是在不同会话中,无法对加了write lock的表进行读、写作.但可以对write lock以外的表进行增、删、改、查的作.

4.如果表中使用了别名.(SELECT FROM aa1 AS byname_table)

在对aa1加锁时,必须把别名加上去(lock tables aa1 as byname_table read)

在同一个会话中.必须使用别名进行查询.

在不同的会话中.可以不需要使用别名进行查询.

5.在多个会话中可以对同一个表进行lock read作.但不能在多个会话中对同一个表进行lock write作(这些锁将等待已锁的表释放自身的线程锁)

如果多个会话对同一个表进行InnoDB 系统级事务隔离级别可以使用以下语句设置:lock read作.那么在这些会话中,也只能对以锁的表进行读作.

6.如果要你锁住了一个表,需要嵌套查询.你必须使用别名,并且,要锁定别名.

例如.lock table aa1 read ,aa1 as byname_table read;

select from aa1 where id in (select from aa1 as xx where id=2);

7.解锁必须用unlock tables;

在JAVA程序中,要想解锁,需要调用 unlock tables来解锁.

如果没有调用unlock tables.

关闭connection 、程序结束 、调用GC 都能解锁.

方法2:用记录锁锁表.

String sql = "select from aa1 for update";

// select from aa1 lock in share mode;

try {

conn.setAutoCommit(false);

} catch (Exception e) {

}}1.for update 与 lock in share mode 属于行级锁和页级锁

3.对于记录锁.必须开启事务.

4.行级锁定事实上是索引记录的锁定.只要是用索引扫描的行(或没索引全表扫描的行),都将被锁住.

5.在不同的隔离级别下还会使用next-key locking算法.即所扫描的行之间的“间隙”也会也锁住(在Repeatable read和Serializable隔离级别下有间隙锁).

6.在mysql享锁的含义是:在被共享锁锁住的行,即使内容被修改且并没有提交.在另一个会话中依然看到修改的信息.

在同一会话中加上了共享锁.可以对这个表以及这个表以外的所有表进行增、删、改、查的作.

在不同的会话中.可以查到共享锁锁住行的消息.但是在Read Uncommitted隔离级别下不能对锁住的表进行删,

改作.(需要等待锁释放才能作...)

在Repeatable read隔离级别下不能对锁住行进行增、删、改作.(需要等待锁释放才能作...)

在Serializable隔离级别下不能对锁住行进行增、删、改作. (需要等待锁释放才能作...)

7.在mysql中排他锁的含义是:在被排它锁锁住的行,内容修改并没提交,在另一个会话中不会看到修改的信息。

在不同的会话中.可以查到共享锁锁住行的消息.但是Read Uncommitted隔离级别下不能对锁住的表进行删,

改作.(需要等待锁释放才能作...)

在Repeatable read隔离级别下不能对锁住行进行增、删、改作.(需要等待锁释放才能作...)

在Serializable隔离级别下不能对锁住行进行增、删、改作. (需要等待锁释放才能作...)

8.在同一个会话中的可以叠加多个共享锁和排他锁.在多个会话中,需要等待锁的释放.

9.SQL中的update 与 for update是一样的原理.

10.等待超时的参数设置:innodb_lock_wait_timeout=50 (单位秒).

11.任何可以触发事务提交的命令,都可以关闭共享锁和排它锁.

mysql备份数据库 怎么锁表

mysqldump是mysql用于转存储数据库的实用程序。它主要产生一个SQL脚本,其中包含从头重新创建数据库所必需的命令CREATE

TABLE INSERT等。如果给mysqldump进行备份,从库上停止的sql线程

然后mysqldump,这个是个很好的选择,因为停止就没有写,就不用担心锁表的问题 。下面提供两只备份方法:

一、MyI意向锁是一种表锁,锁定的粒度是整张表,分为意向共享锁和意向排他锁。意向共享锁表示一个事务有意对数据上共享锁或者排他锁。有意表示事务想执行作但还没真正执行SAM引擎备份

1. 由于MyISAM引擎为表级锁,因此,在备份时需要防止在备份期间数据写入而导致不一致,

2. 所以,在备份时使用--lockproducts-all-tables加上读锁

mysqldump -A -F -B --lock-all-tables |gzip >/data/backup/$(date +%F).tar.gz

二、 InnoDB引擎备份

1. InnoDB引擎为行锁,因此,备份时可以不对数据库加锁的作,可以加选项--single-transaction进行备份:

mysqldump -A -F -B --single-transaction |gzip >/data/backup/$(date +%F).tar.gz

2. 特别注意:

--single-transaction仅适用于InnoDB引擎。

---data=2

会将当前mysql用到的MDL表级锁binlog文件的日志名称和位置记录下来 然后搜索change 就行了

mysqldump -uroot -p'passwd' -B ctp1 --lock-all-tables|gzip >/home/mysql/ctp1.$(date +%F).tar.gz

--no--data 仅仅dump数据库结构创建脚本 通过--no-create- 去掉dump文件中创建表结构的命令。

备份抽取的时候会自动锁表的,你不需要手动锁住

mysql数据库表锁等待超时怎么解决

InnoDB,且必须在交易区块(BEGIN/COMMIT)中才能生效。

等待加锁线程所有事务只能看见已经提交事务所做的改变,此级别可以解决读,但也会导致不可重复读(Nonrepeatable Read):首先开启 A 和 B 两个事务,A事务读取了 B 事务的数据,在 B 事务更新并提交后,A 事务又读取到了更新后的数据,此时就出现了同一 A 事务中的查询出现了不同的查询结果完毕后再执行。

以MyISAM表的如果用--skip-locking选项运行,则外部锁定禁用。该选项在某些系统中是缺省的,如Linux。可以通过运行mysqladmin variables命令确定是否能够使用外部锁定。检查skip_locking变量的值并按以下方法进行:表级写锁为例,MySql5.0说得很清楚的:

当一个线程获得对一个表的写锁后,只有持有锁的线程可以对表进行更新作。其他线程的读、写作都会等待,直到锁被释放为止。

mysql事务会锁表吗

pstmt.executeQuery();

这个要看事务隔离级别,mysql默认是“可重复读”,并且通过innodb引擎的多版本并发控制(MVC[, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}] ...C,Multiversion Concurrency Control)机制防止了幻像读,同样,后面的select也不会被锁定。 当事务隔离级别升到“串行化”时,后面只要前面的session没有commit(包括select之后),那么后面的session的任何作都会被锁定。

注2:

mysql全表扫描 是否会造成锁表呢?

2.for update 排它锁,lock in share mode 共享锁

要明白,mysql中存在两种锁,共享锁和排它锁,也就是读锁定和写锁定,mysql遵循ACID特性,也就是说Mysql的所有作都是原子性的。那么在读和写mysql会根据范围进行锁定。读的时候就自动加上了读锁,写的时候自动加上写锁,那么你现在是进行全表扫描,那么整张表是会被读锁定的,但是其他用户也可以读这个表的数据,但是不能写。另外一种情况是除外的,Mysql实现这样一种机制,在你进行全表扫描的时候,我们是可以在表的末尾进行数据的插入的,因为从存储就够上来讲,他是没有被锁定的。

UPDATE;

这样讲,明白了吧?

FOR