ITPub博客

首页 > Linux操作系统 > Linux操作系统 > undo,tablespace,session

undo,tablespace,session

Linux操作系统 作者:mzd75 时间:2013-12-04 17:48:10 0 删除 编辑
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/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2013-11-30

  • 博文量
    74
  • 访问量
    213514