English 中文(简体)
如何在Oracle找到锁定的行踪
原标题:How to find locked rows in Oracle

我们有一个Oracle数据库,客户账户表有大约100万头。 多年来,我们建造了四个不同的铀(两个以Oracle形式,两个在Net),所有这些都仍在使用。 我们还有一些背景任务(既有持久性,也有计划)。

有时,在账户表中的行文中,有朝一日(即30秒以上)的长锁,导致持续的背景任务失败。 有关背景任务一旦更新时间结束,就重新开始。 我们在事件发生几分钟后便发现了这一点,但到那时,锁已被释放。

我们有理由相信,它可能是一种错失的技工组织,但却没有能够找到一种“king枪”。

我发现了一些问题,其中列出了几个区块,但当你找到两个争取连任的工作时,情况就是如此。 我想知道,当第二次工作试图打锁时,哪几行会关。

我们回头11g,但自8i起就一直在处理这个问题。

最佳回答

<代码>Oracle锁定概念与其他系统的概念有很大不同。

在锁定<代码>Oracle的行文时,记录本身有新的价值(如果有的话)更新,另外,锁(基本上指在滚动部分居住的交易锁的点)也列入记录。

这意味着在<代码>Oracle上打上记录意味着更新记录中的元数据并印发一个逻辑页码。 例如,你不能在仅读到的表格空间上填写<代码>SlectT>。

超过这一点,记录本身在承诺后没有更新:而是更新了滚动部分。

这意味着,每份记录都有一些关于最后更新的交易的信息,即使交易本身已经很久死亡。 为了查明交易是否活着(因此,如果记录是活的,则需要访问滚动部分)。

甲骨文没有传统的锁定者,这意味着,获得所有锁的目录要求扫描所有物体的所有记录。 这将需要太长的时间。

你可以获得一些特殊锁,如锁定的元件(使用<代码>v$lock_object)、锁料(使用<代码>v$session等,但不包括数据库中所有物体的所有锁定清单。

问题回答

您可以通过询问如下,在Oracle找到锁定的表格:

    select
   c.owner,
   c.object_name,
   c.object_type,
   b.sid,
   b.serial#,
   b.status,
   b.osuser,
   b.machine
from
   v$locked_object a ,
   v$session b,
   dba_objects c
where
   b.sid = a.session_id
and
   a.object_id = c.object_id;

我建议你使用<代码>v$transaction查询长期经营的交易<>。 您可以加入<代码>v$session,其中应使您了解国际交易日志(行业方案和机栏)以及用户。

看见dba_blockers,dba_waitersdba_locks。 姓名应当自译自明。

可以说,你可以创造一份工作,把<条形码>dba_blockers和目前使用的<条码>sql_id中的数值贴在一分钟后。 (通过v$session 和v$sqlstats

您也可在<条码>上查阅。 这将是一个超过5秒的违约记录。 企业经理的“SQL监测”网页也可以看到这一点。

下表列出了以下PL/SQL组,所有锁定的囚室。 其他答复仅发现阻挡session,发现实际锁定的rows要求每行读和测试。

(尽管如此,你可能不需要执行这一法典。) 如果你重新出现僵局,通常会更容易使用<条码>GV$SESSION.BLOC_SESSION和其他有关数据词典。 请尝试另一种做法,然后由你来管理这一极其缓慢的法典。

首先,请提出一个样本表和一些数据。 页: 1

--Sample schema.
create table test_locking(a number);
insert into test_locking values(1);
insert into test_locking values(2);
commit;
update test_locking set a = a+1 where a = 1;

第2号会议设立了一个表格,以存放锁定的地雷监测器。

--Create table to hold locked ROWIDs.
create table locked_rowids(the_rowid rowid);
--Remove old rows if table is already created:
--delete from locked_rowids;
--commit;

在第2次会议上,PL/SQL组整读整个表格,每行各样,并储存锁定的ROWIDs。 警告说,这可能非常缓慢。 在你真实版本的这种询问中,将提及TEST_LOCines的内容改为你自己的表格。

--Save all locked ROWIDs from a table.
--WARNING: This PL/SQL block will be slow and will temporarily lock rows.
--You probably don t need this information - it s usually good enough to know
--what other sessions are locking a statement, which you can find in
--GV$SESSION.BLOCKING_SESSION.
declare
    v_resource_busy exception;
    pragma exception_init(v_resource_busy, -00054);
    v_throwaway number;
    type rowid_nt is table of rowid;
    v_rowids rowid_nt := rowid_nt();
begin
    --Loop through all the rows in the table.
    for all_rows in
    (
        select rowid
        from test_locking
    ) loop
        --Try to look each row.
        begin
            select 1
            into v_throwaway
            from test_locking
            where rowid = all_rows.rowid
            for update nowait;
        --If it doesn t lock, then record the ROWID.
        exception when v_resource_busy then
            v_rowids.extend;
            v_rowids(v_rowids.count) := all_rows.rowid;
        end;

        rollback;
    end loop;

    --Display count:
    dbms_output.put_line( Rows locked:  ||v_rowids.count);

    --Save all the ROWIDs.
    --(Row-by-row because ROWID type is weird and doesn t work in types.)
    for i in 1 .. v_rowids.count loop
        insert into locked_rowids values(v_rowids(i));
    end loop;
    commit;
end;
/

最后,我们可以通过加入LOCKED_ROWIDS表来看待锁定的行。

--Display locked rows.
select *
from test_locking
where rowid in (select the_rowid from locked_rowids);


A
-
1




相关问题
Export tables from SQL Server to be imported to Oracle 10g

I m trying to export some tables from SQL Server 2005 and then create those tables and populate them in Oracle. I have about 10 tables, varying from 4 columns up to 25. I m not using any constraints/...

Connecting to Oracle 10g with ODBC from Excel VBA

The following code works. the connection opens fine but recordset.recordCount always returns -1 when there is data in the table. ANd If I try to call any methods/properties on recordset it crashes ...

How to make a one to one left outer join?

I was wondering, is there a way to make a kind of one to one left outer join: I need a join that matches say table A with table B, for each record on table A it must search for its pair on table B, ...

Insert if not exists Oracle

I need to be able to run an Oracle query which goes to insert a number of rows, but it also checks to see if a primary key exists and if it does, then it skips that insert. Something like: INSERT ALL ...

How can I store NULLs in NOT NULL field?

I just came across NULL values in NOT-NULL fields in our test database. How could they get there? I know that NOT-NULL constraints can be altered with NOVALIDATE clause, but that would change table s ...

Type reference scope

I m studying databases and am currently working on a object-relational DB project and I ve encountered a small problem with the number of possible constraints in an object table. I m using "Database ...

OracleParameter and DBNull.Value

we have a table in an Oracle Database which contains a column with the type Char(3 Byte). Now we use a parameterized sql to select some rows with a DBNull.Value and it doesn t work: OracleCommand ...

热门标签