create table "informix".t1
(
id integer,
name char(10),
col3 datetime year to second
default current year to second,
primary key (id)
) with crcols extent size 16 next size 16 lock mode row;
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
begin;
delete from t1 where id=1 该表在id列上有主
++++++++++++++++++++++++++++++++++++++++++++++++++++++
informix@ER1 ~ >oncheck -pt ttdb:t1 |grep -E "partnum|lockid"
Partition partnum 6291523
Partition lockid 6291523
Partition partnum 6291524
Partition lockid 6291523
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
informix@ER1 ~ >onstat -k |grep 45084ca8
44197820 0 45084ca8 44198018 HDR+X 600044 101 K- 1 D
44197930 0 45084ca8 44198b40 HDR+IX 600043 0 0
44198018 0 45084ca8 44197930 HDR+X 600043 101 0 D
44198b40 0 45084ca8 0 HDR+S 100002 206 0
可以看到在数据库上加了共享锁
在表上加了趋向独占锁;
在数据行上加了独占锁;
在索引行加了独占锁;
########################################################
session1:
先做,用紫色圈起来,做了一个update,更新了一行;
600045是oncheck -pt dbname:tabname 看到的lockid;
900002是oncheck -pt dbname:tabname 看到的涉及到的分区的partnum;
session2:
后做,用红色圈起来,做一个alter fragment操作期望把某个分区(非update涉及到的分区)detach出来成单独的表;
该会话就会产生锁等待;
session1的wtlist中就会出现session2的owner;
为了保证alter fragment可以成功,可以通过FORCE_DDL_EXEC来实现:
SET ENVIRONMENT FORCE_DDL_EXEC '60';
alter fragment on table customer detach datadbs5 customer5;
设置FORCE_DDL_EXEC环境表示当前会话拥有最高优先级,并且指定如果当前会话在60秒内无法获得独占锁,则当前alter fragment操作失败。如果发现其他会话在占用该表,就会把该会话置为长事务,强行退出并回滚。
被退出的会话可以看到如下信息:
458: Long transaction aborted.
12204: RSAM error: Long transaction detected.
online.log中可以到:
Forced DDL 0x46e00648 Aborted. Rollback Duration: 0 Seconds
在使用完FORCE_DDL_EXEC 之后,需要设置SET ENVIRONMENT FORCE_DDL_EXEC 'off'。
FORCE_DDL_EXEC 的相关特性:
1、值对日志数据库生效;
2、FORCE_DDL_EXEC由informix用户执行;
3、不能由其他会话对该表做DDL;
表附加的过程如下:
alter fragment on table customer attach customer5 as (c_w_id < 51 AND c_w_id >= 41) after datadbs4;