Trước khi cố gắng thực hiện bất kỳ thay đổi lược đồ nào trên cơ sở dữ liệu sản xuất của mình, bạn nên đảm bảo rằng bạn có một kế hoạch khôi phục vững chắc; và quy trình thay đổi của bạn đã được thử nghiệm và xác thực thành công trong một môi trường riêng biệt. Đồng thời, bạn có trách nhiệm đảm bảo rằng thay đổi không gây ra hoặc ít tác động nhất có thể có thể chấp nhận được đối với doanh nghiệp. Đó chắc chắn không phải là một nhiệm vụ dễ dàng.
Trong bài viết này, chúng ta sẽ xem xét cách thực hiện các thay đổi cơ sở dữ liệu trên MySQL và MariaDB theo cách có kiểm soát. Chúng tôi sẽ nói về một số thói quen tốt trong công việc DBA hàng ngày của bạn. Chúng tôi sẽ tập trung vào các yêu cầu và nhiệm vụ trước trong quá trình hoạt động thực tế và các vấn đề mà bạn có thể gặp phải khi xử lý các thay đổi giản đồ cơ sở dữ liệu. Chúng tôi cũng sẽ nói về các công cụ nguồn mở có thể giúp bạn trong quá trình này.
Kịch bản kiểm tra và khôi phục
Sao lưu
Có nhiều cách để mất dữ liệu của bạn. Lỗi nâng cấp lược đồ là một trong số đó. Không giống như mã ứng dụng, bạn không thể bỏ một nhóm tệp và tuyên bố rằng một phiên bản mới đã được triển khai thành công. Bạn cũng không thể chỉ đặt lại một bộ tệp cũ hơn để khôi phục các thay đổi của mình. Tất nhiên, bạn có thể chạy một tập lệnh SQL khác để thay đổi lại cơ sở dữ liệu, nhưng có những trường hợp cách chính xác duy nhất để khôi phục các thay đổi là khôi phục toàn bộ cơ sở dữ liệu từ bản sao lưu.
Tuy nhiên, điều gì sẽ xảy ra nếu bạn không đủ khả năng khôi phục cơ sở dữ liệu của mình về bản sao lưu mới nhất hoặc thời lượng bảo trì của bạn không đủ lớn (xem xét hiệu suất hệ thống), vì vậy bạn không thể thực hiện sao lưu toàn bộ cơ sở dữ liệu trước khi thay đổi?
Người ta có thể có một môi trường phức tạp, dư thừa, nhưng miễn là dữ liệu được sửa đổi ở cả vị trí chính và vị trí chờ, thì không có nhiều việc phải làm. Nhiều tập lệnh chỉ có thể chạy một lần hoặc không thể hoàn tác các thay đổi. Hầu hết mã thay đổi SQL được chia thành hai nhóm:
- Chạy một lần - bạn không thể thêm cùng một cột vào bảng hai lần.
- Không thể hoàn tác - khi bạn đã bỏ cột đó, cột đó sẽ biến mất. Không nghi ngờ gì nữa, bạn có thể khôi phục cơ sở dữ liệu của mình, nhưng đó không chính xác là hành động hoàn tác.
Bạn có thể giải quyết vấn đề này bằng ít nhất hai cách có thể. Một là kích hoạt nhật ký nhị phân và sao lưu, tương thích với PITR. Bản sao lưu đó phải đầy đủ, hoàn chỉnh và nhất quán. Đối với xtrabackup, miễn là nó chứa tập dữ liệu đầy đủ, nó sẽ tương thích với PITR. Đối với mysqldump, có một tùy chọn để làm cho nó tương thích với PITR. Đối với những thay đổi nhỏ hơn, một biến thể của sao lưu mysqldump sẽ là chỉ lấy một tập dữ liệu con để thay đổi. Điều này có thể được thực hiện với tùy chọn --where. Bản sao lưu phải là một phần của bảo trì theo kế hoạch.
mysqldump -u -p --lock-all-tables --where="WHERE employee_id=100" mydb employees> backup_table_tmp_change_07132018.sql
Một khả năng khác là sử dụng TẠO BẢNG NHƯ CHỌN.
Bạn có thể lưu trữ dữ liệu hoặc các thay đổi cấu trúc đơn giản dưới dạng một bảng tạm thời cố định. Với cách tiếp cận này, bạn sẽ nhận được một nguồn nếu bạn cần khôi phục các thay đổi của mình. Nó có thể khá hữu ích nếu bạn không thay đổi nhiều dữ liệu. Việc khôi phục có thể được thực hiện bằng cách lấy dữ liệu ra khỏi nó. Nếu có bất kỳ lỗi nào xảy ra khi sao chép dữ liệu vào bảng, dữ liệu đó sẽ tự động bị xóa và không được tạo, vì vậy hãy đảm bảo rằng câu lệnh của bạn tạo ra một bản sao bạn cần.
Rõ ràng, cũng có một số hạn chế.
Vì thứ tự của các hàng trong các câu lệnh SELECT bên dưới không phải lúc nào cũng có thể được xác định, CREATE TABLE ... BỎ QUA CHỌN VÀ TẠO BẢNG ... REPLACE SELECT bị gắn cờ là không an toàn cho việc sao chép dựa trên câu lệnh. Các câu lệnh như vậy tạo ra cảnh báo trong nhật ký lỗi khi sử dụng chế độ dựa trên câu lệnh và được ghi vào nhật ký nhị phân bằng định dạng dựa trên hàng khi sử dụng chế độ MIXED.
Một ví dụ rất đơn giản của phương pháp này có thể là:
CREATE TABLE tmp_employees_change_07132018 AS SELECT * FROM employees where employee_id=100;
UPDATE employees SET salary=120000 WHERE employee_id=100;
COMMMIT;
Một tùy chọn thú vị khác có thể là cơ sở dữ liệu hồi tưởng MariaDB. Khi một lần cập nhật hoặc xóa sai xảy ra và bạn muốn hoàn nguyên về trạng thái của cơ sở dữ liệu (hoặc chỉ một bảng) tại một thời điểm nhất định, bạn có thể sử dụng tính năng hồi tưởng.
Khôi phục điểm trong thời gian cho phép DBA khôi phục dữ liệu nhanh hơn bằng cách khôi phục các giao dịch về thời điểm trước đó thay vì thực hiện khôi phục từ bản sao lưu. Dựa trên các sự kiện DML dựa trên ROW, hồi tưởng có thể chuyển đổi nhật ký nhị phân và đảo ngược các mục đích. Điều đó có nghĩa là nó có thể giúp hoàn tác các thay đổi hàng nhất định một cách nhanh chóng. Ví dụ, nó có thể thay đổi các sự kiện DELETE thành INSERT và ngược lại, và nó sẽ hoán đổi các phần WHERE và SET của các sự kiện UPDATE. Ý tưởng đơn giản này có thể tăng tốc độ khôi phục đáng kể sau một số loại sai lầm hoặc thảm họa. Đối với những người đã quen thuộc với cơ sở dữ liệu Oracle, đó là một tính năng nổi tiếng. Hạn chế của hồi tưởng MariaDB là thiếu hỗ trợ DDL.
Tạo Nô lệ sao chép bị trì hoãn
Kể từ phiên bản 5.6, MySQL hỗ trợ sao chép bị trì hoãn. Máy chủ phụ có thể tụt hậu so với máy chủ ít nhất trong một khoảng thời gian nhất định. Độ trễ mặc định là 0 giây. Sử dụng tùy chọn MASTER_DELAY cho CHANGE MASTER TO để đặt độ trễ thành N giây:
CHANGE MASTER TO MASTER_DELAY = N;
Sẽ là một lựa chọn tốt nếu bạn không có thời gian để chuẩn bị một tình huống khôi phục thích hợp. Bạn cần có đủ độ trễ để nhận thấy sự thay đổi có vấn đề. Ưu điểm của phương pháp này là bạn không cần khôi phục cơ sở dữ liệu của mình để lấy ra dữ liệu cần thiết để sửa chữa thay đổi của bạn. DB ở chế độ chờ đang hoạt động, sẵn sàng thu thập dữ liệu, giảm thiểu thời gian cần thiết.
Tạo một nô lệ không đồng bộ không phải là một phần của cụm
Khi nói đến cụm Galera, việc thử nghiệm các thay đổi không hề đơn giản. Tất cả các nút chạy cùng một dữ liệu và tải nặng có thể gây hại cho việc kiểm soát luồng. Vì vậy, bạn không chỉ cần kiểm tra xem các thay đổi có được áp dụng thành công hay không mà còn cả tác động đến trạng thái cụm. Để làm cho quy trình thử nghiệm của bạn gần với khối lượng công việc sản xuất nhất có thể, bạn có thể muốn thêm một nô lệ không đồng bộ vào cụm của mình và chạy thử nghiệm của bạn ở đó. Việc kiểm tra sẽ không ảnh hưởng đến việc đồng bộ hóa giữa các nút trong cụm, vì về mặt kỹ thuật, nó không phải là một phần của cụm, nhưng bạn sẽ có tùy chọn để kiểm tra bằng dữ liệu thực. Có thể dễ dàng thêm nô lệ như vậy từ ClusterControl.
ClusterControl thêm nô lệ không đồng bộNhư được hiển thị trong ảnh chụp màn hình ở trên, ClusterControl có thể tự động hóa quá trình thêm nô lệ không đồng bộ theo một số cách. Bạn có thể thêm nút vào cụm, trì hoãn nô lệ. Để giảm tác động đến bản chính, bạn có thể sử dụng bản sao lưu hiện có thay vì bản chính làm nguồn dữ liệu khi xây dựng trang phụ.
Cơ sở dữ liệu nhân bản và đo thời gian
Một thử nghiệm tốt phải càng gần với sự thay đổi sản xuất càng tốt. Cách tốt nhất để làm điều này là sao chép môi trường hiện có của bạn.
Cụm sao chép ClusterControl để thử nghiệmThực hiện thay đổi thông qua sao chép
Để kiểm soát tốt hơn các thay đổi của mình, bạn có thể áp dụng chúng trên máy chủ phụ trước thời hạn và sau đó thực hiện chuyển đổi. Đối với sao chép dựa trên câu lệnh, điều này hoạt động tốt, nhưng đối với sao chép dựa trên hàng, điều này có thể hoạt động ở một mức độ nhất định. Sao chép dựa trên hàng cho phép các cột thừa tồn tại ở cuối bảng, vì vậy, miễn là nó có thể viết các cột đầu tiên là được. Đầu tiên hãy áp dụng các cài đặt này cho tất cả các nô lệ, sau đó chuyển đổi dự phòng cho một trong các nô lệ và sau đó thực hiện thay đổi cho chủ và đính kèm đó làm nô lệ. Nếu sửa đổi của bạn liên quan đến việc chèn hoặc xóa một cột ở giữa bảng, thì sửa đổi đó sẽ hoạt động với tính năng sao chép dựa trên hàng.
Hoạt động
Trong cửa sổ bảo trì, chúng tôi không muốn có lưu lượng ứng dụng trên cơ sở dữ liệu. Đôi khi rất khó để tắt tất cả các ứng dụng trên toàn công ty. Ngoài ra, chúng tôi muốn chỉ cho phép một số máy chủ cụ thể truy cập MySQL từ xa (ví dụ:hệ thống giám sát hoặc máy chủ dự phòng). Với mục đích này, chúng ta có thể sử dụng tính năng lọc gói Linux. Để xem những quy tắc lọc gói nào khả dụng, chúng ta có thể chạy lệnh sau:
iptables -L INPUT -v
Để đóng cổng MySQL trên tất cả các giao diện chúng tôi sử dụng:
iptables -A INPUT -p tcp --dport mysql -j DROP
và để mở lại cổng MySQL sau cửa sổ bảo trì:
iptables -D INPUT -p tcp --dport mysql -j DROP
Đối với những người không có quyền truy cập root, bạn có thể thay đổi max_connection thành 1 hoặc 'bỏ qua mạng'.
Ghi nhật ký
Để bắt đầu quá trình ghi nhật ký, hãy sử dụng lệnh tee tại dấu nhắc máy khách MySQL, như sau:
mysql> tee /tmp/my.out;
Lệnh đó yêu cầu MySQL đăng nhập cả đầu vào và đầu ra của phiên đăng nhập MySQL hiện tại của bạn vào một tệp có tên /tmp/my.out. Sau đó, thực thi tệp kịch bản của bạn bằng lệnh nguồn.
Để biết rõ hơn về thời gian thực hiện của mình, bạn có thể kết hợp nó với tính năng trình biên dịch. Bắt đầu trình biên dịch bằng
SET profiling = 1;
Sau đó, thực hiện Truy vấn của bạn với
SHOW PROFILES;
bạn sẽ thấy danh sách các truy vấn mà trình biên dịch có thống kê. Vì vậy, cuối cùng, bạn chọn truy vấn để kiểm tra
SHOW PROFILE FOR QUERY 1;
Công cụ di chuyển giản đồ
Nhiều khi không thể thực hiện ALTER trực tiếp trên máy chủ - hầu hết các trường hợp, nó gây ra độ trễ trên máy tớ và điều này có thể không được các ứng dụng chấp nhận. Tuy nhiên, điều có thể làm là thực hiện thay đổi trong chế độ luân phiên. Bạn có thể bắt đầu với nô lệ và sau khi thay đổi được áp dụng cho nô lệ, hãy di chuyển một trong các nô lệ làm chủ mới, giáng cấp chủ cũ thành nô lệ và thực hiện thay đổi trên đó.
Một công cụ có thể giúp thực hiện nhiệm vụ như vậy là pt-online-schema-change của Percona. Pt-online-schema-change rất đơn giản - nó tạo một bảng tạm thời với lược đồ mới mong muốn (ví dụ:nếu chúng tôi đã thêm chỉ mục hoặc xóa một cột khỏi bảng). Sau đó, nó tạo ra các trình kích hoạt trên bảng cũ. Những trình kích hoạt đó ở đó để phản chiếu những thay đổi xảy ra trên bảng ban đầu sang bảng mới. Các thay đổi được phản ánh trong quá trình thay đổi giản đồ. Nếu một hàng được thêm vào bảng ban đầu, thì hàng đó cũng được thêm vào bảng mới. Nó mô phỏng cách mà MySQL thay đổi các bảng trong nội bộ, nhưng nó hoạt động trên một bản sao của bảng mà bạn muốn thay đổi. Có nghĩa là bảng gốc không bị khóa và máy khách có thể tiếp tục đọc và thay đổi dữ liệu trong đó.
Tương tự như vậy, nếu một hàng được sửa đổi hoặc xóa trên bảng cũ, thì hàng đó cũng được áp dụng trong bảng mới. Sau đó, quá trình sao chép dữ liệu nền (sử dụng LOW_PRIORITY INSERT) giữa bảng cũ và bảng mới bắt đầu. Sau khi dữ liệu đã được sao chép, RENAME TABLE sẽ được thực thi.
Một công cụ hấp dẫn khác là gh-ost. Gh-ost tạo một bảng tạm thời với lược đồ đã thay đổi, giống như pt-online-schema-change đã làm. Nó thực hiện các truy vấn CHÈN, sử dụng mẫu sau để sao chép dữ liệu từ bảng cũ sang bảng mới. Tuy nhiên, nó không sử dụng trình kích hoạt. Thật không may, các tác nhân kích hoạt có thể là nguồn gốc của nhiều hạn chế. gh-ost sử dụng luồng nhật ký nhị phân để nắm bắt các thay đổi của bảng và áp dụng chúng vào bảng ma một cách không đồng bộ. Sau khi chúng tôi xác minh rằng gh-ost có thể thực hiện thay đổi giản đồ của chúng tôi một cách chính xác, đã đến lúc thực thi nó. Hãy nhớ rằng bạn có thể cần phải loại bỏ các bảng cũ được tạo bởi gh-ost theo cách thủ công trong quá trình kiểm tra quá trình di chuyển. Bạn cũng có thể sử dụng cờ --initially-drop-ghost-table và --initially-drop-old-table để yêu cầu gh-ost làm điều đó cho bạn. Lệnh cuối cùng để thực thi giống hệt như chúng tôi đã sử dụng để kiểm tra sự thay đổi của mình, chúng tôi chỉ thêm --execute vào đó.
pt-online-schema-change và gh-ost rất phổ biến đối với người dùng Galera. Tuy nhiên, Galera có một số tùy chọn bổ sung. Hai phương pháp Tổng cách ly đơn hàng (TOI) và Nâng cấp giản đồ cuộn (RSU) đều có ưu và nhược điểm của chúng.
TOI - Đây là phương pháp sao chép DDL mặc định. Nút khởi tạo tập ghi phát hiện DDL tại thời điểm phân tích cú pháp và gửi một sự kiện sao chép cho câu lệnh SQL trước khi bắt đầu xử lý DDL. Nâng cấp lược đồ chạy trên tất cả các nút cụm trong cùng một trình tự thứ tự tổng thể, ngăn các giao dịch khác cam kết trong suốt thời gian hoạt động. Phương pháp này phù hợp khi bạn muốn các bản nâng cấp giản đồ trực tuyến của mình tái tạo thông qua cụm và đừng ngại khóa toàn bộ bảng (tương tự như cách các thay đổi lược đồ mặc định đã xảy ra trong MySQL).
SET GLOBAL wsrep_OSU_method='TOI';
RSU - chỉnh sửa lược đồ nâng cấp cục bộ. Trong phương pháp này, việc ghi của bạn chỉ ảnh hưởng đến nút mà chúng được chạy. Các thay đổi không sao chép sang phần còn lại của cụm. Phương pháp này phù hợp với các hoạt động không xung đột và nó sẽ không làm chậm cụm.
SET GLOBAL wsrep_OSU_method='RSU';
Trong khi nút xử lý nâng cấp giản đồ, nó sẽ giải đồng bộ hóa với cụm. Khi hoàn tất quá trình nâng cấp giản đồ, nó áp dụng các sự kiện sao chép bị trì hoãn và tự đồng bộ hóa với cụm. Đây có thể là một lựa chọn tốt để chạy các tác phẩm có chỉ mục nặng.
Kết luận
Chúng tôi đã trình bày ở đây một số phương pháp khác nhau có thể giúp bạn lập kế hoạch thay đổi giản đồ của mình. Tất nhiên tất cả phụ thuộc vào ứng dụng và yêu cầu kinh doanh của bạn. Bạn có thể thiết kế kế hoạch thay đổi của mình, thực hiện các thử nghiệm cần thiết, nhưng vẫn có khả năng nhỏ xảy ra sự cố. Theo định luật Murphy - “mọi thứ sẽ trở nên sai trái trong bất kỳ tình huống nhất định nào, nếu bạn cho họ cơ hội”. Vì vậy, hãy đảm bảo bạn đã thử các cách khác nhau để thực hiện những thay đổi này và chọn cách bạn cảm thấy hài lòng nhất.