Randy's profileWelcome to Randy's Live ...PhotosBlogListsMore ![]() | Help |
|
|
March 09 Oracle锁
在现代的多用户多任务系统中,必然会出现多个用户同时访问共享的某个对象,这个对象可能是表,行,或者内存结构,为了解决多个用户并发性访问带来的数据的安全性,完整性及一致性问题,必须要有一种机制,来使对这些共享资源的并发性访问串行化,oracle中的锁就可以提供这样的功能,当事务在对某个对象进行操作前,先向系统发出请求,对其加相应的锁,加锁后该事务就对该数据对象有了一定的控制权限,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作(可以做select动作,但select 利用的是undo中的前镜像数据了). 按锁保护的内容分类 dml锁 在 Oracle数据库中,当一个事务首次发起一个DML语句时就获得一个TX锁,该锁保持到事务被提交或回滚。在数据行上只有X锁(排他锁),就是说TX锁只能是排他锁,在记录行上设置共享锁没有意义。当两个或多个会话在表的同一条记录上执行DML语句时,第一个会话在该条记录上加锁,其他的会话处于等待状态。当第一个会话提交后,TX锁被释放,其他会话才可以加锁。 在数据表上,oracle默认是共享锁,在执行dml语句的时候,oracle会先申请对象上的共享锁,防止其他会话在这个对象上做ddl语句,成功申请表上的共享锁后,再在受影响的记录上加排它所,防止其他会话对这些做修改动作。 这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了SS、SX、S、X等多种模式,在数据库中用0-6来表示。不同的SQL操作产生不同类型的TM锁。如表1所示。 和锁相关的性能视图介绍 LMODE取值0,1,2,3,4,5,6, 数字越大锁级别越高, 影响的操作越多。 ID1,ID2的取值含义根据type的取值而有所不同 Dba_locks 和v$lock 内容差不多,略 V$session 如果某个session被因为某些行被其他会话锁定而阻塞,则该视图中的下面四个字段列出了这些行所属对象的相关信息 手工释放锁 怎样快速查出Oracle 数据库中的锁等待
---- 这些锁定中有"只读锁"、"排它锁","共享排它锁"等多种类型,而且每种类型又有"行级锁"(一次锁住一条记录),"页级锁"(一次锁住一页,即数据库中存储记录的最小可分配单元),"表级锁"(锁住整个表)。 ---- 若为"行级排它锁",则除被锁住的该行外,该表中其它行均可被其它的用户进行修改(Update)或删除(delete)操作,若为"表级排它锁",则所有其它用户只能对该表进行查询(select)操作,而无法对其中的任何记录进行修改或删除。当程序对所做的修改进行提交(commit)或回滚后(rollback)后,锁住的资源便会得到释放,从而允许其它用户进行操作。 ---- 但是,有时,由于程序中的原因,锁住资源后长时间未对其工作进行提交;或是由于用户的原因,如调出需要修改的数据后,未及时修改并提交,而是放置于一旁;或是由于客户服务器方式中客户端出现"死机",而服务器端却并未检测到,从而造成锁定的资源未被及时释放,影响到其它用户的操作。 ---- 因而,如何迅速地诊断出锁住资源的用户以及解决其锁定便是数据库管理员的一个挑战。 ---- 由于数据库应用系统越来越复杂, 一旦出现由于锁资源未及时释放的情况,便会引起对一相同表进行操作的大量用户无法进行操作,从而影响到系统的使用。此时,DBA应尽量快地解决问题。但是,由于在Oracle 8.0.x 中执行"获取正在等待锁资源的用户名"的查询语句 select a.username, a.sid, a.serial#, b.id1 ---- 十分缓慢,(在 Oracle 7.3.4中执行很快),而且,执行"查找阻塞其它用户的用户进程"的查询语句 ---- 执行得也十分缓慢。因而,往往只好通过将 v$session 中状态为"inactive"(不活动)并且最后一次进行操作时间至当前已超过 20 分钟以上(last_call_et>20*60 秒)的用户进程清除,然后才使得问题得到解决。 ---- 因而,我想出了一个解决办法。即通过将问题发生时的 v$lock,v$session视图中的相关记录保存于自己建立的表中,再对该表进行查询,则速度大大提高,可以迅速发现问题。经实际使用,效果非常好。在接到用户反映后,几秒钟即可查出由于锁住资源而影响其它用户的进程,并进行相应的处理。 ---- 首先,以 dba 身份(不一定为system)登录入数据库中,创建三个基本表:my_session,my_lock, my_sqltext,并在将会进行查询的列上建立相应的索引。语句如下: rem 从 v$session 视图中取出关心的字段,创建 my_session 表,并在查询要用到的字段上创建索引,以加快查询速度 drop table my_session; create unique index my_session_u1 on my_session(sid); ---- rem 从 v$lock 视图中取出字段,创建 my_lock 表,并在查询要用到的字段上创建索引,以加快查询速度 create index my_lock_n1 on my_lock(sid); ---- rem 从 v$sqltext 视图中取出字段,创建 my_sqltext 表,并在查询要用到的字段上创建索引,以加快查询速度 create index my_sqltext_n1 on my_sqltext ( hash_value); ---- 然后,创建一个 SQL 脚本文件,以便需要时可从 SQL*Plus 中直接调用。其中,首先用 truncate table 表名命令将表中的记录删除。之所以用 truncate 命令,而不是用delete 命令,是因为delete 命令执行时,将会产生重演记录,速度较慢,而且索引所占的空间并未真正释放,若反复做 insert及delete,则索引所占的空间会不断增长,查询速度也会变慢。而 truncate命令不产生重演记录,速度执行较delete快,而且索引空间被相应地释放出来。删除记录后,再将三个视图中的相关记录插入自己创建的三个表中。最后,对其进行查询,由于有索引,同时由于在插入时条件过滤后,记录数相对来说较少,因而查询速度很快,马上可以看到其结果。 alter system kill session 'sid, serial#'; prompt '获取数据.....' insert into my_lock insert into my_sqltext column username format a10 prompt "正在等待别人的用户" prompt "被等待的用户" prompt "查出其 sql " ---- 以上思路也可用于其它大型数据库系统如 Informix, Sybase,DB2中。通过使用该脚本,可以极大地提高获取系统中当前锁等待的情况,从而及时解决数据库应用系统中的锁等待问题。而且,由于实际上已取出其 program 名及相应的 sql 语句,故可以在事后将其记录下来,交给其开发人员进行分析并从根本上得到解决。 August 24 8.17 Oracle BackupWarning: Log archiving (ARCHIVELOG mode) is currently disabled. If
you restore the database from this backup, any transactions that take place between this backup and the next backup will be lost. It is recommended that you enable ARCHIVELOG mode before proceeding so that all transactions can be recovered upon restore. See the section 'Enabling ARCHIVELOG Mode...' in the online help for instructions. Backup with log archiving disabled will shut down and restart the database. Are you sure [Y/N]? y Backup in progress... 恢复管理器: Release 10.2.0.1.0 - Production on 星期日 8月 17 23:09:54 2008
Copyright (c) 1982, 2005, Oracle. All rights reserved.
连接到目标数据库: XE (DBID=2543674749)
RMAN> set echo on;
2> shutdown immediate; 3> startup mount; 4> configure controlfile autobackup format for device type disk clear; 5> configure retention policy to redundancy 2; 6> configure controlfile autobackup on; 7> sql "create pfile=''C:\ORACLEXE\APP\ORACLE\PRODUCT\10.2.0\SERVER\DATABASE\SPF ILE2INIT.ORA'' from spfile"; 8> backup as backupset device type disk database; 9> configure controlfile autobackup off; 10> alter database open; 11> delete noprompt obsolete; 12> 回显已打开 使用目标数据库控制文件替代恢复目录
数据库已关闭 数据库已卸载 Oracle 实例已关闭 已连接到目标数据库 (未启动)
Oracle 实例已启动 数据库已装载 系统全局区域总计 285212672 字节
Fixed Size 1287016 字节
Variable Size 113249432 字节 Database Buffers 167772160 字节 Redo Buffers 2904064 字节 RMAN 配置参数已成功重置为默认值
新的 RMAN 配置参数:
CONFIGURE RETENTION POLICY TO REDUNDANCY 2; 已成功存储新的 RMAN 配置参数 新的 RMAN 配置参数:
CONFIGURE CONTROLFILE AUTOBACKUP ON; 已成功存储新的 RMAN 配置参数 sql 语句: create pfile=''C:\ORACLEXE\APP\ORACLE\PRODUCT\10.2.0\SERVER\DATABASE\S
PFILE2INIT.ORA'' from spfile 启动 backup 于 17-8月 -08 分配的通道: ORA_DISK_1 通道 ORA_DISK_1: sid=35 devtype=DISK 通道 ORA_DISK_1: 启动全部数据文件备份集 通道 ORA_DISK_1: 正在指定备份集中的数据文件 输入数据文件 fno=00003 name=C:\ORACLEXE\ORADATA\XE\SYSAUX.DBF 输入数据文件 fno=00001 name=C:\ORACLEXE\ORADATA\XE\SYSTEM.DBF 输入数据文件 fno=00004 name=C:\ORACLEXE\ORADATA\XE\USERS.DBF 输入数据文件 fno=00002 name=C:\ORACLEXE\ORADATA\XE\UNDO.DBF 通道 ORA_DISK_1: 正在启动段 1 于 17-8月 -08 |
|
|