首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

Shell 腳本實戰:MySQL 存儲引擎批量檢查與自動轉換(MyISAM→InnoDB)for Percona XtraDB Cluster

     編輯:MySQL 綜合教學

業務背景:PXC 遷移強制要求 InnoDB,百張表手動改造不可行

Percona XtraDB Cluster (PXC) 僅支持 InnoDB 存儲引擎。遷移過程中需將歷史 MyISAM 表批量轉換,且需支持:單機巡檢、引擎統計、審計日誌、分步執行(檢查/轉換分離)、手動干預名單。

腳本設計目標與功能矩陣

模式參數核心功能產出
檢查模式ck掃描非系統庫所有表,輸出 db.tb engine,統計各引擎數量,MyISAM 表寫入 check_log屏幕輸出 + check_log
轉換模式al讀取 check_log 執行 ALTER TABLE ... ENGINE=InnoDB,轉換後清理日誌執行日誌 + 清空 check_log

靈活性設計:ck/al 可獨立執行;check_log 支持手動編輯(排除不轉換的表);執行前自動備份舊日誌。

核心邏輯與關鍵代碼片段

1. 遠程連接與權限預檢

MYSQL_CMD="mysql -u${USER} -h${HOST} -P${PORT} -p${PASS} -e"
# 必需權限:SELECT (information_schema)、ALTER (目標庫表)、RELOAD (FLUSH TABLES)

2. 獲取用戶表列表(排除系統庫)


GET_TABLES_SQL="
SELECT CONCAT(TABLE_SCHEMA,'.',TABLE_NAME)
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql','test','information_schema','performance_schema','sys')
  AND ENGINE IN ('MyISAM','InnoDB')
  AND TABLE_TYPE='BASE TABLE';
"
TABLES=$(${MYSQL_CMD} "${GET_TABLES_SQL}" -s -N)

3. 檢查模式(ck):掃描、統計、生成日誌


> ${CHECK_LOG}  # 清空舊日誌
echo "=== Engine Check $(date) ===" | tee -a ${CHECK_LOG}

for tb in ${TABLES}; do
  db=${tb%.*}; tn=${tb#*.}
  ENGINE=$(${MYSQL_CMD} "SELECT ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA='${db}' AND TABLE_NAME='${tn}'" -s -N)
  echo "${db}.${tn} ${ENGINE}" | tee -a ${CHECK_LOG}
  [[ "${ENGINE}" == "MyISAM" ]] && echo "${db}.${tn}" >> ${CHECK_LOG}.myisam
done

# 統計輸出
echo "=== Summary ===" | tee -a ${CHECK_LOG}
awk '{print $2}' ${CHECK_LOG} | sort | uniq -c | sort -nr | tee -a ${CHECK_LOG}

4. 轉換模式(al):讀取日誌、執行 ALTER、驗證


[[ ! -f ${CHECK_LOG}.myisam ]] && { echo "ERROR: ${CHECK_LOG}.myisam not found, run 'ck' first"; exit 1; }

while read tb; do
  [[ -z "${tb}" ]] && continue
  echo "[$(date)] Converting ${tb} to InnoDB..."
  ${MYSQL_CMD} "ALTER TABLE \`${tb}\` ENGINE=InnoDB;"
  # 驗證
  NEW_ENGINE=$(${MYSQL_CMD} "SELECT ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA='${tb%.*}' AND TABLE_NAME='${tb#*.}'" -s -N)
  [[ "${NEW_ENGINE}" == "InnoDB" ]] && echo "  ✓ Success" || echo "  ✗ Failed"
done < ${CHECK_LOG}.myisam

# 清理日誌防止重複執行
rm -f ${CHECK_LOG} ${CHECK_LOG}.myisam

執行示例與輸出解讀


# 1. 掃描檢查
$ sh ck_engine_status.sh 10.10.10.12 3001 ck
db1.tb1 InnoDB
db1.tb2 MyISAM   ← 寫入 check_log.myisam
db2.tb3 InnoDB
...
=== Summary ===
   128 InnoDB
    17 MyISAM
     3 MEMORY

# 2. 手動編輯 check_log.myisam(可選:刪除不想轉換的表)

# 3. 執行轉換
$ sh ck_engine_status.sh 10.10.10.12 3001 al
[2024-01-15 10:30:01] Converting db1.tb2 to InnoDB...
  ✓ Success
...

生產環境避坑指南

風險對策
ALTER TABLE 鎖表導致業務阻塞使用 pt-online-schema-change 替代直接 ALTER,或低峰期執行
大表轉換耗時數小時,Binlog 膨脹分批轉換、調大 max_binlog_size、監控 Seconds_Behind_Master
外鍵約束導致轉換失敗先 DROP FOREIGN KEY,轉換後重建
分區表/臨時表不支持直接轉換腳本增加 PARTITION、TEMPORARY 過濾邏輯
權限不足導致靜默失敗啟用 set -e、捕獲 SQL 錯誤碼、郵件告警

進階擴展:多實例巡檢與 Ansible 化

  • IP 列表文件 + 循環調用,實現集群級巡檢。
  • 封裝為 Ansible Module,納入 CI/CD 流水線,實現「遷移前自動掃描 → 異常阻斷 → 遷移後驗證」全流程自動化。

總結

「分步執行、日誌審計、手工干預、統計可視」是運維腳本專業度的體現。本腳本通過 ck/al 解耦、**MyISAM 白名單機制**、**執行後自動清理日誌** 等設計,在 PXC 遷移百萬級表場景中實現零事故交付。建議團隊將此類腳本納入「資料庫變更工具箱」,配合 pt-osc、gh-ost 形成標準化變更能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved