问题描述
嗨,
我有一个数据仓库应用程序运行到 “Enqueue TX行锁争用等待”。
情况如下:
表在point_id列上有50个哈希分区。数据加载过程正在尝试使用ROWID值删除行,它正在使用TX行锁争用锁定多个分区。这阻止了其他会话对该表执行任何操作。
SQL> desc odr.V _ accnt _ r_0000411
名称为空?类型
-
点id不是空数 (10)
START_TIME_INT不是空数 (10)
END_TIME_INT不是空数 (10)
BATCH_ID不是空数 (10)
PARENT_点id不是空数 (10)
这里是delete语句。
删除/* 动态采样 (gt 3) */从V_ACCNT_R_0000411中删除 (从gtt_pid_relation gt中选择核心 _ row_id)
我们想了解为什么上述删除会导致行锁定问题。
非常感谢,
拉维
我有一个数据仓库应用程序运行到 “Enqueue TX行锁争用等待”。
情况如下:
表在point_id列上有50个哈希分区。数据加载过程正在尝试使用ROWID值删除行,它正在使用TX行锁争用锁定多个分区。这阻止了其他会话对该表执行任何操作。
SQL> desc odr.V _ accnt _ r_0000411
名称为空?类型
-
点id不是空数 (10)
START_TIME_INT不是空数 (10)
END_TIME_INT不是空数 (10)
BATCH_ID不是空数 (10)
PARENT_点id不是空数 (10)
这里是delete语句。
删除/* 动态采样 (gt 3) */从V_ACCNT_R_0000411中删除 (从gtt_pid_relation gt中选择核心 _ row_id)
我们想了解为什么上述删除会导致行锁定问题。
非常感谢,
拉维
专家解答
TX行争用字面意思是,即,对于一个特定的行。哈希分区不会改变这一点。例如
所以我有8个分区,我从其中4个删除了行。在另一个会话中,我然后尝试一些删除
这是有效的,因为它不会与具有一些活动事务的分区冲突。但是这个:
我被删除阻止了。但是这些仍然是 * 行 * 级别的锁。例如,如果我选择不在已删除集中的行,那很好
顺便说一句,您希望拥有2个哈希分区的幂,否则您的数据之间将不会均匀地间隔
SQL> create table t
2 partition by hash ( object_id)
3 partitions 8
4 as select * from dba_objects
5 where object_id is not null;
Table created.
SQL>
SQL> select dbms_rowid.rowid_Object(rowid), count(*)
2 from t
3 group by dbms_rowid.rowid_Object(rowid);
DBMS_ROWID.ROWID_OBJECT(ROWID) COUNT(*)
------------------------------ ----------
162760 9947
162759 9897
162758 9851
162761 9744
162762 9743
162763 9660
162764 9948
162765 9762
8 rows selected.
SQL>
SQL> select partition_name from user_tab_partitions where table_name = 'T';
PARTITION_NAME
------------------------------
SYS_P4910
SYS_P4911
SYS_P4912
SYS_P4913
SYS_P4914
SYS_P4915
SYS_P4916
SYS_P4917
8 rows selected.
SQL>
SQL> create table gtt ( r rowid );
Table created.
SQL>
SQL> begin
2 for i in ( select partition_name from user_tab_partitions where table_name = 'T' and rownum <= 4 )
3 loop
4 execute immediate
5 'insert into gtt select rowid from t partition ('||i.partition_name||') where rownum <= 500';
6 end loop;
7 end;
8 /
PL/SQL procedure successfully completed.
SQL>
SQL> select count(*) from gtt;
COUNT(*)
----------
2000
1 row selected.
SQL>
SQL> delete from t where rowid in ( select r from gtt ) ;
2000 rows deleted.
SQL>
所以我有8个分区,我从其中4个删除了行。在另一个会话中,我然后尝试一些删除
SQL> delete from t partition ( SYS_P4916 ); 9948 rows deleted.
这是有效的,因为它不会与具有一些活动事务的分区冲突。但是这个:
SQL> delete from t partition ( SYS_P4912 ); [waiting]
我被删除阻止了。但是这些仍然是 * 行 * 级别的锁。例如,如果我选择不在已删除集中的行,那很好
SQL> delete from t partition ( SYS_P4912 ) 2 where object_id = 162203; 1 row deleted.
顺便说一句,您希望拥有2个哈希分区的幂,否则您的数据之间将不会均匀地间隔
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




