更改字符集也無濟於事。當您使用utf8或utf8mb4時,每個字符都存儲在可變數量的字節中。可以存儲在單個字節中的字符以這種方式存儲。
從MEDIUMTEXT更改爲TEXT不會有太大幫助。這些列中的每個字符串都以可變長度存儲,只能保存到您存儲的字符串所需的長度。 TEXT可以存儲高達64KB的字符串,MEDIUMTEXT可以存儲高達16MB的字符串。我想每個這樣的字符串可能需要一個單一的長度指示符,這將是每個TEXT兩個字節和每個MEDIUMTEXT三個字節。所以你可以在整個數據庫中最多節省300MB每列(可能甚至不會那麼多)。這不會產生足夠的差異。
你可以找出你的表空間有多少可用空間。運行SHOW TABLE STATUS LIKE 'sometable'
其中「sometable」是表空間中任何表的名稱。
返回的字段之一是data_free
。這是表空間中的可用空間字節數。當在同一個全局表空間中有多個表時,每個表都報告相同的值。這並不意味着你的自由空間是所有這些數字的總和,實際上它是每個表格狀態重複的一個空閒空間。
爲了節省空間,一些人宣稱InnoDB的故事與ROW_FORMAT=COMPRESSED
,但這需要您使用文件每表。由於您已經在全局表空間中擁有表,因此即使將表重構爲每個表的文件,它也不會縮小全局表空間。當你將表移動到它們自己的文件中時,它只會留下一個大部分爲空的巨大的全局表空間。所以這隻會讓你的存儲問題變得更糟。
我可以建議的唯一事情就是你要做以下步驟。當你這樣做時,沒有人可以使用你的數據庫。
轉儲InnoDB表中的所有數據,並在必要時將轉儲的輸出保存到另一個卷。哪裏有空間。您可以壓縮轉儲的輸出:
mysqldump ... | gzip -c > dump.sql.gz
停止您的mysqld進程。
- 刪除您的整個全局表空間,即
rm /var/lib/mysql/ibdata1
和您可能仍有的任何* .ibd文件。 當然,您應該首先進行備份。
- 在您的/etc/my.cnf中啓用
innodb_file_per_table
。還根據MySQL的版本啓用innodb_file_format=Barracuda
。
- 啓動你的mysqld進程。它會自動將全局表空間重新創建爲新的小文件。
- 恢復您傾銷的表格。它們將被放入獨立的InnoDB文件中,而不是全局表空間。
- 如有必要,ALTER每個表使用
ROW_FORMAT=COMPRESSED
。
這顯然需要很長時間來轉儲和重新加載300M行。這將需要許多小時,並且在此期間您的數據庫將無法使用。
如果在執行此過程時無法讓數據庫不可用,則必須在副本上執行此操作,並且在完成過程並且副本與主服務器同步後,您可以快速將主副本替換爲副本。這在切換時仍會導致服務短暫中斷,但速度很快。
下次開始時爲您的數據庫服務器提供更大的存儲卷。計劃您需要的存儲量並對其進行計劃。
重新發表您的評論,即您已從MEDIUMTEXT更改爲TEXT並保存了空間。
INFORMATION_SCHEMA中的大小(與SHOW TABLE STATUS報告的大小相同)只是估計值,它們可能已過時或以其他方式關閉。偶爾運行ANALYZE TABLE可以更新統計信息。
一個表也可以被分割,並且偶爾重建它可以回收一些空間。使用OPTIMIZE TABLE。
另一種可能性是您的MEDIUMTEXT列實際上存儲的文本字符串長度超過TEXT列的長度,並且您的ALTER TABLE會截斷它們。
這裏有一個演示:
mysql> create table m (m mediumtext);
mysql> insert into m set m = repeat('X', 1024*1024*2);
Query OK, 1 row affected (0.05 sec)
mysql> select length(m) from m;
+-----------+
| length(m) |
+-----------+
| 2097152 |
+-----------+
mysql> alter table m modify column m text;
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> select length(m) from m;
+-----------+
| length(m) |
+-----------+
| 0 |
+-----------+
我填補了MEDIUMTEXT數據的2MB,然後使用ALTER給列更改爲TEXT。它不會簡單地截斷爲可以放入TEXT列的64KB,它會將文本截斷爲零個字符。
所以,我希望你不只是消滅所有的文本數據。
你在儲存什麼?這是一個數據庫的一部分,知道你正在存儲什麼類型的數據,以及是否有值得改變的數據,以最大限度地減少數據量是很有趣的。 – junkfoodjunkie
_英語字母在拉丁文中採用與utf8中相同的1個字節。 –
請提供'SHOW CREATE TABLE';可能會有其他提示(標準化,整數大小,標誌等)。 –