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
- Tạo bản sao thiết lập Master / Slave
- Chuyển đổi mọi bảng MyISAM trên nô lệ sang InnoDB
- 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:
- Trên Slave, hãy chạy
SHOW SLAVE STATUS\G
và đảm bảo Seconds_Behind_Master bằng 0
- 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ờ)
- Trên Master, chạy
service mysql stop
(Bắt đầu ngừng hoạt động)
- Lặp lại bước 1
- 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ì:
- Trên Slave, hãy chạy
SHOW SLAVE STATUS\G
và đảm bảo Seconds_Behind_Master bằng 0
- 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ờ)
- 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)
- Trên Master mới, chạy
STOP SLAVE;
- 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.