自動化運維(備份、巡檢、Schema 變更、數據修復)離不開 Shell + MySQL 組合。本文總結 5 種調用模式,覆蓋 90%+ 生產場景,並給出輸出美化、錯誤處理、密碼安全最佳實踐。
OS: CentOS 7.9 MySQL: 5.7.44 / 8.0.36 Client: mysql 8.0 (兼容 5.7 协议)
#!/bin/bash
# shell_call_sql1.sh
LOG="call_sql_$(date +%Y%m%d%H%M%S).log"
echo "Start: $(date)" >> "$LOG"
mysql -uroot -p'123456' -e "
TEE /tmp/temp.log;
DROP DATABASE IF EXISTS tempdb;
CREATE DATABASE tempdb;
USE tempdb;
CREATE TABLE IF NOT EXISTS tb_tmp(id SMALLINT, val VARCHAR(20));
INSERT INTO tb_tmp VALUES (1,'jack'),(2,'robin'),(3,'mark');
SELECT * FROM tb_tmp;
NOTEE;
QUIT
" >> "$LOG" 2>&1
echo -e "\n--- Output ---" >> "$LOG"
cat /tmp/temp.log >> "$LOG"
echo "Script executed successfully." >> "$LOG"
關鍵點: TEE/NOTEE 將交互輸出同時寫入文件;-e 後接單引號包裹的多行 SQL;密碼寫在命令行**僅限測試**,生產見文末安全節。
# temp.sql TEE /tmp/temp.log; DROP DATABASE IF EXISTS tempdb; CREATE DATABASE tempdb; USE tempdb; CREATE TABLE IF NOT EXISTS tb_tmp(id SMALLINT, val VARCHAR(20)); INSERT INTO tb_tmp VALUES (1,'jack'),(2,'robin'),(3,'mark'); SELECT * FROM tb_tmp; NOTEE;
調用:
mysql -uroot -p'123456' -e "SOURCE /root/temp.sql;"
或直接管道:
mysql -uroot -p'123456' < /root/temp.sql > /tmp/temp.log 2>&1
# 生成 10 萬條 INSERT
for i in {1..100000}; do
echo "INSERT INTO t VALUES ($i, 'val_$i');"
done | mysql -uroot -p'123456' -D testdb
優勢: 無臨時文件,內存常駐,速度極快。配合 pv 可顯示進度:
cat huge.sql | pv | mysql -uroot -p'123456' -D testdb
#!/bin/bash mysql -uroot -p'123456' <此模式下,所有語句在**同一連接**中執行,支持事務、會話變量、臨時表等上下文依賴。
方式 5:Shell 變量雙向交互(核心技能:捕獲結果供後續邏輯判斷)
生產級安全與健壯性增強
- 密碼不入命令行:
# ~/.my.cnf (chmod 600) [client] user=backup_user password=StrongPass#2024 host=127.0.0.1 port=3306腳本中直接mysql --defaults-file=~/.my.cnf ...,無需-u -p。- 錯誤捕獲與重試:
retry=3 until mysql --defaults-file=~/.my.cnf -e "$SQL"; do ((retry--)) || { echo "FAIL after 3 retries"; exit 1; } sleep 2 done- 輸出格式化:
-H(HTML)、-X(XML)、--table(默認)、--vertical(垂直)、-s(制表符分隔,便於解析)。- 超時控制:
--connect-timeout=10 --max-allowed-packet=1G。實戰模板:Schema 變更自動化腳本
#!/bin/bash # deploy_schema.sh set -euo pipefail SQL_FILE=$1 [ -f "$SQL_FILE" ] || { echo "Usage: $0"; exit 1; } echo "[$(date)] Starting schema deployment: $SQL_FILE" mysql --defaults-file=~/.my.cnf --connect-timeout=10 -v < "$SQL_FILE" 2>&1 | tee -a deploy.log if [ ${PIPESTATUS[0]} -eq 0 ]; then echo "[$(date)] SUCCESS" else echo "[$(date)] FAILED" exit 1 fi 掌握這 5 種模式與安全模式,Shell 操作 MySQL 將游刃有餘,支撐起千萬級實例的自動化運維體系。