Sửa đổi các cột của các bảng mysql rất lớn với ít hoặc không có thời gian chết


18

Tôi định kỳ cần thực hiện các thay đổi đối với các bảng trong mysql 5.1, chủ yếu là thêm các cột. Rất đơn giản với lệnh bảng thay đổi. Nhưng các bảng của tôi hiện có tới 40 triệu hàng và chúng đang tăng nhanh ... Vì vậy, các lệnh bảng thay đổi đó mất vài giờ. Vài tháng nữa họ sẽ đoán.

Vì tôi đang sử dụng amazon RDS, tôi không thể có máy chủ nô lệ để chơi và sau đó quảng bá để thành thạo. Vì vậy, câu hỏi của tôi là nếu có một cách để làm điều này với thời gian chết tối thiểu? Tôi không ngại một hoạt động mất hàng giờ hoặc thậm chí vài ngày nếu người dùng vẫn có thể sử dụng db tất nhiên ... Ít nhất họ có thể đọc trong khi các cột được thêm vào không? Điều gì xảy ra nếu ứng dụng của tôi cố gắng viết? Chèn hay cập nhật? Nếu nó thất bại ngay lập tức thì điều đó thực sự không tệ lắm, nếu nó bị treo và gây ra sự cố cho máy chủ db thì đó là một vấn đề lớn ..

Đây phải là một vấn đề mở rộng khá phổ biến, mọi người cần thêm các cột .. Điều gì thường được thực hiện cho một db sản xuất? Nô lệ -> di cư chủ?

Cập nhật - Tôi quên đề cập đến việc tôi đang sử dụng công cụ lưu trữ innodb


1
Trong trường hợp ai đó vẫn đang tìm kiếm một câu trả lời .. blog.staginginstance.com/ Kẻ ^^
ẩn danh

Câu trả lời:


10

Tôi định kỳ cần thực hiện các thay đổi đối với các bảng trong mysql 5.1, chủ yếu là thêm các cột.

Đừng. Không thực sự. Chỉ cần không. Nó phải là một dịp rất hiếm khi điều này là bao giờ cần thiết.

Giả sử dữ liệu của bạn thực sự được chuẩn hóa để bắt đầu, cách đúng để giải quyết vấn đề là thêm một bảng mới có mối quan hệ 1: 1 vào bảng cơ sở (không bắt buộc trên bảng mới).

Phải thêm các cột thường xuyên thường là một chỉ báo của cơ sở dữ liệu không được chuẩn hóa - nếu lược đồ của bạn không được chuẩn hóa thì đó là vấn đề bạn cần khắc phục.

Cuối cùng, nếu lược đồ của bạn thực sự, thực sự được chuẩn hóa và bạn thực sự, thực sự phải tiếp tục thêm các cột sau đó:

  1. Đảm bảo bạn đã có một cột dấu thời gian trên cơ sở dữ liệu hoặc nó đang tạo nhật ký sao chép
  2. Tạo một bản sao (B) của bảng (A)
  3. thêm các cột mới vào B (điều này vẫn sẽ chặn với myisam)
  4. vô hiệu hóa giao dịch
  5. đổi tên bảng gốc (A) thành một cái gì đó khác (sao lưu)
  6. đổi tên bảng mới (B) với tên của bảng gốc (A)
  7. phát lại các giao dịch từ khi bắt đầu hoạt động từ nhật ký sao chép hoặc từ bảng sao lưu
  8. cho phép giao dịch.

2
Cảm ơn bạn đã từng bước tiếp cận. Có thực sự không phổ biến để sửa đổi bảng? Tôi hiểu rằng thay vào đó tôi có thể thêm một bảng khác với cột mới (trong trường hợp cần thêm một cột) và để nó tham chiếu bảng lớn ban đầu trong mối quan hệ 1: 1. Nhưng có vẻ không đúng khi có 15 bảng 1: 1 rất lớn khi tất cả chúng đều nằm trong 1 bảng ... Tất nhiên, hiệu năng truy vấn cũng bị ảnh hưởng, không đề cập đến các vấn đề lập chỉ mục. Tôi không phải là chuyên gia, nhưng cơ sở dữ liệu của tôi được chuẩn hóa khá tốt và có vẻ như tôi cần phải sửa đổi định kỳ ..
apptree

2
"Có thực sự không phổ biến để sửa đổi các bảng?" - Vâng.
symcbean

1
Không, nhưng người ta có thể lập luận rằng nếu điều đó xảy ra THƯỜNG XUYÊN - không phải là một phần của nâng cấp phần mềm lớn - thì ai đó cần phải bị sa thải vì không nhận ra rằng tất cả các bảng nên ở đó ngay từ đầu. Vấn đề / mánh khóe ở đây là "thường xuyên", không phải "Một vài tháng một lần".
TomTom

22
Là một nhà phát triển, đặc biệt là một công ty hoạt động trong các công ty mới thành lập và công ty trẻ, tôi không thể đồng ý ít hơn với symcbean và @TomTom. Mọi thứ thay đổi, sản phẩm thay đổi, mục tiêu kinh doanh thay đổi và cấu trúc cơ sở dữ liệu cần thay đổi theo chúng. Cung cấp dịch vụ DBA tốt có nghĩa là nói "có" với những thay đổi đó, sau đó tìm ra cách thực hiện chúng một cách hiệu quả. Cơ sở dữ liệu bình thường hóa nặng nề là một khái niệm đã chết từ lâu. Họ dẫn đến hiệu suất xấu và chu kỳ dev chậm.
p9090

