表的其他的重要物理参数
1、MSSM(Manual segment space management)上的freelists
2、maxtrans
3、logging
CREATE TABLESPACE NOASSM DATAFILE
'D:\ORA1101G\ORADATA\GX\USERS_NOASSM1.DBF' SIZE 100M AUTOEXTEND OFF
LOGGING
ONLINE
PERMANENT
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
BLOCKSIZE 8K
SEGMENT SPACE MANAGEMENT MANUAL
FLASHBACK ON
create table t_freelist
(
a integer,
b varchar2(10)
) tablespace noassm
四个session
declare
i integer;
begin
i:=dbms_utility.get_time;
-- Test statements here
for j in 1..100000 loop
insert into t_freelist values(j,'xx');
end loop;
commit;
dbms_output.put_line((dbms_utility.get_time-i)/100);
end;
alter table t_freelist storage (freelists 5)
select e.TOTAL_WAITs,e.TIME_WAITED,e.WAIT_CLASS from v$system_event e
where event = 'buffer busy waits'
0 1 49 261 Concurrency
1 10 4426 300 Concurrency
2 1 4428 300 Concurrency
3 5 8892 375 Concurrency
4 1 9072 414 Concurrency
freelist TOTAL_WAITs TIME_WAITED WAIT_CLASS
1
5
10
1
CREATE TABLESPACE USERS DATAFILE
'D:\ORA1101G\ORADATA\GX\USERS01.DBF' SIZE 1868M AUTOEXTEND ON NEXT 1280K MAXSIZE UNLIMITED
LOGGING
ONLINE
PERMANENT
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
BLOCKSIZE 8K
SEGMENT SPACE MANAGEMENT AUTO
select dbms_metadata.get_ddl('TABLE','T_FREELIST') from dual
CREATE TABLE "SCOTT"."T_FREELIST"
( "A" NUMBER(38,0),
"B" VARCHAR2(10)
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS"
declare
-- Local variables here
i integer;
begin
i:=dbms_utility.get_time;
-- Test statements here
for j in 1..100000 loop
insert into t_freelist values(j,'xx');
end loop;
commit;
dbms_output.put_line((dbms_utility.get_time-i)/100);
end;
SQL> alter table t_freelist storage (freelists 5);
alter table t_freelist storage (freelists 5)
*
第 1 行出现错误:
ORA-10620: Operation not allowed on this segment
drop table t_freelist purge
create table t_freelist
(
a integer,
b varchar2(10)
) tablespace users
STORAGE(FREELISTS 10)
9416 427 Concurrency
10195 455 Concurrency
尽管提高freelists设置较高的值,可以提高并发处理的效率,但是可能会导致使用较多的磁盘空间。
多个freelists的工作机制
1、 每一个freelist有较少的free block
2、 当存在多个freelist时候,会多出一个主freelist
3、 每一个freelist只能从主freelist申请新的free block,而不会从其他的freelist申请新的free blocks。
并行加载大量数据的时候,为了提高效率,可能采用并行加载方法。这时候,可以暂时将表的freelist设定一个较高的值,等任务结束后,再将表的freelist设定一个较合理的值。
Inittrans和maxtrans
在块的首部有一个事务表,这个事务表建立一些数据行记录哪些事务将块上的哪些行的数据锁定,这个事务表的初始化行数由Inittrans设定,其默认值为2。随着这个块上的事务数增加,事务表的条目也开始增加,增加到最大的条目数maxtrans(假定这个块有足够的自由空间),每一个事务条目占用23左右字节数。
ORA9IR2> create table t1 ( x int ) maxtrans 2;
ORA9IR2> create table t2 ( x int ) maxtrans 2;
ORA9IR2> insert into t1 values ( 1 );
ORA9IR2> insert into t1 values ( 2 );
ORA9IR2> insert into t1 values ( 3 );
ORA9IR2> insert into t2 values ( 1 );
ORA9IR2> insert into t2 values ( 2 );
ORA9IR2> insert into t2 values ( 3 );
显然,t1,t2的数据在同一个块上。
ORA9IR2> commit;
Session 1
ORA9IR2> update t1 set x=x where x=1;
ORA9IR2> update t2 set x=x where x=1;
session 2
ORA9IR2> update t1 set x=x where x=2;
session 3
ORA9IR2> update t2 set x=x where x=3;
session 2
ORA9IR2> update t2 set x=x where x=2;
that'll block. T2 has a lock by session 1 and session 3 -- maxtrans (max conccurrent transactions) on that block is limited to two, so session 2 must wait
back to session 3
ORA9IR2> update t1 set x=x where x=3;
that'll block as well. then session 2 will recieve
ORA9IR2> update t2 set x=x where x=2;
update t2 set x=x where x=2
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
在10g以后的版本maxtrans是255
logging 与nologging
通常对象(主要是表、索引)采用logging的方式被创建的,这说明在创建对象的时候,能够生成redo的时候,就会生成redo。 而nologging则允许某一些操作,可以不生成redo。
Nologging则只影响几个特定的操作。如对象创建,直接路径加载。
archive log list
数据库日志模式 非存档模式
自动存档 禁用
存档终点 USE_DB_RECOVERY_FILE_DEST
最早的联机日志序列 380
当前日志序列 382
drop table t_logging purge;
drop table t_nologging purge;
select a.sid,a.statistic#,a.value
from v$sesstat a, v$statname b
where a.STATISTIC#=b.STATISTIC# and
b.NAME like 'redo size' and
sid=( select sid from v$mystat where rownum=1)
--1954800
create table t_logging logging
as
select * from all_objects
select a.sid,a.statistic#,a.value
from v$sesstat a, v$statname b
where a.STATISTIC#=b.STATISTIC# and
b.NAME like 'redo size' and
sid=( select sid from v$mystat where rownum=1)
--2072888
select 2072888-1954800 from dual
118088
select a.sid,a.statistic#,a.value
from v$sesstat a, v$statname b
where a.STATISTIC#=b.STATISTIC# and
b.NAME like 'redo size' and
sid=( select sid from v$mystat where rownum=1)
--2072888
create table t_nologging nologging
as
select * from all_objects
select a.sid,a.statistic#,a.value
from v$sesstat a, v$statname b
where a.STATISTIC#=b.STATISTIC# and
b.NAME like 'redo size' and
sid=( select sid from v$mystat where rownum=1)
--2186732
select 2186732-2072888 from dual
113844
select table_name,logging from user_tables where table_name in ('T_LOGGING','T_NOLOGGING')
T_LOGGING YES
T_NOLOGGING NO
select * from v$sesstat
where statistic#=140
and sid = (select sid from v$session where username=USER);
select * from v$statname where lower(name) like '%redo%'
--140
select * from v$session where audsid=userenv('sessionid');
SELECT SYS_CONTEXT ('USERENV', 'SESSION_USER') FROM DUAL;
select * from v$session where sid = ( select sid from v$mystat where rownum=1);
select a.sid,a.statistic#,a.value
from v$sesstat a, v$statname b
where a.STATISTIC#=b.STATISTIC# and
b.NAME like 'redo size' and
sid=( select sid from v$mystat where rownum=1)
create table as select
insert /*+ APPEND */
direct path loads
will already skip logging in a noarchivelog mode database as they do direct writes to the datafiles
other operations such as insert/update/delete/merge will always generate redo regardless of the
mode