Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Tạo một chỉ mục trên một bảng sản xuất MySQL khổng lồ mà không cần khóa bảng

[2017] Cập nhật:MySQL 5.6 hỗ trợ cập nhật chỉ mục trực tuyến

https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html#online-ddl-index-syntax-notes

Trong MySQL 5.6 trở lên, bảng vẫn có sẵn cho các hoạt động đọc và ghi trong khi chỉ mục đang được tạo hoặc xóa. Câu lệnh CREATE INDEX hoặc DROP INDEX chỉ kết thúc sau khi hoàn tất tất cả các giao dịch đang truy cập vào bảng, để trạng thái ban đầu của chỉ mục phản ánh nội dung gần đây nhất của bảng. Trước đây, việc sửa đổi bảng trong khi một chỉ mục đang được tạo hoặc bị xóa thường dẫn đến bế tắc hủy bỏ câu lệnh INSERT, UPDATE hoặc DELETE trên bảng.

[2015] Cập nhật các khối chỉ báo bảng ghi trong MySQL 5.5

Từ câu trả lời trên:

"Nếu bạn đang sử dụng phiên bản lớn hơn 5.1 chỉ số được tạo trong khi cơ sở dữ liệu trực tuyến. Vì vậy, đừng lo lắng, bạn sẽ không làm gián đoạn việc sử dụng hệ thống sản xuất."

Đây là **** FALSE **** (ít nhất là đối với bảng MyISAM / InnoDB, đây là thứ mà 99,999% người ngoài kia sử dụng. Phiên bản Clustered thì khác.)

Thực hiện các thao tác CẬP NHẬT trên bảng sẽ CHẶN trong khi chỉ mục đang được tạo. MySQL thực sự, thực sự ngu ngốc về điều này (và một số thứ khác).

Tập lệnh thử nghiệm:

(   
  for n in {1..50}; do
    #(time mysql -uroot -e 'select  * from website_development.users where id = 41225\G'>/dev/null) 2>&1 | grep real;
    (time mysql -uroot -e 'update website_development.users set bio="" where id = 41225\G'>/dev/null) 2>&1 | grep real;
  done
) | cat -n &
PID=$!
sleep 0.05
echo "Index Update - START"
mysql -uroot website_development -e 'alter table users add index ddopsonfu (last_name, email, first_name, confirmation_token, current_sign_in_ip);'
echo "Index Update - FINISH"
sleep 0.05
kill $PID
time mysql -uroot website_development -e 'drop index ddopsonfu on users;'

Máy chủ của tôi (InnoDB):

Server version: 5.5.25a Source distribution

Đầu ra (lưu ý cách khối hoạt động thứ 6 trong ~ 400ms cần để hoàn thành cập nhật chỉ mục):

 1  real    0m0.009s
 2  real    0m0.009s
 3  real    0m0.009s
 4  real    0m0.012s
 5  real    0m0.009s
Index Update - START
Index Update - FINISH
 6  real    0m0.388s
 7  real    0m0.009s
 8  real    0m0.009s
 9  real    0m0.009s
10  real    0m0.009s
11  real    0m0.009s

Vs các thao tác đọc không chặn (hoán đổi chú thích dòng trong tập lệnh):

 1  real    0m0.010s
 2  real    0m0.009s
 3  real    0m0.009s
 4  real    0m0.010s
 5  real    0m0.009s
Index Update - START
 6  real    0m0.010s
 7  real    0m0.010s
 8  real    0m0.011s
 9  real    0m0.010s
...
41  real    0m0.009s
42  real    0m0.010s
43  real    0m0.009s
Index Update - FINISH
44  real    0m0.012s
45  real    0m0.009s
46  real    0m0.009s
47  real    0m0.010s
48  real    0m0.009s

Cập nhật Lược đồ của MySQL mà không có thời gian chết

