InnoDB資料表空間檔案平滑遷移

season0891發表於2010-04-16

作/譯者:葉金榮(Email: InnoDB資料表空間檔案平滑遷移),來源:http://imysql.cn,轉載請註明作/譯者和出處,並且不能用於商業用途,違者必 究。

前言

InnoDB儲存引擎滿足了MVCC和ACID特性,在需要支援事務的環境下必不可少。有些環境下,採用InnoDB可能效果比MyISAM還要來 的好。不過,在很多人眼中看來,InnoDB表空間檔案由於無法實現跨伺服器平滑遷移,因此不願意使用。實際情況真是這樣嗎?本文就來探討一下 InnoDB表空間檔案的平滑遷移可能性。

如何遷移?

從MySQL文件中我們瞭解到,InnoDB的表空間可以是共享的或獨立的。如果是共享表空間,則所有的表空間都放在一個檔案 裡:ibdata1,ibdata2..ibdataN,這種情況下,目前應該還沒辦法實現表空間的遷移,除非完全遷移,因此不在本次討論之列;我們只討 論獨立表空間的情況。

不管是共享還是獨立表空間,InnoDB每個資料表的後設資料(metadata)總是儲存在 ibdata1 這個共享表空間裡,因此該檔案必不可少,它還可以用來儲存各種資料字典等資訊。資料字典中,會儲存每個資料表的ID號,每次發生資料表空間新增時,都會使 得該ID自增一個值(++1),例如:CREATE TABLE xx ENGINE = InnoDB / ALTER TABLE xx ENGINE = InnoDB 都會使得ID值增加。
有了上面的理解,想要實現InnoDB表空間檔案的平滑遷移就很容易了,呵呵。下面是一些例子:
假定我們有2臺DB主機,一個是A,一個B;現在想把A上的某個InnoDB表空間檔案遷移到B上直接用。

一、遷移失敗的例子

直接從A上把表空間檔案 yejr.ibd 拷貝到 B 上後,匯入表空間,報錯,無法使用。這是由於A,B上建立該表時的順序不一致,導致表的ID不一樣,無法匯入。
注意:,在這裡,表空間檔案直接拷貝的前提是該表空間處於"乾淨"狀態下,也就是所有的資料均已經重新整理到磁碟中,否則可能導致無法使用或部 分資料丟失。
1. 在B上將舊的表空間廢棄

(root@imysql.cn/17:52:47)[yejr]>ALTER TABLE yejr DISCARD TABLESPACE;
Query OK, 0 rows affected (0.00 sec)

2. 拷貝到目標機器

scp yejr.ibd B:/home/mysql/yejr/yejr.ibd
....

3. 啟用該表空間

(root@imysql.cn/17:52:47)[yejr]>ALTER TABLE yejr IMPORT TABLESPACE;
ERROR 1030 (HY000): Got error -1 from storage engine

4. 檢視錯誤

InnoDB: Operating system error number 13 in a file operation.
InnoDB: The error means mysqld does not have the access rights to
InnoDB: the directory.
InnoDB: Error: trying to open a table, but could not
InnoDB: open the tablespace file './test/b.ibd'!
InnoDB: Error: cannot reset lsn's in table `test/b`
InnoDB: in ALTER TABLE ... IMPORT TABLESPACE

5. 很明顯,是許可權的問題,修正過來,然後重新匯入

(root@imysql.cn/17:52:47)[yejr]>ALTER TABLE yejr DISCARD TABLESPACE;
ERROR 1030 (HY000): Got error -1 from storage engine

6. 怎麼還是錯誤?繼續看日誌

InnoDB: Error: tablespace id in file './yejr/yejr.ibd' is 15, but in the InnoDB
InnoDB: data dictionary it is 13.
InnoDB: Have you moved InnoDB .ibd files around without using the
InnoDB: commands DISCARD TABLESPACE and IMPORT TABLESPACE?
InnoDB: Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html
InnoDB: for how to resolve the issue.
InnoDB: cannot find or open in the database directory the .ibd file of
InnoDB: table `yejr/yejr`
InnoDB: in ALTER TABLE ... IMPORT TABLESPACE

從上面的日誌得知,由於在A伺服器上,yejr表的ID是15,而在B伺服器上,yejr表的ID卻是13,二者不一致,因此遷移失敗。
既然只是因為ID不一樣,而且有了上面的理論基礎,我們完全可以人為的讓它們的ID一致嘛,請看下面的第2次嘗試。

二、人工干預下的成功遷移

1. 上面的例子中,B上面的yejr表ID為13,而A上面為15;因此只需要讓B上的yejr表ID增加2就可以了。

(root@imysql.cn/17:52:47)[yejr]>ALTER TABLE yejr RENAME TO yejr1;
Query OK, 0 rows affected (0.00 sec)
#這個時候,yejr的ID變為14
(root@imysql.cn/17:52:47)[yejr]>ALTER TABLE yejr1 RENAME TO yejr;
Query OK, 0 rows affected (0.00 sec)
#這個時候,yejr的ID變為15

2. 然後,我們再匯入

(root@imysql.cn/17:52:47)[yejr]>ALTER TABLE yejr IMPORT TABLESPACE;
Query OK, 0 rows affected (0.00 sec)
(root@imysql.cn/17:52:47)[yejr]>select count(*) from yejr;
+----------+
| count(*) |
+----------+
| 3 |
+----------+
1 row in set (0.00 sec)

看到了吧,成功了,呵呵。想要讓他ID增加的方式也可以重複建立表,根據實際情況或者個人喜好而定了。
以上測試均在mysql 5.0.67版本下通過,只不過顯示資料稍作處理了。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/90618/viewspace-659944/,如需轉載,請註明出處,否則將追究法律責任。

相關文章