说到达梦数据库,很多人以为都是基于Oracle 8i或者9i的代码copy的;实际上从测试来看并不是这样。这里我要说明,达梦没有给我一毛钱,我不是打广告。这里我通过简单的例子来对了一下窥视:

SQL> create table killdb(a number,b varchar2(200)) tablespace enmotech;
executed successfully
used time: 3.444(ms). Execute id is 212.
SQL> 
SQL> insert into killdb values(5,'www.killdb.com');
affect rows 1
 
used time: 0.525(ms). Execute id is 213.
SQL> commit;
executed successfully
used time: 0.974(ms). Execute id is 214.
 
SQL> select segment_name,SEGMENT_TYPE,HEADER_FILE,HEADER_BLOCK,BYTES,BLOCKS,EXTENTS,INITIAL_EXTENT,MAX_EXTENTS,FREELISTS,FREELIST_GROUPS from dba_Segments where segment_name='KILLDB';
 
SEGMENT_NAME SEGMENT_TYPE HEADER_FILE HEADER_BLOCK BYTES                BLOCKS               EXTENTS              INITIAL_EXTENT       MAX_EXTENTS          FREELISTS FREELIST_GROUPS
------------ ------------ ----------- ------------ -------------------- -------------------- -------------------- -------------------- -------------------- --------- ---------------
KILLDB       TABLE        0           48           262144               32                   2                    131072               2147483645           NULL      NULL
 
used time: 268.345(ms). Execute id is 215.
SQL> 
SQL>  DECLARE
2   INFO DBMS_PAGE.DPH_ARR_T;
3       BEGIN
   INFO = NEW DBMS_PAGE.DPH_T[1];
   DBMS_PAGE.DATA_PAGE_HEAD_LOAD(5,0,48,INFO[1]);
   SELECT * FROM ARRAY INFO;
   END;
4   5   6   7   8     /
 
N_SLOT      N_REC       HEAP_LOW    HEAP_HIGH   BRANCH_NO   FREE_LIST_OFF REC_MIN_OFF REC_MAX_OFF EXTERNAL    USED_TINYINT
----------- ----------- ----------- ----------- ----------- ------------- ----------- ----------- ----------- ------------
3           1           138         0           0           NULL          82          90          NULL        152
 
used time: 0.764(ms). Execute id is 216.
SQL> 
SQL>  DECLARE
2   HEAD DBMS_PAGE.DPH_T;
3   INFO dbms_page.REC_ARR_T;
4   BEGIN
5   DBMS_PAGE.DATA_PAGE_HEAD_LOAD(5,0,48,HEAD);
6   INFO = NEW dbms_page.REC_T[HEAD.N_REC];
7   FOR I IN 1..HEAD.N_REC LOOP
8   DBMS_PAGE.DATA_PAGE_REC_BY_SLOT_NO_LOAD(5,0,48,I,INFO[I]);
9   END LOOP;
10  SELECT * FROM ARRAY INFO;
11  END;
/12  
 
SLOT_NO     OFFSET      LEN         IS_DEL      TRX_ID               CLU_ROWID            ROLL_ADDR_FILE ROLL_ADDR_PAGE ROLL_ADDR_OFF
----------- ----------- ----------- ----------- -------------------- -------------------- -------------- -------------- -------------
1           98          40          0           6029                 1                    NULL           NULL           NULL
 
used time: 0.742(ms). Execute id is 223.
SQL> set long 9999
SQL> SP_TABLEDEF('SYSDBA','KILLDB');
 
COLUMN_VALUE
-------------------------------------------------------------------------------------------------------
CREATE TABLE "SYSDBA"."KILLDB" ( "A" NUMBER, "B" VARCHAR2(200)) STORAGE(ON "ENMOTECH", CLUSTERBTR) ;
 
used time: 0.427(ms). Execute id is 310.
SQL> select dump(a,b) from killdb;
select dump(a,b) from killdb;
[-6111]:Fail to cast string.
used time: 0.652(ms). Execute id is 0.
SQL> select dump(a) from killdb;
 
DUMP(A)           
------------------
Typ=9 Len=2: 193,6
 
used time: 0.575(ms). Execute id is 225.
SQL> select dump(b) from killdb;
 
DUMP(B)                                                          
-----------------------------------------------------------------
Typ=2 Len=14: 119,119,119,46,107,105,108,108,100,98,46,99,111,109
 
used time: 0.527(ms). Execute id is 226.
SQL> select group_id,id,path,page_size,FREE_PAGE_NO from v$datafile;
 
