求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
从一种强制停库方法到Oracle NFS文件锁
 

发布于2012-4-6

 

今天在QQ技术群中,一个朋友介绍了一种快速停库重启的方法。笔者感觉有必要研究重演一下,供来日不时之需。

1、问题简介

事情的起源是这样,一个朋友需要修改processes参数,重新启动数据库。但是因为各种原因,不能登陆入sqlplus。他希望能有解决问题的方法。于是,QQ群中另一个朋友提出一种快速重新停止库的方法。

简单的说,在Linux/Unix环境下,将$ORACLE_HOME/dbs目录下的lk<sid>文件更名删除。之后就可以重新启动。

2、原理分析

这个lk文件是什么呢?在笔者虚拟机环境下,也找到了相应的文件。

[oracle@oracle11gdbs]$ cd $ORACLE_HOME/dbs

[oracle@oracle11gdbs]$ pwd

/u01/oracle/dbs

[oracle@oracle11gdbs]$ ls

hc_DBUA0.dat init.ora lkWILSON peshm_DBUA0_0 snapcf_wilson.f

hc_wilson.dat initwilson.ora orapwwilson peshm_wilson_0 spfilewilson.ora

强制打开文件,可以看到如下提示。

oracle@oracle11gdbs]$ cat lkWILSON

DO NOT DELETE THIS FILE![oracle@oracle11gdbs]$

在MOS中,我们找到了一些关于lk文件的信息。

大部分和lk文件相关的信息都是和启动数据库时候独占文件有关的。出现最多的问题就是在启动过程中遭遇到ORA-01102错误。

[oracle@oracle11g~]$ oerr ora 01102

01102, 00000, "cannot mount database in EXCLUSIVE mode"

// *Cause: Some other instance has the database mounted exclusive or shared.

// *Action: Shutdown other instance or mount in a compatible mode.

数据库在启动的时候,默认是要以EXCLUSIVE独占的方式进行。我们在一台数据库服务器上,一般也就安装一个实例。如果在启动过程报错ORA-01102,通常的问题可能不是启动模式,而是上次关闭系统时,一些资源对象没有正确释放掉。例如:

  • 早期的Oracle 7/8中,在$ORACLE_HOME/dbs目录下的sgadef<sid>.dbf文件不能释放删除;
  • Oracle后台活动进程,如pmon, smon, lgwr和dbwr没有释放掉;
  • 虽然数据库关闭,但是操作系统层面的共享内存和信号量没有释放;
  • 在Oracle 8之后版本中,$ORACLE_HOME/dbs目录下的lk<sid>文件没有释放;

其中,谈到了sgadef和lk文件。这两个文件在Oracle中的作用是用于锁定shared memory。如果该文件存在,那么即使没有内存被分配,Oracle依然认为此时有内存空间被锁定。

解决01102错误的方法其实也比较简单,就是在OS层面删除掉sgadef和lk文件。这样Oracle就不会认为说此时有内存被分配出。

3、Oracle NFS Lock

对NFS设备,Oracle每个版本都存在一个兼容性列表。只有通过兼容性列表测试(Oracle Storage Compatibility Test)的设备,Oracle才承诺进行NFS支持。

在Oracle启动的过程中,NFS相关问题主要在Lock锁定方面:

  • OS层面锁定

当数据库启动的时候,Oracle会对文件设置OS级别的锁定。在数据库停止的时候,Oracle会释放OS级别的锁定。这个锁操作,不同的数据库版本具有不同的方式。在Oracle7、8时代,这个文件名称为$ORACLE_HOME/dbs/sgadef<sid>。而之后的版本中,这个文件名称为$ORACLE_HOME/dbs/lk<sid>。

  • NFS锁定守护daemon进程

为了在OS层面上实现对文件的锁定,Oracle必须调用NFS锁定守护进程。在大部分的Unix系统中,这两个守护进程的名称为:rpc.lockd和rpc.statd。

在实际启动过程中,如果遇到mount数据文件的问题,很可能就是daemon进程终止造成的。所以可以尝试启动该进程。

4、强制关库实验

下面我们实验一下那个朋友的方法,以及如何处理。

--当前wilson实例存活

[oracle@oracle11g~]$ ps -ef | grep pmon

oracle 5644 1 0 14:44 ? 00:00:00 ora_pmon_wilson

oracle 5779 5744 0 14:46 pts/0 00:00:00 grep pmon

进入lk文件所在目录。

[oracle@oracle11g~]$ cd $ORACLE_HOME/dbs

[oracle@oracle11gdbs]$ pwd

/u01/oracle/dbs

[oracle@oracle11gdbs]$ ls

hc_DBUA0.dat init.ora lkWILSON peshm_DBUA0_0 snapcf_wilson.f

hc_wilson.dat initwilson.ora orapwwilson peshm_wilson_0 spfilewilson.ora

更名该文件。

[oracle@oracle11gdbs]$mv lkWILSON lkWILSON_bak

[oracle@oracle11gdbs]$ ls

hc_DBUA0.dat init.ora lkWILSON_bak peshm_DBUA0_0 snapcf_wilson.f

hc_wilson.dat initwilson.ora orapwwilson peshm_wilson_0 spfilewilson.ora

注意,此时我们依然可以登录,pmon核心进程依然存在。

[oracle@oracle11gdbs]$ ps -ef | grep pmon

oracle 5644 1 0 14:44 ? 00:00:00 ora_pmon_wilson

oracle 5799 5744 0 14:48 pts/0 00:00:00 grep pmon

SQL> conn / as sysdba

Connected.

SQL> startup force

ORACLE instance started.

Total System Global Area 414298112 bytes

Fixed Size 1336904 bytes

Variable Size 327158200 bytes

Database Buffers 79691776 bytes

Redo Buffers 6111232 bytes

Database mounted.

Database opened.

SQL>

此时,数据库实例没有如同想象的那样被立即停止。而是依然存在,可以登录入系统。重新启动系统之后,依然可以看到lk<sid>文件重新创建成功。

[oracle@oracle11gdbs]$ ls

hc_DBUA0.dat initwilson.ora orapwwilson snapcf_wilson.f

hc_wilson.dat lkWILSON peshm_DBUA0_0 spfilewilson.ora

init.ora lkWILSON_bak peshm_wilson_0

证明:直接删除该文件似乎是不能起到立即终止实例运行的作用。

5、结论

过去在一些文章中介绍过一种快速关闭实例的方法。就是在os层面使用kill方法将oracle实例全部删除,在强制释放共享内存和信号量。


相关文章 相关文档 相关视频



我们该如何设计数据库
数据库设计经验谈
数据库设计过程
数据库编程总结
数据库性能调优技巧
数据库性能调整
数据库性能优化讲座
数据库系统性能调优系列
高性能数据库设计与优化
高级数据库架构师
数据仓库和数据挖掘技术
Hadoop原理、部署与性能调优

 
分享到
 
 
     


MySQL索引背后的数据结构
MySQL性能调优与架构设计
SQL Server数据库备份与恢复
让数据库飞起来 10大DB2优化
oracle的临时表空间写满磁盘
数据库的跨平台设计
更多...   


并发、大容量、高性能数据库
高级数据库架构设计师
Hadoop原理与实践
Oracle 数据仓库
数据仓库和数据挖掘
Oracle数据库开发与管理


GE 区块链技术与实现培训
航天科工某子公司 Nodejs高级应用开发
中盛益华 卓越管理者必须具备的五项能力
某信息技术公司 Python培训
某博彩IT系统厂商 易用性测试与评估
中国邮储银行 测试成熟度模型集成(TMMI)
中物院 产品经理与产品管理
更多...