Cách tránh tự bắn vào chân mình bằng Liquibase

Chưa bao giờ xảy ra trước đây và chúng ta lại bắt đầu!

Trong dự án tiếp theo, chúng tôi quyết định sử dụng Liquibase ngay từ đầu để tránh các vấn đề trong tương lai. Hóa ra, không phải tất cả thành viên trẻ trong nhóm đều biết cách sử dụng nó một cách chính xác. Tôi đã tổ chức một hội thảo nội bộ và sau đó tôi quyết định đăng nó thành một bài báo.

Bài viết bao gồm các mẹo hữu ích và mô tả về ba cạm bẫy rõ ràng nhất mà bạn có thể gặp phải khi làm việc với các công cụ di chuyển cơ sở dữ liệu quan hệ, đặc biệt là Liquibase. Được thiết kế dành cho các nhà phát triển Java ở cấp độ Sơ cấp và Trung cấp; đối với các nhà phát triển có kinh nghiệm hơn, nó có thể hữu ích cho việc cấu trúc và lặp lại những gì có thể đã được biết đến nhiều nhất.

Cách tránh tự bắn vào chân mình bằng Liquibase

Liquibase và Flyway là những công nghệ cạnh tranh chính để giải quyết các vấn đề kiểm soát phiên bản của các cấu trúc quan hệ trong thế giới Java. Cái đầu tiên hoàn toàn miễn phí, trong thực tế nó thường được chọn để sử dụng nhiều nhất, đó là lý do tại sao Liquibase được chọn làm người hùng của ấn phẩm. Tuy nhiên, một số phương pháp được mô tả có thể phổ biến, tùy thuộc vào kiến ​​trúc ứng dụng của bạn.

Việc di chuyển các cấu trúc quan hệ là một cách bắt buộc để giải quyết tính linh hoạt yếu kém của các kho dữ liệu quan hệ. Trong thời đại OOP, phong cách làm việc với cơ sở dữ liệu có nghĩa là chúng ta sẽ mô tả lược đồ một lần và không chạm vào nó nữa. Nhưng thực tế là mọi thứ luôn thay đổi và việc thay đổi cấu trúc bảng là cần thiết khá thường xuyên. Đương nhiên, quá trình này có thể gây đau đớn và khó chịu.

Tôi sẽ không đi sâu vào mô tả công nghệ và hướng dẫn thêm thư viện vào dự án của bạn; khá nhiều bài viết đã viết về chủ đề này:

Ngoài ra, đã có một bài viết xuất sắc về chủ đề những lời khuyên hữu ích:

Советы

Tôi muốn chia sẻ lời khuyên và nhận xét của mình, những lời khuyên được sinh ra từ mồ hôi, máu và nỗi đau khi giải quyết vấn đề di cư.

1. Trước khi bắt đầu công việc, bạn nên làm quen với phần thực hành tốt nhất trên website chất lỏng

những điều đơn giản nhưng rất quan trọng được mô tả, nếu không sử dụng thư viện có thể làm phức tạp cuộc sống của bạn. Ví dụ: cách tiếp cận phi cấu trúc để quản lý các tập hợp thay đổi sớm hay muộn sẽ dẫn đến sự nhầm lẫn và quá trình di chuyển bị gián đoạn. Nếu bạn không triển khai các thay đổi phụ thuộc lẫn nhau đối với cấu trúc cơ sở dữ liệu và logic dịch vụ cùng một lúc thì có khả năng cao là điều này sẽ dẫn đến các thử nghiệm màu đỏ hoặc môi trường bị hỏng. Ngoài ra, các đề xuất sử dụng Liquibase trên trang web chính thức có chứa một điều khoản về việc phát triển và thử nghiệm các tập lệnh khôi phục cùng với các tập lệnh di chuyển chính. Vâng, trong bài viết https://habr.com/ru/post/178665/ Có các ví dụ về mã liên quan đến việc di chuyển và cơ chế khôi phục.

