前言

时常会接到客户或一线工程师反馈oracle数据库报“ora-01110”等错误,本人过往也处理过好几次类似的故障,发现基本上是由于开发人员或初级维护人员在执行数据库表空间扩容时,不小心将本身需要扩容到ASM磁盘组的数据文件扩容到了本地节点上;抑或是开发人员发现执行步骤错误之后直接物理删除错误文件,且未通知数据库维护人员导致。本文通过真实操作案例分享,讲述在ASM环境下如何防止误将数据文件扩容到本地文件系统的方法,希望各位技术人员未来能杜绝此类误操作发生。

在巡检中发现,数据库数据文件扩容到节点2本地目录中,导致只有单个节点能读取到该数据文件,节点一无法锁定数据文件。

数据文件
节点一alert_ log文件报错内容

案例处理

对误建立在节点2本地的数据文件迁移至ASM磁盘组,具体解决操作见下方。(注意:操作时需停止数据库所有实例,在变更期间数据库无法对外提供任何服务,需要提前申请停机时间操作。)

实施操作步骤

节点2:

Offline相应表空间:

col CHECKPOINT_CHANGE# for 9999999999999999999

select file#,CHECKPOINT_CHANGE#,status from v$datafile where file# in ('23','25','27');

col CHECKPOINT_CHANGE# for 9999999999999999999

select file#,CHECKPOINT_CHANGE#,status from V$DATAFILE_HEADER datafile_head where file# in ('23','25','27');

CHECKPOINT_CHANGE# 号一致

alter tablespace CSG_MD offline;

alter tablespace TBS_META_NW offline;

alter tablespace TS_KPI offline;

rman 备份数据文件

rman target /

backup datafile 23,25,27;

rman 恢复数据文件

rman target /

run{

set newname for datafile '/dev/shm/data/CMX_DATA1.dbf' to '+ORADATA/sjzy/datafile/CMX_DATA1.dbf';

set newname for datafile '/dev/shm/data/CMX_DATA2.dbf' to '+ORADATA/sjzy/datafile/CMX_DATA2.dbf';

set newname for datafile '/dev/shm/data/CMX_DATA3.dbf' to '+ORADATA/sjzy/datafile/CMX_DATA3.dbf';

restore datafile 23,25,27;

}

修改控制文件指针

alter database rename file '/dev/shm/data/CMX_DATA1.dbf' to '+ORADATA/sjzy/datafile/CMX_DATA1.dbf';

alter database rename file '/dev/shm/data/CMX_DATA2.dbf' to '+ORADATA/sjzy/datafile/CMX_DATA2.dbf';

alter database rename file '/dev/shm/data/CMX_DATA3.dbf' to '+ORADATA/sjzy/datafile/CMX_DATA3.dbf';

检查

select file#,name,status,bytes/1024 from v$datafile where file# in ('23','25','27');

name 结果为:+ORADATA/sjzy/datafile/CMX_DATA1.dbf

online 相应表空间:

alter tablespace CSG_MD online;

alter tablespace TBS_META_NW online;

alter tablespace TS_KPI online;

防止误将数据文件扩容到本地文件系统的方法

在rac asm环境下,创建表空间或给表空间扩容时,容易出现在数据文件中少写+号,或是磁盘组的名称中出现空格等问题,将数据文件写到本地文件系统,导致只有一个节点能读写,而其他节点无法读写存在异常的数据文件。

解决方法:通过在数据库部署db级别的触发器,可以有效防止该问题的发生。创建表空间或扩容时,数据文件名的开头必须包含正确的磁盘组名称:“+磁盘组名”。

脚本示例:

第一步、创建一个type,如果为了使split函数具有通用性,请将其size 设大些。

create or replace type type_split as table of varchar2(4000)

/

第二步、创建function split

create or replace function split

(

p_list varchar2,

p_sep varchar2 := ','

) return type_split pipelined

is

l_idx pls_integer;

v_list varchar2(4000) := p_list;

begin

loop

l_idx := instr(v_list,p_sep);

if l_idx > 0 then

pipe row(substr(v_list,1,l_idx-1));

v_list := substr(v_list,l_idx+length(p_sep));

else

pipe row(v_list);

exit;

end if;

end loop;

return;

end split;

/

第三步、创建触发器:

CREATE OR REPLACE TRIGGER cs_pnp_trigger

BEFORE ALTER OR CREATE ON DATABASE

DECLARE

v_oper varchar2(32); --operation type

v_obj_name varchar2(32); --object name

v_obj_type varchar2(32); --object type

v_sql_txt ora_name_list_t;

v_n BINARY_INTEGER;

v_stmt varchar2(4000); --sql statement

v_n2 number := 0;

v_dg_count number := 1;

v_in_dg number := 1;

v_tmp_dgname varchar2(100) := '';

BEGIN

--dbms_output.put_line(v_stmt);

select ora_sysevent, ora_dict_obj_name(), ora_dict_obj_type()

into v_oper, v_obj_name, v_obj_type

from dual;

--dbms_output.put_line(ora_sysevent||':'||v_obj_type||':'||v_obj_name);

IF (v_oper = 'CREATE' OR v_oper = 'ALTER') AND v_obj_type = 'TABLESPACE' THEN

v_stmt := '';

v_n := nvl(ora_sql_txt(v_sql_txt), 0);

FOR i IN 1 .. v_n LOOP

v_stmt := v_stmt || v_sql_txt(i);

END LOOP;

for j in (select * from table(split(v_stmt, chr(39)))) loop

v_n2 := v_n2 + 1;

if v_n2 mod 2 = 0 then

select COLUMN_VALUE

into v_tmp_dgname

from table(split(j.COLUMN_VALUE, '/'))

where rownum < 2;

select count(*)

into v_dg_count

from v$asm_diskgroup

where '+' || name = upper(v_tmp_dgname);

dbms_output.PUT_LINE(j.COLUMN_VALUE || v_dg_count);

if v_dg_count = 0 then

v_in_dg := 0;

exit;

end if;

end if;

end loop;

END IF;

IF v_in_dg = 0 THEN

RAISE_APPLICATION_ERROR(-20998,

'cs_pnp_trigger:

Attempt To CREATE or ALTER TABLESPACE in CLUSTER

and the diskgroup name "' || v_tmp_dgname ||

'" is INCORRECT!');

END IF;

END cs_pnp_trigger;

/

第四步、验证脚本:

以错误方式创建表空间:

SQL> create tablespace test1 datafile 'data' size 10m autoextend off;

create tablespace test1 datafile 'data' size 10m autoextend off

*

ERROR at line 1:

ORA-00604: error occurred at recursive SQL level 1

ORA-20998: cs_pnp_trigger:

Attempt To CREATE or ALTER TABLESPACE in CLUSTER

and the diskgroup name "data" is INCORRECT!

ORA-06512: at line 45

以错误方式扩容表空间:

SQL> alter tablespace users add datafile 'data_vg' size 10m autoextend off;

alter tablespace users add datafile 'data_vg' size 10m autoextend off

*

ERROR at line 1:

ORA-00604: error occurred at recursive SQL level 1

ORA-20998: cs_pnp_trigger:

Attempt To CREATE or ALTER TABLESPACE in CLUSTER

and the diskgroup name "data_vg" is INCORRECT!

ORA-06512: at line 45

部署触发器后,在创建表空间或给表空间扩容时,误操作将无法执行成功,误操作的数据文件不会生成,后台日志也不会报相关的操作提示。

第五步、如果不需要该触发器,可以采用如下步骤删除

drop TRIGGER cs_pnp_trigger;

drop function split;

drop type type_split ;

End

