Chạy database migration khi deploy - Nên hay không?
deployment
9
deploy
2
code
39
White

Cẩm Huỳnh viết ngày 05/07/2017

Có một thủ pháp thường hay được sử dụng khi deploy app là chạy database migration ngay khi deploy, nhưng liệu đó có phải là một good practice (tam dịch: cách làm tốt) hay không?

Tất nhiên, để đảm bảo tính khách quan, mình giữ lập trường "câu trả lời vẫn luôn là còn tùy", nhưng 99.9999% trường hợp là KHÔNG.

Giả sử ta có một app cần phải đổi tên cột dob của bảng users thành date_of_birth.

Dễ ợt như a ă â đúng không, ta chỉ cần một đoạn code migration như sau.

def change
  rename_column "users", :dob, :date_of_birth
end

Và trong đoạn code trả về cho người dùng.

# trước khi sửa
render_json({id: user.id, date_of_birth: user.dob})

# sau khi sửa
render_json({id: user.id, date_of_birth: user.date_of_birth})

Như đầu đề, ta sẽ chạy migration code cùng lúc với deploy. Có thể nó khá phức tạp tùy theo từng app nhưng chung quy lại gồm 3 bước: a) Kéo code mới từ SCM về b) chạy đoạn code migration ở trên và c) restart lại ứng dụng để áp dụng mã mới.

Vậy thì vấn đề của cách làm trên là ở đâu?

Vấn đề

Có thể bạn sẽ để ý được là ở khoảng thời gian sau b) cho tới khi c) kết thúc, phần API đọc và ghi users của bạn sẽ bị lỗi không ngừng nghỉ với rate là 100%, lý do là vì lúc đó cột dob đã bị gỡ khỏi database nhưng code mới thì chưa được release lên.

Đương nhiên bạn có thể đảo ngược thứ tự giữa b)c) nhưng vấn đề không đổi, cột date_of_birth chưa được tạo.

Là một lập trình viên, đôi lúc bạn sẽ nghĩ là vài giây đó thì thấm tháp vào đâu, nhưng chắc chắn 99.99% đồng nghiệp của bạn đang làm cho bộ phận tiếp nhận phàn nàn từ khách hàng sẽ nghĩ khác, những phần tử trong 0.001% còn lại (ừ thì 1 + 1 = 3) chắc hết chiều hôm đó thôi việc.

Giải pháp

Không có một giải pháp chuẩn nào cho việc này cả nhưng nói một cách hàn lâm thì nguyên tắc chung là (nghĩa bình dân đã thể hiện với công nghệ Quơ Quaise):

Đảm bảo bản deploy hiện tại tương thích với bản deploy trướcĐỪNG CÓ VĂNG LỖI FFS !!!!! ở bất kì thời điểm nào của deploy.

Vậy với vấn đề ở trên (định dùng chữ bài toán nhưng sợ bạn rule keeper ở #random phàn nàn) cách giải quyết là chia thành nhiều bản deploy nhỏ (chú ý mỗi bước sau đây là một bản deploy).

a) tạo ra cột date_of_birth trong bảng users.

b) sửa đoạn code ghi ngày sinh và đoạn code đọc ngày sinh.

## ghi
User.update(user_id, date_of_birth: params[:dob])

## đọc
user = User.read(user_id)
date_of_birth = user.date_of_birth || user.dob
render_json({id: user.id, date_of_birth: date_of_birth)

c) Viết đoạn script migrate tất cả dữ liệu từ dob qua date_of_birth.

d) Xóa đoạn code đọc đi (đừng xóa đoạn viết nếu bạn không muốn đồng nghiệp quay qua hỏi thăm bằng tiếng Đan Mạch).

e) Tạo migration để xóa cột dob.

Kết luận

Quản lý database schema là một vấn đề khó và đòi hỏi sự cẩn thận, tốt nhất là bạn nên đùn công việc này cho người khác nếu có thể (troll đó cơ mà nếu đùn được thì tốt).

Các bước thực hiện có thể sẽ khác nhau tùy trường hợp nhưng ý tưởng cơ bản thì là như trên, bạn có thể xào nấu lại tùy thích.


Lời cuối: Chúc chúng ta không bị banh server và ngủ ngon mỗi đêm.

Bài viết được đăng lại từ hqc.io.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Cẩm Huỳnh

40 bài viết.
336 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
39 9
(Ảnh) Vì sao lại là Bật Đèn? Ai từng đọc qua Tắt Đèn hẳn đã biết tác phẩm được kết thúc bằng tình huống: Buông tay, chị vội choàng dậy, mở cửa...
Cẩm Huỳnh viết 1 năm trước
39 9
White
37 6
Làm thế nào để chỉ với một đoạn text vài trăm ký tự, bạn có thể làm ngốn vài gigabyte bộ nhớ và từ chối dịch vụ của một hệ thống dùng XML? _____ ...
Cẩm Huỳnh viết 4 tháng trước
37 6
White
34 25
Vừa rồi mình vừa tiết kiệm được $5 mỗi tháng sau khi migrate cái (Link) từ Digital Ocean sang Heroku Free Dyno. (Ảnh) Kết quả thật mĩ mãn vì hầu ...
Cẩm Huỳnh viết 12 tháng trước
34 25
Bài viết liên quan
White
2 0
Nhận thấy một số bạn khi pull code về server gặp phải trường hợp như sau. Tiêu Phong deploy lên server nên khi clone code về đã dùng lệnh git clon...
Ôm Boom viết hơn 1 năm trước
2 0
White
34 25
Vừa rồi mình vừa tiết kiệm được $5 mỗi tháng sau khi migrate cái (Link) từ Digital Ocean sang Heroku Free Dyno. (Ảnh) Kết quả thật mĩ mãn vì hầu ...
Cẩm Huỳnh viết 12 tháng trước
34 25
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
40 bài viết.
336 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!