1. 程式人生 > 資料庫 >MySQL優化總結

MySQL優化總結

優化有風險,涉足需謹慎!

一、優化可能帶來的問題?

  • 優化不總是對一個單純的環境進行,還很可能是一個複雜已投產的系統環境;
  • 優化手段本身就有很大的風險,只不過我們可能沒有能力意識到和預見到;
  • 任何的技術可以解決一個問題,但必然存在帶來一個問題的風險;
  • 對於優化來說解決問題而帶來的問題,控制在可接受的範圍內才是有效果的,保持現狀或出現更差的情況都是失敗的;

二、優化的需求

  • 穩定性和業務的持續性,通常比效能更重要;
  • 優化不可避免涉及到變更,變更就有風險;
  • 優化使效能變好,維持和變差等概率事件;
  • 切記優化,應該是各部門協同參與的工作,任何單一部門都不能對資料庫進行優化;
  • 所有優化工作,都是因業務需要;

三、優化的參與者

在進行資料庫優化時,應該有DBA、業務部門代表,應用程式設計人員、應用程式開發人員、運維等相關人員共同參與。

四、優化思路

在資料庫優化上由兩個主要方面:

  • 安全:資料可持續性;
  • 效能:資料的高效能訪問;

五、優化的範圍

儲存、主機、作業系統方面

  • 主機架構穩定性;
  • I/O規劃及配置;
  • Swap交換分割槽;
  • OS核心引數和網路問題;
  • 應用程式方面;
  • 應用程式穩定性;
  • SQL語句效能;
  • 序列訪問資源;
  • 效能欠佳會話管理;
  • 這個應用是否適合使用MySQL;

資料庫方面

  • 記憶體;
  • 資料庫結構(物理&邏輯);
  • 例項配置;

不管是在設計系統,定位問題還是優化,都可以按照上面順序執行!

六、優化維度

資料庫優化維度有以下四個:

  • 硬體;
  • 系統配置;
  • 資料庫表結構;
  • SQL及索引;

優化選擇:

  • 優化成本:硬體>系統配置>資料庫表結構>SQL及索引
  • 優化效果:硬體<系統配置<資料庫表結構<SQL及索引

七、優化工具

檢查問題常用工具如下:

  • mysqladmin:mysql客戶端,可進行管理操作;
  • mysqlshow:功能強大的檢視shell命令;
  • show [SESSION|GLOBAL] variables:檢視資料庫引數資訊;
  • show [SESSION|GLOBAL] status:檢視資料庫的狀態資訊;
  • information_schema:獲取元資料的方法;
  • show engine innodb status:Innodb引擎的所有狀態;
  • show processlist:檢視當前所有連線session狀態;
  • explain:獲取查詢語句的執行計劃;
  • show index:查看錶的索引資訊;
  • slow-log:記錄慢查詢語句;
  • mysqldumpslow:分析slowlog檔案;
  • mysqlslap:分析慢日誌;
  • mysql profiling:統計資料庫整體狀態工具;
  • Performance Schema mysql:效能狀態統計的資料;
  • mysqlslap:分析慢日誌;

第三方工具:

  • zabbix:監控主機、系統、資料庫(部署zabbix監控平臺);
  • pt-query-digest:分析慢日誌;
  • sysbench:壓力測試工具;
  • workbench:管理、備份、監控、分析、優化工具(比較費資源);

八、資料庫層面問題解決思路

針對突然的業務辦理卡頓,無法進行正常的業務處理!需要立馬解決的場景!

1、show processlist;
2、show index from table;
3、通過執行計劃判斷,索引問題(有沒有、合不合理)或者語句本身問題
4、show status like '%lock%'; # 查詢鎖狀態
5、kill SESSION_ID; # 殺掉有問題的session

① 常規調優思路

針對業務週期性的卡頓,例如在每天10-11點業務特別慢,但是還能夠使用,過了這段時間就好了。

1、檢視slowlog,分析slowlog,分析出查詢慢的語句。
2、按照一定優先順序,進行一個一個的排查所有慢語句。
3、分析top sql,進行explain除錯,檢視語句執行時間。
4、調整索引或語句本身。

② 系統層面

CPU方面:vmstat、sar top、htop、nmon、mpstat
記憶體方面:free、ps -aux
IO裝置(磁碟、網路):iostat、 ss 、 netstat 、 iptraf、iftop、lsof

九、系統層面問題解決方法

在實際的生產中,一般認為 cpu只要不超過90%都沒什麼問題 !

當前可能有以下特殊情況:

  • 問題一:CPU負載高、IO負載低

