February 2010 Archives

Oracle中如何dump内存中的块

| 3 Comments

oracle里,假如我们去dump一个快,我们通常都会用到alter system dump datafile XXX block XXX,当你执行上述命令的时候,oracle会这么做:

首先判断一下你要dump的这个block是否在buffer cache中,如果在,则buffer cache中这个block的内容就会是你的dump文件中的内容,这时候oracle不会产生实际的物理I/O去相应的datafile中读这个block(所以这里有可能会存在不一致的情况,这种情况用BBED非常容易模拟);如果不在,oracle会产生实际的物理I/O去相应的datafile中读这个block,读到的内容就是你的dump文件中的内容,注意此时oracle不会把读到的那个block缓存在buffer cache中。

 

那么问题来了,oracle里有没有纯粹的不产生物理I/O,而只是从buffer cachedump缓存在其中的block的内容的方法呢?

 

答案是有的,如下的两条语句联合使用就可以达到上述目的了:

alter session set events 'immediate trace name set_tsn_p1 level <tablespace#+1>';

alter session set events  'immediate trace name buffer level <RDBA>';

这里的tablespace#是指ts$中的ts#

RDBA需要自己做一下转换,比如

SQL> exec sys.cdba('01000020','H');

.

The file is 4

The block is 32

这里datafile number4,用10位长度的bit表示就是0000 0001 00

这里block number32,用22位长度的bit表示就是 00 0000 0000 0000 0010 0000,所以这里拼起来的8位长度byte表示的RDBA就是01000020

 

我们来看一个实际的例子:

SQL> oradebug setmypid

Statement processed.

SQL> alter session set events 'immediate trace name set_tsn_p1 level 5';

 

Session altered.

 

SQL> alter session set events  'immediate trace name buffer level 0x01000020';

 

Session altered.

 

SQL> oradebug tracefile_name;

/u01/app/oracle/admin/ipratest/udump/ipratest_ora_6771106.trc

 

$ cat /u01/app/oracle/admin/ipratest/udump/ipratest_ora_6771106.trc

/u01/app/oracle/admin/ipratest/udump/ipratest_ora_6771106.trc

Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production

......省略显示部分内容

Dump of buffer cache at level 10 for tsn=4, rdba=16777248

BH (700000018f8d2e8) file#: 4 rdba: 0x01000020 (4/32) class: 1 ba: 7000000182ba000

  set: 3 blksize: 8192 bsi: 0 set-flg: 2 pwbcnt: 0

  dbwrid: 0 obj: 51147 objn: 51147 tsn: 4 afn: 4

  hash: [700000084fa03d8,7000000bc9292e0] lru: [700000084fa0458,70000006cf86c58]

  lru-flags: on_auxiliary_list

  ckptq: [NULL] fileq: [NULL] objq: [NULL]

  st: FREE md: NULL tch: 0

  flags:

  Buffer contents not dumped

这里我们可以看到,因为0x01000020不在buffer cache中,所以dump出来的内容为空。

 

SQL> select empno,ename,dbms_rowid.rowid_relative_fno(rowid)||'_'||dbms_rowid.rowid_block_number(rowid) location from scott.emp;

 

EMPNO ENAME      LOCATION

----- ---------- --------------------------------------------------------------------------------

 7369 SMITH      4_32

 7498 CUIHUA     4_32

......省略显示部分内容

 7934 MILLER     4_32

 

12 rows selected

 

SQL> oradebug setmypid

Statement processed.

SQL> alter session set events 'immediate trace name set_tsn_p1 level 5';

 

Session altered.

 

SQL> alter session set events  'immediate trace name buffer level 0x01000020';

 

Session altered.

 

SQL> oradebug tracefile_name;

/u01/app/oracle/admin/ipratest/udump/ipratest_ora_3747844.trc

 

$ cat /u01/app/oracle/admin/ipratest/udump/ipratest_ora_3747844.trc

/u01/app/oracle/admin/ipratest/udump/ipratest_ora_3747844.trc

Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production

......省略显示部分内容

*** SESSION ID:(398.232) 2010-02-20 16:36:35.170

Dump of buffer cache at level 10 for tsn=4, rdba=16777248

