暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

oracle 12c 学习系列(1)--12c初体验

原创 Roger 2013-07-07
637
oracle 12c发布已经有几天了,最近一直比较忙,没时间研究,趁周末在家玩玩,熟悉下12c的新特性.
其中有2个比较新的概念是multitenant container database (CDB) ,pluggable database(pdb).

一个CDB包含0个或1个甚至多个PDB. 每个CDB都包含如下的内容:
Exactly one root (存放oracle提供的metadata信息和公共user信息)

The root stores Oracle-supplied metadata and common users. An example of metadata is the source code for Oracle-supplied
PL/SQL packages (see "Data Dictionary Architecture in a CDB"). A common user is a database user known in every container
(see "Common Users in a CDB"). The root container is named CDB$ROOT.

Exactly one seed PDB (这是oracle提供的system 模板,这里面的对象的只读的)

The seed PDB is a system-supplied template that the CDB can use to create new PDBs. The seed PDB is named PDB$SEED.
You cannot add or modify objects in PDB$SEED.

Zero or more user-created PDBs (用户存放的数据)

A PDB is a user-created entity that contains the data and code required for a specific set of features. For example,
a PDB can support a specific application, such as a human resources or sales application. No PDBs exist at creation of the CDB.
You add PDBs based on your business requirements.

每个CDB中的组件,都可以理解为是一个container(容器). 那么到底是怎么样一个结构呢,大家可以参考官方文档的图,如下:

 



 

可以看出,上面的一个CDB中包含了4个container,分别是:root,seed,hrpdb,salespdb.
当然,只有hrpdb和sealespdb里面的数据才是我们的实际业务数据.这里需要注意的是,虽然从上图来看,逻辑上来看是一个整体。然而其物理结构是有所不同的,例如文件的存放位置.
首先我们来看下12c pdb的结构图:



 

可以看到,实际上是共享一个instance memory结构.  下面我们来手工创建一个pdb.
SQL> select v.name, v.open_mode, nvl(v.restricted, 'n/a') "RESTRICTED", d.status
2 from v$PDBs v inner join dba_pdbs d
3 using (GUID)
4 order by v.create_scn
5 /

NAME OPEN_MODE RES STATUS
------------------------------ ---------- --- -------------
PDB$SEED READ ONLY NO NORMAL
PDBORCL READ WRITE NO NORMAL

SQL> set timing on
SQL> create pluggable database killdb
2 admin user killdb identified by killdb
3 file_name_convert = ('/pdbseed/', '/killdb/')
4 /

Pluggable database created.

Elapsed: 00:01:20.33

注意这里的file_name_convert是创建pdb中cdb的语法,如果你去查询v$parameter你会发现其实并没有这个参数.

官方文档中只有PDB_FILE_NAME_CONVERT 这个参数. 下面我们打开pdb中所有的CDB.
SQL> alter pluggable database all open;

Pluggable database altered.

Elapsed: 00:00:19.03
SQL>

SQL> select PDB_ID,PDB_NAME from dba_pdbs;

PDB_ID PDB_NAME
---------- ----------------------------------------------------------------------------
3 PDBORCL
2 PDB$SEED
4 KILLDB

Elapsed: 00:00:00.01
SQL> select file_name ,bytes/1024/1024 from cdb_data_files where con_id=3;

FILE_NAME BYTES/1024/1024
---------------------------------------------------------------------- ---------------
/oracle/oradata/orcl/pdborcl/system01.dbf 260
/oracle/oradata/orcl/pdborcl/sysaux01.dbf 620
/oracle/oradata/orcl/pdborcl/SAMPLE_SCHEMA_users01.dbf 5
/oracle/oradata/orcl/pdborcl/example01.dbf 323.125

Elapsed: 00:00:00.02
SQL> select file_name ,bytes/1024/1024 from cdb_data_files where con_id=4;

FILE_NAME BYTES/1024/1024
---------------------------------------------------------------------- ---------------
/oracle/oradata/orcl/killdb/system01.dbf 250
/oracle/oradata/orcl/killdb/sysaux01.dbf 590

Elapsed: 00:00:00.04

SQL> select member from v$Logfile;

MEMBER
------------------------------------------------------------
/oracle/oradata/orcl/redo03.log
/oracle/oradata/orcl/redo02.log
/oracle/oradata/orcl/redo01.log

SQL> select name from v$controlfile;

NAME
----------------------------------------------------------------------------------------
/oracle/oradata/orcl/control01.ctl
/oracle/fast_recovery_area/orcl/control02.ctl

大家可以发现,我这里的orcl这个CDB中,有2个我自己创建的pdb。同时大家也可以发现,这2个pdb都有属于自己的system datafile,这说明了什么
?说明一个CDB中的每个pdb都属于自己的数据字典信息,换句话讲,一个CDB中的每个pdb的数据字典信息都是独立的,每个pdb就可以理解为一个单独的数据库,只不过这些pdb是共享的一个实例和redo,以及controlfile,undotbs. 如下,查询你会发现每个pdb的数据字典信息都不一致:
SQL>  alter pluggable database all open;

Pluggable database altered.

SQL> alter session set container=PDBORCL;

Session altered.

SQL> select count(1) from dba_objects;

COUNT(1)
----------
91517

SQL> alter session set container=killdb;

Session altered.

SQL> select count(1) from dba_objects;

COUNT(1)
----------
90761

这样设计有什么好处?显然好处之一就是便于进行迁移。同时我们也知道12c可以在线进行datafile 的move移动,先测试一把:
SQL> alter database move datafile 12 to '/oracle/oradata/orcl/roger01.dbf';

Database altered.

SQL> l
1* alter database move datafile 12 to '/oracle/oradata/orcl/roger01.dbf'
SQL> select file#,name from v$datafile;

FILE# NAME
---------- --------------------------------------------------------------------------------
1 /oracle/oradata/orcl/system01.dbf
3 /oracle/oradata/orcl/sysaux01.dbf
4 /oracle/oradata/orcl/undotbs01.dbf
5 /oracle/oradata/orcl/pdbseed/system01.dbf
6 /oracle/oradata/orcl/users01.dbf
7 /oracle/oradata/orcl/pdbseed/sysaux01.dbf
8 /oracle/oradata/orcl/pdborcl/system01.dbf
9 /oracle/oradata/orcl/pdborcl/sysaux01.dbf
10 /oracle/oradata/orcl/pdborcl/SAMPLE_SCHEMA_users01.dbf
11 /oracle/oradata/orcl/pdborcl/example01.dbf
12 /oracle/oradata/orcl/roger01.dbf
13 /oracle/oradata/orcl/killdb/system01.dbf
14 /oracle/oradata/orcl/killdb/sysaux01.dbf

13 rows selected.

通过监控发可以发现move datafile的时候会出现type为MV的锁,mode是4,6. 换句话讲,在move的过程的中,该datafile的对象是可以进行访问的. 经测试发现在move datafile期间,该datafile上的对象是可以进行dml和select操作的,如下:
---Session1
SQL> l
1* select segment_name,tablespace_name from dba_segments where segment_name='T'
SQL> /

SEGMENT_NAME TABLESPACE_NAME
------------------------------ ------------------------------
T USERS
SQL> alter database move datafile 6 to '/oracle/oradata/orcl/killdb/users01.dbf';

Database altered.

----Session 2
SQL> delete from t where object_id < 1000;

996 rows deleted.

SQL> delete from t where rownum < 10;

9 rows deleted.

SQL> /

9 rows deleted.

SQL> /

9 rows deleted.

SQL> commit;

Commit complete.

这里只列出delete的操作,其他操作就不列了.  online 移动datafile是12c中一个很好的特性之一,对我们做迁移来讲是太好不过了,比如存储更换,可以直接move,都不需要用rman去进行restore了.

那么多move datafile的实质到底如何呢 ?下面我们通过10046 event和strace命令来跟踪下move datafile的操作。

----Session 1
SQL> select sid from v$mystat where rownum < 2;

SID
----------
30

SQL> select spid from v$process where addr=(select paddr from v$session where sid=30);

SPID
------------------------
4192
SQL> show user
USER is "SYS"
SQL> oradebug setmypid
Statement processed.
SQL> oradebug event 10046 trace name context forever,level 12;
Statement processed.
SQL> alter database move datafile 6 to '/oracle/oradata/orcl/users01.dbf';

Database altered.

SQL> oradebug event 10046 trace name context off
Statement processed.
SQL> oradebug close_trace
Statement processed.
SQL> oradebug tracefile_name
/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_4192.trc
SQL>

----Session 3


[oracle@12c_single ~]$ ps -ef|grep -v grep|grep 4192
oracle 4192 4191 0 11:32 ? 00:00:02 oracleorcl (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
[oracle@12c_single ~]$ strace -fr -o /tmp/4192.log -p 4192
Process 4192 attached - interrupt to quit
^CProcess 4192 detached
[oracle@12c_single ~]$


----10046 trace event

针对controlfile的读写:


[root@12c_single ~]# cat /oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_4192.trc |grep 'control'
WAIT #139835385925424: nam='control file sequential read' ela= 317 file#=0 block#=1 blocks=1 obj#=442 tim=43780028339
WAIT #139835385925424: nam='control file sequential read' ela= 113 file#=1 block#=1 blocks=1 obj#=442 tim=43780029029
WAIT #139835385925424: nam='control file sequential read' ela= 196 file#=0 block#=16 blocks=1 obj#=442 tim=43780029935
........
WAIT #139835385925424: nam='control file parallel write' ela= 3611 files=2 block#=89 requests=2 obj#=442 tim=43780090566
WAIT #139835385925424: nam='control file parallel write' ela= 3450 files=2 block#=23 requests=2 obj#=442 tim=43780094311
........


从跟踪来看,move datafile的过程中会对controlfile进行顺序读和parallel write. 我们来看下对数据文件的读写情况:


[root@12c_single ~]# cat /oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_4192.trc |grep 'db file'
WAIT #139835385925424: nam='db file sequential read' ela= 64 file#=6 block#=1 blocks=1 obj#=442 tim=43780046459
WAIT #139835385925424: nam='db file single write' ela= 65 file#=6 block#=1 blocks=1 obj#=442 tim=43780078849
WAIT #139835385925424: nam='db file sequential read' ela= 53941 file#=6 block#=2 blocks=127 obj#=442 tim=43780166313
WAIT #139835385925424: nam='db file single write' ela= 48912 file#=6 block#=2 blocks=127 obj#=442 tim=43780215734
WAIT #139835385925424: nam='db file sequential read' ela= 26990 file#=6 block#=129 blocks=128 obj#=442 tim=43780244920
WAIT #139835385925424: nam='db file single write' ela= 68495 file#=6 block#=129 blocks=128 obj#=442 tim=43780313982
WAIT #139835385925424: nam='db file sequential read' ela= 29335 file#=6 block#=257 blocks=128 obj#=442 tim=43780346831
WAIT #139835385925424: nam='db file single write' ela= 48586 file#=6 block#=257 blocks=128 obj#=442 tim=43780396042
WAIT #139835385925424: nam='db file sequential read' ela= 44739 file#=6 block#=385 blocks=128 obj#=442 tim=43780443595
.........
WAIT #139835385925424: nam='db file sequential read' ela= 48956 file#=6 block#=25345 blocks=128 obj#=442 tim=43798447850
WAIT #139835385925424: nam='db file single write' ela= 47854 file#=6 block#=25345 blocks=128 obj#=442 tim=43798496353
WAIT #139835385925424: nam='db file sequential read' ela= 27800 file#=6 block#=25473 blocks=128 obj#=442 tim=43798527302
WAIT #139835385925424: nam='db file single write' ela= 47581 file#=6 block#=25473 blocks=128 obj#=442 tim=43798575454
WAIT #139835385925424: nam='db file sequential read' ela= 272 file#=6 block#=1 blocks=1 obj#=442 tim=43798579382
WAIT #139835385925424: nam='db file single write' ela= 1417 file#=6 block#=1 blocks=1 obj#=442 tim=43798581335
WAIT #139835385925424: nam='db file sequential read' ela= 348 file#=6 block#=1 blocks=1 obj#=442 tim=43799611993
WAIT #139835385925424: nam='db file single write' ela= 4429 file#=6 block#=1 blocks=1 obj#=442 tim=43799617061



我们可以看到,trace文件的前部和尾部都是对该数据文件的header block进行读,然后写.中间部分内容是按照128 block单位进行读写.
可以发现,是会将整个datafile的block都读一遍。细心的朋友也行会发现,这里居然是db file single write,按理说应该是db file parallel write
才对,因为后面的p3=128. 如果是single write,那么p3应该是1才对.

那么这里只有一种解释,将每个block都写一次,每次读完后都写128次.

每次db file single write之前也是对应的db file sequential read,大家注意后的p3也是128,并不是1. 12c的官方文档是这样解释这个event的:
file#   See "file#"

block# See "block#"

blocks This is the number of blocks that the session is trying to read (should be 1)

所以这里给人似乎有点难以理解,难道是每次读1个block,读128次?

另外,关于move datafile操作,我相信肯定也是会触发检查点的.

我们再来看下strace 该进程的trace内容是如何的 :

----fd 信息
[root@12c_single ~]# cd /proc/4192/fd
[root@12c_single fd]# ls -ltr
total 0
lr-x------ 1 oracle oinstall 64 Jul 7 12:06 9 -> /dev/urandom
lr-x------ 1 oracle oinstall 64 Jul 7 12:06 8 -> /dev/urandom
lr-x------ 1 oracle oinstall 64 Jul 7 12:06 7 -> /dev/zero
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 6 -> anon_inode:[eventpoll]
lr-x------ 1 oracle oinstall 64 Jul 7 12:06 5 -> /proc/4192/fd
lr-x------ 1 oracle oinstall 64 Jul 7 12:06 4 -> /oracle/product/12.1/db_1/rdbms/mesg/oraus.msb
lr-x------ 1 oracle oinstall 64 Jul 7 12:06 3 -> /dev/null
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 270 -> /oracle/oradata/orcl/killdb/sysaux01.dbf
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 269 -> /oracle/oradata/orcl/killdb/system01.dbf
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 268 -> /oracle/oradata/orcl/roger01.dbf
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 267 -> /oracle/oradata/orcl/pdborcl/example01.dbf
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 266 -> /oracle/oradata/orcl/pdborcl/SAMPLE_SCHEMA_users01.dbf
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 265 -> /oracle/oradata/orcl/pdborcl/sysaux01.dbf
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 264 -> /oracle/oradata/orcl/pdborcl/system01.dbf
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 263 -> /oracle/oradata/orcl/pdbseed/sysaux01.dbf
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 262 -> /oracle/oradata/orcl/pdbseed/system01.dbf
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 261 -> /oracle/oradata/orcl/users01.dbf
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 260 -> /oracle/oradata/orcl/undotbs01.dbf
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 259 -> /oracle/oradata/orcl/sysaux01.dbf
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 258 -> /oracle/fast_recovery_area/orcl/control02.ctl
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 257 -> /oracle/oradata/orcl/control01.ctl
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 256 -> /oracle/oradata/orcl/system01.dbf
l-wx------ 1 oracle oinstall 64 Jul 7 12:06 2 -> /dev/null
l-wx------ 1 oracle oinstall 64 Jul 7 12:06 13 -> pipe:[24450]
lrwx------ 1 oracle oinstall 64 Jul 7 12:06 11 -> /oracle/admin/orcl/adump/orcl_ora_4192_20130707113215690516143795.aud
lr-x------ 1 oracle oinstall 64 Jul 7 12:06 10 -> pipe:[24449]
l-wx------ 1 oracle oinstall 64 Jul 7 12:06 1 -> /dev/null
lr-x------ 1 oracle oinstall 64 Jul 7 12:06 0 -> /dev/null

----读操作
[root@12c_single ~]# cat /tmp/4192.log |grep pread
4192 0.002157 pread(257, "\25\302\0\0\1\0\0\0\0\0\0\0\0\0\1\4\241\360\0\0\0\0\0\0\0\0\20\fM\212IP"..., 16384, 16384) = 16384
4192 0.000113 pread(258, "\25\302\0\0\1\0\0\0\0\0\0\0\0\0\1\4\241\360\0\0\0\0\0\0\0\0\20\fM\212IP"..., 16384, 16384) = 16384
4192 0.000284 pread(257, "\25\302\0\0\20\0\0\0\225\7\0\0\377\377\1\4Y\7\0\0\200\3\0\0\0\0\0\0\0\0\0\0"..., 16384, 262144) = 16384
.......
4192 0.000050 pread(257, "\25\302\0\0Y\0\0\0\213\7\0\0\377\377\1\4\341O\0\0\3\0\3\0\0\0\0\0\0\0/o"..., 16384, 1458176) = 16384
4192 0.000052 pread(257, "\25\302\0\0\377\2\0\0\225\7\0\0\377\377\1\4\252\262\0\0\33\0\6\0\335\7\0\0\0\0\0\0"..., 16384, 12566528) = 16384
4192 0.000054 pread(260, "\v\242\0\0\1\0\200\1\0\0\0\0\0\0\1\0047\300\0\0\0\0\0\0\0\0\20\fM\212IP"..., 8192, 8192) = 8192
4192 0.000250 pread(257, "\25\302\0\0\1\0\0\0\0\0\0\0\0\0\1\4\271\203\0\0\0\0\0\0\0\0\20\fM\212IP"..., 16384, 16384) = 16384
4192 0.000053 pread(258, "\25\302\0\0\1\0\0\0\0\0\0\0\0\0\1\4\271\203\0\0\0\0\0\0\0\0\20\fM\212IP"..., 16384, 16384) = 16384
.......
4192 0.000097 pread(257, "\25\302\0\0\30\0\0\0\230\7\0\0\377\377\1\4.\316\0\0\0\0\0\0\0 \0\0\16\0\0\0"..., 16384, 393216) = 16384
4192 0.000123 pread(261, "\v\242\0\0\1\0\200\1\0\0\0\0\0\0\1\0047\300\0\0\0\0\0\0\0\0\20\fM\212IP"..., 8192, 8192) = 8192
4192 0.000105 pread(257, "\25\302\0\0\1\0\0\0\0\0\0\0\0\0\1\4\337\203\0\0\0\0\0\0\0\0\20\fM\212IP"..., 16384, 16384) = 16384
4192 0.000060 pread(258, "\25\302\0\0\1\0\0\0\0\0\0\0\0\0\1\4\337\203\0\0\0\0\0\0\0\0\20\fM\212IP"..., 16384, 16384) = 16384
4192 0.000055 pread(257, "\25\302\0\0\20\0\0\0\231\7\0\0\377\377\1\4YO\0\0\200\3\0\0\0\10\0\0\0\0\0\0"..., 16384, 262144) = 16384
........
4192 0.000058 pread(257, "\25\302\0\0\17\0\0\0\232\7\0\0\377\377\1\4\306\3\0\0\0\7\0\0\0\0\0\0\0\0\0\0"..., 16384, 245760) = 16384
4192 0.000402 pread(257, "\25\302\0\0\21\0\0\0\232\7\0\0\377\377\1\4\254\275\0\0\0\0\0\0\0\0\0\0\315>\3240"..., 16384, 278528) = 16384

----写操作


[root@12c_single ~]# cat /tmp/4192.log |grep pwrite
4192 0.000231 pwrite(257, "\25\302\0\0\30\0\0\0\226\7\0\0\377\377\1\4)\316\0\0\0\0\0\0\0 \0\0\16\0\0\0"..., 16384, 393216) = 16384
4192 0.001686 pwrite(258, "\25\302\0\0\30\0\0\0\226\7\0\0\377\377\1\4)\316\0\0\0\0\0\0\0 \0\0\16\0\0\0"..., 16384, 393216) = 16384
......
4192 0.001631 pwrite(258, "\25\302\0\0\1\0\0\0\0\0\0\0\0\0\1\4\271\203\0\0\0\0\0\0\0\0\20\fM\212IP"..., 16384, 16384) = 16384
4192 0.000057 pwrite(261, "\v\242\0\0\1\0\200\1\0\0\0\0\0\0\1\0046\300\0\0\0\0\0\0\0\0\20\fM\212IP"..., 8192, 8192) = 8192
4192 0.000057 pwrite(257, "\25\302\0\0Y\0\0\0\227\7\0\0\377\377\1\4\333O\0\0\3\0\3\0\0\0\0\0\0\0/o"..., 16384, 1458176) = 16384
4192 0.001907 pwrite(258, "\25\302\0\0Y\0\0\0\227\7\0\0\377\377\1\4\333O\0\0\3\0\3\0\0\0\0\0\0\0/o"..., 16384, 1458176) = 16384
4192 0.000076 pwrite(257, "\25\302\0\0\27\0\0\0\227\7\0\0\377\377\1\4\"\316\0\0\0\0\0\0\0 \0\0\16\0\0\0"..., 16384, 376832) = 16384
4192 0.001767 pwrite(258, "\25\302\0\0\27\0\0\0\227\7\0\0\377\377\1\4\"\316\0\0\0\0\0\0\0 \0\0\16\0\0\0"..., 16384, 376832) = 16384
4192 0.000058 pwrite(257, "\25\302\0\0\22\0\0\0\227\7\0\0\377\377\1\4\257\275\0\0\0\0\0\0\0\0\0\0\315>\3240"..., 16384, 294912) = 16384
4192 0.001790 pwrite(258, "\25\302\0\0\22\0\0\0\227\7\0\0\377\377\1\4\257\275\0\0\0\0\0\0\0\0\0\0\315>\3240"..., 16384, 294912) = 16384
4192 0.000503 pwrite(257, "\25\302\0\0\20\0\0\0\227\7\0\0\377\377\1\4YG\0\0\200\3\0\0\0\0\0\0\0\0\0\0"..., 16384, 262144) = 16384
4192 0.001587 pwrite(258, "\25\302\0\0\20\0\0\0\227\7\0\0\377\377\1\4YG\0\0\200\3\0\0\0\0\0\0\0\0\0\0"..., 16384, 262144) = 16384
4192 0.000062 pwrite(257, "\25\302\0\0\1\0\0\0\0\0\0\0\0\0\1\4\267\203\0\0\0\0\0\0\0\0\20\fM\212IP"..., 16384, 16384) = 16384
4192 0.001828 pwrite(258, "\25\302\0\0\1\0\0\0\0\0\0\0\0\0\1\4\267\203\0\0\0\0\0\0\0\0\20\fM\212IP"..., 16384, 16384) = 16384
4192 0.000383 pwrite(261, "\35\242\0\0\2\0\200\1\353\371\32\0\0\0\1\4\233N\0\0\6\0\0\0\10\0\0\0\0d\0\0"..., 1040384, 16384) = 1040384
4192 0.000439 pwrite(261, "!\242\0\0\201\0\200\1]\25\r\0\0\0\2\4\210\231\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1048576, 1056768) = 1048576
4192 0.000370 pwrite(261, "\6\242\0\0\1\1\200\1\313\364\32\0\0\0\2\4 \214\0\0\1\0\0\0sg\1\0\260\364\32\0"..., 1048576, 2105344) = 1048576
4192 0.000458 pwrite(261, " \242\0\0\201\1\200\1c\4\33\0\0\0\1\4w\340\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1048576, 3153920) = 1048576
4192 0.000353 pwrite(261, " \242\0\0\1\2\200\1e\4\33\0\0\0\1\4u\340\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1048576, 4202496) = 1048576
4192 0.000191 pwrite(261, " \242\0\0\201\2\200\1g\4\33\0\0\0\1\4s\340\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1048576, 5251072) = 1048576
......
4192 0.000386 pwrite(261, "\0\242\0\0\201b\200\1\0\0\0\0\0\0\1\5\1\304\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1048576, 206577664) = 1048576
4192 0.000426 pwrite(261, "\0\242\0\0\1c\200\1\0\0\0\0\0\0\1\5\201\305\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1048576, 207626240) = 1048576
4192 0.000399 pwrite(261, "\0\242\0\0\201c\200\1\0\0\0\0\0\0\1\5\1\305\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1048576, 208674816) = 1048576
4192 0.000269 pwrite(261, "\v\242\0\0\1\0\200\1\0\0\0\0\0\0\1\0047\300\0\0\0\0\0\0\0\0\20\fM\212IP"..., 8192, 8192) = 8192
4192 0.000081 pwrite(257, "\25\302\0\0\30\0\0\0\230\7\0\0\377\377\1\4.\316\0\0\0\0\0\0\0 \0\0\16\0\0\0"..., 16384, 393216) = 16384
4192 0.001666 pwrite(258, "\25\302\0\0\30\0\0\0\230\7\0\0\377\377\1\4.\316\0\0\0\0\0\0\0 \0\0\16\0\0\0"..., 16384, 393216) = 16384
.......
4192 0.000225 pwrite(257, "\25\302\0\0\17\0\0\0\232\7\0\0\377\377\1\4\306\3\0\0\0\7\0\0\0\0\0\0\0\0\0\0"..., 16384, 245760) = 16384
4192 0.001583 pwrite(258, "\25\302\0\0\17\0\0\0\232\7\0\0\377\377\1\4\306\3\0\0\0\7\0\0\0\0\0\0\0\0\0\0"..., 16384, 245760) = 16384
4192 0.000066 pwrite(257, "\25\302\0\0\1\0\0\0\0\0\0\0\0\0\1\4\337\203\0\0\0\0\0\0\0\0\20\fM\212IP"..., 16384, 16384) = 16384
4192 0.001472 pwrite(258, "\25\302\0\0\1\0\0\0\0\0\0\0\0\0\1\4\337\203\0\0\0\0\0\0\0\0\20\fM\212IP"..., 16384, 16384) = 16384
[root@12c_single ~]#


我们可以发现对controlfile的读写,其次是会读undotbs.  写操作主要集中在controlfile和datafile 261上。
由于会触发检查点,那么更新controlfile是必然的,这点无容置疑.我们重点来看下对datafile 261的操作.

针对datafile 261的第1次写操作:
4192       0.000057 pwrite(261, "\v\242\0\0\1\0\200\1\0\0\0\0\0\0\1\0046\300\0\0\0\0\0\0\0\0\20\fM\212IP"..., 8192, 8192) = 8192

从offset 8192来看,这里是操作的datafile header block.

针对datafile 261的第2次写操作:
4192       0.000383 pwrite(261, "\35\242\0\0\2\0\200\1\353\371\32\0\0\0\1\4\233N\0\0\6\0\0\0\10\0\0\0\0d\0\0"..., 1040384, 16384) = 1040384

这里offset是16384,而我们的block size是8k,换句话讲是从第2个block开始写的. 后面的1043384表示写了127个block,跟我们10046 trace是完全能对上的.

大家注意后面每次针对datafile 261的写都是以128 block为单位的,也就是每次写单位是1m. 写完之后,最后再更新datafile header block.
所以,从strace process的结果来看,是多block写的,跟前面10046 trace的db file single write似乎有点不一致.

最后来个简单的总结:

1. oracle database 12c感觉确实比较强悍,引入了很多新特性,例如多个lgwr,虚拟column等等
2. 引入了cdb,pdb的概念,但是对于同一个cdb来讲,不管其中包含多少个pdb,其本身是共享redo,undo和controlfile的,
同时也是共享一个instance memory结构.
3. 每个pdb都属于自己的数据字典信息,这样可以便于进行pdb的迁移.
4. 较为重要的一个特性move datafile,非常棒,我这里测试发现move datafile的时候回产生type为MV的锁,mode为4,6.
但是并不会阻塞dml和select操作.(或许我是vm测试较为简单,高并发环境或许有所不同)

后面会逐步分享12c的其他特性,敬请期待~~~
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论