彻底理解move 操作
前几天群里有人问,move 操作,我这里做了几个实验,方便大家了解move 的基本操作。
(1) oracle 的move 操作,rowid 如何变化?
SQL> drop table daodao;
表已删除。
SQL> create table daodao (id int, name char(2000)) tablespace users;
表已创建。
SQL> insert into daodao values (1,'aa');
已创建 1 行。
SQL> insert into daodao values (2,'bb');
已创建 1 行。
SQL> insert into daodao values (3,'cc');
已创建 1 行。
SQL> insert into daodao values (4,'dd');
已创建 1 行。
SQL> insert into daodao values (5,'ee');
已创建 1 行。
SQL> insert into daodao values (6,'ff');
已创建 1 行。
SQL> insert into daodao values (7,'gg');
已创建 1 行。
SQL> insert into daodao values (8,'hh');
已创建 1 行。
SQL> insert into daodao values (9,'ii');
已创建 1 行。
SQL> insert into daodao values (10,'jj');
已创建 1 行。
SQL> commit;
提交完成。
SQL> select rowid from daodao;
ROWID
------------------
AAur6aAAFAAC2/lAAA
AAur6aAAFAAC2/lAAB
AAur6aAAFAAC2/lAAC
AAur6aAAFAAC2/mAAA
AAur6aAAFAAC2/mAAB
AAur6aAAFAAC2/mAAC
AAur6aAAFAAC2/nAAA
AAur6aAAFAAC2/nAAB
AAur6aAAFAAC2/nAAC
AAur6aAAFAAC2/oAAA
已选择10行。
SQL> select Dbms_Rowid.rowid_block_number(rowid) from daodao;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------
749541
749541
749541
749542
749542
749542
749543
749543
749543
749544
已选择10行。
SQL> delete from daodao where mod(id,2)=1;
已删除5行。
SQL> select Dbms_Rowid.rowid_block_number(rowid) from daodao;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------
749541
749542
749542
749543
749544
SQL> alter table daodao move;
表已更改。
SQL> select Dbms_Rowid.rowid_block_number(rowid) from daodao;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------
749548
749548
749548
749549
749549
SQL> select id,Dbms_Rowid.rowid_block_number(rowid) from daodao;
ID DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
---------- ------------------------------------
2 749548
4 749548
6 749548
8 749549
10 749549
move操作后,数据的rowid发生了改变,我们知道,index是通过rowid来fetch数据行的,所以,table上的index是必须要rebuild的。
(2) move 操作索引会失效
SQL> create index daodao_index on daodao(id);
索引已创建。
SQL> alter table daodao move;
表已更改。
SQL> select id,Dbms_Rowid.rowid_block_number(rowid) from daodao;
ID DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
---------- ------------------------------------
2 749540
4 749540
6 749540
8 749541
10 749541
SQL> select index_name,status from user_indexes where index_name='DAODAO_INDEX';
INDEX_NAME STATUS
------------------------------ --------
DAODAO_INDEX UNUSABLE
从这里可以看到,当daodao进行move操作后,该table 上的inedx的状态为UNUSABLE,这时,我们可以使用alter index daodao_index rebuild online的命令,
进行在线rebuild。
(3) move 操作的锁问题
另外当我们对表进行move 的时候,需要加锁,我们可以看下
建立一个大表:
SQL> create table daodao_big as select a.* from dba_objects a, (select * from dba_objects b where rownum <200)b;
Table created.
SQL> alter table daodao_big move;
打开另外一个会话,可以看到:
SQL> SELECT b.session_id AS sid,
2 NVL(b.oracle_username, '(oracle)') AS username,
3 a.owner AS object_owner,
4 a.object_name,
5 Decode(b.locked_mode, 0, 'None',
6 1, 'Null (NULL)',
7 2, 'Row-S (SS)',
8 3, 'Row-X (SX)',
9 4, 'Share (S)',
10 5, 'S/Row-X (SSX)',
11 6, 'Exclusive (X)',
12 b.locked_mode) locked_mode,
13 b.os_user_name
14 FROM dba_objects a,
15 v$locked_object b
16 WHERE a.object_id = b.object_id;
SID USERNAME OBJECT_OWNER
---------- ------------------------------ ------------------------------
OBJECT_NAME
--------------------------------------------------------------------------------
LOCKED_MODE OS_USER_NAME
---------------------------------------- ------------------------------
159 SYS SYS
DAODAO_BIG
Exclusive (X) oracle
这里是6号锁,独占锁.
这就意味着,table在进行move操作时,我们只能对它进行select的操作。反过来说,当我们的一个session对table进行DML操作且没有commit时,
在另一个session中是不能对这个table进行move操作的,否则oracle会返回这样的错误信息:ORA-00054
(4) 现在来看下move 能否降低高水位?
SQL> create table dd_hwm as select * from dba_objects;
Table created.
SQL> show user;
USER is "SYS"
SQL> exec show_space('DD_HWM');
PL/SQL procedure successfully completed.
SQL> set serverout on;
SQL> exec show_space('DD_HWM');
Free Blocks............................. 0
Total Blocks............................ 768
Total Bytes............................. 6,291,456
Total MBytes............................ 6
Unused Blocks........................... 69
Unused Bytes............................ 565,248
Last Used Ext BlockId................... 63,369
Last Used Block......................... 59
PL/SQL procedure successfully completed.
SQL> desc dba_segments;
Name Null? Type
----------------------------------------- -------- ----------------------------
OWNER VARCHAR2(30)
SEGMENT_NAME VARCHAR2(81)
PARTITION_NAME VARCHAR2(30)
SEGMENT_TYPE VARCHAR2(18)
TABLESPACE_NAME VARCHAR2(30)
HEADER_FILE NUMBER
HEADER_BLOCK NUMBER
BYTES NUMBER
BLOCKS NUMBER
EXTENTS NUMBER
INITIAL_EXTENT NUMBER
NEXT_EXTENT NUMBER
MIN_EXTENTS NUMBER
MAX_EXTENTS NUMBER
PCT_INCREASE NUMBER
FREELISTS NUMBER
FREELIST_GROUPS NUMBER
RELATIVE_FNO NUMBER
BUFFER_POOL VARCHAR2(7)
SQL> select header_file,header_block from dba_segments where segment_name ='DD_HWM';
HEADER_FILE HEADER_BLOCK
----------- ------------
1 175449
SQL> alter system dump datafile 1 block 175449;
System altered.
SQL> select get_trace from dual;
GET_TRACE
--------------------------------------------------------------------------------
/u01/app/oracle/admin/huangchao/udump/huangchao_ora_13180.trc
SQL> !cat /u01/app/oracle/admin/huangchao/udump/huangchao_ora_13180.trc| grep Highwater
Highwater:: 0x0040f7c4 ext#: 20 blk#: 59 ext size: 128
!cat /u01/app/oracle/admin/huangchao/udump/huangchao_ora_13180.trc| grep below
#blocks below: 698
SQL> select get_fb('0x0040f7c4') from dual;
GET_FB('0X0040F7C4')
--------------------------------------------------------------------------------
datafile# is:1
datablock is:63428
dump command:alter system dump datafile 1 block 63428;
SQL> delete from dd_hwm where rownum <20000;
19999 rows deleted.
SQL> commit;
Commit complete.
SQL> alter table dd_hwm move;
Table altered.
SQL> exec show_space('DD_HWM');
Free Blocks............................. 0
Total Blocks............................ 512
Total Bytes............................. 4,194,304
Total MBytes............................ 4
Unused Blocks........................... 79
Unused Bytes............................ 647,168
Last Used Ext BlockId................... 63,881
Last Used Block......................... 49
PL/SQL procedure successfully completed.
SQL> select header_file,header_block from dba_segments where segment_name ='DD_HWM';
HEADER_FILE HEADER_BLOCK
----------- ------------
1 178985 -- 从这里看段头发生改变
SQL> alter system dump datafile 1 block 178985;
System altered.
SQL> !cat /u01/app/oracle/admin/huangchao/udump/huangchao_ora_13180.trc| grep Highwater
Highwater:: 0x0040f7c4 ext#: 20 blk#: 59 ext size: 128
Highwater:: 0x0040f9ba ext#: 18 blk#: 49 ext size: 128
SQL> select get_fb('0x0040f9ba') from dual;
GET_FB('0X0040F9BA')
--------------------------------------------------------------------------------
datafile# is:1
datablock is:63930
dump command:alter system dump datafile 1 block 63930;
SQL> !cat /u01/app/oracle/admin/huangchao/udump/huangchao_ora_13180.trc| grep below
#blocks below: 698 -- 第一次的高水位下的块
#blocks below: 432 -- 第二次的高水位下管理的块
table的HWM降低了!
我们还可以使用别的方法来降低table的HWM,比如shrink,CTAS 等操作,其实到现在可以看出move操作也可以用来解决table中的行迁移的问题。
彻底理解move 操作相关推荐
- oracle move不能操作分区,关于Oracle分区表的move操作
关于分区表的move操作还是很值得深究的一个问题.如果分区表中含有lob字段,难度还会加大. 对于普通的表而言,做move操作室理所 关于分区表的move操作还是很值得深究的一个问题.如果分区表中含有 ...
- oracle move不能操作分区,Oracle分区表的move操作
对于普通的表而言,做move操作室理所当然,oracle提供的方式很直接快捷.当然了这个命令也不是高可用的范畴.但是对于数据重组还是很方便快捷的. 一般来说,如果尝试对分区表进行move操作,会得到如 ...
- DS18B20 理解与操作源码
最近研究了DS18B20 数字温度传感器,它的时序控制确实有点小烦躁,参看了很多资料. 其中http://www.cnblogs.com/fengmk2/archive/2007/03/11/6709 ...
- 基础 | numpy ndarray 之内功心法,理解高维操作!
多维数据的形象表示 import numpy as np # 一维数据不用赘言 data_1d = np.array([0, 1, 2, 3]) # 二维数据作为 m 行 n 列的表格,例如 2 行 ...
- git 配置origin_git中各种命令中的origin和master如何理解和操作?
git的服务器端(remote)端包含多个repository,每个repository可以理解为一个项目(远程仓库).而每个repository(远程仓库.远程项目)下有多个branch(分支). ...
- 深入理解++和 -- 操作
目录 博文内容: 深刻认识C语言的++/--操作 本讲将会教你如何理解前置++,后置++问题 ★博文转载请注明出处. ++.--操作 基操: 深刻理解 a++ 复杂表达式 总结: 后记: ●由于作者水 ...
- 理解Java操作数据库原理
2019独角兽企业重金招聘Python工程师标准>>> 参考:https://blog.csdn.net/xiaozhegaa/article/details/70208646 上面 ...
- 深入理解Redis--fork操作
1.fork操作 (1)同步操作 虽然fork同步操作是非常快的,但是如果需要同步的数据量过大(比如超过20G),fork就会阻塞redis主进程. (2)与内存量息息相关 内存越大,fork同步数据 ...
- 深入理解文件操作——纯C(2)
最新文章
- 浅谈网络游戏的设计——服务器端编程 (3)
- linux 解压 目录,linux 中目录、文件的解压缩
- Maven中使用本地JAR包
- 在c语言中引用数组元素时,其数组下标的数据类型允许是什么
- 蓝桥杯 历届试题 剪格子
- PHP Linux安装
- springboot启动命令linux,springboot项目命linux环境下命令启动
- 基于任务分析的非递归遍历二叉树
- 虚拟内存和swap分区的关系
- Xshel和Xftp免费版
- win10很多软件显示模糊_Windows 10系统中屏幕字体变模糊,用这3个方法快速解决!...
- PHP解密小程序加密信息
- 解空间树搜索 及 最优解
- java-读取Excel文件,自定义读取固定行、列(不区分xls、xlsx)
- 【软件测试】公司招个测试员,我又面试了100多人,结局......
- Oracle存储过程
- C语言字符类型输入方式选择
- 欧氏距离,马氏距离(转载)
- Q.me推出! Amortech展示了它的卡尔加里软件开发技能
- 毕业四年多,如梦初醒
热门文章
- [ip核][vivado]串并转换器OSERDES学习
- 使用Python Django开发web应用5 URL映射、模板和视图
- Peluso音乐现场Matt Lee-萨克斯录音P49电子管话筒
- sci-hub如何使用
- 即时搜索对搜索引擎策略的影响
- 单片机不同晶振怎么计算延迟时间?
- Trip.com W1D5
- 逻辑 || !运算用法
- Makefile中的常用函数subst、foreach、wildcard、notdir、patsubst
- Android 源码系列之二十通过反射解决在HuaWei手机出现Register too many Broadcast Receivers的crash