Làm thế nào để bạn quản lý cơ sở dữ liệu trong phát triển, thử nghiệm và sản xuất?


171

Tôi đã có một thời gian khó khăn để cố gắng tìm các ví dụ tốt về cách quản lý các lược đồ cơ sở dữ liệu và dữ liệu giữa các máy chủ phát triển, thử nghiệm và sản xuất.

Đây là thiết lập của chúng tôi. Mỗi nhà phát triển có một máy ảo chạy ứng dụng của chúng tôi và cơ sở dữ liệu MySQL. Đó là hộp cát cá nhân của họ để làm bất cứ điều gì họ muốn. Hiện tại, các nhà phát triển sẽ thực hiện thay đổi lược đồ SQL và chuyển cơ sở dữ liệu sang tệp văn bản mà họ cam kết vào SVN.

Chúng tôi muốn triển khai một máy chủ phát triển tích hợp liên tục sẽ luôn chạy mã cam kết mới nhất. Nếu chúng ta làm điều đó ngay bây giờ, nó sẽ tải lại cơ sở dữ liệu từ SVN cho mỗi bản dựng.

Chúng tôi có một máy chủ thử nghiệm (ảo) chạy "phát hành ứng viên". Triển khai đến máy chủ thử nghiệm hiện là một quy trình rất thủ công và thường liên quan đến việc tôi tải SQL mới nhất từ ​​SVN và điều chỉnh nó. Ngoài ra, dữ liệu trên máy chủ thử nghiệm không nhất quán. Bạn kết thúc với bất kỳ dữ liệu thử nghiệm nào mà nhà phát triển cuối cùng cam kết có trên máy chủ hộp cát của mình.

Nơi mọi thứ đổ vỡ là việc triển khai để sản xuất. Vì chúng ta không thể ghi đè dữ liệu trực tiếp bằng dữ liệu thử nghiệm, điều này liên quan đến việc tạo lại thủ công tất cả các thay đổi lược đồ. Nếu có một số lượng lớn các thay đổi lược đồ hoặc tập lệnh chuyển đổi để thao tác dữ liệu, điều này có thể thực sự có lông.

Nếu vấn đề chỉ là lược đồ, thì đó sẽ là một vấn đề dễ dàng hơn, nhưng có dữ liệu "cơ sở" trong cơ sở dữ liệu cũng được cập nhật trong quá trình phát triển, chẳng hạn như dữ liệu meta trong bảng bảo mật và quyền.

Đây là rào cản lớn nhất mà tôi thấy trong việc tiến tới tích hợp liên tục và xây dựng một bước. Làm thế nào để bạn giải quyết nó?


Một câu hỏi tiếp theo: làm thế nào để bạn theo dõi các phiên bản cơ sở dữ liệu để bạn biết tập lệnh nào sẽ chạy để nâng cấp một thể hiện cơ sở dữ liệu đã cho? Là một bảng phiên bản như Lance đề cập dưới quy trình chuẩn?


Cảm ơn bạn đã tham khảo Tarantino. Tôi không ở trong môi trường .NET, nhưng tôi thấy trang wiki DataBaseChangeMangement của họ rất hữu ích. Đặc biệt là bản trình bày Powerpoint này (.ppt)

Tôi sẽ viết một tập lệnh Python để kiểm tra tên của *.sqlcác tập lệnh trong một thư mục đã cho dựa vào một bảng trong cơ sở dữ liệu và chạy các tập lệnh không có theo thứ tự dựa trên một số nguyên tạo thành phần đầu tiên của tên tệp. Nếu đó là một giải pháp khá đơn giản, như tôi nghi ngờ nó sẽ có, thì tôi sẽ đăng nó ở đây.


Tôi đã có một kịch bản làm việc cho điều này. Nó xử lý việc khởi tạo DB nếu nó không tồn tại và chạy các kịch bản nâng cấp khi cần thiết. Ngoài ra còn có các công tắc để xóa một cơ sở dữ liệu hiện có và nhập dữ liệu thử nghiệm từ một tệp. Đó là khoảng 200 dòng, vì vậy tôi sẽ không đăng nó (mặc dù tôi có thể đưa nó lên pastebin nếu có hứng thú).



