Bảng thay đổi trên cơ sở dữ liệu sản xuất trực tiếp


24

Làm thế nào để hầu hết hệ thống cơ sở dữ liệu "phổ biến" (MySQL, Postgres ...) xử lý các bảng thay đổi trên cơ sở dữ liệu sản xuất trực tiếp (như thêm, xóa hoặc thay đổi loại colums)?

Tôi biết cách chính xác là sao lưu mọi thời gian ngừng hoạt động và thực hiện sau đó thực hiện các thay đổi.

Nhưng ... có bất kỳ hệ thống cơ sở dữ liệu hiện tại nào hỗ trợ thực hiện những việc này "trực tuyến" mà không dừng lại không? (có thể chỉ trì hoãn các truy vấn tham chiếu một cột vừa được thay đổi / xóa)

Và điều gì xảy ra khi tôi chỉ làm một ALTER TABLE...cơ sở dữ liệu đang chạy? Có phải mọi thứ dừng lại khi điều này xảy ra? Dữ liệu có thể bị hỏng? v.v.

Một lần nữa, tôi chủ yếu đề cập đến Postgres hoặc MySQL vì đây là những gì tôi gặp phải.

(Và, vâng, bất cứ lúc nào tôi phải làm điều này trước khi tôi thực hiện "đúng cách", sao lưu mọi thứ, lên lịch trình, v.v ... nhưng tôi chỉ muốn biết liệu có thể thực hiện loại này và mọi thứ "nhanh chóng không bẩn "hoặc nếu có bất kỳ hệ thống DB nào thực sự hỗ trợ thay đổi lược đồ" nhanh, sống và bẩn ")


Ai đó chỉ đề xuất Thay đổi lược đồ trực tuyến cho MySQL từ tập lệnh Facebook (có hướng dẫn ở đây và nguồn ở đây ) ... có vẻ như là một cách hay để tự động hóa một bộ các cách "hacky" để thực hiện ... có ai đã từng sử dụng nó trong một cái gì đó tương tự sản xuất?


3
Lưu ý: "cách chính xác" được chỉ định có liên quan đến MySQL và không phải với PostgreSQL. "Cách chính xác" trong PostgreSQL thường rất dễ dàng, mặc dù nó có thể được tham gia. Sử dụng pg_reorgcó thể giúp với các kịch bản khó khăn hơn.
Sean

Tôi rất thích có một video chi tiết về điều này, với ai đó giải thích càng nhiều chiến lược càng tốt.
Sandeepan Nath

Câu trả lời:


22

Khi bạn phát hành một ALTER TABLEPostgreSQL, nó sẽ ACCESS EXCLUSIVEkhóa một khóa chặn mọi thứ bao gồmSELECT . Tuy nhiên, khóa này có thể được tóm tắt khá nếu bảng không yêu cầu viết lại, không mới UNIQUE, CHECKhoặc FOREIGN KEYnhững hạn chế cần phải tốn kém quét toàn bảng để xác minh, vv

Nếu nghi ngờ, bạn thường chỉ có thể thử nó! Tất cả DDL trong PostgreSQL là giao dịch, do đó, việc hủy bỏ ALTER TABLEnếu mất quá nhiều thời gian và bắt đầu giữ các truy vấn khác là khá tốt . Các mức khóa được yêu cầu bởi các lệnh khác nhau được ghi lại trong trang khóa .

Một số hoạt động chậm thông thường có thể được tăng tốc để an toàn để thực hiện mà không có thời gian chết. Ví dụ: nếu bạn có bảng tvà bạn muốn thay đổi cột customercode integer NOT NULLthành textvì khách hàng đã quyết định tất cả các mã khách hàng phải bắt đầu bằng một X, bạn có thể viết:

ALTER TABLE t ALTER COLUMN customercode TYPE text USING ( 'X'||customercode::text );

... nhưng điều đó sẽ khóa toàn bộ bảng để viết lại. Vì vậy, thêm một cột với một DEFAULT. Nó có thể được thực hiện trong một vài bước để tránh khóa dài, nhưng các ứng dụng phải có khả năng đối phó với sự trùng lặp tạm thời:

ALTER TABLE t ADD COLUMN customercode_new text;
BEGIN;
LOCK TABLE t IN EXCLUSIVE MODE;
UPDATE t SET customercode_new = 'X'||customercode::text;
ALTER TABLE t DROP COLUMN customercode;
ALTER TABLE t RENAME COLUMN customercode_new TO customercode;
COMMIT;

Điều này sẽ chỉ ngăn chặn ghi vào ttrong quá trình; tên khóa EXCLUSIVEcó phần lừa đảo ở chỗ nó loại trừ mọi thứ trừSELECT ; các ACCESS EXCLUSIVEchế độ là người duy nhất mà không bao gồm hoàn toàn everyting. Xem các chế độ khóa . Có nguy cơ rằng thao tác này có thể bị bế tắc do nâng cấp khóa theo yêu cầu ALTER TABLE, nhưng tệ nhất là bạn sẽ phải thực hiện lại.