原因如下:

  • 記憶體不足,磁碟效能差;

  • SQL問題:資料庫層,排查SQL問題;

  • IO出問題了(磁碟到臨界了、raid設計不好、raid降級、鎖、在單位時間內tps過高);

  • tps過高: 大量的小資料IO、大量的全表掃描;

  • 問題二:IO負載高、CPU負載低

原因如下:

  • 大量小的IO 寫操作;

  • autocommit ,產生大量小IO;

  • IO/PS,磁碟的一個定值,硬體出廠的時候,廠家定義的一個每秒最大的IO次數;

  • 大量大的IO 寫操作;

  • SQL問題的機率比較大;

  • 問題三:IO和CPU負載過高

  • 硬體不夠了或sql存在問題!

十、基礎優化

  • 定位問題點

硬體 --> 系統 --> 應用 --> 資料庫 --> 架構(高可用、讀寫分離、分庫分表)

  • 處理方向

明確優化目標、效能和安全的折中、防患未然!

  • 硬體優化

主機方面:

  • 根據資料庫型別,主機CPU選擇、記憶體容量選擇、磁碟選擇;
  • 平衡記憶體和磁碟資源;
  • 隨機的I/O和順序的I/O;
  • 主機 RAID卡的BBU(Battery Backup Unit)關閉;
  • CPU的選擇

cpu的兩個關鍵因素:核數、主頻

根據不同的業務型別進行選擇:

  • cpu密集型:計算比較多,OLTP 主頻很高的cpu、核數還要多;
  • IO密集型:查詢比較,OLAP 核數要多,主頻不一定高的;

記憶體的選擇

  • OLAP型別資料庫,需要更多記憶體,和資料獲取量級有關;
  • OLTP型別資料一般記憶體是cpu核心數量的2倍到4倍,沒有最佳實踐;

儲存的選擇

  • 根據儲存資料種類的不同,選擇不同的儲存裝置;
  • 配置合理的RAID級別(raid5、raid10、熱備盤);

對與作業系統來講,不需要太特殊的選擇,最好做好冗餘(raid1)(ssd、sas 、sata)

raid卡:

  • 實現作業系統磁碟的冗餘(raid1);
  • 平衡記憶體和磁碟資源;
  • 隨機的I/O和順序的I/O;
  • 主機 RAID卡的BBU(Battery Backup Unit)要關閉;

網路裝置方面

  • 使用流量支援更高的網路裝置(交換機、路由器、網線、網絡卡、HBA卡);

注意:以上這些規劃應該在初始設計系統時就應該考慮好。

伺服器硬體優化

1、物理狀態燈;
2、自帶管理裝置:遠端控制卡(FENCE裝置:ipmi ilo idarc),開關機、硬體監控;
3、第三方的監控軟體、裝置(snmp、agent)對物理設施進行監控;
4、儲存裝置:自帶的監控平臺。EMC2(hp收購了), 日立(hds),IBM低端OEM hds,高階儲存是自己技術,華為儲存;

系統優化

  • CPU:基本不需要調整,在硬體選擇方面下功夫即可;
  • 記憶體:基本不需要調整,在硬體選擇方面下功夫即可;
  • swap:MySQL儘量避免使用swap。阿里雲的伺服器中預設swap為0;
  • IO:raid、no lvm、 ext4或xfs、ssd、IO排程策略;
  • 不使用swap分割槽:
/proc/sys/vm/swappiness的內容改成0(臨時)
/etc/sysctl.conf上新增vm.swappiness=0(永久)

這個引數決定了Linux是傾向於使用swap,還是傾向於釋放檔案系統cache。在記憶體緊張的情況下,數值越低越傾向於釋放檔案系統cache。當然,這個引數只能減少使用swap的概率,並不能避免Linux使用swap。

修改MySQL的配置引數innodb_flush_method,開啟O_DIRECT模式。這種情況下,InnoDB的buffer pool會直接繞過檔案系統cache來訪問磁碟,但是redo log依舊會使用檔案系統cache。值得注意的是,Redo log是覆寫模式的,即使使用了檔案系統的cache,也不會佔用太多。

  • IO排程策略:

臨時修改為deadline:

echo deadline > /sys/block/sda/queue/scheduler

永久修改:

 vi /boot/grub/grub.conf
#更改到如下內容:
kernel /boot/vmlinuz-2.6.18-8.el5 ro root=LABEL=/ elevator=deadline rhgb quiet

十一、系統引數調整

Linux系統引數優化

vim /etc/sysctl.conf
net.ipv4.ip_local_port_range =102465535# 使用者埠範圍 
net.ipv4.tcp_max_syn_backlog =4096
net.ipv4.tcp_fin_timeout =30
fs.file-max=65535# 系統最大檔案控制代碼,控制的是能開啟檔案最大數量

使用者限制(mysql可以不設定以下引數)

vim/etc/security/limits.conf
* soft nproc65535
* hard nproc65535
* soft nofile65535
* hard nofile65535

十二、應用優化

業務應用和資料庫應用獨立,防火牆:iptables、selinux等其他無用服務(關閉):

$ chkconfig --level 23456 acpid off
$ chkconfig --level 23456 anacronoff
$ chkconfig --level 23456 autofsoff
$ chkconfig --level 23456 avahi-daemonoff
$ chkconfig --level 23456 bluetoothoff
$ chkconfig --level 23456 cupsoff
$ chkconfig --level 23456 firstbootoff
$ chkconfig --level 23456 haldaemonoff
$ chkconfig --level 23456 hplipoff
$ chkconfig --level 23456 ip6tablesoff
$ chkconfig --level 23456 iptablesoff
$ chkconfig --level 23456 isdnoff
$ chkconfig --level 23456 pcscdoff
$ chkconfig --level 23456 sendmailoff
$ chkconfig --level 23456 yum-updatesdoff

安裝圖形介面的伺服器不要啟動圖形介面 runlevel 3,另外,將來我們的業務是否真的需要MySQL,還是使用其他種類的資料庫。用資料庫的最高境界就是不用資料庫。

十三、資料庫優化

SQL優化方向

執行計劃、索引、SQL改寫

架構優化方向

高可用架構、高效能架構、分庫分表

十四、資料庫引數優化

例項整體(高階優化,擴充套件)
thread_concurrency #併發執行緒數量個數 
sort_buffer_size #排序快取 
read_buffer_size #順序讀取快取 
read_rnd_buffer_size #隨機讀取快取 
key_buffer_size #索引快取 
thread_cache_size #執行緒快取(1G—>8, 2G—>16, 3G>32,3G—>64)

連線層(基礎優化)

設定合理的連線客戶和連線方式:

max_connections #最大連線數,看交易筆數設定 
max_connect_errors #最大錯誤連線數,能大則大 
connect_timeout #連線超時 
max_user_connections #最大使用者連線數 
skip-name-resolve #跳過域名解析 
wait_timeout #等待超時 
back_log #可以在堆疊中的連線數量

SQL層(基礎優化)

query_cache_size: 查詢快取
OLAP型別資料庫,需要重點加大此記憶體快取.
但是一般不會超過GB.
對於經常被修改的資料,快取會立馬失效。
我們可以實用記憶體資料庫(redis、memecache),替代他的功能。

十五、儲存引擎層(innodb基礎優化引數)

default-storage-engine
innodb_buffer_pool_size # 沒有固定大小,50%測試值,看看情況再微調。但是儘量設定不要超過實體記憶體70%
 innodb_file_per_table=(1,0) 
innodb_flush_log_at_trx_commit=(0,1,2) #1是最安全的,0是效能最高,2折中 
binlog_sync
Innodb_flush_method=(O_DIRECT, fdatasync)
innodb_log_buffer_size #100M以下 
innodb_log_file_size #100M 以下 
innodb_log_files_in_group #5個成員以下,一般2-3個夠用(iblogfile0-N) 
innodb_max_dirty_pages_pct #達到百分之75的時候刷寫 記憶體髒頁到磁碟。 
max_binlog_cache_size #可以不設定 
max_binlog_size #可以不設定 
innodb_additional_mem_pool_size #小於2G記憶體的機器,推薦值是20M。32G記憶體以上100M

注:在生產環境中,資料庫的各個引數都是隨著需求去更改的,但是沒有必要去為了更改一個配置引數去重啟資料庫,但是我們可以先將需要更改的配置項設定為全域性環境變數,以便生效,然後再寫入配置檔案中,只要資料庫不重啟,設定的環境變數就不會失效,一旦重啟,配置檔案就會生效。

配置檔案可以參考如下格式:

cat /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port=3306
server_id=1 
slow_query_log = 1
slow_query_log_file = /usr/local/mysql/data/slow-query.log
long_query_time = 1
log-queries-not-using-indexes
max_connections = 1024
back_log = 128
wait_timeout = 60
interactive_timeout = 7200
key_buffer_size=256M
query_cache_size = 256M
query_cache_type=1
query_cache_limit=50M
max_connect_errors=20
sort_buffer_size = 2M
max_allowed_packet=32M
join_buffer_size=2M
thread_cache_size=200
innodb_buffer_pool_size = 2048M
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size=32M
innodb_log_file_size=128M
innodb_log_files_in_group=3
log-bin=mysql-bin
binlog_cache_size=2M
max_binlog_cache_size=8M
max_binlog_size=512M
expire_logs_days=7
read_buffer_size=1M
read_rnd_buffer_size=16M
bulk_insert_buffer_size=64M
log-error = /usr/local/mysql/data/mysqld.err