4
Không phổ biến để thay đổi bảng ??? Có thể trong các công ty lớn, nhưng trong đội ngũ nhanh nhẹn xảy ra khá thường xuyên, các yêu cầu thay đổi ...
tibo

12

Tôi chỉ phải làm điều này gần đây. Những gì Amazon khuyến nghị là sử dụng Bộ công cụ Percona. Tôi đã tải xuống và có thể chạy một cái gì đó như:

./pt-online-schema-change h=databasenameHostName,D=databasename,t=tablename --recursion-method=none --execute --user username --password password --alter "MODIFY someColumn newDataType"

và nó hoạt động rất tốt. Nó cho bạn biết bao nhiêu thời gian còn lại trong quá trình.

Nó thực sự tạo ra một bảng mới với cột mới và sau đó sao chép dữ liệu hiện có. Hơn nữa, nó tạo ra một kích hoạt để dữ liệu mới cũng được đẩy sang bảng mới. Sau đó, nó đổi tên các bảng một cách tự động, bỏ bảng cũ và bạn đang chạy và chạy với cột mới và không có thời gian chết trong khi bạn chờ đợi các bản cập nhật.


Nhóm Percona có một bài viết ngắn về việc kích hoạt tính năng log_bin_trust_feft_creators, thông qua các nhóm tham số RDS (như SET GLOBAL log_bin_trust_feft_creators = 1 không hoạt động trên RDS), được yêu cầu bởi công cụ thay đổi lược đồ pt-online. Thêm chi tiết: percona.com/blog/2016/07/01/pt-online-schema-change-amazon-rds
user1652110

nó làm việc cho tôi
Adiii

4

symcbean cung cấp một số khuyến nghị vững chắc .

Để trả lời câu hỏi của bạn, cách dễ nhất và tốt nhất để giảm thiểu tác động là nhân rộng nhiều cơ sở dữ liệu. Dual master với một thủ tục chuyển đổi dự phòng thích hợp dừng sao chép trên hoạt động, cho phép thay đổi trên không hoạt động mà không ảnh hưởng đến hoạt động.

Bạn có khả năng có thể làm điều này trên một cơ sở dữ liệu trực tiếp duy nhất và giảm thiểu tác động bằng cách sử dụng một quy trình tương tự như quy trình tôi đã nêu chi tiết trong câu trả lời này . Phải thừa nhận rằng, điều này tương tự như những gì symcbean đã mô tả nhưng bao gồm các chi tiết kỹ thuật. Bạn cũng có thể sử dụng trường auto_increment chứ không chỉ dấu thời gian.

Cuối cùng, nếu tập dữ liệu của bạn đang phát triển quá lớn, bạn cũng cần xem xét việc lưu trữ giữa cơ sở dữ liệu OLTPOLAP . Tập dữ liệu giao dịch của bạn không cần quá lớn, nếu bạn thiết kế phù hợp.


2

Từ hướng dẫn: http://dev.mysql.com/doc/refman/5.1/en/alter-table.html

Trong hầu hết các trường hợp, ALTER TABLE tạo một bản sao tạm thời của bảng gốc. MySQL kết hợp việc thay đổi thành bản sao, sau đó xóa bảng gốc và đổi tên bảng mới. Trong khi ALTER TABLE đang thực thi, bảng gốc có thể đọc được bởi các phiên khác. Các cập nhật và ghi vào bảng bị đình trệ cho đến khi bảng mới sẵn sàng và sau đó được tự động chuyển hướng đến bảng mới mà không có bất kỳ cập nhật thất bại nào.

Vì vậy, đọc sẽ làm việc tốt. Các bài viết sẽ bị đình trệ, nhưng được thực hiện sau đó. Nếu bạn muốn ngăn chặn điều này, bạn sẽ phải sửa đổi phần mềm của mình.


Vì vậy, tôi đã làm điều này và vô hiệu hóa các phần của trang web của tôi ghi vào bảng mà tôi đang sửa đổi ngay bây giờ. Cho đến nay tôi đã nhận được một số ngoại lệ "Khóa thời gian chờ vượt quá; hãy thử khởi động lại giao dịch", điều đó không quá tệ. Tuy nhiên, họ đã ở trên PURELY đọc các hoạt động ...
apptree

0

Tôi đang ở trong tình huống tương tự khi tôi phải thay đổi 1 bảng giao dịch gần 65GB. Tôi nghe 2 giải pháp

  1. Sử dụng thẳng về phía trước và để cho nó chạy (X số giờ hoặc ngày)
  2. Đảm bảo bạn đã có một cột dấu thời gian trên cơ sở dữ liệu hoặc nó đang tạo nhật ký sao chép
    • Tạo một bản sao (B) của bảng (A)
    • thêm các cột mới vào B (điều này vẫn sẽ chặn với myisam)
    • vô hiệu hóa giao dịch
    • đổi tên bảng gốc (A) thành một cái gì đó khác (sao lưu)
    • đổi tên bảng mới (B) với tên của bảng gốc (A)
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.