2. Nếu bạn bắt đầu sử dụng các công cụ di chuyển, không cho phép chỉnh sửa thủ công trong cấu trúc cơ sở dữ liệu

Như người ta vẫn nói: “Một lần Persil, luôn luôn Persil.” Nếu cơ sở ứng dụng của bạn bắt đầu được Liquibase quản lý thì mọi thay đổi thủ công sẽ ngay lập tức dẫn đến trạng thái không nhất quán và mức độ tin cậy vào các tập hợp thay đổi sẽ bằng XNUMX. Rủi ro tiềm ẩn bao gồm mất nhiều giờ để khôi phục cơ sở dữ liệu; trong trường hợp xấu nhất là máy chủ đã chết. Nếu bạn có một Kiến trúc sư DBA “kiểu cũ” trong nhóm của mình, hãy kiên nhẫn và chu đáo giải thích cho anh ấy rằng mọi chuyện sẽ tồi tệ như thế nào nếu anh ấy chỉ chỉnh sửa cơ sở dữ liệu theo sự hiểu biết của chính anh ấy từ một Nhà phát triển SQL có điều kiện.

3. Nếu bộ thay đổi đã được đẩy vào kho lưu trữ, hãy tránh chỉnh sửa

Nếu một nhà phát triển khác thực hiện thao tác kéo và áp dụng một bộ thay đổi mà sau này sẽ được chỉnh sửa, anh ấy chắc chắn sẽ nhớ đến bạn bằng một lời nói tử tế khi gặp lỗi khi khởi động ứng dụng. Nếu việc chỉnh sửa bộ thay đổi bằng cách nào đó bị rò rỉ vào quá trình phát triển, bạn sẽ phải tuân theo độ dốc trơn trượt của các hotfix. Bản chất của vấn đề nằm ở việc xác thực các thay đổi bằng tổng băm - cơ chế chính của Liquibase. Khi chỉnh sửa mã bộ thay đổi, số lượng băm sẽ thay đổi. Chỉ có thể chỉnh sửa các tập thay đổi khi có thể triển khai toàn bộ cơ sở dữ liệu từ đầu mà không làm mất dữ liệu. Trong trường hợp này, việc tái cấu trúc mã SQL hoặc XML, ngược lại, có thể giúp cuộc sống trở nên dễ dàng hơn và khiến quá trình di chuyển dễ đọc hơn. Một ví dụ là tình huống khi bắt đầu ứng dụng, lược đồ của cơ sở dữ liệu nguồn đã được thống nhất trong nhóm.

4. Đã xác minh bản sao lưu cơ sở dữ liệu nếu có thể

Ở đây, tôi nghĩ, mọi thứ đều rõ ràng. Nếu đột nhiên quá trình di chuyển không thành công, mọi thứ có thể được trả lại. Liquibase có một công cụ để khôi phục các thay đổi, nhưng các tập lệnh khôi phục cũng do chính nhà phát triển viết và chúng có thể gặp sự cố với xác suất tương tự như các tập lệnh của bộ thay đổi chính. Điều này có nghĩa là sẽ rất hữu ích nếu đảm bảo an toàn với các bản sao lưu trong mọi trường hợp.

5. Sử dụng các bản sao lưu cơ sở dữ liệu đã được chứng minh trong quá trình phát triển, nếu có thể

Nếu điều này không mâu thuẫn với hợp đồng và quyền riêng tư, thì không có dữ liệu cá nhân trong cơ sở dữ liệu và nó không nặng bằng hai mặt trời - trước khi sử dụng nó trên các máy chủ di chuyển trực tiếp, bạn có thể kiểm tra xem nó sẽ hoạt động như thế nào trên máy của nhà phát triển và tính toán gần như 100% các vấn đề có thể xảy ra trong quá trình di chuyển.

6. Giao tiếp với các nhà phát triển khác trong nhóm

Trong một quá trình phát triển được tổ chức tốt, mọi người trong nhóm đều biết ai đang làm gì. Trên thực tế, điều này thường không xảy ra, do đó, nếu bạn đang chuẩn bị thay đổi cấu trúc cơ sở dữ liệu như một phần nhiệm vụ của mình, bạn nên thông báo thêm cho toàn bộ nhóm về điều này. Nếu ai đó đang thực hiện các thay đổi song song, bạn nên sắp xếp cẩn thận. Bạn nên liên lạc với đồng nghiệp sau khi kết thúc công việc chứ không chỉ khi mới bắt đầu. Nhiều vấn đề tiềm ẩn với các tập thay đổi có thể được giải quyết ở giai đoạn xem xét mã.

7. Hãy nghĩ về việc bạn đang làm!

Nó có vẻ giống như lời khuyên hiển nhiên có thể áp dụng cho mọi tình huống. Tuy nhiên, nhiều vấn đề có thể tránh được nếu nhà phát triển một lần nữa phân tích những gì mình đang làm và những gì nó có thể ảnh hưởng. Làm việc với quá trình di chuyển luôn đòi hỏi sự chú ý và độ chính xác cao hơn.

bẫy

Bây giờ chúng ta hãy xem những cái bẫy điển hình mà bạn có thể rơi vào nếu không làm theo lời khuyên ở trên, và chính xác thì bạn nên làm gì?

Tình huống 1: Hai nhà phát triển đang cố gắng thêm các bộ thay đổi mới cùng một lúc

Cách tránh tự bắn vào chân mình bằng Liquibase
Vasya và Petya muốn tạo một bộ thay đổi phiên bản 4 mà không biết về nhau. Họ đã thực hiện các thay đổi đối với cấu trúc cơ sở dữ liệu và đưa ra yêu cầu kéo với các tệp bộ thay đổi khác nhau. Cơ chế hoạt động sau đây được đề xuất:

Làm thế nào để quyết định

  1. Bằng cách nào đó, các đồng nghiệp phải đồng ý về thứ tự thực hiện các thay đổi của họ, ví dụ: Petin nên được áp dụng trước.
  2. Ai đó nên thêm cái thứ hai cho mình và đánh dấu bộ thay đổi của Vasya bằng phiên bản 5. Điều này có thể được thực hiện thông qua Cherry Pick hoặc hợp nhất gọn gàng.
  3. Sau khi thay đổi, bạn chắc chắn nên kiểm tra tính hợp lệ của các hành động được thực hiện.
    Trên thực tế, cơ chế Liquibase sẽ cho phép bạn có hai bộ thay đổi phiên bản 4 trong kho lưu trữ, vì vậy bạn có thể giữ nguyên mọi thứ. Nghĩa là, bạn sẽ chỉ có hai thay đổi đối với phiên bản 4 với các tên khác nhau. Với cách tiếp cận này, việc điều hướng các phiên bản cơ sở dữ liệu sau này trở nên rất khó khăn.

Ngoài ra, Liquibase, giống như ngôi nhà của người hobbit, còn ẩn chứa nhiều bí mật. Một trong số đó là khóa validCheckSum, xuất hiện trong phiên bản 1.7 và cho phép bạn chỉ định giá trị băm hợp lệ cho một tập hợp thay đổi cụ thể, bất kể nội dung nào được lưu trữ trong cơ sở dữ liệu. Tài liệu https://www.liquibase.org/documentation/changeset.html nói như sau:

Thêm tổng kiểm tra được coi là hợp lệ cho Bộ thay đổi này, bất kể nội dung nào được lưu trữ trong cơ sở dữ liệu. Được sử dụng chủ yếu khi bạn cần thay đổi một ChangeSet và không muốn xuất hiện lỗi trên cơ sở dữ liệu mà nó đã chạy (không phải quy trình được đề xuất)

Có, vâng, thủ tục này không được khuyến khích. Nhưng đôi khi một pháp sư ánh sáng mạnh mẽ cũng thành thạo các kỹ thuật bóng tối

Tình huống 2: Di chuyển phụ thuộc vào dữ liệu