Bạn thậm chí có thể tránh khóa đó và thực hiện toàn bộ hoạt động bằng cách tạo một hàm kích hoạt trên tđó bất cứ khi nào một INSERThoặc UPDATEđi vào, tự động cư trú customercode_newtừ đó customercode.

Ngoài ra còn có các công cụ tích hợp như CREATE INDEX CONCURRENTLYALTER TABLE ... ADD table_constraint_using_indexđược thiết kế để cho phép các DBA giảm thời lượng khóa độc quyền bằng cách thực hiện công việc chậm hơn theo cách thân thiện đồng thời.

Công pg_reorgcụ này hoặc công cụ kế thừa của nó pg_repackcũng có thể được sử dụng cho một số hoạt động tái cấu trúc bảng.


1
Điều quan trọng trong những gì @Craig nói là "nếu nó không yêu cầu viết lại." Sử dụng an ALTER TABLE t ADD COLUMN i INTlà thao tác nhanh (thường <1ms) sau khi có được khóa. Tuy nhiên, việc có được khóa có thể xếp hàng các kết nối, do đó, nó không "miễn phí" ... mặc dù thế giới này tốt hơn những gì bạn phải làm trong MySQL. Thêm một NOT NULLràng buộc là khó khăn hơn và không dành cho trái tim.
Sean

Nó có vẻ là sự đồng thuận pg_repacklà sự kế thừa được cải thiện pg_reorg.
Erwin Brandstetter

Câu trả lời hay, liên quan đến việc thêm một cột với mặc định (hoặc được tính toán) một cách ít "chặn" hơn là tạo toàn bộ bảng mới, chặn bảng cũ để chèn / cập nhật / xóa nhưng cho phép chọn và điền vào bảng mới. Cuối cùng, phát hành một khóa độc quyền ngắn gọn trên bảng cũ để chọn, xóa nó và đổi tên mới thành cũ. Tùy thuộc vào kịch bản của bạn, bạn thậm chí có thể bắt đầu điền vào cái mới mà không chặn chèn vào cái cũ và phát hành khóa độc quyền đó trong khi giải quyết khác biệt (hy vọng chỉ cần chèn một vài bản ghi mới)
jean

7

Percona đã đưa ra công cụ riêng để thực hiện các thay đổi lược đồ trực tuyến

Công cụ này được gọi là pt-online-giản đồ-thay đổi

Nó liên quan đến kích hoạt, vì vậy xin vui lòng đọc tài liệu cẩn thận.

Theo Tài liệu, các hoạt động chính được thực hiện là

  • Kiểm tra vệ sinh
  • Chunk
  • Thay đổi lược đồ trực tuyến
    • Tạo và thay đổi bảng tạm thời
    • Nắm bắt các thay đổi từ bảng này sang bảng tạm thời
    • Sao chép các hàng từ bảng vào bảng tạm thời
    • Đồng bộ hóa bảng và bảng tạm thời
    • Hoán đổi / đổi tên bảng và bảng tạm thời
    • Dọn dẹp

cảm ơn, có vẻ như là một phiên bản "được bán" của phương pháp tiếp cận của Facebook mà tôi có thể tin tưởng hơn ...
NeuronQ

pt-online-giản đồ thay đổi chắc chắn là cách ưa thích để làm điều này nếu bạn đang chạy máy chủ MySQL của riêng bạn. Kể từ Percona Tools 2.2, (đáng buồn thay) họ không hỗ trợ RDS / Aurora trên AWS. pt-online-lược đồ thay đổi chèn một trình kích hoạt trên bảng nguồn để sao chép các hàng (mức độ ưu tiên thấp cho MyISAM) vào bảng_temp đích và thực hiện một khóa thả nhanh và đổi tên ở cuối khi tất cả các hàng được đồng bộ hóa giữa nguồn và đích những cái bàn.
phpguru

6

Tắt hệ thống và thực hiện tất cả các thay đổi cùng một lúc có thể rất rủi ro. Nếu có sự cố xảy ra và thường xuyên xảy ra, không có cách nào dễ dàng quay lại.

Là một nhà phát triển Agile, đôi khi tôi cần phải cấu trúc lại các bảng mà không có bất kỳ thời gian chết nào, vì các bảng đó đang được sửa đổi và đọc từ đó.