Do đó, chỉ có một phương pháp mà tôi biết để cập nhật một lược đồ MySql và không bị ngừng hoạt động. Bản gốc vòng tròn:

  • Master A có cơ sở dữ liệu MySQL của bạn đang chạy trên đó
  • Đưa Master B vào hoạt động và để nó sao chép các ghi từ Master A (B là nô lệ của A)
  • Thực hiện cập nhật giản đồ trên Master B. Nó sẽ bị trễ trong quá trình nâng cấp
  • Để Master B bắt kịp. Bất biến:Thay đổi giản đồ của bạn PHẢI có khả năng xử lý các lệnh được sao chép từ một lược đồ phiên bản xuống. Các thay đổi lập chỉ mục đủ điều kiện. Các bổ sung cột đơn giản thường đủ điều kiện. Xóa một cột? chắc là không.
  • ATOMICALLY hoán đổi tất cả các ứng dụng khách từ Master A sang Master B. Nếu bạn muốn an toàn (tin tôi đi, bạn tin tưởng), bạn nên đảm bảo rằng bản ghi cuối cùng cho A được sao chép thành B TRƯỚC B viết đầu tiên. Nếu bạn cho phép ghi đồng thời lên 2+ bậc thầy, ... thì bạn hiểu rõ hơn về việc sao chép MySQL ở mức DEEP hoặc bạn đang hướng tới một thế giới đau khổ. Đau đớn tột cùng. Như bạn có chuyên mục là AUTOINCREMENT ??? bạn đang gặp khó khăn (trừ khi bạn sử dụng số chẵn trên một tổng thể và tỷ lệ cược trên phương thức khác). KHÔNG tin tưởng sao chép MySQL để "làm điều đúng". Nó KHÔNG thông minh và sẽ không cứu bạn. Nó chỉ kém an toàn hơn một chút so với việc sao chép nhật ký giao dịch nhị phân từ dòng lệnh và phát lại chúng bằng tay. Tuy nhiên, việc ngắt kết nối tất cả các máy khách khỏi máy chủ cũ và chuyển chúng sang máy chủ mới có thể được thực hiện trong vài giây, nhanh hơn rất nhiều so với việc chờ đợi bản nâng cấp giản đồ kéo dài nhiều giờ.
  • Bây giờ Master B là master mới của bạn. Bạn có lược đồ mới. Cuộc sống là tốt. Uống một ly bia; điều tồi tệ nhất đã qua.
  • Lặp lại quy trình với Master A, nâng cấp giản đồ của anh ấy để anh ấy trở thành master phụ mới của bạn, sẵn sàng tiếp quản trong trường hợp master chính của bạn (master B bây giờ) mất điện hoặc vừa lên và chết vì bạn.

Đây không phải là một cách dễ dàng để cập nhật lược đồ. Làm việc được trong môi trường sản xuất nghiêm túc; Vâng, đúng vậy. Làm ơn, làm ơn, làm ơn, nếu có cách dễ dàng hơn để thêm chỉ mục vào bảng MySQL mà không chặn ghi, hãy cho tôi biết.

Googling dẫn tôi đến bài viết này trong đó mô tả một kỹ thuật tương tự. Thậm chí tốt hơn, họ khuyên bạn nên uống cùng một thời điểm trong quá trình tiến hành (Lưu ý rằng tôi đã viết câu trả lời của mình trước khi đọc bài báo)!

pt-online-schema-change của Percona

bài viết Tôi đã liên kết ở trên nói về một công cụ, pt -online-schema-change , hoạt động như sau:

  • Tạo bảng mới với cấu trúc giống như bảng gốc.
  • Cập nhật giản đồ trên bảng mới.
  • Thêm trình kích hoạt trên bảng gốc để các thay đổi được giữ đồng bộ với bản sao
  • Sao chép hàng loạt hàng từ bảng gốc.
  • Di chuyển bảng gốc ra khỏi chỗ trống và thay thế bằng bảng mới.
  • Bỏ bảng cũ.

Tôi chưa bao giờ tự mình thử công cụ. YMMV

RDS

Tôi hiện đang sử dụng MySQL thông qua RDS của Amazon . Đó là một dịch vụ thực sự tiện lợi bao bọc và quản lý MySQL, cho phép bạn thêm các bản sao đã đọc mới chỉ với một nút duy nhất và nâng cấp cơ sở dữ liệu một cách minh bạch trên SKU phần cứng. Nó thực sự tiện lợi. Bạn không có quyền truy cập SUPER vào cơ sở dữ liệu, vì vậy bạn không thể bắt chước trực tiếp với việc sao chép (đây là một phước lành hay lời nguyền?). Tuy nhiên, bạn có thể sử dụng Đọc Quảng cáo bản sao để thực hiện các thay đổi giản đồ của bạn trên một nô lệ chỉ đọc, sau đó thăng cấp cho nô lệ đó trở thành chủ nhân mới của bạn. Chính xác là thủ thuật giống như tôi đã mô tả ở trên, chỉ là dễ thực hiện hơn rất nhiều. Họ vẫn không giúp được gì nhiều cho bạn. Bạn phải định cấu hình lại và khởi động lại ứng dụng của mình.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Giới thiệu về tính khả dụng cao của cơ sở dữ liệu cho MySQL &MariaDB

  2. Cách lưu trữ ảnh trong cơ sở dữ liệu MySQL

  3. Lỗi nghiêm trọng:Gọi đến hàm không xác định mysqli_result ()

  4. Hướng dẫn thiết kế cơ sở dữ liệu cho bản tin trong MySQL

  5. SQL - NẾU TỒN TẠI CẬP NHẬT ELSE INSERT INTO