mysql 修改大表字段,報錯ERROR 1878 (HY000): Temporary file write failure. 用pt-online-schema-change


在線上一個表上執行了alter 增加字段操作,報異常:ERROR 1878 (HY000): Temporary file write failure. 初步懷疑表太大,臨時空間不夠。

1.查了下表的大小將近28G,索引18G,mysql配置的tmp緩存目錄只有2G

select data_length,index_length   from tables where  table_schema='dbName'  and table_name = 'tableName';  

 

select concat(round(sum(data_length/1024/1024),2),'MB') as data_length_MB,  concat(round(sum(index_length/1024/1024),2),'MB') as index_length_MB  

    from tables where  table_schema='dbName'  and table_name = 'tableName'; 

 

解決方法:

一、更改mysql 的tmp目錄,讓tmp目錄空間更大,然后重新執行 變更sql語句。

mkdir -p /data/tmp

chown -R mysql:mysql /data/tmp

chmod a+w /data/tmp

vim /etc/my.cnf      #把tmpdir設置到 /data/tmp

tmpdir=/data/tmp

service mysqld restart 需要重啟mysql服,對線上業務影響較大。

 

 innodb 在 ddl 的時候所執行的操作:

1. 按照原始表 (original_table) 的表結構和 ddl 語句,新建一個不可見的臨時表 (temporary_table)

2. 在原表上面加上 WRITE LOCK 阻塞所有的更新操作 (insert、delete、update等操作)

3. 執行 insert into tmp_table select * from original_table

4. rename original_table 和 tmp_table 最后 drop original_table

5. 最后釋放掉 write lock

 

二、采用pt-online-schema-change方式進行修改。

 

「來自 2018 年的補充:目前 MySQL 自己也提供了 onlineddl 的工具,在數據量不大的時候還是非常好用的,直接指定 inplace 也可以輕松達到不鎖表加字段的效果」。

 

通過以上的步驟我們可以很容易的發現,這樣操作在表鎖定的情況是只能查詢,不能寫入。為了解決這個問題所以 percona 公司推出了一個不會阻塞的工具 pt-online-schema-change。

這里不得不再次介紹一下 pt-online-schema-change 是怎么做到在不阻塞寫入的情況下改動數據庫的:

1. 首先創建一個和你要執行的 alter 操作的表一樣的空的表結構。

2. 執行我們賦予的表結構的修改,然后 copy 原表中的數據到新表里面。

3. 在原表上創建一個觸發器在數據 copy 的過程中,將原表的更新數據的操作全部更新到新的表中來。 這里特別注意一下,如果原表中已經定義了觸發器那么工具就不能工作了,因為 pt 使用到了數據庫的觸發器。

4. copy 完成之后,用 rename table 新表代替原表,默認刪除原表。

 

轉自:https://blog.csdn.net/educast/article/details/89520434

原理 pt-online-schema-change 使用解析:https://blog.csdn.net/isoleo/article/details/103818332

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM