oracle
第二天视频4,5(undo 表空间,session)
SQL> create undo tablespace undotbs2 datafile 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\undotbs02.dbf' size 10m;--创建一个UNDO表空间,类型是UNDO
select * from Dba_Segments WHERE tablespace_name='UNDOTBS2';
以前需要自己创建
SQL> create rollback segment sg1;
Rollback segment created.
SQL> create public rollback segment sg1;
--实际上没创建
看看UNDO
SQL> desc t;
Name Null? Type
----------------------------------------- -------- -------------------
ID NUMBER(38)
SQL> alter table t add name varchar2(10) default 'a';
Table altered.
SQL> select * from t;
no rows selected
SQL> insert into t values(1,'a');
1 row created.
SQL> insert into t values(2,'b');
1 row created.
SQL> commit
2 ;
Commit complete.
SQL> select * from t;
ID NAME
---------- ----------
1 a
2 b
现在做这样一个动作
SQL> update t set name='c' where id=1;
1 row updated.
SQL> select * from t;
ID NAME
---------- ----------
1 c
2 b
SQL> select distinct sid from v$mystat;
SID
----------
147
alter system kill session(143,2746);--这个2746对应的是SERIAL#编号
此时不提交,打开另外一个窗口,也用SYS用户登录
SQL> select * from t;--查询到的是a
ID NAME
---------- ----------
1 a
2 b
SQL> select distinct sid from v$mystat;
SID
----------
153
服务器端对应的地址
SQL> select paddr from v$session where sid =153;
PADDR
----------------
000007FF0BE64200
SQL> select pid,spid from v$process where addr='000007FF0BE64200';--服务器操作系统的进程ID
PID SPID
---------- ------------
18 5796
这两个编号,PID是oracle内部的给进程的编号,SPID是操作系统进程ID
WINDOWS进程是一个可执行程序,实际上下面有很多线程。
UNIX是一个实实在在工作的进程
写一个死循环,如果在应用里看到的就是等待
SQL> declare
2 i number :=0;
3 begin
4 loop
5 i :=1;
6 end loop;
7 end;
8 /
declare
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
session杀掉之后,为这个session服务的进程就停止工作了,但是进程并没有立刻从操作系统上消失,还占用一定的资源,但已经不工作了。
PMON会检查,然后释放掉。
此时看到的是正常的,若是其他数据库,只能等待,只有ORACLE数据库能看到,等待意味着对并发性支持不好,两个窗口是两个不同的session
其他数据库没有undo的概念,其他数据库把修改前的数据放在日志里。
此时介绍一下SESSION,SESSION描述的是进程和进程之间通信的过程,比如QQ之间的通信
一旦登陆成功,ORACLE就创建一个SESSION,用这个SESSION描述整个客户端进程和服务器端进程通信的过程。
1.database
2.instance
3.session
目前一共提到过两个SID
一个是建库的时候的system identifier
另外一个 session identifier
不需要用用户来区分了。
登录成功,oracle创建一个session
--sys
select * from v$session where sid in ('147','153');
再打开一个cmd
orakill tsid 5796--windows下
此时153这SESSION 也结束了
再来看看客户端进程,PROCESS,WINDOWS是两个值.
select * from v$session where sid in ('147','153');--PROCES147,5604:3944--客户端进程
5604是sqlplus.exe,3944是线程(Threads)
oracle
第二天视频6(SESSION,PROCESS,CONNECTION,UNDO)
v$process 在服务器上查
难以理解的概念
1.session-此时介绍一下SESSION,SESSION描述的是进程和进程之间通信的过程,比如QQ之间的通信
一旦登陆成功,ORACLE就创建一个SESSION,用这个SESSION描述整个客户端进程和服务器端进程通信的过程。
2.process--操作系统的概念
3.connection--不是数据库概念,两个进程建立的连接通道
客户端进程和服务器端进程事先建立的连接通道。
select * from v$license
SQL> show parameter cpu
NAME TYPE VALUE
------------------------------------ ----------- --------
cpu_count integer 4--oracle按照这个卖
parallel_threads_per_cpu integer 2
哪个进程校验用户名密码
sqlplus a/b@a
sqlplus a/b@test
select count(*) from v$session--38
select count(*) from v$process--39,进程默认比session 多一个
sqlplus a/b@test
尝试连数据库的时候,ORACLE数据库,后台起了一个进程,此时多了一个进程,这个进程即将为这个session服务
只不过由于用户名口令校验失败,SESSION还不存在。
select addr from v$process
minus
select paddr from v$session
没连上数据库,此时已经建立了连接通道,session 没有之前已经建立了连接
连接数据库的权限
connect是个角色,connect 封装了create session权限
select * from system_privilege_map
select * from dba_roles
select * from dba_sys_privs where grantee='CONNECT'
再回来看看,UNDO
exit的时候自动提交
两边都是C
SQL> select * from t;
ID NAME
---------- ----------
1 c
2 b
SQL> insert into t values(3,'d');
1 row created.
SQL> exit
C:\Users\HP>sqlplus / as sysdba--重新登录
SQL> select * from t;--此时3已经存在,被提交了
ID NAME
---------- ----------
1 c
2 b
3 d
SQL> insert into t values(4,'d');
1 row created.
SQL> disconnect--不连接
SQL> show user
USER is ""
SQL> conn / as sysdba
Connected.
SQL> select * from t;--此时4也被提交
ID NAME
---------- ----------
1 c
2 b
3 d
4 d
SQL> update t set name='a' where id=1;--修改一下
1 row updated.
SQL> select distinct sid from v$mystat;
SID
----------
143
另外一个CMD
SQL> select distinct sid from v$mystat;
SID
----------
147
SQL> select * from t;--读出来的是C,是如何看到的C的呢
ID NAME
---------- ----------
1 c
2 b
3 d
4 d
刚刚引入了SESSION的概念,还得再引入一个概念ROWID
SQL> select t.*,t.rowid from t;
ID NAME ROWID
---------- ---------- ------------------
1 c AAAC7qAAJAAAAAPAAA
2 b AAAC7qAAJAAAAAPAAB
3 d AAAC7qAAJAAAAARAAA
4 d AAAC7qAAJAAAAARAAB
SQL> select object_id ,data_object_id from dba_objects where object_name='T' and wner='SYS';
OBJECT_ID DATA_OBJECT_ID
---------- --------------
12007 12010--不一样,因为之前MOVE过
每一行都有一个唯一的标示
AAAC7q AAJ AAAAAP AAA--18位的64进制数
64
A~Z 0~25
a~z 26~51
0~9 52~61
+ 62
/ 63
select * from dba_objects;--都有object_id,但有的没有data_object_id
select distinct object_type from dba_objects where data_object_id is null--不是段,这里的索引是分区索引,表是分区表
SQL> alter table t move;
alter table t move
*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified
nowait,另一个窗口的UPDATE未结束,将另一个窗口进行rollback
然后接着move
SQL> alter table t move;
Table altered.
再查查看,DATA_OBJECT_ID又变了.
SQL> select object_id ,data_object_id from dba_objects where object_name='T' and wner='SYS';
OBJECT_ID DATA_OBJECT_ID
---------- --------------
12007 12018
rowid也变化了。
SQL> select t.*,t.rowid from t;
ID NAME ROWID
---------- ---------- ------------------
1 c AAAC7yAAJAAAAAcAAA
2 b AAAC7yAAJAAAAAcAAB
3 d AAAC7yAAJAAAAAcAAC
4 d AAAC7yAAJAAAAAcAAD
AAAC7y AAJ AAAAAc AAA--前六位代表的是数据段编号
SQL> select 2*power(64,2)+59*64+50 from dual;--12018对应的就是DATA_OBJECT_ID,数据段编号
2*POWER(64,2)+59*64+50
----------------------
12018
AAJ--9,代表的相对文件编号,代表的是RELATIVE_FNO(相对文件编号,在表空间内部的编号,只能是1~1023),不是FILE_ID(该文件不变化,绝对文件编号,代表的是数据库编号,最多是65535)
AAAAAc--28,数据块,在9号文件上第28个块上存放的
AAA--一个快上有很多行,最多能放256个行片,这个片上的第一条数据
这四条数据都在同一块上
根据ROWID能准确的找到这条数据的物理位置
使用索引也是通过ROWID找,ROWID就是页码
不允许行移动就是不希望ROWID发生变化
oracle
第二天视频7(UNDO)
SQL> select * from t;
ID NAME
---------- ----------
1 c
2 b
3 d
4 d
再改一下
SQL> update t set name='a' where id=1;
1 row updated.
SQL> select * from t;
ID NAME
---------- ----------
1 a
2 b
3 d
4 d
SQL> select t.*,t.rowid from t;
ID NAME ROWID
---------- ---------- ------------------
1 a AAAC7yAAJAAAAAcAAA
2 b AAAC7yAAJAAAAAcAAB
3 d AAAC7yAAJAAAAAcAAC
4 d AAAC7yAAJAAAAAcAAD
alter system dump datafile 9 block 28;--写入跟踪文件里,属于用户进程
SQL> show parameter user
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
license_max_users integer 0
parallel_adaptive_multi_user boolean TRUE
user_dump_dest string F:\ORACLE\PRODUCT\10.2.0\ADMIN
\TEST\UDUMP
SQL> select paddr from v$session where sid=147;
PADDR
----------------
000007FF0BE631B0
SQL> select spid from v$process where addr='000007FF0BE631B0';
SPID
------------
4824
block_row_dump:
tab 0, row 0, @0x1f78
tl: 8 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] c1 02
col 1: [ 1] 61--对应的是a
tab 0, row 1, @0x1f6f
tl: 8 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [ 1] 62
tab 0, row 2, @0x1f66
tl: 8 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [ 1] 64
tab 0, row 3, @0x1f5d
tl: 8 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 05
col 1: [ 1] 64
SQL> select ascii('a') from dual;
ASCII('A')
----------
97
97是10进制数,它的16进制数是61,61是a
SQL> select dump(1,16) from dual;
DUMP(1,16)
-----------------
Typ=2 Len=2: c1,2,也就是C1,02
SQL> select utl_raw.cast_to_number('c102') from dual;
UTL_RAW.CAST_TO_NUMBER('C102')
------------------------------
1
已经是啊a,为什么另一个SESSION 读出来是c呢
lb:lock byte
0x2
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0002.005.00000092 0x00000000.0000.00 C--- 0 scn 0x0000.00059377
0x02 0x0005.01c.00000097 0x00800d04.0029.22 ---- 1 fsc 0x0000.00000000
0x03 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
Uba:undo block address
0x00800d04
SQL> select to_number('00800d04','xxxxxxxxxxx') from dual;--转换成10进制
TO_NUMBER('00800D04','XXXXXXXXXXX')
-----------------------------------
8391940
SQL> select dbms_utility.data_block_address_file(8391940) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(8391940)
---------------------------------------------
2
SQL> select dbms_utility.data_block_address_block(8391940) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(8391940)
----------------------------------------------
3332
我们把修改前的c放到了2号文件上3332个块上了。2号文件正是UNDO 表空间,这就是UNDO的用途,把修改前的数据放在UNDO里。
当其他SESSION查询的时候,这个c是从UNDO里查出来的。
alter system dump datafile 2 block 3332;
22代表34
0x22 0x10e4最后1个
col 1: [ 1] 63
select * from v$transaction
2 3332
usn:undo segment number
select * from dba_rollback_segs;system有undo段
select * from v$rollstat;--唯独有一个XACTS是1,1代表这个UNDO段具有活动事务数量
0x0080070f.0039.07--代表下面4列
SQL> select to_number('0080070f','xxxxxxxx') from dual;
TO_NUMBER('0080070F','XXXXXXXX')
--------------------------------
8390415
SQL> select dbms_utility.data_block_address_file(8390415) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(8390415)
---------------------------------------------
2
SQL> select dbms_utility.data_block_address_block(8390415) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(8390415)
----------------------------------------------
1807
3*16+9=57
SYSTEM有个UNDO段,只为放在SYSTEM表空间的对象所使用
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/148459/viewspace-1062209/
,如需转载,请注明出处,否则将追究法律责任。