Làm cách nào để chuyển đổi bảng hàng 66.862.521 từ MyISAM sang InnoDB mà không ngoại tuyến trong vài giờ?


18

có thể (và làm thế nào) để chuyển đổi một bảng MyISAM khổng lồ thành InnoDB mà không cần lấy ứng dụng ngoại tuyến. Nó yêu cầu chèn một vài hàng vào bảng đó mỗi giây nhưng có thể tạm dừng nó trong khoảng 2 phút.

Rõ ràng ALTER TABLE ... engine = innodb sẽ không hoạt động. Do đó, tôi đã có kế hoạch tạo một bảng mới với công cụ innodb và sao chép nội dung vào đó. Và cuối cùng, tạm dừng chuỗi nhật ký ứng dụng và RENAME TABLE.

Thật không may, ngay cả việc sao chép theo lô nhỏ 100 hàng cũng tạo ra độ trễ đáng kể sau một thời gian.

Chỉnh sửa : Các hàng hiện tại không bao giờ thay đổi, bảng này được sử dụng để đăng nhập.



3
Vâng, câu hỏi đó là về giảm thiểu thời gian trò chuyện. Tôi không quan tâm nếu các cuộc trò chuyện mất vài ngày hoặc vài tuần. Nhưng nó phải hoạt động ở chế độ nền mà không yêu cầu thời gian xuống của ứng dụng và không tạo ra độ trễ đáng chú ý.
Hendrik Brummermann

Câu trả lời:


15

Tạo một thiết lập Master-Master như sau:

  • Tạo chủ thứ hai, MasterB
  • MasterB hoạt động như nô lệ cho logTable
  • Tạo logTable_newnhư là innodb
  • Chạy INSERT INTO logTable_new SELECT * FROM logTable(psuedocode) trên MasterB, nó sẽ gửi bản sao tới MasterA
  • Khi logTable_newbật MasterA, đồng bộ hóa, trao đổi các bảng

10

Đưa ra các ràng buộc của:

Tôi không quan tâm nếu các cuộc trò chuyện mất vài ngày hoặc vài tuần. Nhưng nó phải hoạt động ở chế độ nền mà không yêu cầu thời gian xuống của ứng dụng và không tạo ra độ trễ đáng chú ý

Khi bạn đang ghi nhật ký, nếu bạn có một số cách tốt để đặt điểm đánh dấu để bạn có thể cho biết bạn bắt đầu quy trình gì, thì bạn có thể áp dụng lại bất kỳ nhật ký nào hoặc ghi nhật ký vào tệp văn bản sau này bạn có thể ăn chúng với LOAD DATA INFILE

Một phần của vấn đề là việc viết theo lô nhỏ hơn có nghĩa là các chỉ mục phải được tính toán lại nhiều lần; tốt hơn hết là bạn nên chạy tất cả cùng một lúc, nhưng điều này có thể gây ra một số độ trễ 'đáng chú ý' trên hệ thống .. nhưng bạn không phải làm điều đó trên máy chủ sản xuất của mình.

  1. Tạm dừng ghi nhật ký hoặc đặt một số điểm đánh dấu để bạn có thể áp dụng lại nhật ký từ thời điểm này sau này.
  2. Sao chép bảng MyISM của bạn sang hệ thống khác
  3. Trên hệ thống khác, tạo bảng InnoDB dưới một tên khác và di chuyển dữ liệu (thậm chí có thể nhanh hơn để kết xuất và sử dụng LOAD DATA INFILE)
  4. Sao chép bảng InnoDB trở lại hệ thống ban đầu
  5. Đặt một điểm đánh dấu khác để ghi nhật ký.
  6. Áp dụng lại tất cả các bản ghi vào bảng mới từ giữa hai điểm đánh dấu cuối cùng.
  7. (lặp lại các bước 5 & 6 nếu bước 6 mất hơn một phút hoặc lâu hơn, cho đến khi chỉ mất vài giây)
  8. Hoán đổi các bảng (đổi tên bảng cũ thành bảng_BACKUP, bảng mới dưới tên của bảng cũ)
  9. Bắt kịp các bản ghi kể từ điểm đánh dấu cuối cùng.

9

Thật không may, ngay cả việc sao chép theo lô nhỏ 100 hàng cũng tạo ra độ trễ đáng kể sau một thời gian.

Bạn có thêm bất kỳ độ trễ nào giữa mỗi đợt hay chỉ là cập nhật các bản cập nhật và chạy từng đợt trực tiếp sau đợt trước?

Nếu vậy, hãy thử kịch bản chuyển đổi bằng ngôn ngữ yêu thích của bạn với nội dung như:

repeat
    copy oldest 100 rows that haven't been copied yet to new table
    sleep for as long as that update took
until there are <100 rows unprocessed
stop logging service
move the last few rows
rename tables
restart logging
delete the old table when you are sure the conversion has worked

Điều này sẽ đảm bảo rằng việc chuyển đổi không chiếm hơn một nửa công suất máy chủ của bạn, thậm chí cho phép chênh lệch tải được áp đặt khi việc sử dụng hệ thống thay đổi theo thời gian.

Hoặc nếu bạn muốn sử dụng càng nhiều thời gian càng tốt khi dịch vụ tương đối nhàn rỗi nhưng bị tắt (có khả năng tạm dừng khá lâu) khi cơ sở dữ liệu cần thực hiện một số công việc cho người dùng, hãy thay thế sleep for as long as the update tookbằng if the server's load is above <upper measure>, sleep for some seconds then check again, loop around the sleep/check until the load drops below <lower measure>. Điều này có nghĩa là nó có thể hấp về phía trước trong thời gian yên tĩnh nhưng sẽ tạm dừng hoàn toàn khi máy chủ đang bận thực hiện khối lượng công việc bình thường. Việc xác định tải sẽ phụ thuộc vào HĐH của bạn - trong Linux và tương tự giá trị trung bình tải trong 1 phút từ /proc/loadavghoặc đầu ra uptimenên làm. <lower measure><upper measure>có thể là cùng một giá trị, mặc dù thông thường trong các điều khiển như thế này có sự khác biệt để quá trình của bạn không bắt đầu sau đó ngay lập tức tạm dừng do việc khởi động lại của chính nó có ảnh hưởng đến biện pháp tải.

Tất nhiên điều này sẽ không hoạt động đối với các bảng nơi các hàng cũ có thể được sửa đổi, nhưng sẽ hoạt động tốt đối với bảng nhật ký như bảng bạn mô tả.

Bạn sẽ muốn bỏ qua sự khôn ngoan thông thường của việc tạo các chỉ mục sau khi điền vào bảng mới trong trường hợp này. Mặc dù điều đó thực sự hiệu quả hơn khi bạn muốn mọi thứ diễn ra nhanh nhất có thể (ảnh hưởng đến phần còn lại của hệ thống bị nguyền rủa), trong trường hợp này bạn không muốn tải trọng lớn vào cuối quá trình như các chỉ mục được tạo hoàn toàn trong một lần vì đây là quá trình bạn không thể tạm dừng khi mọi thứ bận rộn.


4

Có công việc nào như vầy không?

  1. Tạm dừng ghi nhật ký (vì vậy $auto_incrementtrên bảng ghi nhật ký của bạn mytable không thay đổi).
  2. Lưu ý $auto_incrementgiá trị sử dụng SHOW TABLE STATUS LIKE 'mytable'.
  3. CREATE TABLE mytable_new LIKE mytable
  4. ALTER TABLE mytable_new AUTO_INCREMENT=$auto_increment ENGINE=Innodb
  5. RENAME TABLE mytable TO mytable_old, mytable_new TO mytable
  6. Cho phép đăng nhập lại. Bảng Innodb bây giờ sẽ bắt đầu điền.
  7. INSERT INTO mytable SELECT * FROM mytable_old.

Bạn có thể thực hiện bước 7 theo đợt hoặc trong một tuyên bố vì không nên chặn việc ghi nhật ký thông thường.


nó vẫn sẽ bị chặn, vì cách innodb xử lý auto_increment ,. theo mặc định innodb sẽ khóa cấp độ bảng khi chèn vào cột auto_increment và giải phóng khóa ngay khi quá trình chèn kết thúc ,.
ovais.tariq
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.