半自动化搭建Data Guard的想法和实践(一) (r9笔记第74天)
一直以来搭建Data Guard是一件看起来还蛮有含量的工作,因为这其中涉及的工作比较琐碎,比较细,况且手工搭建起来都会碰到各种各样的问题,如果中途碰到一点儿小问题,那可能需要花点时间来排查,如果想要脚本自动化,那简直寸步难行。所以搭建Data Guard一方面会需要很多的提前准备和配置,另一方面这个工作自动化的驱动力不够,毕竟环境不会像MySQL业务一样动辄几十成百上千的规模,所以由此而来,好像搭建一个套环境的成本也值了,如果尝试自动化,半自动化,那花费的时间估计够搭建10套环境了。所以目前来看,行业内也鲜有自动化搭建的案例。
当然如果一件事情本来你需要花2个小时搞定,结果花了10分钟就能搞定,那么对于工作来说,这就是一种福利了,另一方面从规范角度来看,自动化,半自动化,一个重要的基础就是标准化,规范化。这些基础做不好,那么自动化,半自动化也是磕磕绊绊。所以我也是借这个机会来完善规范一些我们做的不好的地方。举个例子来说明就具体多了。
我在备库配置网络的时候,把主库的listener.ora拷贝到备库,修改了HOST信息,就准备启动监听,但是奇怪的是监听怎么都启动不了。错误信息如下:
$ lsnrctl start LISTENER_1529
LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 28-JUL-2016 16:37:17
Copyright (c) 1991, 2013, Oracle. All rights reserved.
Starting /U01/app/oracle/product/11.2.0.4/bin/tnslsnr: please wait...
TNSLSNR for Linux: Version 11.2.0.4.0 - Production
System parameter file is /U01/app/oracle/product/11.2.0.4/network/admin/listener.ora
Log messages written to /U01/app/oracle/diag/tnslsnr/stest3/listener_1529/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=stest3.cyou.com)(PORT=1529)))
TNS-01201: Listener cannot find executable /U01/app/oracle/product/11.2.0.4/db_1/bin/oracle for SID test
Listener failed to start. See the error message(s) above...
对于网络监听这块,本身Oracle的解析就有些不是很健壮的地方,有些空格的约束问题,更多的细节,可以参考http://blog.itpub.net/23718752/viewspace-1061787/
所以根据错误,看起来和空格还没有关系,但是我排除再三,排除了字符集,空格,DB信息错误等,还是没有找到问题的症结。一筹莫展的时候,突然发现 listener.ora中的ORACLE_HOME为/U01/app/oracle/product/11.2.0.4/db_1,在主库则为/U01/app/oracle/product/11.2.0.4,最后发现是这样一个问题,看起来着实让人有些无奈。而这种问题说实在的解决了对自己 的技术提高有多少,我看未必,但是又厄待解决。
所以这也更加坚定了我简化Data Guard配置的一个决心。 而另外一个考虑就是基于安全和脚本的健壮性,我决定使用半自动化搭建的方式,主库就是主库,容不得半点失误,所以我不会考虑在主动自动化运行任何的脚本,脚本都需要确认审核后执行,对于配置的添加和修改尤其需要注意,而对于备库而言,自动化则大有可为,所以我需要在主库中获取一些基本的元数据文件(比如listener.ora之类的文件),改进处理后放入备库。大体的流程图如下:
首先第1步就是从主库中获取这些元数据文件,只有抓取,没有任何写入。 第二步是在中控机器中进行元数据文件的处理,这大体涉及以下几个方面: 1. 在tnsnames.ora中添加备库的tns连接串,修改host 2.istener.ora修改host为备库主机名 3. hosts中追加主机名的配置 4. 添加db_unique_name到参数文件中 5. 添加local_listener 6. 添加dg_broker_start 7. 添加standby_file_management=auto 8. 添加db_file_name_convert 9. 添加log_file_name_convert 10.开通主备库的防火墙权限 第三步则是在主库中进行配置,大体有如下的工作: 1.修改/etc/hosts,追加备库的配置 10.127.133.190 stest2.cyou.com 2. 追加配置到tnsnames.ora,修改host为主机名 stest2=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = stest2.cyou.com)(PORT = 1529))) (CONNECT_DATA = (SERVICE_NAME = test)(server=dedicated))) 3.检查主库是否force logging,是否含有standby logfile,是否启用spfile,是否启用dg broker,是否设置local_listener 第四步则是把生成的文件,脚本拷贝到备库端,在备库运行部署。有下面的一些工作需要考虑。 1./sbin/ifconfig得到IP 根据db名改为主机名 生成类似下面的形式, IP <db_unique_name><dg_number>.oracle.com 10.127.133.190 stest2.oracle.com 2.追加主库的配置 10.127.xxxx test.oracle.com --参考主库的/etc/hosts 3.hostname stest2.cyou.com 4.修改 /etc/sysconfig/network 5.创建必要的目录结构,比如审计日志的目录(基于参数audit_file_dest) 6.启动监听 这些步骤做好了之后,80%的工作就完成了。我们就可以看看怎么来搭建备库了。一种方式是使用duplicate来在线从头主库同步数据到备库,这种方式简单快捷,也是推荐的方式。 两个命令即可搞定。 rman target sys@test auxiliary sys/xxxx@stest2 nocatalog duplicate target database for standby from active database nofilenamecheck; 这些工作都完成了,就完成了90%,还剩下最后一步,即配置DG Broker,这个是作为一个基本的标准规范,省时省力。 在主库运行两个命令即可搞定,这个步骤手动完成,因为是最后的收官阶段,一旦有问题,这个阶段一定会抛出异常。 create configuration dg_test as primary database is test connect identifier is test; add database stest2 as connect identifier is test2 maintained as physical; 脚本已经开始写了,感觉越写发现有很多的细节需要准备,越是这样,越觉得这件事情还是值得去做的。
- 恶心的0.5四舍五入问题
- 乐视金融更名 相关域名引关注
- weblogic.nodemanager.common.ConfigException: Native version is enabled but nodemanager native librar
- hadoop 2.6伪分布安装
- ssh 免密码设置失败原因总结
- C++服务器开发之基于对象的编程风格
- The jQuery UI CSS Framework
- hadoop:将WordCount打包成独立运行的jar包
- Hadoop: MapReduce2多个job串行处理
- UE4新手引导之下载和安装虚幻4游戏引擎
- mac 下卸载mysql的方法
- ZooKeeper 笔记(1) 安装部署及hello world
- mybatis 使用经验小结
- ZooKeeper 笔记(2) 监听数据变化
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- LeetCode85|只出现一次的数字III
- LeetCode84|只出现一次的数字
- LeetCode83|排序矩阵查找
- LeetCode82|翻转字符串里的单词
- LeetCode81|移动零
- LeetCode80|反转字符串中的元音字母
- LeetCode79|平方数之和
- LeetCode91|寻找重复数
- LeetCode90|两个数组的交集
- LeetCode89|在排序数组中查找数字I
- LeetCode88|两数之和IV-输入BST
- LeetCode98|判定字符是否唯一
- LeetCode97|合并两个有序链表
- LeetCode99|数组中出现次数超过一半的数字
- redis源码之hash结构的实现