BH (700000066f9f608) file#: 4 rdba: 0x01000020 (4/32) class: 1 ba: 7000000664de000

  set: 3 blksize: 8192 bsi: 0 set-flg: 2 pwbcnt: 0

  dbwrid: 0 obj: 51147 objn: 51147 tsn: 4 afn: 4

  hash: [700000018f8d2e8,7000000bc9292e0] lru: [700000048f7c698,700000031f94738]

  ckptq: [NULL] fileq: [NULL] objq: [700000048f7c708,7000000b81495f0]

  st: XCURRENT md: NULL tch: 1

  flags: only_sequential_access

  LRBA: [0x0.0.0] HSCN: [0xffff.ffffffff] HSUB: [65535]

  buffer tsn: 4 rdba: 0x01000020 (4/32)

  scn: 0x0008.aa1369dd seq: 0x02 flg: 0x06 tail: 0x69dd0602

  frmt: 0x02 chkval: 0x4021 type: 0x06=trans data

Hex dump of block: st=0, typ_found=1

Dump of memory from 0x07000000664DE000 to 0x07000000664E0000

7000000664DE000 06A20000 01000020 AA1369DD 00080206  [....... ..i.....]

......省略显示部分内容

7000000664DFFE0 49544805 434C4552 4B03C250 030777B4  [ITH.CLERK..P..w.]

7000000664DFFF0 0C110101 0102C209 FF02C115 69DD0602  [............i...]

Block header dump:  0x01000020

 Object id on Block? Y

 seg/obj: 0xc7cb  csc: 0x08.aa1369db  itc: 2  flg: E  typ: 1 - DATA

     brn: 0  bdba: 0x1000019 ver: 0x01 opc: 0

     inc: 0  exflg: 0

 

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0x0003.00a.000016a6  0x01c003e0.03aa.05  --U-    1  fsc 0x0000.aa1369dd

0x02   0x0001.023.00001129  0x020005e7.0307.03  C---    0  scn 0x0008.aa136850

 

data_block_dump,data header at 0x7000000664de064

===============

tsiz: 0x1f98

hsiz: 0x2e

pbl: 0x7000000664de064

bdba: 0x01000020

     76543210

flag=--------

ntab=1

nrow=14

frre=2

fsbo=0x2e

fseo=0x1aa7

avsp=0x1d88

tosp=0x1d88

0xe:pti[0]      nrow=14 offs=0

0x12:pri[0]     offs=0x1b2a

0x14:pri[1]     offs=0x1aa7

0x16:pri[2]     sfll=9

......省略显示部分内容

0x2c:pri[13]    offs=0x1d3a

block_row_dump:

tab 0, row 0, @0x1b2a

tl: 38 fb: --H-FL-- lb: 0x0  cc: 8

col  0: [ 3]  c2 4a 46

col  1: [ 5]  53 4d 49 54 48

col  2: [ 5]  43 4c 45 52 4b

col  3: [ 3]  c2 50 03

col  4: [ 7]  77 b4 0c 11 01 01 01

col  5: [ 2]  c2 0b

col  6: *NULL*

col  7: [ 2]  c1 15

......省略显示部分内容

end_of_block_dump

BH (700000018f8d2e8) file#: 4 rdba: 0x01000020 (4/32) class: 1 ba: 7000000182ba000

  set: 3 blksize: 8192 bsi: 0 set-flg: 2 pwbcnt: 0

  dbwrid: 0 obj: 51147 objn: 51147 tsn: 4 afn: 4

  hash: [700000084fa03d8,700000066f9f608] lru: [700000084fa0458,70000006cf86c58]

  lru-flags: on_auxiliary_list

  ckptq: [NULL] fileq: [NULL] objq: [NULL]

  st: FREE md: NULL tch: 0

  flags:

  Buffer contents not dumped

可以从上述测试中看到,0x01000020buffer cache中的时候,我们用上述两条语句成功dump出了buffer cache0x01000020的内容。

oracle如何入门

| 3 Comments

关于如何学习oracle的问题,大师们已经写过很多文章了,比如eygle的"如何学习Oracle-eygle的方法经验谈",熊哥的"浅谈ORACLE的学习"等,朋友们可以去仔细看一下上述文章,在我看来,大概已经无人能出其右了

 

但我这里还是想以我自己这几年的实际经历来说一说我是如何入门的,这就算是送给各位想入门的朋友们的春节礼物吧。

 

我从2004年开始接触oracle,真正开始努力是从20068月份开始的,从这个时间点开始,我真可是说是未曾有一天懈怠,当真算得上是深陷其中,不能自拔

 

现在我回想起来,我的oracle的入门过程大致是分为四个阶段,在说这四个阶段之前,我想提的一点就是我在HIT的两年里曾经用过半年的时间来准备考GREGRE对我最大的帮助就是极大的扩展了我的词汇量和阅读能力,这使得从一开始oracle的任何文档对我来说就不存在一丁点阅读上的障碍。

 

这四个阶段大致为:

第一阶段:

2004年到20068月,我用了大概两年多的时间断断续续的看完了OCP 9i的一套培训教材(一共4本书)。很惭愧,用了两年多的时间才看完。但是大家要理解我,我本科和研究生都是学数学的,2004年以前连最基本的sql都不会写,而且那段时间项目的开发还是有一定的工作量,我基本上只能利用业余时间。

 

第二阶段:

20068月到2008年年初,因为那时候我的oracle已经有了一点基础,所以我开始大量的看oracle的各种官方文档,但是这些文档我大都只是过了一遍,唯一的例外就是《10gR2 Concepts》和《Oracle 10gR2 Clusterware and RAC Administration and Deployment Guide》,这两本书我都分别看过两遍。

 

第三阶段:

2008年年初到现在,我开始在metalink上大量阅读文章,在我真正开始接触metalink的时候我才发现,哇赛,这是多么精彩的一个世界!在我看来,metalink就是最好的老师了!我曾经不止一次的对熊哥说:"熊哥,我发现我现在已经高度依赖metalink了,一天不上就会觉得非常难受"。呵呵,这真的是我的切身体会,直到现在,我工作的第一件事情依然是把metalink打开,平常没事就泡在上面,迄今为止,我已经在metalink上看过超过1500篇文章了。

 

第四阶段:

20093月到现在,我开始仔细阅读DSIDSI其实我看的并不多,迄今为止,我只看过了如下几本:

DSI303_Advanced Backup,Restore and Recovery Techniques

DSI401-Dumps Crashes and Corruptions

DSI402_Space and Transaction Management

DSI402e-Data types and block structures

DSI403e-Recovery Architecture Components

DSI404e_query_optimizer

DSI405_Performance Tuning

总的感觉是DSI没什么,真的没有我想像的那么难。

 

当我看完DSI405后,我真的觉得我的oracle已经入门了,呵呵,希望这不要是错觉。

 

熊哥在上述介绍oracle的学习方法里这样提到"武侠世界中的高手,都是从无数次战斗中取得经验,再武功大进。学习ORACLE也一样,如果没有充分的实验,实际生产环境的实战,仍然只能说是只能入了ORACLE的门,算不上登入大堂。"

 

很经典!我时刻铭记在心 

关于外键列上的索引

| 1 Comment

yangtingkun在"外键列上是否需要索引"这篇文章里介绍了在外键列上建索引的必要性,这篇文章里有提到:

这时会话被锁住,因为缺少了外键索引后,主表删除或更新记录会导致子表整个表被锁,而这会导致严重的系统并发问题。

 

这里怎样理解"主表删除或更新记录会导致子表整个表被锁"?

在这篇文章里,我们深入剖析了上述问题,并且得出了如下结论:

1、  在子表外键列上没有索引的情况下,主表删除或更新记录是否锁子表(lock the entire table in shared mode)跟子表上是否有mode3TM enqueue有关;锁子表的本质原因是因为oracle这里想对子表上的TM enqueueconvert

2、  在子表外键列上有索引的情况下,主表删除或更新记录不会锁子表(lock the entire table in shared mode),不锁子表的本质原因是因为这时oracle就不对子表上的TM enqueueconvert了;

3、  alter table XXX disable table lock不能对子表做,否则主表就不能删除或者更新记录了。

4、  alter table XXX disable table lock并不能够解决在子表外键列上无索引情况下的并发问题。这个跟DSI405里描述的并不一致(405里说用了alter table XXX disable table lock后就可以不用在外键列上建索引了)

 

详细内容请参见附带的word文档:

关于外键列上的索引.doc

 

ASSM和MSSM下block结构的一点差异

| No Comments

我曾经在"利用BBED修改block内数据的一个例子"这篇文章里提到了一个计算block内部offsetbase的计算方法,即:

BASE的计算方法为:

对于ASSM76+itc-1)*24

对于MSSM68+itc-1)*24

 

有朋友在MSN上问我说:为什么这里ASSM要比MSSM多了8byte

正好也有朋友在MSN上问我为啥不写一些关于block存储格式的文章,我这里就一并回答了吧。

 

首先,我觉得没有必要写block存储格式了,因为BBEDmapprint就可以精准的了解一个block的结构了,除了ASSMsegment headerL1L2L3用不了mapprint之外,其他的基本上都可以。所以,除了写那些用BBED看不了的block的结构之外,写其他的意义并不大。

 

接着我们来回答一下第一个朋友的问题,即为什么这里ASSM要比MSSM多了8byte

 

要回答上述问题,我们先来看一下一个data block必然会有的三个component的大小:

SQL> select * from v$type_size where component in ('KCB','KTB');

 

COMPONENT TYPE     DESCRIPTION                       TYPE_SIZE

--------- -------- -------------------------------- ----------

KCB       KCBH     BLOCK COMMON HEADER                      20

KTB       KTBIT    TRANSACTION VARIABLE HEADER              24

KTB       KTBBH    TRANSACTION FIXED HEADER                 48

 

从结果里我们可以看到,一个data blockcache layer的大小是20byte,其transaction layer的固定部分的大小是48byte(因为必然会有一个ITL),所以这里对于MSSM而言,其base的计算方法就是:20+48+itc-1)*24,即上文中提到的68+itc-1)*24

 

那么对于ASSM而言,为什么会多了8byte呢?我们继续往下看:

我们随便看一个MSSMblock

BBED> map /v

 File: /dras21/astca/system02.dbf (125)

 Block: 1426                                  Dba:0x1f400592

------------------------------------------------------------

 KTB Data Block (Table/Cluster)

 struct kcbh, 20 bytes                      @0      

    ub1 type_kcbh                           @0      

    ub1 frmt_kcbh                           @1      

    ub1 spare1_kcbh                         @2      

    ub1 spare2_kcbh                         @3      

    ub4 rdba_kcbh                           @4      

    ub4 bas_kcbh                            @8      

    ub2 wrp_kcbh                            @12     

    ub1 seq_kcbh                            @14     

    ub1 flg_kcbh                            @15     

    ub2 chkval_kcbh                         @16     

    ub2 spare3_kcbh                         @18     

 struct ktbbh, 96 bytes                     @20     

    ub1 ktbbhtyp                            @20     

    union ktbbhsid, 4 bytes                 @24     

    struct ktbbhcsc, 8 bytes                @28      

    b2 ktbbhict                             @36     

    ub1 ktbbhflg                            @38     

    ub1 ktbbhfsl                            @39     

    ub4 ktbbhfnx                            @40     

    struct ktbbhitl[3], 72 bytes            @44     

 struct kdbh, 14 bytes                      @116    

    ub1 kdbhflag                            @116    

    b1 kdbhntab                             @117    

    b2 kdbhnrow                             @118    

    sb2 kdbhfrre                            @120    

    sb2 kdbhfsbo                            @122    

    sb2 kdbhfseo                            @124    

    b2 kdbhavsp                             @126    

    b2 kdbhtosp                             @128    

 struct kdbt[1], 4 bytes                    @130    

    b2 kdbtoffs                             @130    

    b2 kdbtnrow                             @132    

 sb2 kdbr[32]                               @134    

 ub1 freespace[4966]                        @198    

 ub1 rowdata[3024]                          @5164   

 ub4 tailchk                                @8188

注意看这里kdbhoffset116

 

我们再来看一个ASSMblock

BBED> map /v

 File: /dras21/astca/armshistemptbs_03.dbf (121)

 Block: 274445                                Dba:0x1e44300d

------------------------------------------------------------

 KTB Data Block (Table/Cluster)

 struct kcbh, 20 bytes                      @0      

    ub1 type_kcbh                           @0      

    ub1 frmt_kcbh                           @1      

    ub1 spare1_kcbh                         @2      

    ub1 spare2_kcbh                         @3      

    ub4 rdba_kcbh                           @4      

    ub4 bas_kcbh                            @8      

    ub2 wrp_kcbh                            @12     

    ub1 seq_kcbh                            @14     

    ub1 flg_kcbh                            @15     

    ub2 chkval_kcbh                         @16     

    ub2 spare3_kcbh                         @18     

 struct ktbbh, 96 bytes                     @20     

    ub1 ktbbhtyp                            @20     

    union ktbbhsid, 4 bytes                 @24     

    struct ktbbhcsc, 8 bytes                @28     

    b2 ktbbhict                             @36     

    ub1 ktbbhflg                            @38     

    ub1 ktbbhfsl                            @39     

    ub4 ktbbhfnx                            @40     

    struct ktbbhitl[3], 72 bytes            @44     

 struct kdbh, 14 bytes                      @124    

    ub1 kdbhflag                            @124    

    b1 kdbhntab                             @125    

    b2 kdbhnrow                             @126    

    sb2 kdbhfrre                            @128    

    sb2 kdbhfsbo                            @130    

    sb2 kdbhfseo                            @132    

    b2 kdbhavsp                             @134    

    b2 kdbhtosp                             @136    

 struct kdbt[1], 4 bytes                    @138    

    b2 kdbtoffs                             @138    

    b2 kdbtnrow                             @140    

 sb2 kdbr[32]                               @142    

 ub1 freespace[4958]                        @206    

 ub1 rowdata[3024]                          @5164  

 ub4 tailchk                                @8188

注意看这里kdbhoffset124,比MSSM多了8byte

 

所以上述问题的答案就是:在ASSM下,oracle改变了block内部table directoryrow directory的位置,oracle把它们顺延了8byte,所以对于ASSM而言,其base的计算方法就是:20+48+8+itc-1)*24,即上文中提到的76+itc-1)*24

backupset和backuppiece的区别

| No Comments

朋友itpub上问backupsetbackuppiece的区别,我很能理解这位朋友为什么会有这样的疑问,因为我在六年前看9i OCP的培训教材的时候也不明白这两者之间的区别是什么。

 

我们只需要做如下这样一些测试并配合list backup就可以知道backupsetbackuppiece的区别了:

1、多个channel并且指定filesperset

configure device type disk parallelism 3;

run{

backup incremental level=0

format 'D:\oracle\oradata\testdb\backup\testdb_%t_%s_%p.bak' database

filesperset 3;

}

 

2、单个channel且不指定filesperset

configure device type disk parallelism 1;

run{

backup incremental level=0

format 'D:\oracle\oradata\testdb\backup\testdb_%t_%s_%p.bak' database;

}

 

3、单个channel且指定maxsetsize

configure device type disk parallelism 1;

configure maxsetsize to 450M;

run{

backup incremental level=0

format 'D:\oracle\oradata\testdb\backup\testdb_%t_%s_%p.bak' database;

}

 

4、单个channel且指定maxpiecesize

configure device type disk parallelism 1;

configure maxsetsize to unlimited;

run{

allocate channel c1 device type disk maxpiecesize 300M;

backup incremental level=0

format 'D:\oracle\oradata\testdb\backup\testdb_%t_%s_%p.bak' database;

release channel c1;

}

 

5、多个channel且指定filesperset,但请注意filesperset的位置:

configure device type disk parallelism 3;

run{

backup incremental level=0

format 'D:\oracle\oradata\testdb\backup\testdb_%t_%s_%p.bak' database

plus archivelog

format 'D:\oracle\oradata\testdb\backup\testdb_arc_%t_%s_%p.bak'

delete all input

filesperset 2;

}

 

6:多个channel且指定filesperset,但请注意filesperset的位置:

configure device type disk parallelism 3;

run{

backup incremental level=0

format 'D:\oracle\oradata\testdb\backup\testdb_%t_%s_%p.bak' database filesperset 2

plus archivelog

format 'D:\oracle\oradata\testdb\backup\testdb_arc_%t_%s_%p.bak'

delete all input;

}

 

从结果里我们可以得到如下结论:

1、  backupsetbackuppiece组成,每一个backuppiece就是一个单个的物理文件;

2、  如果你在分配channel的时候不指定maxpiecesize,则每个backupset只会包含一个backuppiece;反之一个backupset里会有多个backuppiece(即物理文件);

3、  一次备份中backupset的数量跟分配channel的个数、是否指定filespersetfilesperset的位置、是否指定maxsetsize有关。

 