GROUP_ID    ID          PATH                                        PAGE_SIZE   FREE_PAGE_NO        
----------- ----------- ------------------------------------------- ----------- --------------------
0           0           /opt/dm/dmdbms/data/enmotech/SYSTEM.DBF     8192        1808
1           0           /opt/dm/dmdbms/data/enmotech/ROLL.DBF       8192        1488
3           0           /opt/dm/dmdbms/data/enmotech/TEMP.DBF       8192        16
4           0           /opt/dm/dmdbms/data/enmotech/MAIN.DBF       8192        48
5           0           /opt/dm/dmdbms/data/enmotech/enmotech01.dbf 8192        64
 
used time: 0.663(ms). Execute id is 229.
SQL>  select id,path,MODIFY_TRX from v$datafile;
 
ID          PATH                                        MODIFY_TRX          
----------- ------------------------------------------- --------------------
0           /opt/dm/dmdbms/data/enmotech/SYSTEM.DBF     6029
0           /opt/dm/dmdbms/data/enmotech/ROLL.DBF       6029
0           /opt/dm/dmdbms/data/enmotech/TEMP.DBF       6029
0           /opt/dm/dmdbms/data/enmotech/MAIN.DBF       6029
0           /opt/dm/dmdbms/data/enmotech/enmotech01.dbf 6029
 
used time: 0.577(ms). Execute id is 308.
SQL> 
SQL> select owner,object_name,OBJECT_ID,OBJECT_TYPE,STATUS from dba_objects where object_name='KILLDB';
 
OWNER  OBJECT_NAME OBJECT_ID OBJECT_TYPE STATUS
------ ----------- --------- ----------- ------
SYSDBA KILLDB      1282      TABLE       VALID
 
used time: 7.276(ms). Execute id is 232.
 
SQL> select dump(1282) from dual;
 
DUMP(1282)          
--------------------
Typ=7 Len=4: 2,5,0,0
 
dmdba@test25:~#   dd if=/opt/dm/dmdbms/data/enmotech/enmotech01.dbf bs=8192 skip=48 count=1|od -x
1+0 records in
1+0 records out
8192 bytes (8.2 kB) copied, 6.4457e-05 s, 127 MB/s
0000000 0005 0000 0030 0000 ffff ffff ffff ffff
0000020 ffff ffff 0014 0000 0000 0000 a9af 0000
0000040 0000 0000 0003 008a 0000 0000 0001 ffff
0000060 0052 005a ffff 0098 0000 03ff 0200 0005    
0000100 0000 0008 0000 010c 0005 0000 0008 0000
0000120 00c4 0000 0000 0000 0000 ffff ffff ffff
0000140 ffff 2800 8200 06c1 778e 7777 6b2e 6c69  
0000160 646c 2e62 6f63 016d 0000 0000 ff00 ffff
0000200 7fff ffff 178d 0000 0000 0000 0000 0000
0000220 0000 0000 0000 0000 0000 0000 0000 0000
*
0017760 0000 005a 0062 0052 0000 0000 0000 0000
0020000
dmdba@test25:~#

由于x86这里是反向存储,因此c1 06即a列dump value 196,6

778e 7777 6b2e 6c69 646c 2e62 6f63 016d 转换后为:8e77 7777 2e6b 696c 6c64 622e 636f 6d01

其中的77 7777 2e6b 696c 6c64 622e 636f 6d即为我们的数据 www.killdb.com,长度为14。

从dump的page header信息来看,其中:

0005 中 05表示tablespace id 05

第3,4 偏移量为file id 00 00

第6,7偏移量 0030为段头的header page地址,即48

178d 为最近一次修改的事务ID 6029. 类似Oracle checkpoint 。

从dump page的结果来看,在page的尾部没有类似Oracle一样的tail校验机制(block头scn的低位的后4位+block type+seq = block尾部的tail值). 因此从这里也能看出一个问题,如果使用了大于4k的page size,那么达梦数据库也存在partial write问题;换句话说达梦数据库也不支持原子写,而且还没有类似Oracle一样的严格的校验机制。

因此从物理结构来看与Oracle 完全不同,实际上Oracle 8i开始的block结构并没有太大的变化。

所以我认为达梦数据库应该是纯自研,猜测达梦是基于Oracle 8i/9i的说法应该可以洗洗睡了。

不过从相关视图的查询结果来看,达梦基于o的兼容是基于Oracle 12.1进行的。

最后简单总结一下这个小测试得到的几个结论:

1、达梦数据库默认创建的table是簇表,也就是索引组织表,也可以创建为普通堆表;可以参考之前写的文章 达梦数据库学习笔记-表与分区表

2、达梦不支持原子写,也存在partial write问题;

3、达梦不存在类似Oracle一样针对block的严格校验机制(之前已写过类似文章 达梦数据库学习笔记 -达梦IO写入性能与partial write

4、达梦数据page的结构与Oracle block 结构完全不同,其page头部即存在tablespace id+ file id + header page number;

但是page中的行数据存放格式跟oracle一样,也是row头存放列长度+type+row数据的模式。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