centos7创建asm磁盘_ASM环境下防止误将数据文件扩容到本地文件系统的方法相关推荐

  1. centos7创建asm磁盘_asm磁盘路径包含混合路径时的设置

    如果asm磁盘发现路径中,既有udev方式创建的磁盘,又有asmlib创建的磁盘,那么,在asm_diskstring中,需要把两种情况都设置: asm_diskstring string /dev/ ...

  2. centos7创建asm磁盘_Oracle ASM 磁盘组基础知识整理(收藏版)

    为什么要写这么一篇基础知识呢?还是有那么一点点原因的,不是胡编乱造还真是有真实存在的事件的,前两周里因一套生产环境数据库磁盘不足无法对其进行表空间扩容,需要向存储岗申请存储资源,当存储岗划好资源加完存 ...

  3. linux+oracle磁盘空间,Linux下Oracle软件、数据文件等所在的磁盘分区空间不足的解决思路...

    虚拟机中的Oracle运行的久了,归档.数据文件不断增长,原来安装ORACLE的分区空间不足. 此时可以重新向虚拟机增加一块硬盘,将ORACLE的数据文件或归档的目录挂载到新增加的磁盘分区上. --我 ...

  4. linux上mysql分区磁盘位置_Linux下Oracle软件、数据文件等所在的磁盘分区空间不足的解决思路...

    虚拟机中的ORACLE运行的久了,归档.数据文件不断增长,原来安装ORACLE的分区空间不足.此时可以重新向虚拟机增加一块硬盘,将OR 虚拟机中的Oracle运行的久了,归档.数据文件不断增长,原来安 ...

  5. 多路径下使用ASMLIB创建ASM磁盘

    多路径下使用ASMLIB创建ASM磁盘 Asmlib有扫描磁盘有默认的顺序,通常为/dev/sd*,而多路径配置磁盘目录往往映射在/dev/mapper下 因此 #  egrep -v "^ ...

  6. mysql 磁盘组_AIX使用LV创建ASM磁盘组

    AIX使用LV创建ASM磁盘组 来源:互联网 作者:佚名 时间:2015-06-19 05:07 CREATE ASM ON AIX LV DEVICE OS:AIX 6100-03 ASM版本 10 ...

  7. 如何在Win Server 2008R2环境下,把域帐户加到本地管理员组??

    如何在Win Server 2008R2环境下,把域帐户加到本地管理员组 我们在大型企业中,经常不会用域管理员登陆,而是将某个OU下特定用户加入到全局组,或者将某个用户加入到本地管理员组中,但是局域网 ...

  8. docker环境下安装nginx、挂载文件、docker容器中文乱码

    docker环境下安装nginx.挂载文件.docker容器中文乱码 文章目录 docker环境下安装nginx.挂载文件.docker容器中文乱码 1.首先下载docker的nginx镜像 2.查看 ...

  9. 在 win10 环境下,设置自己写的 程序 开机自动 启动的方法

    原文:https://jingyan.baidu.com/article/c33e3f48d1360fea15cbb5c9.html win10组策略中设置在开关机时运行的脚本 分步阅读 win10组 ...

最新文章

  1. JAVA面试题系列:如何解决Redis的并发竞争问题
  2. c语言小程序跑马灯,微信小程序实现文字跑马灯效果
  3. windows网络负载平衡
  4. matlab工程计算及应用 课程名称,《 MATLAB 工程计算及应用》教学大纲课程名称MATLAB 工程计算及应用.pdf...
  5. vue 列表渲染 v-for
  6. ImageNet标签竟然部分有误!数据集MNIST也会出错?
  7. Learn Python 014: Funtions
  8. 《操作系统》实验报告——进程通信
  9. 自己动手写操作系统 - Hello DTOS
  10. Opencv之疲劳检测
  11. 使用命令代码清除系统垃圾文件
  12. 数据在云中存储安全如何保障?从三个方面出发
  13. 如何实现团队高效协作?
  14. CDA数据分析师认证与Pearson VUE达成深度合作
  15. 我是培训机构出身的程序员,不敢告诉任何人
  16. 如何运用计算机教学教学的收获,计算机教学中行动感悟法的应用
  17. Serial Box for Mac(软件序列号查询工具)
  18. Java实现合并word文档并打开合并后文档
  19. 【概率机器人】3.1 卡尔曼滤波、扩展卡尔曼滤波和无迹卡尔曼滤波
  20. ACM Divisions

热门文章

  1. java list比较器_JAVA比较器
  2. mysql autoenlist默认_mysql连接参数详解
  3. 信号扫描_科研必备“武器”之扫描电子显微镜
  4. 1899-11-30 php mysql_PHP学习十一--PHP操作MYSQL数据库
  5. 简洁明了!Java实现单向环形链表以解决约瑟夫环Josepfu问题
  6. Java集合(1)--集合概述
  7. 判断使用设备是PC还是phone
  8. JDK / JRE zip
  9. 【从零开始搭建自己的.NET Core Api框架】(二)搭建项目的整体架构
  10. IntelliJ IDEA2017 激活方法 最新的