create index online 和create index 不同及注意点

简介: CREATE INDEX ONLINE 锁模式变化模拟 SESSION 139 SQL>  insert into test123   2  select * from dba_objects;   50062 rows inserte...

CREATE INDEX ONLINE 锁模式变化模拟

SESSION 139
SQL>  insert into test123
  2  select * from dba_objects;
 
50062 rows inserted
不提交
SESSION 148
SQL> create index test123_i on test123(owner) online;

回话148堵塞

SQL>  select * from v$lock where sid in ('139','148') order by sid;
 
ADDR             KADDR                   SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------
0000000096669B90 0000000096669BB8        139 TM        53479          0          3          0         66          1
00000000966E6578 00000000966E65B0        139 TX       589843        343          6          0         66          0
0000000096669DD0 0000000096669DF8        148 TM        53481          0          4          0         40          0
0000000096669CB0 0000000096669CD8        148 TM        53479          0          2          4         42          0
00000000978E54F0 00000000978E5510        148 DL        53479          0          3          0         42          0
00000000978E53A0 00000000978E53C0        148 DL        53479          0          3          0         42          0

堵塞正是由于
0000000096669CB0 0000000096669CD8        148 TM        53479          0          2          4         42          0
可以看到已经以模式2也就是SS模式获得TM锁,但是期望以模式4获得TM锁也就是S模式,但是在OBJECTS 53479上被139会话以模式3也就是SX模式获得
因为SS和SX兼容所以可以获得,但是如果想获得S模式,S和SX是不兼容,所以堵塞
顺便提一下OBJECT_ID=53479 就是表TEST123,而对象53481是对象SYS_JOURNAL_53480,就是为了保证在建立索引的同时把可能的更改记录到所谓的日志表中
待索引建立完成后同步到日志中,这也是ONLINE建立索引所独有的。
此时我们COMMIT回话139

SQL>  select * from v$lock where sid in ('139','148') order by sid;
 
ADDR             KADDR                   SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------
00000000978E53A0 00000000978E53C0        148 DL        53479          0          3          0        821          0
0000000096669DD0 0000000096669DF8        148 TM        53481          0          4          0        819          0
0000000096669CB0 0000000096669CD8        148 TM        53479          0          2          0         14          0
00000000978E54F0 00000000978E5510        148 DL        53479          0          3          0        821          0

一旦提交后期望的锁即可获得,而且获得后会降级为2也就是SS模式而不是S模式

然后我们又在会话139进行多次DML操作,看看CREATE INDEX ONLINE 是否堵塞 随后的DML


SQL>  select * from v$lock where sid in ('139','148') order by sid;
 
ADDR             KADDR                   SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------
000000009666A250 000000009666A278        139 TM        53479          0          3          0         84          0
00000000966C0868 00000000966C08A0        139 TX       131088        311          6          0         80          0
0000000096669DD0 0000000096669DF8        148 TM        53481          0          4          0        562          0
00000000978E54F0 00000000978E5510        148 DL        53479          0          3          0        563          0
00000000978E53A0 00000000978E53C0        148 DL        53479          0          3          0        563          0
0000000096669CB0 0000000096669CD8        148 TM        53479          0          2          0        549          0

这里可以看到实际不会堵塞随后的DML操作,因为降级后只需要对TEST123获得SS模式即可,SS模式是SX模式是兼容的。
所以CREATE INDEX ONLINE会
1、如果在本表上有DML没有提交,那么CREATE INDEX ONLINE会等待其提交,因为初始的时候需要以S模式获得表上TM锁,S模式和SX模式不兼容
2、如果获得了表上S模式锁后,也就是进行创建过程中,实际对表的TM S锁已经降级为SS,这个时候就不会堵塞随后的DML了。这也是为什么
CREATE INDEX ONLINE优于CREATE INDEX的地方,他不会堵塞随后的DML,因为TM锁是SS模式而不是S模式。
   但是还是要注意第一点,所以为了保险还是关闭应用建立索引吧,特别是大表,CREATE INDEX ONLINE也不一定保险。

CREATE INDEX  锁模式变化模拟

其实CREATE INDEX 没什么好模拟的,
如果你还有DML操作在表上,那么一定有TX模式的TM锁,建立索引会报错如下
SQL> create index test123_i
  2  on test123(owner);
 
create index test123_i
on test123(owner)
 
ORA-00054: resource busy and acquire with NOWAIT specified

当然如果可以建立索引的话你会看到如下
回话148建立索引,查看其锁TM为模式4及模式S
SQL>  select * from v$lock where sid in ('139','148') order by sid;
 
ADDR             KADDR                   SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------
00000000978E53A0 00000000978E53C0        148 DL        53479          0          3          0          6          0
00000000978E54F0 00000000978E5510        148 DL        53479          0          3          0          6          0
00000000966F2BA8 00000000966F2BE0        148 TX       458790        367          6          0          6          0
0000000096669CB0 0000000096669CD8        148 TM           18          0          3          0          6          0
0000000096669B90 0000000096669BB8        148 TM        53479          0          4          0          6          0


