簡體   English   中英

您如何管理開發、測試和生產中的數據庫?

[英]How do you manage databases in development, test, and production?

我很難找到關於如何在開發、測試和生產服務器之間管理數據庫模式和數據的好例子。

這是我們的設置。 每個開發人員都有一個運行我們的應用程序和 MySQL 數據庫的虛擬機。 這是他們的個人沙箱,可以為所欲為。 目前,開發人員將對 SQL 模式進行更改,並將數據庫轉儲到他們提交到 SVN 的文本文件中。

我們想要部署一個持續集成開發服務器,該服務器將始終運行最新提交的代碼。 如果我們現在這樣做,它將為每個構建從 SVN 重新加載數據庫。

我們有一個運行“候選發布”的測試(虛擬)服務器。 部署到測試服務器目前是一個非常手動的過程,通常需要我從 SVN 加載最新的 SQL 並對其進行調整。 另外,測試服務器上的數據不一致。 您最終會得到最后一個開發人員在他的沙箱服務器上提交的任何測試數據。

一切都失敗的地方是部署到生產。 由於我們不能用測試數據覆蓋實時數據,這涉及手動重新創建所有架構更改。 如果有大量模式更改或轉換腳本來操作數據,這會變得非常麻煩。

如果問題只是架構,這將是一個更簡單的問題,但數據庫中有“基礎”數據也在開發過程中更新,例如安全和權限表中的元數據。

這是我在向持續集成和一步構建邁進的過程中看到的最大障礙。 怎么解決呢?


一個后續問題:如何跟蹤數據庫版本,以便知道要運行哪些腳本來升級給定的數據庫實例? 標准程序下方是否有像 Lance 提到的版本表?


感謝您參考塔倫蒂諾。 我不在 .NET 環境中,但我發現他們的DataBaseChangeMangement wiki 頁面非常有幫助。 特別是這個Powerpoint Presentation (.ppt)

我將編寫一個 Python 腳本,該腳本根據數據庫中的表檢查給定目錄中*.sql腳本的名稱,並根據構成該表第一部分的整數按順序運行不存在的腳本。文檔名稱。 如果這是一個非常簡單的解決方案,正如我懷疑的那樣,那么我會在這里發布。


我有一個工作腳本。 如果數據庫不存在,它會處理初始化數據庫並根據需要運行升級腳本。 還有用於擦除現有數據庫和從文件導入測試數據的開關。 它大約有 200 行,所以我不會發布它(盡管如果有興趣,我可能會將它放在 pastebin 上)。

有幾個不錯的選擇。 我不會使用“恢復備份”策略。

  1. 編寫所有架構更改的腳本,並讓 CI 服務器在數據庫上運行這些腳本。 有一個版本表來跟蹤當前的數據庫版本,並且只有在它們是用於較新版本時才執行腳本。

  2. 使用遷移解決方案。 這些解決方案因語言而異,但對於 .NET,我使用 Migrator.NET。 這允許您對數據庫進行版本控制並在版本之間上下移動。 您的架構是在 C# 代碼中指定的。

您的開發人員需要為他們處理的每個錯誤/功能編寫更改腳本(架構和數據更改),而不僅僅是將整個數據庫轉儲到源代碼控制中。 這些腳本會將當前的生產數據庫升級到開發中的新版本。

您的構建過程可以將生產數據庫的副本恢復到適當的環境中,並在其上運行源代碼管理中的所有腳本,這會將數據庫更新到當前版本。 我們每天都這樣做,以確保所有腳本都能正確運行。

看看 Ruby on Rails 如何做到這一點。

首先是所謂的遷移文件,它們基本上將數據庫模式和數據從版本 N 轉換到版本 N+1(或者在從版本 N+1 降級到 N 的情況下)。 數據庫有表,告訴當前版本。

測試數據庫總是在單元測試之前被清除干凈,並填充來自文件的固定數據。

Refactoring Databases: Evolutionary Database Design這本書可能會給你一些關於如何管理數據庫的想法。 也可以在http://martinfowler.com/articles/evodb.html 上閱讀簡短版本

在一個 PHP+MySQL 項目中,我將數據庫修訂號存儲在數據庫中,當程序連接到數據庫時,它會首先檢查修訂版本。 如果程序需要不同的修訂版,它將打開一個用於升級數據庫的頁面。 每次升級都在 PHP 代碼中指定,這將更改數據庫架構並遷移所有現有數據。

您還可以考慮使用SQL Compare 之類的工具來編寫不同版本數據庫之間的差異的腳本,從而使您可以在版本之間快速遷移

  • 將你的數據庫命名如下 - dev_<<db>> , tst_<<db>> , stg_<<db>> , prd_<<db>> (顯然你永遠不應該硬編碼數據庫名稱
  • 因此,您甚至可以在同一物理服務器上部署不同類型的數據庫(我不建議這樣做,但您可能必須......如果資源緊張)
  • 確保您能夠在這些數據之間自動移動數據
  • 將數據庫創建腳本與人口分開 = 應該總是可以從頭開始重新創建數據庫並填充它(從舊的數據庫版本或外部數據源
  • 不要在代碼中使用硬編碼連接字符串(即使不在配置文件中)-在配置文件連接字符串模板中使用,您確實動態填充,需要重新編譯的 application_layer 的每次重新配置都是錯誤的
  • 確實使用數據庫版本控制和 db 對象版本控制-如果您負擔得起,請使用現成的產品,如果不能自己開發一些東西
  • 跟蹤每個 DDL 更改並將其保存到某個歷史記錄表中( 示例在這里
  • 每日備份! 測試您能夠以多快的速度從備份中恢復丟失的內容(使用自動恢復腳本
  • 即使您的 DEV 數據庫和 PROD 具有完全相同的創建腳本,您也會遇到數據問題,因此允許開發人員創建 prod 的精確副本並使用它(我知道我會收到此錯誤,但更改當狗屎擊中粉絲時,心態和業務流程將花費你少得多 - 所以強迫編碼員合法地下標,無論它做什么,但要確保這一點。

這是我一直不滿意的事情 - 我們對這個問題的解決方案。 幾年來,我們為每個版本維護了一個單獨的更改腳本。 此腳本將包含上一個生產版本的增量。 隨着應用程序的每次發布,版本號都會增加,如下所示:

  • dbChanges_1.sql
  • dbChanges_2.sql
  • ...
  • dbChanges_n.sql

這很有效,直到我們開始維護兩條開發線:用於新開發的主干/主線,以及用於錯誤修復、短期增強等的維護分支。不可避免地,需要對分支中的架構進行更改。 此時,我們已經在 Trunk 中擁有 dbChanges_n+1.sql,因此我們最終采用了如下方案:

  • dbChanges_n.1.sql
  • dbChanges_n.2.sql
  • ...
  • dbChanges_n.3.sql

同樣,這也很有效,直到有一天我們抬頭看到主線中有 42 個增量腳本,分支中有 10 個。 啊!

這些天我們只是維護一個增量腳本並讓 SVN 版本它 - 即我們在每個版本中覆蓋腳本。 我們避免在分支中進行架構更改。

所以,我對此也不滿意。 我真的很喜歡從 Rails 遷移的概念。 我對LiquiBase非常着迷。 它支持增量數據庫重構的概念。 值得一看,我很快就會詳細介紹。 有人有經驗嗎? 我很想知道你的結果。

我們的設置與 OP 非常相似。

開發人員在具有私有數據庫的 VM 中進行開發。

【開發商即將入駐私人分支機構】

測試在不同的機器上運行(實際上是在托管在服務器上的虛擬機中)[將很快由 Hudson CI 服務器運行]

通過將參考轉儲加載到數據庫中進行測試。 應用開發人員架構補丁,然后應用開發人員數據補丁

然后運行單元和系統測試。

生產作為安裝人員部署給客戶。

我們所做的:

我們對我們的沙箱數據庫進行模式轉儲。 然后是一個sql數據轉儲。 我們將其與之前的基線進行比較。 那對 deltas 是將 n-1 升級到 n。

我們配置轉儲和增量。

所以為了安裝 N CLEAN 版本,我們將轉儲運行到一個空的數據庫中。 要打補丁,請應用中間的補丁。

( Juha 提到 Rail 有一個記錄當前數據庫版本的表的想法是一個很好的想法,應該使安裝更新不那么令人擔憂。)

Delta 和轉儲必須在 Beta 測試之前進行審查。 我無法解決這個問題,因為我已經看到開發人員為自己將測試帳戶插入到數據庫中。

恐怕我同意其他海報。 開發人員需要編寫他們的更改腳本。

在許多情況下,簡單的 ALTER TABLE 行不通,您也需要修改現有數據 - 開發人員需要考慮需要哪些遷移並確保它們編寫正確(當然,您需要在某些時候仔細測試)發布周期)。

此外,如果您有任何感覺,您將讓您的開發人員為他們的更改編寫回滾腳本,以便在需要時可以恢復它們。 這也應該被測試,以確保它們的回滾不僅沒有錯誤地執行,而且使數據庫處於與以前相同的狀態(這並不總是可能或可取的,但大多數時候是一個很好的規則) .

我不知道你如何將它連接到 CI 服務器。 也許您的 CI 服務器需要有一個已知的構建快照,它會在每晚恢復到該快照,然后應用此后的所有更改。 這可能是最好的,否則一個損壞的遷移腳本不僅會破壞當晚的構建,還會破壞所有后續的構建。

如果您在 .NET 環境中,那么解決方案是Tarantino (archived) 它在 NANT 構建中處理所有這些(包括要安裝哪些 sql 腳本)。

我們使用命令行mysql-diff :它輸出兩個數據庫模式(來自實時數據庫或腳本)之間的差異作為 ALTER 腳本。 mysql-diff 在應用程序啟動時執行,如果架構發生變化,它會報告給開發人員。 因此開發人員不需要手動編寫 ALTER,模式更新是半自動發生的。

查看dbdeploy ,已經有 Java 和 .net 工具可用,您可以遵循他們的 SQL 文件布局和架構版本表標准並編寫您的 Python 版本。

對於 oracle 數據庫,我們使用oracle-ddl2svn工具。

這個工具自動化了下一個過程

  1. 對於每個數據庫方案獲取方案 ddls
  2. 把它放在版本控制下

手動解決實例之間的更改

我已經編寫了一個工具(通過連接到Open DBDiff )比較數據庫模式,並將向您建議遷移腳本。 如果您進行了刪除或修改數據的更改,它將引發錯誤,但會為腳本提供建議(例如,當新模式中缺少一列時,它將檢查該列是否已重命名並創建 xx - 生成script.sql.suggestion 包含重命名語句)。

http://code.google.com/p/migrationscriptgenerator/恐怕只有 SQL Server :( 它也是非常 alpha,但它非常低摩擦(特別是如果你將它與 Tarantino 或http://code.google結合使用) .com/p/simplescriptrunner/ )

我使用它的方式是在您的 .sln 中有一個 SQL 腳本項目。 您在本地還有一個 db_next 數據庫,您可以對其進行更改(使用 Management Studio 或NHibernate Schema ExportLinqToSql CreateDatabase或其他東西)。 然后您使用 _dev 和 _next 數據庫執行遷移腳本生成器,這將創建。 用於遷移的 SQL 更新腳本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM