版本控制数据库的正确策略

2022-09-04 08:20:08

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

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


答案 1

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

可以基于升级方法创建程序员能力矩阵:

  • 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 分钟)操作的进度。请不要忘记实现这样的“快乐”。

最初,数据库版本存储在单独的表中。请不要使用此方法,因为最好单独对实体进行版本控制,并避免在升级过程中锁定整个数据库。

将以一个升级过程为例(所有验证和验证步骤都隐藏在处理逻辑后面)。“-”表示更少,“*” - 任何构建<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>

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

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

无论如何,protobuf允许创建一个向后兼容的系统(就存储的数据而言),几乎不费吹灰之力。顺便说一句,优势不错。通过向后兼容系统,您可以轻松实现延迟且完全透明的升级。它可以是后台进程或根据请求进行升级等。好消息是零停机时间,用户满意,并且能够更频繁地进行升级。这意味着您可以快速开发,及时响应客户的要求,换句话说,更成功。

级别 5抱歉,这次不行。请谨慎使用升级策略。出售一个定义了一些模式并将自己锁定在外的系统很容易。没有新功能 - 没有客户。

简单但非常有用的清单:

  • 您是否能够及时解决来自客户方的问题?
  • 客户升级系统是否安全(如果它至少是关键任务怎么办)?
  • 识别问题需要多少时间?
  • 是否有任何自动验证?

感谢您的阅读。


答案 2

我个人使用液态碱。非常少的工具。允许非常复杂的工作流程,如教程,使用预言机和复杂的版本控制方案


推荐