适当的版本控制数据库策略

Luc*_*uke 13 java mysql database version-control

我正在阅读这篇博客,我对于撰写的5篇帖子有疑问.据我所知,您在包含所有SQL DDL语句的大基线脚本上创建.完成此操作后,您可以在单独的脚本中跟踪每个更改.

但是我不明白脚本文件的名称如何与应用程序的特定版本相关联?他说,如果用户报告3.1.5.6723中的错误,您可以将脚本重新运行到该版本.您是否会在自己的文件中跟踪对表等的更改,或者在同一个脚本文件中更改所有DLL,然后在他自己的文件中有视图等?

Ren*_*nov 15

首先,数据库升级是邪恶的,但该博客描述了一场彻头彻尾的噩梦.

可以根据升级方法创建Programmer Competency Matrix:

  • 0级:根本没有升级.客户很害怕并使用应用程序提供的UI或第三方数据库管理解决方案手动移动数据(相信我,这确实是可能的).
  • 级别1:有一个脚本来升级数据库转储.客户感到安全,但他们会在接下来的1 - 2年内修复微小且非常烦人的问题.系统正在运行,但不允许更改.
  • 第2级:表改变.怪异的停机时间,特别是在升级期间出现问题的情况下.巨大的问题,几乎无法保证获得100%安全的结果.数据转换由错误的脚本管理.顾客不高兴.
  • 第3级:无架构设计:一到两个小时的停机时间让错误的脚本转换数据库中的配置(在许多情况下,此步骤可能会损坏数据库).支持人员将所有咖啡储备完全耗尽.
  • 第4级:懒惰透明升级:零停机时间,但仍有一些问题可能发生.客户几乎满意,但仍记得以前的经验.
  • 第5级:理想的架构,无需明确升级.总幸福感.客户不知道升级程序是什么.开发人员富有成效和冷静.

我将描述所有技术问题,但在此之前让我说明以下内容(请原谅我很长的答案):

  • 现在开发周期非常紧凑,数据库很大
  • 几乎任何功能都可能引入方案更改并破坏兼容性,因此要么我们有一个简单而稳定的升级程序,要么我们可以推迟一个功能
  • 客户可能会发现问题,因此有可能需要一些紧急的热修复版本,并需要一些升级步骤
  • 一般来说,避免您和客户之间的任何障碍要好得多

0级和1级 这两种情况都很明显而且很愚蠢.任何人都应该避免这样做.

2级 改变对于小型表来说并不是那么糟糕,但对于大型表来说这可能是一个问题.在非常大的表(> 1Gb)上,ALTER TABLE可能需要几个小时甚至几天才能完成.而且,它确实只解决了架构升级问题,但存储数据呢?我还建议考虑物理数据布局,以了解这种方法背后的实际障碍.整个过程可能不安全,因此请确保备份.

解决方案:

级别3 通过将架构移动到更高层来解决架构升级的问题.无模式解决方案有些局限,主要是因为它禁用了关系模型背后的整体功能.可以提出混合方法以具有快速升级和使用关系代数的能力.有一些有趣的文章:

请注意,升级过程的复杂性仍然存在,它只是移动到应用程序级别.有很多相关的场景,但我将描述一个我已经合作多年的混合系统.我可以将数据模型描述为"具有关系的实体".实体之间的关系在数据库级别上表示,实体本身存储为XML blob.

该系统已经成熟并且拥有足够的客户.有很多功能要求,所以研发和QA团队有点紧张.最初,升级过程是作为独立的Java应用程序实现的,该应用程序从数据库读取XML blob,使用DOM API升级它并将其写回数据库.实际的方法看起来非常简单,但有几个隐藏的问题背后:

  • 升级逻辑可能有些错误,因此有可能编写错误的XML数据,从而显着增加客户的停机时间
  • 读取 - 转换 - 编写1-2GB的XML可能需要一些时间
  • 所有升级程序步骤都应该通过自动化测试来涵盖(我会说CI是必须的)
  • 由于插入了新数据,因此可能会在一两天内发现隐藏的故障,因此备份不再有用
  • 升级代码可能会变得有点混乱,特别是如果您希望/需要在构建之间进行升级(任何敏捷团队的正常要求)