Cách tránh tự bắn vào chân mình bằng Liquibase

Giả sử bạn không có khả năng sử dụng bản sao lưu cơ sở dữ liệu từ máy chủ trực tiếp. Petya đã tạo một bộ thay đổi, thử nghiệm nó cục bộ và hoàn toàn tin tưởng rằng mình đã đúng, đưa ra yêu cầu kéo tới nhà phát triển. Để đề phòng, trưởng dự án làm rõ liệu Petya đã kiểm tra chưa, rồi bổ sung vào. Nhưng việc triển khai trên máy chủ phát triển đã giảm.

Trên thực tế, điều này là có thể xảy ra và không ai tránh khỏi điều này. Điều này xảy ra nếu việc sửa đổi cấu trúc bảng bằng cách nào đó được gắn với dữ liệu cụ thể từ cơ sở dữ liệu. Rõ ràng, nếu cơ sở dữ liệu của Petya chỉ chứa dữ liệu thử nghiệm thì nó có thể không bao gồm tất cả các trường hợp có vấn đề. Ví dụ: khi xóa một bảng, hóa ra có các bản ghi trong các bảng khác bằng Khóa ngoại có liên quan đến các bản ghi trong bảng bị xóa. Hoặc khi thay đổi kiểu cột thì không phải 100% dữ liệu đều chuyển được sang kiểu mới.

Làm thế nào để quyết định

  • Viết các tập lệnh đặc biệt sẽ được sử dụng một lần trong quá trình di chuyển và đưa dữ liệu về dạng thích hợp. Đây là cách chung để giải quyết vấn đề chuyển dữ liệu sang cấu trúc mới sau khi áp dụng di chuyển, nhưng có thể áp dụng cách tương tự trước đó, trong các trường hợp đặc biệt. Tất nhiên, đường dẫn này không phải lúc nào cũng có sẵn vì việc chỉnh sửa dữ liệu trên máy chủ trực tiếp có thể nguy hiểm và thậm chí có tính phá hoại.
  • Một cách khó khăn khác là chỉnh sửa một bộ thay đổi hiện có. Khó khăn là tất cả các cơ sở dữ liệu đã được áp dụng ở dạng hiện có sẽ phải được khôi phục. Rất có thể toàn bộ nhóm phụ trợ sẽ buộc phải triển khai cơ sở dữ liệu cục bộ từ đầu.
  • Và cách phổ biến nhất là chuyển vấn đề với dữ liệu sang môi trường của nhà phát triển, tạo lại tình huống tương tự và thêm một bộ thay đổi mới vào bộ thay đổi bị hỏng, điều này sẽ tránh được sự cố.
    Cách tránh tự bắn vào chân mình bằng Liquibase

Nói chung, cơ sở dữ liệu càng có cấu trúc tương tự với cơ sở dữ liệu máy chủ sản xuất thì càng ít có khả năng xảy ra sự cố di chuyển. Và tất nhiên, trước khi gửi một tập hợp thay đổi đến kho lưu trữ, bạn nên suy nghĩ kỹ xem liệu nó có làm hỏng bất kỳ thứ gì hay không.

Tình huống 3. Liquibase bắt đầu được sử dụng sau khi đi vào sản xuất

Giả sử trưởng nhóm yêu cầu Petya đưa Liquibase vào dự án, nhưng dự án đã được sản xuất và có cấu trúc cơ sở dữ liệu hiện có.

Theo đó, vấn đề là trên bất kỳ máy chủ hoặc máy phát triển mới nào, các bảng này phải được tạo lại từ đầu và môi trường hiện tại phải duy trì trạng thái nhất quán, sẵn sàng chấp nhận các thay đổi mới.

Làm thế nào để quyết định

