mysql的innodb擴容
為了添加一個數據文件到表空間中,首先要關閉 MySQL 數據庫,編輯 my.cnf 文件,確認innodb ibdata文件的實際情況和my.cnf的配置是否一致,這里有兩種情況:
1.my.cnf的配置
innodb_data_file_path=ibdata1:10G;ibdata2:10G:autoextend
如果當前數據庫正在使用ibdata1,或者使用ibdata2,但ibdata2沒有超過10G,則對my.cnf配置直接改成:
innodb_data_file_path=ibdata1:10G;ibdata2:10G;ibdata3:10G:autoextend
2.如果設置了最后一個ibdata自動擴展時,有可能最后一個ibdata的占用空間大于my.cnf的配置空間。例如:
mysql@test:/data1/mysqldata/innodb/data> ls -lh
-rw-rw---- 1 mysql mysql 10737418240 2010-01-26 16:34 ibdata1 -rw-rw---- 1 mysql mysql 16106127360 2010-01-26 16:34 ibdata2
這時,需要精確的計算ibdata2的大小 15360M,修改:
innodb_data_file_path=ibdata1:10G;ibdata2:15360M;ibdata3:10G:autoextend
重啟mysql。
注意:
1、擴容前注意磁盤空間是否足夠。
2、restart后關注是否生成了新的ibdata。
更多說明:
如果,最后一個文件以關鍵字 autoextend 來描述,那么編輯 my.cnf 的過程中,必須檢查最后一個文件的尺寸,并使它向下接近于 1024 * 1024 bytes (= 1 MB) 的倍數(比方說現在autoextend 的/ibdata/ibdata1為18.5M,而在舊的my.ini中為10M,則需要修改為innodb_data_file_path = /ibdata/ibdata1:19M; 且必須是19M,如果指定20M,就會報錯。),并在 innodb_data_file_path 中明確指定它的尺寸。然后你可以添加另一個數據文件。記住只有 innodb_data_file_path 中的最后一個文件可以被指定為 auto-extending。
一個例子:假設起先僅僅只有一個 auto-extending 數據文件 ibdata1 ,這個文件接近于 988 MB。下面是添加了另一個 auto-extending 數據文件后的可能示例 。
innodb_data_home_dir = innodb_data_file_path = /ibdata/ibdata1:988M;/disk2/ibdata2:50M:autoextend
ibdata1 瘦身
0. ibdata1里存了什么
當你啟用了 innodb_file_per_table,表被存儲在他們自己的表空間里,但是共享表空間仍然在存儲其它的 InnoDB 內部數據:
(1)數據字典,也就是 InnoDB 表的元數據
(2)變更緩沖區
(3)雙寫緩沖區
(4)撤銷日志
其中的一些在 Percona 服務器上可以被配置來避免增長過大的。例如你可以通過 innodb_ibuf_max_size 設置最大變更緩沖區,或設置 innodb_doublewrite_file 來將雙寫緩沖區存儲到一個分離的文件。
MySQL 5.6 版中你也可以創建外部的撤銷表空間,所以它們可以放到自己的文件來替代存儲到 ibdata1。
1. 什么引起 ibdata1 增長迅速?
當 MySQL 出現問題通常我們需要執行的第一個命令是:
SHOW ENGINE INNODB STATUS/G
這將展示給我們一些很有價值的信息。我們從** TRANSACTION(事務)**部分開始檢查,然后我們會發現這個:
---TRANSACTION 36E, ACTIVE 1256288 secMySQL thread id 42, OS thread handle 0x7f8baaccc700, query id 7900290 localhost rootshow engine innodb statusTrx read view will not see trx with id >= 36F, sees < 36F
這是一個最常見的原因,一個14天前創建的相當老的事務。這個狀態是活動的,這意味著 InnoDB 已經創建了一個數據的快照,所以需要在撤銷日志中維護舊頁面,以保障數據庫的一致性視圖,直到事務開始。如果你的數據庫有大量的寫入任務,那就意味著存儲了大量的撤銷頁。
如果你找不到任何長時間運行的事務,你也可以監控INNODB STATUS 中的其他的變量,“History list length(歷史記錄列表長度)”展示了一些等待清除操作。這種情況下問題經常發生,因為清除線程(或者老版本的主線程)不能像這些記錄進來的速度一樣快地處理撤銷。
2. 我怎么檢查什么被存儲到了 ibdata1 里了?
很不幸,MySQL 不提供查看什么被存儲到 ibdata1 共享表空間的信息,但是有兩個工具將會很有幫助。第一個是馬克·卡拉漢制作的一個修改版 innochecksum ,它發布在這個漏洞報告里。
它相當易于使用:
# ./innochecksum /var/lib/mysql/ibdata10 bad checksum13 FIL_PAGE_INDEX19272 FIL_PAGE_UNDO_LOG230 FIL_PAGE_INODE1 FIL_PAGE_IBUF_FREE_LIST892 FIL_PAGE_TYPE_ALLOCATED2 FIL_PAGE_IBUF_BITMAP195 FIL_PAGE_TYPE_SYS1 FIL_PAGE_TYPE_TRX_SYS1 FIL_PAGE_TYPE_FSP_HDR1 FIL_PAGE_TYPE_XDES0 FIL_PAGE_TYPE_BLOB0 FIL_PAGE_TYPE_ZBLOB0 other3 max index_id
全部的 20608 中有 19272 個撤銷日志頁。這占用了表空間的 93%。
第二個檢查表空間內容的方式是杰里米·科爾制作的 InnoDB Ruby 工具。它是個檢查 InnoDB 的內部結構的更先進的工具。例如我們可以使用 space-summary 參數來得到每個頁面及其數據類型的列表。我們可以使用標準的 Unix 工具來統計撤銷日志頁的數量:
# innodb_space -f /var/lib/mysql/ibdata1 space-summary | grep UNDO_LOG | wc -l19272
盡管這種特殊的情況下,innochedcksum 更快更容易使用,但是我推薦你使用杰里米的工具去了解更多的 InnoDB 內部的數據分布及其內部結構。
好,現在我們知道問題所在了。
3. ibdata1 瘦身方案
其中的一些在 Percona 服務器上可以被配置來避免增長過大的。例如你可以通過 innodb_ibuf_max_size 設置最大變更緩沖區,或設置 innodb_doublewrite_file 來將雙寫緩沖區存儲到一個分離的文件。
MySQL 5.6 版中你也可以創建外部的撤銷表空間,所以它們可以放到自己的文件來替代存儲到 ibdata1。
通常不能移除 InnoDB 的數據文件。為了減小數據文件的大小,你必須使用 mysqldump 來轉儲(dump)所有的數據表,再重新建立一個新的數據庫,并將數據導入新的數據庫中。具體步驟如下:
(1)備份數據庫
mysqldump -uroot -p123456 --default-character-set=utf8 --opt --extended-insert=true --triggers -R --hex-blob --single-transaction --no-autocommit test > db_name.sql
(2)停止數據庫
service mysqld stop
(3)刪除相關文件
ibdata1 ib_logfile* mysql-bin.index
(4)手動刪除除Mysql之外所有數據庫文件夾,然后啟動數據庫
service mysqld start
(5)還原數據
/usr/local/mysql/bin/mysql -uroot -phigkoo < /data/bkup/mysqldump.sql
主要是使用Mysqldump時的一些參數,建議在使用前看一個說明再操作。另外備份前可以先查看一下當前數據庫里哪些表占用空間大,把一些不必要的給truncate table掉。這樣省些空間和時間
新聞熱點
疑難解答