数据库版本频繁更新不同版本数据库之间的移植是经常让数据库管理员头疼的问题数据库移植不仅仅是导出导入的过程由于新旧运行平台操作系统应用设备等的不同其中涉及的问题方方面面本文将为大家介绍Oracle Database g数据库移植的技巧会遇到的问题和解决方案以及实施移植的步骤等方面内容
在数据库声明周期中最常发生的一件事就是不断地把数据库从老版本移植到新版本不同版本之间的数据库移植有时候可能就像把数据从老版本里导出再导入到新版本中一样简单不过其中涉及到的问题往往比你想象中复杂得多而且移植过程还会涉及到其他一些显着的改变例如操作系统改变模式修改以及相关应用软件的变化等等每一项变化都存在着固有的风险性不过人们常常认为还是应该把这些变化全部结合起来一起清除来个一劳永逸而且这样在移植过程中从头到尾都不去进行检测这种情况出现了如此频繁实在让人非常惊讶
从一个软件工程师的观点来看把这么多重要的改变通通放在一个步骤里实现是不是很好的解决办法并且足够安全呢?此外不仅仅是实施移植而已还要在实际移植之前检测这些变化是否适用于目标环境
还有其他一些值得注意的地方在依赖关系链打断移植过程之前先把它给打断了否则受打击的将是你假设在从Oracleg移植到g的情况下要把基层操作系统从Linux改为Solaris在一个模式里修改主表并且运行更新的或修改了版本的相关应用软件那么应该在哪些步骤打断依赖关系链呢?换句话说哪些步骤更加更安全更熟悉并且被其他很多人应用过了?而哪些步骤其他人都没有尝试过而只适用于你的情况呢?
分清楚哪些是已经被实践过的而哪些又是未知的
如果你是Oracle新版本的边缘用户或者是最近才开始使用新版本的用户那么在你(和你的公司)准备从老版本的关系数据库管理系统软件移植到新版本之前已经有很多前辈为你做过预演了同样的那些前辈们已经跨越了采用Linux作为基本操作系统所带来的阴暗面
考虑到关系数据库管理系统和操作系统的综合转换已经被大家所熟知你的数据库产品所依赖的版本和操作系统是打破依赖关系链的理想之所在如果把所有的操作都结合在一起一步到位的实施那么移植过程是一个要么成功要么失败的过程没有中间地带而失败意味着时间可能都会浪费在这个过程的最简单部分也就是说数据的移出和移入要花费大把的时间如果失败这些过程的执行等于做了无用功如果你把整体移植过程至少分成两个不同的阶段你将会把依赖关系链分割成若干小的关系链这个必须熟习的指导性原则就是通过安全渐进的步骤完成移植过程
对于数据库模式和应用软件的处理则要由你自己来决定除非你已经对模式和应用软件的转换进行了彻底测试并使其正常运作了否则整体移植过程的这一部分是否成功仍是个未知之数如果让新应用软件和数据库上线然后才发现新软件和数据库代码会导致连锁触发(cascading triggers)反应(将会导致实例瘫痪)这样的情况会让你沮丧不已实际产品环境中常包含成千上万条记录而开发人员和测试人员在测试环境下的测试规模只有一百条记录很难进行一次彻底的测试
手动操作和设置导出和导入过程
关于导出和导入的实用工具你不一定要接受其默认参数事实上你应该采用大部分的自定义设置这样能够使移植过程更容易进行而且在产品环境实际进行操作时能够节省大量时间
我们首先来看看索引文件的参数设置在导入过程中最好使用indexfile=filename的设置原因至少有四条
第一这样可以把表和索引等对象信息(全部或部分取决于导出dump文件中包含了什么内容)存储在指定的输出文件中想知道创建模式的源代码在哪里吗?如果你没有源代码那这个参数(连同一个返回所有其他信息的简单查询)对于这些信息的提供会有很大帮助查询部分会将全部的或user_source数据字典的内容输出到文件中包包体存储过程函数和触发器等代码信息都包括在输出的结果文件里再稍微加工一下例如执行CREATE OR REPLACE命令清除SQL*Plus工具存储区域里无用的结果(如标题行换页等)剩下的就是一个模式最重要那部分的当前代码
第二如果你想对表和索引对象进行清洗或重排操作那么在导入时通过这一设置对索引文件进行编辑并对表空间映射和存储参数进行更新时机恰到好处
第三如果你想让逻辑布局维持原样可以分隔索引和表也就是分离SQL CREATE命令(一部分脚本专门用于创建表另一部分专门用于索引)在进行实际的移植之前要尽可能先设置好目标数据库其中一部分工作就是创建新的同样的表空间并运行创建表的脚本提前运行创建表的标本有两个理由一是使逻辑布局生效二是提高移植导入的速度
第四个原因回到了索引文件中所列的索引当执行数据批量插入时是有索引好呢还是没有所以更好呢这对于插入效率有多大的影响?由于每插入一个新记录就必须更新一个或多个索引(假设该记录至少有一个主键)所以对于大型数据库而言Oracle的建议是等所有的数据都已经插入完毕后再构建索引这样的建议无疑又重申了indexfile的重要性因为当导出时使用indexes=n(默认设置是y)的设置把索引忽略掉以后想要在数据全部导入完毕后重新构建索引indexfile就是衔接的桥梁
数据库移植不是简单的导出导入
Oracle g最早的版本是运行在Linux系统下的也提供安装了相关的关系数据库管理系统软件你所运行的新实例包含了很多意想不到的新特性不过这一切都得在你成功的把源数据库(或模式)移植新的目标数据库之后再说你可能正计划在周五的半夜占用八小时的停工和维护时间来执行移植操作那么在移植之前你可以做些什么来尽可能保证整个移植过程顺利无痛的进行呢?只要你对以下四个重要方面做好规划就可以使你的移植过程与众不同统筹管理导出阶段导入阶段和交接阶段
统筹管理/项目规划
如果你是数据库移植计划的负责人你肯定希望整个移植过程能够像你所计划的那样步步顺利
为了使所有的移植步骤能够顺利进行你需要制定一个详细的计划流程图如果没办法做到上述要求那么最低限度你可以制定一条低技术路线拿出一份计划时间表来即使你只是在心血来潮的时候把想法和问题记录下来对于让所有人在移植过程中达到步调一致也能起到一定的作用最好能把以下的方面都认真考虑加以计划
图解移植计划流程召开协调会议
落实每一个团队成员责任确定他们在移植过程中的角色和应负的责任
制定一份联系名录包括如何联系其他关键人员(包括主管系统管理员测试人员开发人员第三方软件供应商客户帐户主管等等)把这份名录分发给相关成员
确定对某些特殊客户的移植操作时间
在工作结束后告知相关负责人员约定时间和地点
通知办公楼保安人员(以及清洁工作人员)关于你们要在办公室里加班的事情以免引起不必要的误会
为文件系统建立一个传输点保证有足够的磁盘空间用来导出数据
要深入认识模式的变化包括修改关键表的时间和机理数据转换过程等)
安排好计划进度表搞清楚是不是整个移植过程中每个数据库管理员都需要留下来全程陪护还是可以把每个人的时间错开
预导出和导出阶段
如果你(或导出操作的负责人)时间充裕的话你完全可以事先对导出操作进行多次演练确保移植计划的这个环节再没有什么小问题出来骚扰你导出过程必须是一步式操作吗?不是的可以根据功能群来分阶段实施导出过程可以考虑把导出过程分解成以下几个功能群支持表主表已修改表历史/静态表
通过以这种方式把表分成不同的功能群你可以交替进行导出和导入操作操作一旦某类群的导出操作完成了你就可以着手进行相应的导入操作在分开执行的情况下导出过程可能需要两个小时而导入过程可能得花四个小时;但并不意味着需要连续运行六个小时才能完成整个过程为什么导出和导入花费的时间不一样呢?要知道导出和导入并不是一对一的镜像关系不要忘记索引是不需要导出的而是在数据都加载到目标数据库之后才重新构建所以导出过程要比导入过程运行得快一点如果稍微优化一下两者都可以以更快的速度运行你要怎么驱动导出过程是用交互模式(interactive mode)还是使用shell 脚本和参数文件的非交互模式?Linux下的Shell脚本具有四个主要的特点
它是一个访问读取过程
能够追蹤反馈信息分析总结系统登录档案
检测管理系统的功能(包括参数文件根据制定路径存储dump和日志文件的功能数据库连接等)
关键步骤或操作之后会询问是否需要继续执行的退出机制
只要一个脚本就能够驱动整个导出进程而且退出点可以作为指示信号使用(和echo语句一起广泛使用可以指示运行到了进程的哪一个步骤)演练和完善脚本过程中一个主要的度量标准就是执行完整个导出操作所花费的时间
如果正在进行的是一个模式移植(schema migration相对于全库移植)那么模式之间的依赖性是什么?找找诸如build_managerprocess_logger等名称或项目Build_manager可能包含一般或公共函数过程和包Process_logger则可能包含所有模式的进程日志(在一个源文本文件中常常能看到pragma autonomous_transaction这是在执行事务失败过程发现错误的一种方法)除非新模式整合了这些外部的和相关的模式否则必须在目标数据库中为这些被遗留下来的部分模式进行说明解释
如果正在执行导出操作那些非导出的模式可能会导致一些问题的出现所以当执行导出操作的时候你可能需要禁用连接修改密码屏蔽其他进程暂停cron服务网络程序的连接往往像杂草一样难以遏制而防止其连接的有效方法之一就是修改密码假设你的导出计划获得了圆满成功最后要决定的就是如何处理源数据库
导入阶段
演练模式的构建和诸如表空间和数据文件等相关物理/逻辑对象的构建这样做的最终目的是不管怎样都不要在这个阶段出现错误提示并保证所有创建脚本都是可重复运行的关于导入的参数文件需要确保源用户和目标用户能够相互匹配利用indexfile的种种好处在目标数据库中预先创建表
对于正在接受修改的表我们必须清楚这些过程发生在什么地方发生的时间和机制这些变化是发生在用户的模式里吗?还是随着新表式的插入发生在某个临时或移植的模式里
必须全面了解主表是如何改变的你可能会想当然地认为定义非空约束(NOT NULL constraints)无关紧要不过应用程序的变化完全依赖于它们换句话说如果由于移植过程中出现一些阻滞你试图重建某个表的时候仅仅关注主键约束(PK)外键约束(FK)和唯一约束(FK)是不够的
那定时任务工具cron和数据库作业呢?你要如何移植/导出所有的这些东西呢?通常与cron作业密切相关的是电子邮件要注意新服务器是否配置好电子邮件通知系统是否需要创建数据库连接
在导入过程进行的时候是否需要开启日志记录呢?有没有必要把所有导入的事件都记录到日志里呢?记录触发器是不是有必要特别是对于行级触发器(即每行都执行)?在导入过程中需要插入数量达百万以上的行对于行级触发器每插入一行就需要执行一次甚至更多的触发器操作如果依赖源数据库的某个表的触发器已经执行某些操作那么在导入过程中有必要再次执行相同的操作吗?以上这些问题都是需要认真考虑的
你可能很聪明地禁用了不少自动功能以便加快导入过程不过千万别聪明过头而忘记把你禁用的功能重新启用由于移植过程很可能都是在午夜进行睡意朦胧的你很可能会导致大量人为错误的产生如果你实在不是熬夜的料最好让其他人帮你检查这些工作和操作步骤特别是当运行的对象对于数据库或模式来说至关重要重要的时候
导入后需要关注的事项
所有的移植工作都顺利完成了?你以为可以松一口气了不过任务还没有真正结束你还需要创建基础备份所以你必须搞清楚以下问题是不是应该在移植完成新数据库构建完毕后立即着手进行备份?你是不是已经能够成功地从导出备份冷备份和热备份转变到RMAN备份?你之前有没有练习过RMAN备份和恢复操作?
首选方案当然是在移植顺利完成后立即开始进行备份不过前提是移植过程非常顺利你的计划和目标非常明确假设由于某些不定因素导致移植完成后应用软件无法正常运行又该怎么办呢?移植完成后产品环境下的完全测试可以减少这种情况的发生但是如果没有进行大规模测试呢?要怎样才能回复到源数据库状态?你是不是还有足够的时间重新再来一遍?只要你对导出过程会发生的问题有充分的认识就不会有二次尝试的必要了
不要以为每个人都对发生的事情了如指掌客户支持人员是不是知道如何把桌面工具软件指向新的数据库?还是会在抱怨对数据库的修改无效后几个星期才知道代开trouble tickets系统查看对于作为数据库管理员的你来说闭上眼也能显而易见的东西对于那些不懂数据库语言的人而言可能相当晦涩
总结
本文所涵盖的数据库移植技巧步骤和问题都来源于真实的案例就像上面说的有些客户服务代表会抱怨数据库没有显示数据的变化很可能是不清楚该如何把桌面客户关系管理工具指向新数据库而导致的这应该是数据库管理员的责任还是客户代表主管的责任呢?插入变换格式后的数据和工作区到主表中也常常会出现问题这就很可能和非空约束有关了
关于数据库移植有一个最起码的常识如果你连事先进行测试并处理好导致失败的问题的时间都没有你更不可能有时间来做第二次尝试?关于移植过程中起到作用的一些外部因素本文所提到的一些技巧和注意事项进行了深入的解析希望大家看过之后在数据库移植过程中能少走弯路顺利完成升级