"Tôi sẽ viết một tập lệnh Python kiểm tra tên của các tập lệnh * .sql trong một thư mục đã cho dựa vào bảng trong cơ sở dữ liệu và chạy các tập lệnh không có theo thứ tự dựa trên một số nguyên tạo thành phần đầu tiên của tên tệp. Nếu đó là một giải pháp khá đơn giản, như tôi nghi ngờ nó sẽ như vậy, thì tôi sẽ đăng nó ở đây. " Âm thanh như bạn đang thực hiện đường bay.
masterxilo

Câu trả lời:


53

Có một vài lựa chọn tốt. Tôi sẽ không sử dụng chiến lược "khôi phục bản sao lưu".

  1. Tập lệnh tất cả các thay đổi lược đồ của bạn và để máy chủ CI của bạn chạy các tập lệnh đó trên cơ sở dữ liệu. Có bảng phiên bản để theo dõi phiên bản cơ sở dữ liệu hiện tại và chỉ thực thi các tập lệnh nếu chúng dành cho phiên bản mới hơn.

  2. Sử dụng giải pháp di chuyển. Các giải pháp này thay đổi theo ngôn ngữ, nhưng đối với .NET tôi sử dụng Migrator.NET. Điều này cho phép bạn phiên bản cơ sở dữ liệu của bạn và di chuyển lên xuống giữa các phiên bản. Lược đồ của bạn được chỉ định trong mã C #.


28

Các nhà phát triển của bạn cần viết các kịch bản thay đổi (lược đồ và thay đổi dữ liệu) cho từng lỗi / tính năng mà họ làm việc, không chỉ đơn giản là đổ toàn bộ cơ sở dữ liệu vào kiểm soát nguồn. Các tập lệnh này sẽ nâng cấp cơ sở dữ liệu sản xuất hiện tại lên phiên bản mới đang được phát triển.

Quá trình xây dựng của bạn có thể khôi phục một bản sao của cơ sở dữ liệu sản xuất vào một môi trường thích hợp và chạy tất cả các tập lệnh từ kiểm soát nguồn trên đó, nó sẽ cập nhật cơ sở dữ liệu lên phiên bản hiện tại. Chúng tôi làm điều này hàng ngày để đảm bảo tất cả các tập lệnh chạy chính xác.


13

Hãy xem cách Ruby on Rails thực hiện điều này.

Đầu tiên có cái gọi là các tệp di chuyển, về cơ bản chuyển đổi lược đồ cơ sở dữ liệu và dữ liệu từ phiên bản N sang phiên bản N + 1 (hoặc trong trường hợp hạ cấp từ phiên bản N + 1 xuống N). Cơ sở dữ liệu có bảng cho biết phiên bản hiện tại.

Cơ sở dữ liệu kiểm tra luôn bị xóa sạch trước khi kiểm tra đơn vị và được điền dữ liệu cố định từ các tệp.


10

Cuốn sách Tái cấu trúc cơ sở dữ liệu: Thiết kế cơ sở dữ liệu tiến hóa có thể cung cấp cho bạn một số ý tưởng về cách quản lý cơ sở dữ liệu. Phiên bản ngắn cũng có thể đọc được tại http://martinfowler.com/articles/evodb.html

Trong một dự án PHP + MySQL tôi đã có số sửa đổi cơ sở dữ liệu được lưu trữ trong cơ sở dữ liệu và khi chương trình kết nối với cơ sở dữ liệu, trước tiên nó sẽ kiểm tra sửa đổi. Nếu chương trình yêu cầu sửa đổi khác, nó sẽ mở một trang để nâng cấp cơ sở dữ liệu. Mỗi nâng cấp được chỉ định trong mã PHP, sẽ thay đổi lược đồ cơ sở dữ liệu và di chuyển tất cả dữ liệu hiện có.


5
  • Đặt tên cho cơ sở dữ liệu của bạn như sau - dev_<<db>> , tst_<<db>> , stg_<<db>> , prd_<<db>>(Rõ ràng là bạn không bao giờ nên mã hóa tên db
  • Do đó, bạn có thể triển khai ngay cả các loại db khác nhau trên cùng một máy chủ vật lý (tôi không khuyến nghị điều đó, nhưng bạn có thể phải ... nếu tài nguyên eo hẹp)
  • Đảm bảo bạn sẽ có thể di chuyển dữ liệu giữa các dữ liệu đó một cách tự động
  • Tách các tập lệnh tạo db khỏi dân số = Luôn luôn có thể tạo lại db từ đầu và điền vào nó (từ phiên bản db cũ hoặc nguồn dữ liệu ngoài
  • không sử dụng các chuỗi kết nối mã cứng trong mã (thậm chí không có trong các tệp cấu hình) - sử dụng trong các mẫu chuỗi kết nối tệp cấu hình mà bạn thực hiện tự động, mỗi cấu hình lại của application_layer cần biên dịch lại là BAD
  • hãy sử dụng phiên bản cơ sở dữ liệu và phiên bản đối tượng db - nếu bạn có đủ khả năng thì nó sẽ sử dụng các sản phẩm đã sẵn sàng, nếu không tự mình phát triển một cái gì đó
  • theo dõi từng thay đổi DDL và lưu nó vào một số bảng lịch sử ( ví dụ ở đây )
  • Sao lưu HÀNG NGÀY! Kiểm tra xem bạn có thể khôi phục thứ gì đó bị mất từ ​​bản sao lưu nhanh đến mức nào (sử dụng tập lệnh khôi phục tự động
  • ngay cả cơ sở dữ liệu DEV của bạn và SẢN PHẨM cũng có cùng một kịch bản tạo, bạn sẽ gặp vấn đề với dữ liệu, vì vậy hãy cho phép các nhà phát triển tạo bản sao chính xác của prod và chơi với nó (Tôi biết tôi sẽ nhận được các lỗi cho cái này, nhưng thay đổi trong tư duy và quy trình kinh doanh sẽ khiến bạn tốn ít tiền hơn khi shit gặp fan - vì vậy, buộc các lập trình viên phải đăng ký hợp pháp bất cứ điều gì họ làm, nhưng hãy đảm bảo điều này

Điểm cuối cùng thực sự là tâm trạng. Nếu cần thiết, nó cho thấy định nghĩa của dự án bị phá vỡ. Phát triển phải dẫn trước khi sản xuất. Nếu dữ liệu sản xuất gây ra tác dụng phụ, nó cho thấy vấn đề lớn hơn. Làm sạch dữ liệu sản xuất. Cũng làm rõ bước cuối cùng với nhân viên bảo vệ dữ liệu, nếu có lý do - như bạn đề xuất - rằng dữ liệu trực tiếp phải có trên các hệ thống phát triển, hãy kiểm tra xem điều này có được áp dụng hợp pháp không. Ngoài ra một bản sao chính xác của dữ liệu sản xuất làm chậm sự phát triển và tích hợp ở một mức độ lớn. Hãy xem xét một quá trình ít tốn kém hơn nếu bạn không đủ khả năng sang trọng như vậy.
hakre

Vấn đề là trong quá trình phát triển, thậm chí không thể hình dung được tất cả các trường hợp góc trong luồng điều khiển và các biến đổi về chất lượng dữ liệu sẽ xảy ra trong sản xuất. Nếu bạn đang ở trong một tập đoàn lớn như vậy, để có các vấn đề pháp lý cho vấn đề đó hơn là một loại giải pháp xáo trộn và / hoặc che giấu dữ liệu phải được thực hiện, điều này làm tăng thêm lớp phức tạp, nhưng nó vẫn phải bảo vệ các khía cạnh chất lượng dữ liệu gây ra lỗi ở nơi đầu tiên dù sao ...
Yordan Georgiev

4

Đây là điều mà tôi liên tục không hài lòng - giải pháp của chúng tôi cho vấn đề này. Trong vài năm, chúng tôi đã duy trì một kịch bản thay đổi riêng cho mỗi bản phát hành. Kịch bản này sẽ chứa các đồng bằng từ bản phát hành sản xuất cuối cùng. Với mỗi lần phát hành ứng dụng, số phiên bản sẽ tăng lên, đưa ra một cái gì đó như sau:

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

Điều này hoạt động đủ tốt cho đến khi chúng tôi bắt đầu duy trì hai dòng phát triển: Trunk / Mainline cho phát triển mới và một nhánh bảo trì để sửa lỗi, cải tiến ngắn hạn, v.v ... Chắc chắn, cần phải thay đổi lược đồ trong nhánh. Tại thời điểm này, chúng tôi đã có dbChanges_n + 1.sql trong Trunk, vì vậy chúng tôi đã kết thúc với một sơ đồ như sau:

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

Một lần nữa, điều này hoạt động đủ tốt, cho đến một ngày chúng tôi nhìn lên và thấy 42 tập lệnh delta trong dòng chính và 10 trong chi nhánh. ARGH!

Ngày nay, chúng tôi chỉ cần duy trì một tập lệnh delta và để SVN phiên bản nó - tức là chúng tôi ghi đè lên tập lệnh với mỗi bản phát hành. Và chúng tôi né tránh thực hiện thay đổi lược đồ trong các chi nhánh.

Vì vậy, tôi cũng không hài lòng với điều này. Tôi thực sự thích khái niệm di chuyển từ Rails. Tôi đã trở nên khá say mê với LiquiBase . Nó hỗ trợ khái niệm tái cấu trúc cơ sở dữ liệu gia tăng. Nó đáng để xem và tôi sẽ sớm xem xét chi tiết. Bất cứ ai có kinh nghiệm với nó? Tôi rất tò mò muốn nghe về kết quả của bạn.


4

Bạn cũng có thể xem xét bằng cách sử dụng một công cụ như SQL So sánh với tập lệnh về sự khác biệt giữa các phiên bản khác nhau của cơ sở dữ liệu, cho phép bạn nhanh chóng di chuyển giữa các phiên bản


3

Chúng tôi có một thiết lập rất giống với OP.

Các nhà phát triển phát triển trong VM với DB riêng.

[Nhà phát triển sẽ sớm tham gia vào các chi nhánh tư nhân]

Kiểm tra được chạy trên các máy khác nhau (thực tế là trong máy chủ VM được lưu trữ trên máy chủ) [Sẽ sớm được chạy bởi máy chủ Hudson CI]

Kiểm tra bằng cách tải kết xuất tham chiếu vào db. Áp dụng các bản vá lược đồ nhà phát triển, sau đó áp dụng các bản vá dữ liệu của nhà phát triển

Sau đó chạy thử nghiệm đơn vị và hệ thống.

Sản xuất được triển khai cho khách hàng như người cài đặt.

Chúng ta làm gì:

Chúng tôi lấy một lược đồ kết xuất DB hộp cát của chúng tôi. Sau đó một bãi chứa dữ liệu sql. Chúng tôi khác với đường cơ sở trước. cặp deltas đó là để nâng cấp n-1 lên n.

chúng tôi cấu hình các bãi và deltas.

Vì vậy, để cài đặt phiên bản N SẠCH, chúng tôi chạy kết xuất vào một db trống. Để vá, áp dụng các bản vá can thiệp.

(Juha đã đề cập đến ý tưởng của Rail về việc có một bảng ghi phiên bản DB hiện tại là một bảng tốt và sẽ giúp việc cài đặt các bản cập nhật ít gặp khó khăn hơn.)

Deltas và bãi phải được xem xét trước khi thử nghiệm beta. Tôi không thể thấy bất kỳ cách nào khác vì tôi đã thấy các nhà phát triển tự chèn tài khoản thử nghiệm vào DB.


3

Tôi sợ tôi đồng ý với các áp phích khác. Các nhà phát triển cần kịch bản thay đổi của họ.

Trong nhiều trường hợp, ALTER TABLE đơn giản sẽ không hoạt động, bạn cũng cần sửa đổi dữ liệu hiện có - nhà phát triển cần phải biết điều gì về việc di chuyển được yêu cầu và đảm bảo rằng chúng được viết chính xác (dĩ nhiên bạn cần kiểm tra kỹ điều này tại một số điểm chu kỳ phát hành).

Hơn nữa, nếu bạn có bất kỳ ý nghĩa nào, bạn cũng sẽ khiến các nhà phát triển của mình quay lại kịch bản cho những thay đổi của họ để họ có thể được hoàn nguyên nếu cần. Điều này cũng nên được kiểm tra, để đảm bảo rằng việc khôi phục của họ không chỉ thực hiện mà không có lỗi, mà còn khiến DB ở trạng thái như trước đây (điều này không phải lúc nào cũng có thể hoặc mong muốn, nhưng hầu hết thời gian là một quy tắc tốt) .

Làm thế nào bạn móc nó vào một máy chủ CI, tôi không biết. Có lẽ máy chủ CI của bạn cần phải có ảnh chụp nhanh xây dựng đã biết, nó sẽ hoàn nguyên vào mỗi đêm và sau đó áp dụng tất cả các thay đổi kể từ đó. Điều đó có lẽ là tốt nhất, nếu không, một kịch bản di chuyển bị hỏng sẽ phá vỡ không chỉ bản dựng đêm đó, mà tất cả các bản tiếp theo.


1

Kiểm tra dbdeploy , đã có sẵn các công cụ Java và .net, bạn có thể làm theo các tiêu chuẩn của chúng cho bố cục tệp SQL và bảng phiên bản lược đồ và viết phiên bản python của bạn.


1

Chúng tôi đang sử dụng dòng lệnh mysql-diff : nó tạo ra sự khác biệt giữa hai lược đồ cơ sở dữ liệu (từ DB trực tiếp hoặc tập lệnh) dưới dạng tập lệnh ALTER. mysql-diff được thực thi khi bắt đầu ứng dụng và nếu lược đồ thay đổi, nó sẽ báo cáo cho nhà phát triển. Vì vậy, các nhà phát triển không cần phải viết ALTER bằng tay, các cập nhật lược đồ diễn ra bán tự động.



0

Tôi đã viết một công cụ (bằng cách nối vào Open DBDiff ) so sánh các lược đồ cơ sở dữ liệu và sẽ đề xuất các tập lệnh di chuyển cho bạn. Nếu bạn thực hiện một thay đổi xóa hoặc sửa đổi dữ liệu, nó sẽ gây ra lỗi, nhưng cung cấp một gợi ý cho tập lệnh (ví dụ: khi một cột bị thiếu trong lược đồ mới, nó sẽ kiểm tra xem cột đã được đổi tên và tạo xx - script.sql.suggestion chứa một tuyên bố đổi tên).

http://code.google.com.vn/p/migationscriptgenerator/ SQL Server Tôi chỉ sợ :( Nó cũng khá alpha, nhưng nó có độ ma sát RẤT thấp (đặc biệt nếu bạn kết hợp nó với Tarantino hoặc http://code.google .com / p / simplescriptrunner / )

Cách tôi sử dụng là để có một dự án tập lệnh SQL trong .sln của bạn. Bạn cũng có một cơ sở dữ liệu db_next cục bộ mà bạn thực hiện các thay đổi của mình (sử dụng Management Studio hoặc NHibernate Schema Export hoặc LinqToSql CreateDatabase hoặc một cái gì đó). Sau đó, bạn thực thi Migrationcriptgenerator với các DB _dev và _next, tạo ra. các kịch bản cập nhật SQL để di chuyển qua.


0

Đối với cơ sở dữ liệu oracle chúng tôi sử dụng oracle-ddl2svn các công cụ .

Công cụ này tự động quá trình tiếp theo

  1. cho mỗi lược đồ db lấy ddls lược đồ
  2. đặt nó dưới phiên bản contol

thay đổi giữa các trường hợp được giải quyết bằng tay

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.