Hàng bị thiếu sau khi chuyển đổi trực tuyến từ MyISAM sang InnoDB


16

Chúng tôi có một cơ sở dữ liệu khá nhỏ mà chúng tôi muốn chuyển đổi từ MyISAM sang InnoDB. Là cơ sở dữ liệu, chúng tôi chỉ chuyển đổi (sử dụng bảng thay đổi) mà không cần gỡ trang web xuống.

Bây giờ việc chuyển đổi đã được thực hiện, rất nhiều hàng không liên tục dường như bị thiếu. Đây có phải là do hoạt động trong quá trình chuyển đổi? Hay là vấn đề ở một nơi khác?


Những bảng nào thiếu hàng? Những cái bạn đã chuyển đổi hoặc các bảng khác?
longneck

Câu trả lời:


20

Thực hiện ALTER để thay đổi công cụ lưu trữ sẽ không làm cho các hàng biến mất. Tuy nhiên, hãy để tôi cung cấp một số lời khuyên vì bạn nói rằng bạn là 'cơ sở dữ liệu' trong câu hỏi của bạn.

Khi sửa đổi lược đồ hiện có hoặc làm bất cứ điều gì có thể ảnh hưởng đến dữ liệu, đây là một số lời khuyên cơ bản:

  1. Tạo một bản sao lưu trước.
  2. Có kế hoạch thay đổi.
  3. Kiểm tra kế hoạch của bạn trên một máy chủ ngoại tuyến.
  4. Có một kế hoạch kiểm tra để so sánh trước và sau dữ liệu.
  5. Lịch trình và có một thời gian chết.
  6. Hãy sao lưu và chụp nhanh ngay sau khi thời gian chết của bạn có hiệu lực và bạn xác minh lưu lượng đã dừng.
  7. Nếu bạn đang chạy MYISAM, hãy sử dụng 'KIỂM TRA BẢNG' để đánh giá những gì bạn đang xử lý trước khi bạn THAY ĐỔI.
  8. Sao chép bảng cục bộ ngoài bản sao lưu của bạn, chỉ trong trường hợp.
  9. Tiếp tục thận trọng, bật "cảnh báo hiển thị" và các đầu ra khác để bạn có bức tranh đầy đủ khi bạn thực hiện các thay đổi của mình.
  10. Nếu dữ liệu quan trọng đối với bạn, hãy thuê một DBA, ngay cả khi chỉ tham khảo ý kiến ​​trong quá trình di chuyển để bạn có một cựu chiến binh dày dạn bên cạnh.

Có lẽ tôi có thể tham gia nhiều hơn, nhưng những điều trên sẽ cung cấp cho bạn các tùy chọn khi có sự cố.

Theo như dữ liệu / hàng bị thiếu của bạn, không có cách nào để biết ảnh chụp nhanh "trước / sau" để so sánh. Bạn có thể so sánh với bản sao lưu mới nhất của mình để ít nhất xác minh điều đó.


Tôi đọc cái này. Kế hoạch DR tốt. Câu trả lời của bạn được +1 vì nhạy cảm hơn với câu hỏi so với tôi ngoài kế hoạch đi tiếp.
RolandoMySQLDBA

1
@randy Đánh dấu đây là câu hỏi yêu thích vì câu trả lời hay của bạn
techExplorer

8

Một trong những cách tốt nhất để chuyển đổi MyISAM sang InnoDB mà không có nhiều thời gian chết chỉ là một điều kiện tiên quyết: Sử dụng Slave sao chép.

Dưới đây là một cái nhìn của con chim về kế hoạch

  1. Tạo bản sao thiết lập Master / Slave
  2. Chuyển đổi mọi bảng MyISAM trên nô lệ sang InnoDB
  3. Trỏ ứng dụng của bạn vào Slave

Nghe có vẻ đơn giản? Có rất nhiều chi tiết đằng sau điều này.

Tạo bản sao thiết lập Master / Slave

Có một cách khéo léo để tạo ra một Slave mà không có nhiều sự xáo trộn đối với Master. Tôi đã viết hai bài viết:

Thay vì chi tiết cách sử dụng rsync, vui lòng đọc hai bài đăng đó.

Chuyển đổi mọi bảng MyISAM trên nô lệ sang InnoDB

Trên DB Slave, bạn có thể tuyên bố SQL sau:

Đối với MySQL 5.5:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql','performance_schema');

Phiên bản cho MySQL trước MySQL 5.5

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql');

Sử dụng đầu ra từ truy vấn, bạn có một tập lệnh chuyển đổi cho nô lệ.

Bạn phải đặt hai dòng này ở đầu tập lệnh:

SET SQL_LOG_BIN = 0;
STOP SLAVE;

Tập lệnh trước tiên sẽ vô hiệu hóa ghi nhật ký nhị phân (nếu bạn đã cấu hình nô lệ để có nhật ký nhị phân), dừng sao chép và chuyển đổi từng bảng MyISAM sang InnoDB.

Đây là cách tạo tập lệnh đó và thực thi nó:

SQLSTMT="SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema')"
INNODB_CONV_SCRIPT=MassConvertMyISAMTablesToInnoDB.sql
echo "SET SQL_LOG_BIN = 0;" > ${INNODB_CONV_SCRIPT}
echo "STOP SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Master) -u... -p... --skip-column-names -A -e"${SQL}" >> ${INNODB_CONV_SCRIPT}
echo "START SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Slave) -u... -p... --skip-column-names -A < ${INNODB_CONV_SCRIPT}

Trỏ ứng dụng của bạn vào Slave

Thực hiện các truy vấn CHỌN từ Slave. Nếu bạn hài lòng với nội dung dữ liệu trên Slave, vui lòng trỏ ứng dụng của bạn tới nô lệ như sau:

  1. Trên Slave, hãy chạy SHOW SLAVE STATUS\Gvà đảm bảo Seconds_Behind_Master bằng 0
  2. Trên Slave, mysqldump -h (IP của Slave) -u ... -p ... --single-giao dịch --routines --triggers --all-cơ sở dữ liệu> MySQLBackup.sql (Hey, một bản sao lưu sẽ tốt về bây giờ)
  3. Trên Master, chạy service mysql stop(Bắt đầu ngừng hoạt động)
  4. Lặp lại bước 1
  5. Trỏ ứng dụng của bạn tới Slave (Thời gian ngừng hoạt động trên kết nối đầu tiên của ứng dụng)

Nếu bạn thực hiện đến thời điểm này vô tình, HÃY THAM GIA !!!

GIA TĂNG THƯỞNG : Nếu bạn thiết lập Master / Thạc sĩ Replication (aka Thông tư Replication) thay vì Master / Slave, bạn có thể làm điều này thay vì:

  1. Trên Slave, hãy chạy SHOW SLAVE STATUS\Gvà đảm bảo Seconds_Behind_Master bằng 0
  2. Trên Slave, mysqldump -h (IP của Slave) -u ... -p ... --single-giao dịch --routines --triggers --all-cơ sở dữ liệu> MySQLBackup.sql (Hey, một bản sao lưu sẽ tốt về bây giờ)
  3. Trỏ ứng dụng của bạn vào Slave (Thời gian ngừng hoạt động bắt đầu và kết thúc trên kết nối đầu tiên của ứng dụng)
  4. Trên Master mới, chạy STOP SLAVE;
  5. Trên Master mới, chạy CHANGE MASTER TO MASTER_HOST='';

Những gì bạn có bây giờ là Master / Slave ngược lại. New Master có dữ liệu InnoDB và Master cũ hiện là nô lệ với dữ liệu MyISAM. Nếu bạn phân chia đọc và viết, các lần đọc có thể đi từ Slave (đọc nhanh hơn từ MyISAM so với InnoDB) và ghi vào Master (hỗ trợ giao dịch cho InnoDB). Giống như Hannah Montana hát, bạn có được những điều tốt nhất của cả hai thế giới (Vâng, tôi có hai cô con gái yêu chương trình) !!!

TIỀN THƯỞNG THÊM KHÁC : Vì Master hiện là InnoDB, bạn có thể thực hiện mysqldump từ Master mà không bị ngừng hoạt động và không can thiệp vào các giao dịch. Chỉ có nhược điểm là tăng I / O CPU và đĩa. Do đó, bạn chỉ có thể sử dụng mysqldump của các cấu trúc bảng trên Master (InnoDB) và mysqldump của dữ liệu trên nô lệ (Một bãi chứa như vậy sẽ không có tham chiếu đến InnoDB hoặc MyISAM. Nó sẽ chỉ là dữ liệu) cộng với mysqldump của cấu trúc bảng để nô lệ có bố cục MyISAM.

Các khả năng có thể tiếp tục vì thiết lập mới này ...

CẬP NHẬT 2011-08-27 19:50 EDT

Lời xin lỗi của tôi. Tôi đã không đọc hết câu hỏi. Bạn đã thực hiện các cuộc trò chuyện rồi .

Chỉ khi bạn đã bật đăng nhập nhị phân và bạn đã có bản sao lưu trước, bạn mới có thể

  • khôi phục / var / lib / mysql đến một vị trí khác, như / var / lib / mysql2
  • chạy service mysql stop
  • chạy service mysql start --datadir=/var/lib/mysql2
  • mysqldump cơ sở dữ liệu từ bản sao lưu đó thành /root/olddata.sql
  • chạy mysqlbinlog chống lại tất cả các bản ghi nhị phân trong / var / lib / mysql (không phải / var / lib / mysql2) từ thời điểm kể từ lần sao lưu cuối cùng vào /root/changes.sql
  • Tải các thay đổi.sql vào mysql (vì nó vẫn đang trỏ vào / var / lib / mysql2)

Điều này sẽ nắm bắt mọi thứ đã được ghi lại và chuyển đổi sẽ bắt đầu. Một lần nữa, đây là tất cả các thông tin liên quan đến bạn đã được đăng nhập nhị phân trước khi sao lưu lần cuối . Nếu không, xin chia buồn.

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.