遷移 MySQL 數據目錄後,常遇到 #1036 – Table 'xxx' is read only 錯誤,導致無法寫入。本文提供經驗證的三步修復法:目錄權限 777 → 所有者 mysql:mysql → mysqladmin flush-tables,並解釋底層原理。
/var/lib/mysql 數據目錄遷移。#1036 – Table 'table_name' is read only。# 假設數據目錄為 /usr/local/mysql/var/mydb
# 1. 授予最大權限(臨時,修復後建議收緊至 750)
chmod -R 0777 /usr/local/mysql/var/mydb/
# 2. 修正所有者為 mysql 進程用戶
chown -R mysql:mysql /usr/local/mysql/var/mydb/
# 3. 刷新表緩存,釋放殘留鎖狀態
/usr/local/mysql/bin/mysqladmin -u root -p flush-tables
# 輸入 root 密碼,無輸出即成功
mysql -u root -p
USE mydb;
INSERT INTO test_table (col) VALUES ('test'); -- 應成功
SELECT * FROM test_table;
| 步驟 | 作用 | 底層機制 |
|---|---|---|
| chmod 777 | 消除文件系統只讀屬性 | InnoDB/MyISAM 需對 .ibd/.MYD/.MYI 寫入,任何只讀位導致錯誤 1036 |
| chown mysql:mysql | 確保 mysqld 進程有 DAC 權限 | Linux DAC 權限檢查:進程有效 UID/GID 必須匹配文件所有者/組 |
| flush-tables | 關閉所有打開的表句柄,清除鎖狀態 | MySQL 表緩存持有文件描述符與鎖信息;遷移後舊實例鎖狀態殘留,flush 強制釋放 |
getenforce → Enforcing 時,setenforce 0 臨時關閉或配置策略 semanage fcontext -a -t mysqld_db_t "/usr/local/mysql/var(/.*)?"。mount | grep /usr/local/mysql 檢查是否含 ro、noexec、nosuid。SHOW VARIABLES LIKE 'read_only'; → ON 時,SET GLOBAL read_only=OFF;(需 SUPER 權限)。ALTER TABLE tbl_name IMPORT TABLESPACE; 導入前需 FLUSH TABLES tbl_name FOR EXPORT 產生 .cfg 文件。mysqldump 邏輯導出導入,而非物理拷貝。useradd -u 27 -g 27 mysql)。掌握「權限 → 所有者 → 刷新」三步法,可在 1 分鐘內解決 95% 的 MySQL 表只讀故障,保障業務快速恢復。