filesperset的位置很关键,比如我这里有10datafile需要备份,那么上述测试5对这10datafile(不含archivelog)会产生多少个backupset?测试6呢?

 

答案是测试5产生了3backupset,测试6产生了6backupset这里请正确理解filesperset 的含义)。

 

如何确定被多次truncate后的data object id

| 1 Comment

今天上午我一个同事误truncate了一个表uplbth,她问我是否可以恢复?

我们先去看一下这个表现在的状况:

SQL> select owner,object_name,object_id,data_object_id from dba_objects where object_name='UPLBTH';

 

OWNER                        OBJECT_NAME      OBJECT_ID DATA_OBJECT_ID

------------------------------ --------------- ---------- --------------

CAIPRA                         UPLBTH               52210          95137

从结果里我们可以看到,这个表的data object id已经比其object id大了太多,极有可能是曾经被多次truncate

后来我问了一下她是否多次truncate过这个表,她说是。然后我对她说,你等我信儿吧。

 

熊哥曾经在"使用ODU恢复Truncate"这篇文章里提到了如何确定被多次truncate后的data object id,我这里用另外一种方式来精确定位我要恢复的data object id

 

利用的原理就是:oracle里有system回滚段,而oracle对数据字典的操作基本上是DML,既然是DML,那就好办了,我们有很大的概率可以成功执行flashback query

 

回到刚才的例子,我首先从dba_objects里知道了uplbthlast_ddl_time2010-2-3 10:18:57;接着,我们直接执行flashback query来确定在执行truncate操作的那个时间点之前uplbthdata object id

SQL> select  owner,object_name,object_id,data_object_id from dba_objects as of timestamp to_timestamp('2010-02-03 10:18:00','YYYY-MM-DD HH24:MI:SS') where object_name='UPLBTH';

 

OWNER                          OBJECT_NAME      OBJECT_ID DATA_OBJECT_ID

------------------------------ --------------- ---------- --------------

CAIPRA                         UPLBTH               52210          77675

 

可以看到,当时的data object id77675,精确的确定了data object id后,剩下的事情就都交给ODU好了:

ODU> unload table caipra.uplbth object 77675

 

Unloading table: UPLBTH,object ID: 52210

Unloading segment,storage(Obj#=52210 DataObj#=77675 TS#=16 File#=15 Block#=18828 Cluster=0)

1888 rows unloaded

 

可以看到,我们成功恢复出来了1880条数据。

注意,这里你用logmnr在缺省情况下是挖不出来data object id的,朋友们可以自己试一下。

Recent Comments

  • Aiko Potsander: Please continue to keep the good work! Cheers. read more
  • 毕业论文: 学习了。 read more
  • cui hua: 不用改数据,你改row directory里的指针就可以了——这就是我文中提到的update internal。 read more
  • yangjiawei: 领导,不好意思,再请问一下 我现在遇到一个问题,我现在已经将ind$里两个索引的状态改好了,数据库也拉起来了~! 但是在修改obj$里name里为DEPENDENCY$这一行数据的data_object_id时遇到了困难,因为他原先的长度为2个字节,现在由于我move了一下,他的长度变成了4个字节,结果如下: 原先: col 1[2] @906: 0xc1 0x5d ==>92 read more
  • cui hua: 可以从上述sql中推断出等待的顺序(如何推断我已经在文中提到了),是不是太直观,但是综合上述症状来看,只有我文中提到的这种可能。 read more
  • yangjiawei: 我最近也正好再研究这些比较Internal的东西,所以想麻烦您能对这个问题写一个比较详细的解释及解决方案,我对这些也是比较感兴趣的,可以吗? read more
  • publover: 好文,但是不明白是如何确定这个等待队列的?否则就无法看出是谁阻塞了谁,但是从SQL中看不出来等待的顺序是什么 read more
  • cui hua: 这些东西过于internal和复杂了,我不打算对外发布,误导了你反而不好。做好备份就可以了,有了完善的备份这些手段都是没有意义的。 read more
  • yangjiawei: 领导啊~能否将详细的处理过程写一份,发给我啊?我很期待能跟您学习一下~!:) read more
  • cui hua: 这个就是128 128 0 read more

About this Archive

This page is an archive of entries from February 2010 listed from newest to oldest.

January 2010 is the previous archive.

March 2010 is the next archive.

Find recent content on the main index or look in the archives to find all content.