Cách tiếp cận sau đây có rủi ro thấp, vì thay đổi được thực hiện trong một số bước có rủi ro thấp rất dễ quay trở lại:

  • Đảm bảo rằng tất cả các mô-đun truy cập vào bảng được bao phủ tốt bằng các kiểm tra tự động.
  • Tạo một bảng mới. Thay đổi tất cả các quy trình sửa đổi bảng cũ, để chúng sửa đổi cả bảng cũ và bảng mới.
  • Di chuyển dữ liệu hiện có vào cấu trúc mới. Thực hiện theo lô nhỏ, để nó không ảnh hưởng nghiêm trọng đến hiệu suất tổng thể trên máy chủ.
  • Xác minh rằng việc di chuyển dữ liệu đã thành công.
  • Chuyển hướng một số quy trình chọn từ bảng cũ sang bảng mới. Sử dụng các kiểm tra tự động để đảm bảo rằng các mô-đun thay đổi vẫn đúng. Hãy chắc chắn rằng hiệu suất của họ là chấp nhận được. Triển khai các thủ tục thay đổi.
  • Lặp lại bước trước cho đến khi tất cả các báo cáo sử dụng bảng mới.
  • Thay đổi các quy trình sửa đổi các bảng để chúng chỉ truy cập vào bảng mới.
  • Lưu trữ bảng cũ và loại bỏ nó khỏi hệ thống.

Chúng tôi đã sử dụng phương pháp này nhiều lần để thay đổi các bảng sản xuất trực tiếp lớn mà không có thời gian chết, không có vấn đề gì cả.


3
tuyệt vời ... nhưng đó chính xác là loại "nỗi đau" mà tôi đang muốn tránh :)
NeuronQ

@NeuronQ " Không có cách nào dễ dàng trở lại " - có trong Postgres: chỉ cần đặt mọi thứ vào một giao dịch và rollbacknếu có gì sai sót.
a_horse_with_no_name

2

Có, nhiều cơ sở dữ liệu hiện đại sẽ cho phép bạn chỉ cần thêm một cột hoặc thay đổi các đặc điểm của một cột, như thêm hoặc xóa nullable.

Nếu bạn đánh rơi một cột, dữ liệu sẽ bị mất, nhưng không có nhiều nỗi sợ tham nhũng.


0

Công cụ Percona sử dụng các trình kích hoạt để hỗ trợ việc thay đổi và nó không hoạt động tốt nếu bảng của bạn đã có các kích hoạt hiện có. Cuối cùng tôi đã phải viết một cái thực sự xử lý tốt các kích hoạt hiện có, vì chúng cực kỳ quan trọng đối với cơ sở dữ liệu của chúng tôi https://github.com/StirlingMarketinggroup/smg-live-alter


-1

Để giải quyết câu hỏi về những gì xảy ra với một ALTER TABLEtuyên bố, nó phụ thuộc vào mức độ thay đổi của bạn. Trong các trường hợp cụ thể, nếu bạn thêm một cột mới, ít nhất là trong MS SQL Server, công cụ sẽ tạo một bản sao tạm thời của bảng, trong khi nó tạo định nghĩa bảng mới, sau đó chèn dữ liệu vào đó. Trong thời gian thay đổi, bảng sẽ không thể truy cập được đối với người dùng.

Một ví dụ về các hoạt động cụ thể cho máy chủ MSSQL có tại đây: http://support.microsoft.com/kb/956176/en-us

Tôi sẽ giả định rằng các RMDB khác có các phương thức tương tự, mặc dù việc triển khai chính xác sẽ là thứ bạn sẽ phải xác minh với tài liệu của nhà cung cấp.


-1 Điều này hoàn toàn sai đối với SQL Server: "Nếu bạn thêm một cột mới, ít nhất là trong MS SQL Server, công cụ sẽ tạo một bản sao tạm thời của bảng, trong khi nó tạo định nghĩa bảng mới, sau đó chèn lại dữ liệu trong đó "
AK

@AlexKuznetsov - Tôi đã tìm ra dòng trước đó, cũng như liên kết với một số trường hợp được liệt kê sẽ làm rõ điều này không phải lúc nào cũng xảy ra. Tôi sửa đổi câu để phản ánh tốt hơn điều này.
SchmitzIT

1
Bạn đang đề cập đến hành vi của GUI, SSMS, chứ không phải hành vi của chính SQL Server. Theo liên kết của bạn, lời khuyên là sử dụng trực tiếp T-SQL để thực hiện các thay đổi DDL. SSMS không phải là một công cụ rất tốt để thay đổi DDL.
AK

@AlexKuznetsov - Tôi đọc bài báo nói rằng có những rủi ro liên quan, nhưng không phải là một sự nản lòng. Dù sao, tôi đã không liên kết bài viết cho bit GUI, nhưng như một dấu hiệu cho thấy một số hoạt động dẫn đến câu lệnh ALTER dẫn đến việc tạo bảng tạm thời do thay đổi cấu trúc dữ liệu cơ bản. Tôi đã không kiểm tra liệu chính xác điều tương tự có được áp dụng khi đưa ra tuyên bố trực tiếp từ T-SQL hay không, nhưng tôi sẽ nghĩ rằng quy trình này khá giống nhau và SL Server thực hiện công việc đằng sau hậu trường.
SchmitzIT

Bạn có thể khởi động Profiler, thực hiện trực tiếp câu lệnh ALTER TABLE và xem điều gì đang xảy ra. Sau đó, bạn có thể thay đổi bảng thông qua hộp thoại và tự mình xem các lệnh đang được thực thi.
AK
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.