oracle每秒并发支持并发写多少条

oracle内存和并发数之间有什么关系_百度知道
oracle内存和并发数之间有什么关系
提问者采纳
在win7下, 再导入, 那么就只能从内存上解决了换64位版本的oracle 10g是一劳永逸的做法, 没有你想像的那么麻烦;set IncreaseUserVa 3072 命令, 如果不愿意这么做的话. 1, 可以通过 bcdedit &#47. 修改操作系统能识别的内存, 通过RMAN备份
其他类似问题
为您推荐:
并发数的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁oracle数据库并发处理
数据库并发处理&一&
数据库并发处理
一、并发处理
数据库的特点就是数据的集中管理和共享。在通常情况下总是有若干个事务并发地运行,这些并行的事务可能并发地存取相同的数据。因此,数据库管理系统的一个重要任务就是要有一种机制去保证这种并发的存取和修改不破坏数据的完整性,确保这些事务能正确地运行并取得正确的结果。
我们知道,事务并发执行时若不加控制的话,将导致不正确的结果和数据库的不一致状态。为保证数据库数据正确地反映所有事务的更新,以及在一事务修改数据时其它事务不同时修改这个数据,数据库系统用锁来控制对数据的并发存取。
二、ORACLE的并发处理机制
无需任何说明,ORACLE自动提供行级锁,它允许用户在没有冲突的情况下更新表中不同的行。行级锁对联机事务处理非常有用。
1、ORACLE锁
ORACLE锁的类型在正常情况下,ORACLE会自动锁住需要加锁的资源以保护数据,
这种锁是隐含的,叫隐含锁。然而,在一些条件下,这些自动的锁在实际应用时并不能满足需要,必须人工加一些锁。这些人工加的锁叫显示锁。
下面指明了会产生隐含锁的SQL语句:
DDL/DCL语句。
下面指明了会产生显示锁的SQL语句:
SELECT FOR UPDATE;
LOCK TABLE INXXX MODE。
解决读的不可重复性可以用下面的方法。在ORACLE中,用SELECT FOR
UPDATE对预期要修改的记录加行排它锁(X),对表加行共享锁(RS)。它常用于要锁住一行,但不去真的修改这一行。锁之间是有相互作用的。
例如,更新时会对表加RX锁,对行加X锁,而只有RS锁和RX锁允许再加RX锁。因此,当存在RS和RX锁时,表允许更新。再比如,当执行DDL和DCL语句时,会对表加排它锁X,而在存在X、RS、SRX、RX和S锁的前提下,都不能再加X锁。因此,当存在X,RS,SRX,RS或S锁时,不能对表做DCL和DDL操作。这样,数据库会自动防止一个用户更新表中的数据,而其他用户在同时修改表的结构。
2、ORACLE只读事务
ORACLE支持只读事务。只读事务有以下特点:
*在事务中只允许查询
*其它事务可修改和查询数据
*在事务中,其它用户的任何修改都看不见
只读事务的写法为:
SET TRANS ACTION READONLY
COMMIT,ROLLBACK,DDL结束只读事务
3、事务一致性的级别
事务是定义和维护一致性的单位,封锁就是要保证这种一致性。如果对封锁的要求高会增加开销,降低并发性和效率;有的事务并不严格要求结果的质量(如用于统计的事务),如果加上严格的封锁则是不必要和不经济的。因此有必要进行进一步的分析,考察不同级别的一致性对数据库数据的质量及并行能力的影响。
一致性级别定义为如下的几个条件:
事务不修改其它任何事务的脏数据。脏数据是被其它事务修改过,但尚未提交的数据。
在事务结束前不对被修改的资源解锁。
事务不读其它任何事务的脏数据。
在读前对数据加共享锁(RS)和行排它锁,直至事务结束。
*满足条件1的事务叫第0级事务。
*满足条件1和2的事务叫第1级一致性事务。
*满足条件1、2和3的事务为2级一致性事务。
ORACLE的读一致性保证了事务不读其它事务的脏数据。
*满足条件1、2、3和4的事务叫第3级一致性事务。
由ORACLE的三个性质:自动加隐式锁、在事务结束时释放锁和读一致性,使ORACLE成为自动满足以上的0、1和2级一致性事务。因此,ORACLE自动防止了脏读(写-读依赖)。但是,ORACLE不能自动防止丢失修改(写-写依赖),读的不可重复性(读-写依赖),彻底解决并发性中的问题还需满足第4个条件(3级一致性事务),这需要程序员根据实际情况编程。
方法如下:
*如果想在一段时间内使一些数据不被其它事务改变,且在本事务内仅仅查询数据,则可用SETTRANSACTIONREADONLY语句达到这一目的。
*如果想在一事务内修改一数据,且避免丢失修改,则应在读这一数据前用SELECTFORUPDATE对该数据加锁。
*如果想在一事务内读一数据,且想基于这一数据对其它数据修改,则应在读数据前对此数据用SELECTFORUPDATE加锁。对此种类型的应用,用这条SQL语句加锁最恰当。
*如果想避免不可重复读现象,可在读前用SELECTFORUPDATE对数据加锁,或用SET
TRANS ACTION READONLY设置只读事务。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。复制代码 代码如下: DELIMITER $$ set @stmt = 'select userid,username from myuser where userid between ? and ?'; prepare s1 from @ set @s1 = 2; set @s2 =
复制代码 代码如下: DELIMITER $$ set @stmt = 'select userid,username from myuser where userid between ? and ?'; prepare s1 from @ set @s1 = 2; set @s2 = 100; execute s1 using @s1,@s2; deallocate prepare s1; $$ DELIMITER ;
用这种形式写的查询,可以随意替换参数,给出代码的人称之为预处理,我想这个应该就是MySQL中的变量绑定吧……但是,在查资料的过程中我却听到了两种声音,一种是,MySQL中有类似Oracle变量绑定的写法,但没有其实际作用,也就是只能方便编写,不能提高效率,这种说法在几个09年的帖子中看到: http://www.itpub.net/thread--1.html http://cuda.itpub.net/redirect.php?fid=73&tid=1210572&goto=nextnewset 另一种说法是MySQL中的变量绑定是能确实提高效率的,这个是希望有的,那到底有木有,还是自己去试验下吧。 试验是在本机进行的,数据量比较小,具体数字并不具有实际意义,但是,能用来说明一些问题,数据库版本是mysql-5.1.57-win32免安装版。   本着对数据库不是很熟悉的态度^_^,试验过程中走了不少弯路,此文以结论为主,就不列出实验的设计过程,文笔不好,文章写得有点枯燥,写出来是希望有人来拍砖,因为我得出的结论是:预处理在有没有cache的情况下的执行效率都不及直接执行…… 我对自己的实验结果不愿接受。。如果说预处理只为了规范下Query,使cache命中率提高的话个人觉得大材小用了,希望有比较了解的人能指出事实究竟是什么样子的——NewSilen 实验准备   第一个文件NormalQuery.sql 复制代码 代码如下: Set profiling=1; Select * From MyTable where DictID = ; Select DictID from MyTable limit 1,100; Select DictID from MyTable limit 2,100; /*从limit 1,100 到limit 100,100 此处省略重复代码*/ ...... Select DictID from MyTable limit 100,100; SELECT query_id,seq,STATE,10000*DURATION FROM information_schema.profiling INTO OUTFILE 'd:/NormalResults.csv' FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
第二个sql文件 StmtQuery.sql 复制代码 代码如下: Set profiling=1; Select * From MyTable where DictID = ; set @stmt = 'Select DictID from MyTable limit ?,?'; prepare s1 from @ set @s = 100; set @s1 = 101; set @s2 = 102; ...... set @s100 =200; execute s1 using @s1,@s; execute s1 using @s2,@s; ...... execute s1 using @s100,@s; SELECT query_id,seq,STATE,10000*DURATION FROM information_schema.profiling INTO OUTFILE 'd:/StmtResults.csv' FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
做几点小说明: 1. Set profiling=1; 执行此语句之后,可以从information_schema.profiling这张表中读出语句执行的详细信息,其实包含不少内容,包括我需要的时间信息,这是张临时表,每新开一个会话都要重新设置profiling属性才能从这张表中读取数据 2. Select * From MyTable where DictID = ;   这行代码貌似和我们的实验没什么关系,本来我也是这么认为的,之所以加这句,是我在之前的摸索中发现,执行过程中有个步骤是open table,如果是第一次打开某张表,那时间是相当长的,所以在执行后面的语句前,我先执行了这行代码打开试验用的表 3. MySQL默认在information_schema.profiling表中保存的查询历史是15条,可以修改profiling_history_size属性来进行调整,我希望他大一些让我能一次取出足够的数据,不过最大值只有100,尽管我调整为150,最后能够查到的也只有100条,不过也够了 4. SQL代码我没有全列出来,因为查询语句差不多,上面代码中用省略号表示了,最后的结果是两个csv文件,个人习惯,你也可以把结果存到数据库进行分析   实验步骤 重启数据库,执行文件NormalQuery.sql,执行文件StmtQuery.sql,得到两个结果文件 再重启数据库,执行StmtQuery.sql,执行文件NormalQuery.sql,得到另外两个结果文件   实验结果 详细结果在最后提供了附件下载,有兴趣的朋友可以看下   结果分析 每一个SQL文件中执行了一百个查询语句,没有重复的查询语句,不存在查询cache,统计执行SQL的平均时间得出如下结果
从结果中可以看出,无论是先执行还是后执行,NormalQuery中的语句都比使用预处理语句的要快一些=.=!
那再来看看每一句查询具体的情况,Normal和Stmt的query各执行了两百次,每一步的详细信息如下:
从这里面可以看出,第一个,normalquery比stmtquery少一个步骤,第二个,虽然stmt在不少步骤上是优于normal的,但在executing一步上输掉太多,最后结果上也是落败
最后,再给出一个查询缓存的实验结果,具体步骤就不列了
在查询缓存的时候,Normal完胜……
大概情况就是这样,我回忆了一下,网上说预处理可以提高效率的,基本都是用编程的方式去执行查询,不知道这个有没有关系,基础有限,希望园子里的大牛能看到,帮忙解惑实验结果附件锁是并发访问的时候用于保护不共享资源不被同时并发修改的机制。
oracle锁分为DML锁,DDL锁,内部锁和latch
DML锁确保一次只能只有一个人修改某一行(TX锁),而且正在处理一个表时别人不能删除(TM锁)。
DDL锁,在DDL操作是系统会自动为对象加上DDL锁,保护这些对象不被其他会话锁修改。
latch是轻量级的串行化设备,用于协调对共享数据结构、对象、文件的多用户访问,一般都是保护共享内存结构使用的锁,在此不做讨论。
一般的锁管理器工作过程:
1.找到想要锁定的那一行地址
2.在锁管理器排队
3.锁定列表
4.搜索列表,查看别人是否锁定这一行
5.在列表中创建一个新的条目,表明已经锁定这一行
6.对列表解锁
接下里修改,之后提交修改后,继续过程:
7.再次排队
8.锁住锁的列表
9.在这个列表中锁定,并释放所有的锁
10.对列表解锁
oracle锁管理方式:
找到需要锁定的那行地址
到达那一行
锁定这一行
通常lock有三个组件:Resource Structure(资源)、Lock Structure(锁)和Enqueue(排队机制)
Resource和lock是数据结构,而Enqueue是算法。
Resource Structure每一个需要并发控制的资源都有用这个数据结构来描述,先关的成员为:owner、waiter和converter,这是三个指针,分别指向3个由Lock Structure组成的链表。
Lock Structure
每当进程需要访问共享资源时,必须先“锁定”该资源,这个动作实际上是从内存中申请一个Lock Structure,
,在其中记录“锁模式、进程ID”等重要信息。然后看是否立即能够获得资源的访问权,如果不能的话将这个Lock structure挂到Resource Structure的Waiter链表中,如果能够获得,则把Lock Structure的owner链表中。
最常用的锁模式
Share 拥有这对资源进行只读访问,允许其他用户并发只读访问
Exclusive 拥有者对资源进行修改访问,不允许其他用户并发访问
Enqueue 算法
Lock使用的是Enqueue算法,可以理解为“先入先出队列”,如果进程的锁定请求不能满足,该进程的Lock Structure就被加到Waiter链表的末端。当占用进程释放锁时,会检查Waiter和Converter队列,把锁分配给先入对的请求者。converter和waiter两个等待队列,算法的有些区别:如果某个操作先后需要2中不同模式的锁,比如先是share mode然后是exclusive mode,则进程会先请求share mode 后获得lock structure会挂在owner队列上,当需要exclusive
mode锁时,进程先释放share mode的锁,然后再次申请exclusive mode的锁,但是可能无法立即获得,这时请求会挂在converter队列下,converter队列会被优先于waiter队列处理。
oracle行级锁机制
首先明白三个概念:
ITL:每个数据块的头部有一个叫做ITL的数据结构,用于记录那些事务修改了这个数据块的内容。
记录头ITL索引:每条记录的记录头部有一个字段,用于记录ITL表项号,可以看做指向ITL表的指针
TX锁,事务锁
TM锁:保护表或视图定义不被修改的锁
当一个事务开始时,必须申请一个TX锁,这种锁保护资源是回滚段、回滚段数据块,因此这个这个申请意味着:用户进程必须先申请到回滚段资源后才能开始一个事务,才能执行DML语句修改数据。
申请到回滚段资源后,用户事务就可以开始修改数据了,事务信息可在v$transaction中查到,在修改数据表的记录时,需要遵守如下操作顺序:
首先获得这个表的TM锁,这个锁用于保护事务执行过程中其他用户不能修改表结构;
事务修改某个数据块记录时,首先需要在改数据块块头的ITL表中申请一个空闲表项,并在其中记录事务号,实际就是在记录这个事物要使用的回滚段地址;
事务修改该数据块的某条记录时,会设置该记录头部的ITL索引指向上一步申请到的表项,然后再修改记录内容,修改前先在回滚段对记录修改前的状态做一个拷贝,然后才能修改数据记录,这个拷贝用于以后的回滚、恢复和一致性读。当其他用户并发修改这条记录时,会根据记录头的ITL索引读取ITL表项内容,查看这个事务是否已经提交,如果没有提交,则这个用户的TX锁会等待前一个用户的TX锁的释放。
例如如下式转储的一个数据块的ITL信息:
Block header dump:& 0×
Object id on Block? Y
seg/obj: 0x10396& csc: 0×00.d62e7& itc: 2& flg: O& typ: 1 – DATA
fsl: 0& fnx: 0×0 ver: 0×01
Itl&&&&&&&&&& Xid&&&&&&&&&&&&&&&&& Uba&&&&&&&& Flag& Lck&&&&&&& Scn/Fsc
0x01&& 0×00029b& 0x00ca.3c& —-&&& 3& fsc 0×0
0x02&& 0×00.00& —-&&& 0& fsc 0×0
seg/obj:seg/obj id
csc:clean scn
itc:itl slots的个数,此时多少个事务在对本data block进行操作
flg: 0=on the freelist
typ:数据块类型
fsl: itl tx freelist slot
fnx: dba of next block on freelist
Itl:interested transaction list index
Xid:transaction id
Uba:undo address
Flag:事务状态标志
Lck:事物所影响行的数量
oracle 在对数据行锁定时,行指向事务ID的一个副本,事务ID存储在包含数据的块中,释放锁时,事务ID会保存下来,这个事务ID时事务特有的,表示了回滚段号、槽和序列号,事务ID留在包含数据行的块中,可以告诉其他会话:一个会话拥有这个数据行。另一个会话会看到锁ID,由于锁ID表示一个事务,所以可以很快的查看持有这个锁的事务是否活动的。如果锁不活动的,则允许会话访问这个数据,如果锁还是活动的,会话会要求一旦释放锁就得到通知。所以这需要一个排队机制:请求锁的会话会排队,等待目前拥有这个锁的事务执行,然后的到这个数据。可以根据v$lock视图的lmode和request
mode判断谁是owner、waiter和converter
owner:lomode&0,request=0
waiter:lmode=0,request&0
converter:lmode&0,request&0
例如下试验可以清楚看到这些信息:
系统已更改。
SQL& create table t1 ( x int );
表已创建。
SQL& create table t2 ( x int );
表已创建。
SQL& insert into t1 values ( 1 );
已创建 1 行。
SQL& insert into t2 values ( 1 );
已创建 1 行。
SQL& select (select username
2&&&&&&&&&&&&&&&& from v$session
3&&&&&&&&&&&&&&&& where sid = v$lock.sid) username,
4&&&&&&&& sid,
5&&&&&&&& id1,
6&&&&&&&& id2,
7&&&&&&&& lmode,
8&&&&&&&& request, block, v$lock.type
9&&& from v$lock
10&& where sid = (select sid
11&&&&&&&&&&&&&&&&& from v$mystat
12&&&&&&&&&&&&&&&& where rownum=1)
USERNAME& SID&& ID1&& ID2&& LMODE& REQUEST&&& BLOCK&&& TYPE
——– —–& —-&& —-& —–&& ——-&& —–&&& —-
SYS&&&&&& 13&&& 66455&& 0&&&& 3&&&&&&& 0&&&&&&&& 0&&&&& TM
SYS&&&&&& 13&&& 66456&& 0&&&& 3&&&&&&& 0&&&&&&&& 0&&&&& TM
SYS&&&&&& 13&&& 2&& 6&&&&&&& 0&&&&&&&& 0&&&&& TX
SQL& select object_name, object_id
2&&& from user_objects
3&& where object_name in (‘T1′,’T2′)
OBJECT_NAME&&& OBJECT_ID
————& ———
T1&&&&&&&&&&& 66455
T2&&&&&&&&&&& 66456
每个事务只能有一个TX锁,但是TM锁依照修改的对象个数而定,TM对应的ID1列就是DML锁定对象ID.
SQL& select username,
2&&&&&&&& v$lock.sid,
3&&&&&&&& trunc(id1/power(2,16)) rbs,
4&&&&&&&& bitand(id1,to_number(‘ffff’,'xxxx’))+0 slot,
5&&&&&&&& id2 seq,
6&&&&&&&& lmode,
7&&&&&&&& request
8& from v$lock, v$session
9& where v$lock.type = ‘TX’
10&&& and v$lock.sid = v$session.sid
11&&& and v$session.username = USER;
USERNAME& SID&&& RBS&&& SLOT&& SEQ&& LMODE& REQUEST
——– —– ——& —–& —— —— ———
SYS&&&&&& 13&&&& 9&&&&& 16&&&&& 662&&&&&& 6&&&& 0
SQL& select XIDUSN, XIDSLOT, XIDSQN& from v$
XIDUSN&&& XIDSLOT&&&& XIDSQN
—— ———- ———-
9&&&&&&&& 16&&&&&&& 662
oracle事务不同于其他数据库之处,不需要专门语句显示开始事务,事务会在修改数据的第一条语句处开始,但是一定要用commit或rollback事务。
oracle的commit做了如下操作:
为事务生成一个SCN
LGWR将所有余下的缓存重做日志条目写至磁盘,并把SCN记录到在线重做日志文件中
v$lock中记录着会话持有的锁,这些锁将被释放,而排队等待这些锁的每一个队列都会被唤醒
如果事务处理的某些块还在缓存中,则会快速的模式访问并清除
Itl&&&&&&&&&& Xid&&&&&&&&&&&&&&&&& Uba&&&&&&&& Flag& Lck&&&&&&& Scn/Fsc
0x01&& 0×00029b& 0x00ca.3c& C—&&& 0& scn 0×0
0x02&& 0×0c0dbca.006e.2f& –U-&&& 1& fsc 0×4
如上的flag列,第一条ITL信息显示数据块当前事务信息已经被清除,第二个还未清除事务ITL信息标志为U;
oracle并发支持,实现了一种多版本体系,能够同时物化多个版本的数据,能够提供读一致性机制,数据读取器绝不会被写入器所阻塞,也就是写不会阻塞读。一种情况例外,那就是在分布式事务处理(2PC)期间。
另外,记住大多数DDL都带排它锁,有些DDL没有DDL锁,如create index idx on t(x)online关键字会改变建立索引的方法。oracle只会得到表上的TM锁,防止其他DDL发生,但是运行DML运行。oracle发生死锁的原因外键未加索引、位图索引发生更新,外键未加索引更新或删除父表都会对整个子表加锁
create table p ( x int primary key );
create table c ( x references p );
insert into p values ( 1 );
insert into p values ( 2 );
insert into c values ( 2 );
delete from p where x = 1;;
这个时候机会发生阻塞:
SQL& select
2&&&&&&& (select username from v$session where sid=a.sid) blocker,
3&&&&&&&& a.sid,
4&&&&&&& ‘ is blocking ‘,
5&&&&&&&& (select username from v$session where sid=b.sid) blockee,
6&&&&&&&&&&&& b.sid
7&&& from v$lock a, v$lock b
8&& where a.block = 1
9&&&& and b.request & 0
10&&&& and a.id1 = b.id1
11&&&& and a.id2 = b.id2;
BLOCKER&&& SID ‘ISBLOCKING’& BLOCKEE&&&& SID
——-& —–& ———&& ——— ——-
SYS&&&&&& 142& is blocking& SYS&&&&&&&&& 13
不需要对外键加索引的情况:
1、没有从父表删除行
2、没有更新父表的唯一键/主键值
3、没有从父表联结子表
TOM oracle 9i&10g编程艺术
阅读(...) 评论()

我要回帖

更多关于 每秒100并发 的文章

 

随机推荐