我试图通过使用更严格的升级过程定义,验证规则和CI系统针对现实数据(跨所有客户收集)执行的大量测试来减轻所有潜在风险.我很惊讶地看到一些步骤失败,因为很久以前由旧的升级脚本引入的旧问题.开发了单独的升级步骤以解决隐藏的问题.还进行了一些优化以将升级时间减少到合理的20-30分钟.基于控制台的进度条实现完成了剩下的工作.

快速注意:任何最终用户都渴望看到任何长时间运行(> 2分钟)操作的进度.请不要忘记实施这样的"快乐".

最初,DB版本存储在单独的表中.请不要使用此方法,因为将实体单独版本化并在升级期间避免整个数据库锁定会更好.

将显示一个升级过程作为示例(所有验证和验证步骤都隐藏在后面<build/><version/>处理逻辑中).' - '意味着更少,'*' - 任何构建

<?xml version="1.0"?>
<upgrade>

   <version name="-7.4">
      <build name="*">
        <script class="upgrade.version7.Replace...Script"/>
        <script class="upgrade.version7.Update...Script"/>
         <!-- 5 scripts skipped -->
      </build>
   </version> 
   <version name="-7.6">
      <build name="*">
    <script class="core.DatabaseUpdateVersion" version="7.6.48"/>
      </build>
   </version>
   <version name="7.6">
      <build name="*">
        <script class="upgrade.version7.Update...Script"/>
    <script class="core.DatabaseUpdateVersion" version="8.0.40"/>
         <!-- 7 scripts skipped -->
      </build>
   </version>

   <version name="8.0">
      <build name="-53">... </build>
      <build name="+52">... </build>
   </version>

   <version name="8.1">
      <build name="-8"> ... </build>      
     <build name="-9">...</build>      
     <build name="-26">...</build>      
     <build name="-40">...</build>      
      <build name="-45">...</build>      
      <build name="-56">...</build>      
      <build name="-61">...</build>      
      <build name="-63">...</build>      
      <build name="-64">...</build>      
      <build name="-68">...</build>      
      <build name="-69">...</build>      
      <build name="-77">...</build>      
      <build name="-79">...</build>      
      <build name="-80">...</build>      
      <build name="-86">...</build>      
      <build name="-88">...</build>
      <build name="-89"> ... </build>
   </version> 

   <version name="8.2">...</version>
</upgrade>
Run Code Online (Sandbox Code Playgroud)

每个脚本都是一个小型Java或Groovy实现(也使用了XSLT).后来还开发了降级程序,但这是完全不同的故事.

应用层的4级数据方案允许做很多有趣的事情.例如,可以用protobuf替换XML .像往常一样,有几个原因(更简单,更快,等等).如果你不喜欢建设者的概念,你可以使用节俭.

无论如何,protobuf允许创建一个向后兼容的系统(就存储的数据而言)几乎没有头疼.顺便说一句,好的优势.让您的系统向后兼容,您可以轻松实现延迟和完全透明的升级.它可以是后台进程或根据请求升级等.好消息是零停机,快乐的用户和更频繁地进行升级的能力.这意味着您可以快速发展,及时响应客户的要求,换句话说就更成功了.

等级5 对不起,暂时不是.请小心升级策略.很容易卖出一个定义了一些架构的系统并锁定自己.没有新功能 - 没有客户.

简单但非常有用的清单:

  • 您能否及时解决客户方面的问题?
  • 客户升级系统是否安全(如果它至少是关键任务的话)?
  • 确定问题需要多长时间?
  • 有自动验证吗?

谢谢你的阅读.

  • 数据库升级不是如上所述的大问题.数据库与您的代码一样多,因此它意味着要改变.只需为每个版本使用升级脚本,确保它已经过测试,创建备份并且您完全安全. (2认同)