Ngoài ra còn có một số cách:

  • Điều đầu tiên và rõ ràng nhất là phải có một tập lệnh riêng phải được áp dụng thủ công khi khởi tạo môi trường mới.
  • Cách thứ hai ít rõ ràng hơn, hãy thực hiện di chuyển Liquibase trong Bối cảnh Liquibase khác và áp dụng nó. Bạn có thể đọc thêm về Bối cảnh Liquibase tại đây: https://www.liquibase.org/documentation/contexts.html. Nói chung, đây là một cơ chế thú vị có thể được sử dụng thành công, chẳng hạn như để thử nghiệm.
  • Con đường thứ ba bao gồm một số bước. Đầu tiên, việc di chuyển phải được tạo cho các bảng hiện có. Sau đó, nó phải được áp dụng cho một số môi trường và do đó sẽ thu được tổng băm của nó. Bước tiếp theo là khởi tạo các bảng Liquibase trống trên máy chủ không trống của chúng tôi và trong bảng có lịch sử sử dụng các bộ thay đổi, bạn có thể đặt bản ghi theo cách thủ công về bộ thay đổi “như thể được áp dụng” với những thay đổi đã tồn tại trong cơ sở dữ liệu . Do đó, trên máy chủ hiện có, việc đếm ngược lịch sử sẽ bắt đầu từ phiên bản 2 và tất cả các môi trường mới sẽ hoạt động giống hệt nhau.
    Cách tránh tự bắn vào chân mình bằng Liquibase

Tình huống 4. Việc di chuyển trở nên lớn và không có thời gian để hoàn thành

Theo quy định, khi bắt đầu phát triển dịch vụ, Liquibase được sử dụng như một phần phụ thuộc bên ngoài và tất cả quá trình di chuyển đều được xử lý khi ứng dụng khởi động. Tuy nhiên, theo thời gian, bạn có thể gặp phải những trường hợp sau:

  • Việc di chuyển trở nên lớn và mất nhiều thời gian để hoàn thành.
  • Cần phải di chuyển trong các môi trường phân tán, chẳng hạn như trên một số phiên bản máy chủ cơ sở dữ liệu cùng một lúc.
    Trong trường hợp này, việc áp dụng di chuyển quá lâu sẽ dẫn đến hết thời gian chờ khi ứng dụng khởi động. Ngoài ra, việc áp dụng di chuyển cho từng phiên bản ứng dụng riêng biệt có thể khiến các máy chủ khác nhau không đồng bộ.

Làm thế nào để quyết định

Trong những trường hợp như vậy, dự án của bạn đã lớn, thậm chí có thể là dành cho người lớn và Liquibase bắt đầu hoạt động như một công cụ bên ngoài riêng biệt. Thực tế là Liquibase với tư cách là một thư viện được biên dịch thành tệp jar và có thể hoạt động như một phần phụ thuộc trong một dự án hoặc độc lập.

Ở chế độ độc lập, bạn có thể giao việc triển khai di chuyển sang môi trường CI/CD của mình hoặc cho quản trị viên hệ thống và chuyên gia triển khai của bạn đảm nhiệm. Để làm điều này, bạn sẽ cần dòng lệnh Liquibase https://www.liquibase.org/documentation/command_line.html. Ở chế độ này, có thể khởi chạy ứng dụng sau khi tất cả các quá trình di chuyển cần thiết đã được thực hiện.

Đầu ra

Trên thực tế, có thể có nhiều cạm bẫy hơn khi làm việc với việc di chuyển cơ sở dữ liệu và nhiều cạm bẫy trong số đó đòi hỏi một cách tiếp cận sáng tạo. Điều quan trọng là phải hiểu rằng nếu bạn sử dụng công cụ này một cách chính xác, bạn có thể tránh được hầu hết những cạm bẫy này. Cụ thể, tôi đã phải giải quyết tất cả các vấn đề được liệt kê dưới nhiều hình thức khác nhau và một số trong số đó là kết quả từ những sai lầm của tôi. Tất nhiên, phần lớn điều này xảy ra do thiếu chú ý, nhưng đôi khi do tội phạm không thể sử dụng công cụ này.

Nguồn: www.habr.com

Thêm một lời nhận xét