导航:首页 > 编程大全 > 数据库的表被锁了

数据库的表被锁了

发布时间:2023-06-09 10:31:52

数据库锁表是什么意思

数据库锁表:在数据库里,同一个数据可能有多个人来读取或更改,为了防止更改的时候别人也同时更改,这里一般要锁住表不让别人改。当然还有其它各种复杂情况。

数据库锁从类型上讲,有共享锁,意向锁,排他锁。从锁的粒度角度来说,可以分为为行、页键、键范围、索引、表或数据库获取锁。(锁粒度是被封锁目标的大小,封锁粒度小则并发性高,但开销大,封锁粒度大则并发性低但开销小)

可能的原因有:

(1)字段不加索引:在执行事务的时候,如果表中没有索引,会执行全表扫描,如果这时候有其他的事务过来,就会发生锁表!

(2)事务处理时间长:事务处理时间较长,当越来越多事务堆积的时候,会发生锁表!

(3)关联操作太多:涉及到很多张表的修改等,在并发量大的时候,会造成大量表数据被锁!

出现锁表的解决方法有:

(1)通过相关的sql语句可以查出是否被锁定,和被锁定的数据!

(2)为加锁进行时间限定,防止无限死锁!

(3)加索引,避免全表扫描!

(4)尽量顺序操作数据!

(5)根据引擎选择合理的锁粒度!

(6)事务中的处理时间尽量短!

生产中出现死锁等问题是比较严重的问题,因为通常死锁没有明显的错误日志,只有在发现错误的时候才能后知后觉的处理,所以,一定要尽力避免!

(1)数据库的表被锁了扩展阅读:

封锁是指事务T在对某个数据对象(例如表、记录等)操作之前,先向系统发出请求,对其加锁。加锁后事务T就对该数据对象有了一定的控制,在事务T释放它的锁之前,其它的事务不能更新此数据对象。

锁表的基本类型有:

(1)排它锁(记为X锁)

排它锁又称为写锁。若事务T 对数据对象A 加上X 锁,则只允许T 读取和修改A , 其它任何事务都不能再对A 加任何类型的锁,直到T 释放A 上的锁。

(2)共享锁(记为S锁)

共享锁又称为读锁。若事务T 对数据对象A 加上S 锁,则其它事务只能再对A 加S 锁,而不能加X 锁,直到T 释放A 上的S 锁。X锁和S锁都是加在某一个数据对象上的。

封锁单元有:

封锁的对象可以是逻辑单元,也可以是物理单元。

逻辑单元: 属性值、属性值集合、元组、关系、索引项、整个索引、整个数据库等;

物理单元:页(数据页或索引页)、块等。

封锁对象可以很大也可以很小,例如对整个数据库加锁、对某个属性值加锁。封锁对象的大小称为封锁的粒度。封锁的粒度越大,系统中能够被封锁的对象就越少,并发度也就越小,但系统开销也越小;封锁的粒度越小,并发度越高,但开销也就越大。

选择封锁粒度时必须同时考虑开销和并发度两个因素,进行权衡,以求得最优的效果。

一般原则为:

(1)需要处理大量元组的用户事务:以关系为封锁单元;

(2)需要处理多个关系的大量元组的用户事务:以数据库为封锁单位;

(3)只处理少量元组的用户事务:以元组为封锁单位

⑵ MySQL数据库表被锁、解锁,删除事务

程序员的职业生涯中,总会遇到数据库表被锁的情况,前些天就又撞见一次。由于业务突发需求,各个部门都在批量操作、导出数据,而数据库又未做读写分离,结果就是:数据库的某张表被锁了!

用户反馈系统部分功能无法使用,紧急排查,定位是数据库表被锁,然后进行紧急处理。这篇文章给大家讲讲遇到类似紧急状况的排查及解决过程,建议点赞收藏,以备不时之需。

用户反馈某功能页面报502错误,于是第一时间看服务是否正常,数据库是否正常。在控制台看到数据库CPU飙升,堆积大量未提交事务,部分事务已经阻塞了很长时间,基本定位是数据库层出现问题了。

查看阻塞事务列表,发现其中有锁表现象,本想利用控制台直接结束掉阻塞的事务,但控制台账号权限有限,于是通过客户端登录对应账号将锁表事务kill掉,才避免了情况恶化。

下面就聊聊,如果当突然面对类似的情况,我们该如何紧急响应?

想象一个场景,当然也是软件工程师职业生涯中会遇到的一种场景:原本运行正常的程序,某一天突然数据库的表被锁了,业务无法正常运转,那么我们该如何快速定位是哪个事务锁了表,如何结束对应的事物?

首先最简单粗暴的方式就是:重启MySQL。对的,网管解决问题的神器——“重启”。至于后果如何,你能不能跑了,要你自己三思而后行了!

重启是可以解决表被锁的问题的,但针对线上业务很显然不太具有可行性。

下面来看看不用跑路的解决方案:

遇到数据库阻塞问题,首先要查询一下表是否在使用。

如果查询结果为空,那么说明表没在使用,说明不是锁表的问题。

如果查询结果不为空,比如出现如下结果:

则说明表(test)正在被使用,此时需要进一步排查。

查看数据库当前的进程,看看是否有慢SQL或被阻塞的线程。

执行命令:

该命令只显示当前用户正在运行的线程,当然,如果是root用户是能看到所有的。

在上述实践中,阿里云控制台之所以能够查看到所有的线程,猜测应该使用的就是root用户,而笔者去kill的时候,无法kill掉,是因为登录的用户非root的数据库账号,无法操作另外一个用户的线程。

如果情况紧急,此步骤可以跳过,主要用来查看核对:

如果情况紧急,此步骤可以跳过,主要用来查看核对:

看事务表INNODB_TRX中是否有正在锁定的事务线程,看看ID是否在show processlist的sleep线程中。如果在,说明这个sleep的线程事务一直没有commit或者rollback,而是卡住了,需要手动kill掉。

搜索的结果中,如果在事务表发现了很多任务,最好都kill掉。

执行kill命令:

对应的线程都执行完kill命令之后,后续事务便可正常处理。

针对紧急情况,通常也会直接操作第一、第二、第六步。

这里再补充一些MySQL锁相关的知识点:数据库锁设计的初衷是处理并发问题,作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则,而锁就是用来实现这些访问规则的重要数据结构。

根据加锁的范围,MySQL里面的锁大致可以分成全局锁、表级锁和行锁三类。MySQL中表级别的锁有两种:一种是表锁,一种是元数据锁(metadata lock,MDL)。

表锁是在Server层实现的,ALTER TABLE之类的语句会使用表锁,忽略存储引擎的锁机制。表锁通过lock tables… read/write来实现,而对于InnoDB来说,一般会采用行级锁。毕竟锁住整张表影响范围太大了。

另外一个表级锁是MDL(metadata lock),用于并发情况下维护数据的一致性,保证读写的正确性,不需要显式的使用,在访问一张表时会被自动加上。

常见的一种锁表场景就是有事务操作处于:Waiting for table metadata lock状态。

MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景。

一旦alter table TableA的操作停滞在Waiting for table metadata lock状态,后续对该表的任何操作(包括读)都无法进行,因为它们也会在Opening tables的阶段进入到Waiting for table metadata lock的锁等待队列。如果核心表出现了锁等待队列,就会造成灾难性的后果。

通过show processlist可以看到表上有正在进行的操作(包括读),此时alter table语句无法获取到metadata 独占锁,会进行等待。

通过show processlist看不到表上有任何操作,但实际上存在有未提交的事务,可以在information_schema.innodb_trx中查看到。在事务没有完成之前,表上的锁不会释放,alter table同样获取不到metadata的独占锁。

处理方法:通过 select * from information_schema.innodb_trxG, 找到未提交事物的sid,然后kill掉,让其回滚。

通过show processlist看不到表上有任何操作,在information_schema.innodb_trx中也没有任何进行中的事务。很可能是因为在一个显式的事务中,对表进行了一个失败的操作(比如查询了一个不存在的字段),这时事务没有开始,但是失败语句获取到的锁依然有效,没有释放。从performance_schema.events_statements_current表中可以查到失败的语句。

处理方法:通过performance_schema.events_statements_current找到其sid,kill 掉该session,也可以kill掉DDL所在的session。

总之,alter table的语句是很危险的(核心是未提交事务或者长事务导致的),在操作之前要确认对要操作的表没有任何进行中的操作、没有未提交事务、也没有显式事务中的报错语句。

如果有alter table的维护任务,在无人监管的时候运行,最好通过lock_wait_timeout设置好超时时间,避免长时间的metedata锁等待。

关于MySQL的锁表其实还有很多其他场景,我们在实践的过程中尽量避免锁表情况的发生,当然这需要一定经验的支撑。但更重要的是,如果发现锁表我们要能够快速的响应,快速的解决问题,避免影响正常业务,避免情况进一步恶化。所以,本文中的解决思路大家一定要收藏或记忆一下,做到有备无患,避免突然状况下抓瞎。

⑶ 如何查询db2数据库表是否被锁

1、首先点击桌面上的SQL server数据库。

⑷ orcal数据库表被锁了怎么解锁

1、在做Oracle监听程序测试时,发现帐户已经被锁定。

⑸ 怎么知道数据库表已经锁表了

可直接在mysql命令行执行:show engine innodb statusG;

查看造成死锁的sql语句,分析索引情况,然后优化sql然后show processlist;

show status like ‘%lock%’

show OPEN TABLES where In_use > 0; 这个语句记录当前锁表状态

另外可以打开慢查询日志,linux下打开需在my.cnf的[mysqld]里面加上以下内容:

slow_query_log=TRUE(有些mysql版本是ON)

slow_query_log_file=/usr/local/mysql/slow_query_log.txt

long_query_time=3

select *from v$locked_object:可以获得被锁的对象的object_id及产生锁的会话sid。通过查询结果中的object_id,可以查询到具体被锁的对象。

(5)数据库的表被锁了扩展阅读:

注意事项

也可以直接把这几个视图和表关联起来,在查询结果中直接得到“alter system kill session 'sid, serial#'”这样的方便的kill sessoin命令。

如果执行kill session命令后,锁并没有除掉,session依然存在。这种情况,通过select spid from v$process where addr in(select paddr from v$session where sid = &sid)查询到oracle会话在服务器上的pid,然后登陆到服务器上,执行kill -9 pid这样就能杀掉进程解锁了。

⑹ MYSQL数据库怎么查看 哪些表被锁了

以下五种方法可以快速定位全局锁的位置,仅供参考。

方法1:利用 metadata_locks 视图
此方法仅适用于 MySQL 5.7 以上版本,该版本 performance_schema 新增了 metadata_locks,如果上锁前启用了元数据锁的探针(默认是未启用的),可以比较容易的定位全局锁会话。

方法2:利用 events_statements_history 视图此方法适用于 MySQL 5.6 以上版本,启用 performance_schema.eventsstatements_history(5.6 默认未启用,5.7 默认启用),该表会 SQL 历史记录执行,如果请求太多,会自动清理早期的信息,有可能将上锁会话的信息清理掉。

方法3:利用 gdb 工具如果上述两种都用不了或者没来得及启用,可以尝试第三种方法。利用 gdb 找到所有线程信息,查看每个线程中持有全局锁对象,输出对应的会话 ID,为了便于快速定位,我写成了脚本形式。也可以使用 gdb 交互模式,但 attach mysql 进程后 mysql 会完全 hang 住,读请求也会受到影响,不建议使用交互模式。

方法4:show processlist
如果备份程序使用的特定用户执行备份,如果是 root 用户备份,那 time 值越大的是持锁会话的概率越大,如果业务也用 root 访问,重点是 state 和 info 为空的,这里有个小技巧可以快速筛选,筛选后尝试 kill 对应 ID,再观察是否还有 wait global read lock 状态的会话。

方法5:重启试试!

⑺ oracle数据库表被锁了不能操作怎么办

首先你要知道表锁住了是不是正常锁?因为任何DML语句都会对表加锁。
你要先查一下是那个会话那个sql锁住了表,有可能这是正常业务需求,不建议随便KILL
session,如果这个锁表是正常业务你把session
kill掉了会影响业务的。
建议先查原因再做决定。
(1)锁表查询的代码有以下的形式:
select
count(*)
from
v$locked_object;
select
*
from
v$locked_object;
(2)查看哪个表被锁
select
b.owner,b.object_name,a.session_id,a.locked_mode
from
v$locked_object
a,dba_objects
b
where
b.object_id
=
a.object_id;
(3)查看是哪个session引起的
select
b.username,b.sid,b.serial#,logon_time
from
v$locked_object
a,v$session
b
where
a.session_id
=
b.sid
order
by
b.logon_time;
(4)查看是哪个sql引起的
select
b.username,b.sid,b.serial#,c.*
from
v$locked_object
a,v$session
b,v$sql
c
where
a.session_id
=
b.sid
and
b.SQL_ID
=
c.sql_id
and
c.sql_id
=
''
order
by
b.logon_time;
(5)杀掉对应进程
执行命令:alter
system
kill
session'1025,41';
其中1025为sid,41为serial#.

⑻ db2数据库里面的一张表被锁定,怎么解锁

请教各位:DB2数据库里如何判断一个表被锁
1、执行命令打开锁的监视开光
UPDATE
MONITOR
SWITCHES
USING
lock
on==>;>;
2、查看数据库的锁的情况
get
snapshot
for
locks
on
tberp
3、某一个用户的锁的情况
get
snapshot
for
application
applid
C0A8084A.040A.031015144751
4、如果表被锁可以关闭该应用连接
force
application
ID1
5、看正在运行的程序有没有处于锁等待状态的
list
applications
for
db
tberp
show
detail

⑼ 数据库 如何解除表的锁定

(1)
HOLDLOCK:
在该表上保持共享锁,直到整个事务结束,而不是在语句执行完立即释放所添加的锁。

(2)
NOLOCK:不添加共享锁和排它锁,当这个选项生效后,可能读到未提交读的数据或“脏数据”,这个选项仅仅应用于SELECT语句。

(3)
PAGLOCK:指定添加页锁(否则通常可能添加表锁)。

(4)
READCOMMITTED用与运行在提交读隔离级别的事务相同的锁语义执行扫描。默认情况下,SQL
Server
2000
在此隔离级别上操作。
(5)
READPAST:
跳过已经加锁的数据行,这个选项将使事务读取数据时跳过那些已经被其他事务锁定的数据行,而不是阻塞直到其他事务释放锁,
READPAST仅仅应用于READ
COMMITTED隔离性级别下事务操作中的SELECT语句操作。

(6)
READUNCOMMITTED:等同于NOLOCK。

(7)
REPEATABLEREAD:设置事务为可重复读隔离性级别。

(8)
ROWLOCK:使用行级锁,而不使用粒度更粗的页级锁和表级锁。

(9)
SERIALIZABLE:用与运行在可串行读隔离级别的事务相同的锁语义执行扫描。等同于
HOLDLOCK。

(10)
TABLOCK:指定使用表级锁,而不是使用行级或页面级的锁,SQL
Server在该语句执行完后释放这个锁,而如果同时指定了HOLDLOCK,该锁一直保持到这个事务结束。
(11)
TABLOCKX:指定在表上使用排它锁,这个锁可以阻止其他事务读或更新这个表的数据,直到这个语句或整个事务结束。

(12)
UPDLOCK
:指定在
读表中数据时设置更新
锁(update
lock)而不是设置共享锁,该锁一直保持到这个语句或整个事务结束,使用UPDLOCK的作用是允许用户先读取数据(而且不阻塞其他用户读数据),并且保证在后来再更新数据时,这一段时间内这些数据没有被其他用户修改。

阅读全文

与数据库的表被锁了相关的资料

热点内容
4kb的txt文件差不多多少字 浏览:984
u盘文件突然变成exe 浏览:164
现在哪些学校初中有学编程的 浏览:402
word查找全选 浏览:599
开工报告附什么文件资料 浏览:150
分区工具app怎么用 浏览:212
安卓坚果云文件路径 浏览:591
sqllog文件 浏览:236
如何在电脑中找到文件路径 浏览:830
数据结构访问和查找有什么区别 浏览:401
怎么清空icloud内的数据 浏览:338
微信锁屏后音乐停止 浏览:668
applepay苹果手机卡 浏览:835
一个14mb的文件能储存多少万汉字 浏览:478
腾讯文档里如何导出数据 浏览:979
java面试题csdn 浏览:410
rpgnvp是什么文件 浏览:594
如何将一列数据复制到excel 浏览:488
sd卡怎么恢复excel文件 浏览:282
gdblinux内核多核调试 浏览:24

友情链接