回话139进行操作
delete test123;
查看锁模式如下
SQL>  select * from v$lock where sid in ('139','148') order by sid;
 
ADDR             KADDR                   SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------
0000000096669DD0 0000000096669DF8        139 TM        53479          0          0          3         15          0
00000000978E54F0 00000000978E5510        148 DL        53479          0          3          0         31          0
0000000096669B90 0000000096669BB8        148 TM        53479          0          4          0         31          1
00000000966F2BA8 00000000966F2BE0        148 TX       458790        367          6          0         31          0
0000000096668868 00000000966688C8        148 TS            4   18509883          6          0         17          0
00000000978E53A0 00000000978E53C0        148 DL        53479          0          3          0         31          0
0000000096669CB0 0000000096669CD8        148 TM           18          0          3          0         31          0

可以看到回话139想以模式3也就是SX模式获得TM锁,但是因为CREATE INDEX 的TM模式是4也就是S模式,是不共享的,所以不能获得,只能堵塞
等待create index 完成,所以CREATE INDEX一定不能再没有确定这个表没有DML操作的情况下使用,除非你确定没有DML操作在这个表上


兼容矩阵

held/get  null  ss   sx   s   ssx   x
null          1    1    1   1     1   1 
ss            1    1    1   1     1
sx            1    1    1
s             1    1         1
ssx          1    1
x             1

相关文章
|
缓存
IDEA 卡住不动的解决办法,超级管用。。。
IDEA 卡住不动的解决办法,超级管用。。。
2010 0
IDEA 卡住不动的解决办法,超级管用。。。
|
SQL 存储 JSON
MySQL执行请求报错 Error: Row size too large (>8126)
最近遇到一个业务问题,在执行一个大的业务查询时会抛出异常报错,所以今天就总结一下 Row size too large (>8126) 报错的相关问题。
|
6月前
|
人工智能 自然语言处理 算法
《DeepSeek-V3:动态温度调节算法,开启推理新境界!》
DeepSeek-V3凭借其创新的动态温度调节算法,成为人工智能领域的焦点。该算法通过灵活调整模型输出的随机性(温度),在不同情境下实现推理速度与精度的动态平衡。低温使模型输出稳定准确,适合事实性任务;高温则激发多样性,适用于创意创作。DeepSeek-V3能根据对话进展、任务类型等实时优化温度,提升多轮对话的质量和效率,显著改善智能客服和内容创作的应用体验。这一技术突破为大语言模型的发展注入了新活力,展现了强大的适应性和竞争力。
283 17
|
12月前
|
机器学习/深度学习 算法 调度
AdEMAMix: 一种创新的神经网络优化器
9月发布的一篇论文中,Pagliardini等人提出了AdEMAMix,一种新的优化算法,旨在克服Adam及其变体(如AdamW)在利用长期梯度信息方面的局限性。通过结合两种不同衰减率的指数移动平均(EMA),AdEMAMix能够更有效地利用历史梯度信息。实验结果显示,AdEMAMix在语言建模和视觉任务中均显著优于AdamW,不仅能加速模型收敛,还能提高学习稳定性。尽管引入了额外计算步骤,但开销极小,展示了在大规模神经网络训练中的潜力。论文详细探讨了其核心思想、实验设置及未来研究方向。
334 8
AdEMAMix: 一种创新的神经网络优化器
|
10月前
|
存储 Java 数据库
Java “ClassCastException”解决
Java中的“ClassCastException”是在运行时尝试将对象强制转换为与其实际类型不兼容的类型时引发的异常。解决方法包括:1. 检查类型转换前使用`instanceof`关键字进行类型判断;2. 确保对象的实际类型与目标类型一致;3. 审查代码逻辑,避免不必要的类型转换。
851 4
|
SQL 数据挖掘
|
缓存 网络协议
Clash连接成功却无法访问
Clash连接成功却无法访问
5588 1
|
关系型数据库 数据库 PostgreSQL
PostgreSQL数据库的字符串拼接语法使用说明
【6月更文挑战第11天】PostgreSQL数据库的字符串拼接语法使用说明
1224 1
|
关系型数据库 MySQL 中间件
【MySQL实战笔记】07 | 行锁功过:怎么减少行锁对性能的影响?-02 死锁和死锁检测
【4月更文挑战第19天】在高并发环境下,死锁发生在多个线程间循环等待资源时,导致无限期等待。MySQL中,死锁可通过`innodb_lock_wait_timeout`参数设置超时或`innodb_deadlock_detect`开启死锁检测来解决。默认的50s超时可能不适用于在线服务,而频繁检测会消耗大量CPU。应对热点行更新引发的性能问题,可以暂时关闭死锁检测(风险是产生大量超时),控制并发度,或通过分散记录减少锁冲突,例如将数据分拆到多行以降低死锁概率。
353 1
|
负载均衡 监控 关系型数据库
PostgreSQL从小白到高手教程 - 第48讲:PG高可用实现keepalived
PostgreSQL技术大讲堂 - 第48讲:PG高可用实现keepalived
430 1