1. 程式人生 > >使用mysqldump備份時為什麼要加上 -q 引數(5.7預設為on)

使用mysqldump備份時為什麼要加上 -q 引數(5.7預設為on)

使用mysqldump備份時為什麼要加上 -q 引數(5.7預設為on)

 

 寫在前面:我們在使用mysqldump備份資料時,請一定記住要加上 -q 引數,後果可能是很嚴重的,不要給自己挖坑哦。

   先來看看 mysqldump -help 中,關於 -q 引數的解釋:

-q, --quick         Don't buffer query, dump directly to stdout.

   簡言之,就是說加上 -q 後,不會把SELECT出來的結果放在buffer中,而是直接dump到標準輸出中,頂多只是buffer當前行結果,正常情況下是不會超過 max_allowed_packet 限制的,它預設情況下是開啟的。

   如果關閉該引數,則會把SELECT出來的結果放在本地buffer中,然後再輸出給客戶端,會消耗更多記憶體。

   在mysqldump.c中也能看到二者的對比(現在流行深入原始碼,雖然我不是專注開發的,找幾行原始碼能力還尚存,用來裝B的,大家知道就好,哈哈):

if (quick)
  res=mysql_use_result(sock);
else
  res=mysql_store_result(sock);

   有理論,也要有實踐不是,我們來看看在實際場景中,加不加 -q 的區別有多大。

  部分備份(啟用-q) 部分備份(禁用-q) 完整備份(啟用-q) 完整備份(禁用-q)
備份總耗時 27.882秒 22.665秒 277.387秒 217.074秒
佔用記憶體(含swap) 3056KB 2.5GB 3048KB 記憶體:12GBswap:305MB

   可以看到,如果只是備份小量資料,足以放在空閒記憶體buffer中的話,禁用 -q 會快一些,但如果是大資料集,沒辦法完全hold在記憶體buffer中時,就會產生swap,效率反而更差,真是賠了夫人又折兵。

   因此,如果使用mysqldump來備份資料時,建議總是加上 -q 引數,避免發生swap反而影響備份效率。

   詳細過程(有耐心的可以繼續往下看)

   1、全量備份:備份時不使用 -q 引數

mysqldump --quick=false -Smysql.sock -B yejr --tables t_yejr

#先看下一開始時的狀態:
Mem:  32863040k total, 29338704k used,  3524336k free,   227632k buffers
Swap: 16777208k total,    23548k used, 16753660k free,  8200416k cached
PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
21986 root      20   0 6119m 5.9g 2192 S 20.6 18.9   0:21.69 mysqldump

#再看下備份結束後的狀態,記憶體不夠用,產生了swap
Mem:  32863040k total, 32521328k used,   341712k free,      440k buffers
Swap: 16777208k total,   336876k used, 16440332k free,   315192k cached
PID   USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+   COMMAND
21986 root      20   0 12.3g  12g  656 R 100.0 39.1   2:23.93 mysqldump

#最後看下備份總耗時
real    4m37.387s
user    2m2.731s
sys     0m24.608s

   2、全量備份:備份時啟用 -q 引數

mysqldump -Smysql.sock -B yejr --tables t_yejr

#先看下一開始時的狀態:
Mem:  32863040k total, 20157476k used, 12705564k free,     4608k buffers
Swap: 16777208k total,        0k used, 16777208k free,   488296k cached

#再看下備份結束後,可以看到,沒有使用到swap
Mem:  32863040k total, 32644496k used,   218544k free,      920k buffers
Swap: 16777208k total,        0k used, 16777208k free, 12618740k cached
PID   USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
25234 root      20   0 50880 3048 2192 S 57.6  0.0   2:22.79 mysqldump

#最後看下總耗時統計:
real    3m37.074s
user    2m6.018s
sys     0m17.315s

   3、部分備份:備份時不使用 -q 引數

mysqldump -w " id<100000 " -Smysql.sock --quick=false -Smysql.sock -B yejr --tables t_yejr

#看下總耗時
real 0m22.665s
user 0m20.458s
sys 0m2.156s

#再看下mysqldump程序消耗的記憶體,最高時大概使用了2.5G記憶體
20619 root      20   0 2571m 2.5g 2208 R 99.9  7.8   0:11.63 mysqldump

   4、部分備份:備份時啟用 -q 引數

mysqldump -w " id<100000 " -Smysql.sock -Smysql.sock -B yejr --tables t_yejr

#看下總耗時,並沒有慢多少
real 0m27.882s
user 0m22.610s
sys 0m0.670s

#再看下mysqldump程序消耗的記憶體,只佔用了極少量記憶體
19690 root      20   0 50880 3056 2200 S 73.4  0.0   0:06.01 mysqldump