一、什么是数据库锁定
当多个并发事务同时对数据库中的某一数据进行操作时,为了保证数据的一致性和准确性,数据库需要对这些数据进行锁定,以保证同一时刻只有一个事务对其进行操作,其他的事务等待锁释放后才能继续对该数据进行操作。数据库锁定分为共享锁定和排他锁定两种类型。 共享锁定是当事务对某一数据进行读取操作时,需要获取的锁定方式。多个事务可以同时获取该数据的共享锁定,而不能进行写操作。 排他锁定是当某一个事务对数据进行写操作时,需要获取的锁定方式。其他事务无法对该数据进行读、写操作,直至排他锁被释放。
二、查看锁定情况
在Oracle数据库中,我们可以通过以下查询语句来查看当前数据库的锁定情况:
SELECT
object_id,
session_id,
oracle_username,
os_user_name,
locked_mode,
mode_held,
mode_requested,
lock_type
FROM
v$locked_object;
以上查询语句将会查询v$locked_object
视图,该视图将会列出当前被锁定的对象、造成锁定的会话、持有该锁定的模式和请求该锁定的模式。
在实际使用过程中,我们可以根据需要针对其中的某一列项进行筛选和排序:
-- 按照session_id排序
SELECT
object_id,
session_id,
oracle_username,
os_user_name,
locked_mode,
mode_held,
mode_requested,
lock_type
FROM
v$locked_object
ORDER BY
session_id;
三、查看所有锁定的会话
如果我们需要列出所有当前正在锁定某一对象的会话,我们可以通过以下查询语句进行查询:
SELECT
s.inst_id,
s.sid,
s.serial#,
s.username,
s.osuser,
l.type,
l.id1,
l.id2,
l.lmode,
l.request
FROM
gv$session s
JOIN gv$lock l ON s.sid = l.sid
WHERE
l.type = 'TM'
AND l.id1 = &obj_id
ORDER BY
lmode DESC,
request;
以上查询语句中,obj_id
为需要查询的对象ID,该语句将会查询gv$session
视图和gv$lock
视图,找出目标对象ID的所有会话信息,包括会话ID、用户名、操作系统用户名等等。
四、查看锁定的表和索引
如果我们需要查询当前所有正在锁定的表和索引,我们可以通过以下查询语句进行查询:
-- 查询锁定表
SELECT
c.owner,
c.object_name,
c.object_type,
s.sid,
s.serial#,
s.username,
s.osuser,
s.machine,
l.type,
l.lmode,
l.request
FROM
dba_objects c
JOIN gv$session s ON c.object_id = s.row_wait_obj# AND s.row_wait_file# = 1 AND s.row_wait_block# = c.data_object_id
JOIN gv$lock l ON s.sid = l.sid AND s.inst_id = l.inst_id
WHERE
c.object_type = 'TABLE'
AND l.type = 'TX'
ORDER BY
lmode DESC,
request;
-- 查询锁定索引
SELECT
c.owner,
c.object_name,
c.object_type,
s.sid,
s.serial#,
s.username,
s.osuser,
s.machine,
l.type,
l.lmode,
l.request
FROM
dba_objects c
JOIN gv$session s ON c.object_id = s.row_wait_obj# AND s.row_wait_file# = 1 AND s.row_wait_block# = c.object_id
JOIN gv$lock l ON s.sid = l.sid AND s.inst_id = l.inst_id
WHERE
c.object_type = 'INDEX'
AND l.type = 'TX'
ORDER BY
lmode DESC,
request;
以上两个查询语句分别查询了被锁定的表和被锁定的索引,并且将查询结果按照锁定模式和请求次数进行排序,以便更好的了解当前锁定的情况。
五、查看等待锁定的会话
如果我们需要查看所有等待锁定的会话信息,我们可以通过以下查询语句进行查询:
SELECT
inst_id,
sid,
serial#,
username,
osuser,
machine,
wait_class,
blocking_session,
event,
p1text,
p1,
p2text,
p2,
p3text,
p3
FROM
gv$session_wait
WHERE
wait_class <> 'Idle'
AND blocking_session IS NULL
AND event NOT LIKE '%message%'
AND event NOT LIKE '%smon%'
ORDER BY
sid;
以上查询语句将会查询出所有正等待锁定的会话信息,包括会话ID、用户名、操作系统用户名、等待类型、阻塞会话等等。
六、总结
根据以上内容,我们可以通过查询v$locked_object
视图、gv$session
和gv$lock
视图,查看当前数据库中的锁定情况、被锁定的会话、被锁定的表和索引以及正等待锁定的会话信息,便于更好的进行数据库维护和管理。