1. 程式人生 > >MySQL學習(五)【MySQL運維實踐】

MySQL學習(五)【MySQL運維實踐】

5.1-MySQL日誌系統

什麼是日誌

  • 日誌(log)是一種順序記錄事件流水的檔案
  • 記錄計算機程式執行過程中發生了什麼
  • 多種多樣的用途
    • 幫助分析程式問題
    • 分析服務請求的特徵、流量等
    • 判斷工作是否成功執行
    • 等等……

MySQL日誌的分類

  • 伺服器日誌
    • 記錄程序啟動執行過程中的特殊事件,幫助分析MySQL服務遇到的問題
    • 根據需求抓取特定的SQL語句,追蹤效能可能存在的問題的業務SQL
  • 事務日誌
    • 記錄應用程式對資料的所有更改
    • 可用於資料恢復
    • 可用於例項間資料同步
分類 日誌名稱
伺服器日誌 服務錯誤日誌
伺服器日誌 慢查詢日誌
伺服器日誌 綜合查詢日誌
事務日誌 儲存引擎事務日誌
事務日誌 二進位制日誌

服務錯誤日誌

  • 記錄例項啟動執行過程中重要訊息
  • 配置引數
    • log_error = /data/mysql_data/node-1/mysql.log
  • 內容並非全是錯誤訊息
  • 如果mysqld程序無法正常啟動首先檢視錯誤日誌

慢查詢日誌

  • 記錄執行時間超過一定閾值的SQL語句
  • 配置引數
slow_query_log = 1
slow_query_log_file = /data/mysql_data/node-1/mysql-slow.log
long_query_time = 5
  • 用於分析系統中可能存在效能問題的SQL

綜合查詢日誌

  • 如果開啟將會記錄系統中所有SQL語句
  • 配置引數
general_log = 1
general_log_file = /data/mysql_data/node-1/mysql-slow.log
  • 偶爾用於幫助分析系統問題,對效能有影響

查詢日誌的輸出與檔案切換

  • 日誌輸出引數

log_output={file|table|none}

  • 如果日誌檔案過大,可以定期截斷並切換新檔案

flush log;

儲存引擎事務日誌

  • 部分儲存引擎擁有重做日誌(redo log)
  • 如InnoDB, TokuDB等WAL(Write Ahead Log)機制儲存引擎
  • 日誌隨著事務commit優先持久化,確保異常恢復不丟資料
  • 日誌順序寫效能較好

InnoDB事務日誌重用機制

  • InnoDB事務日誌採用兩組檔案交替重用

二進位制日誌binlog

  • binlog (binary log)
  • 記錄資料引起資料變化的SQL語句或資料邏輯變化的內容
  • MySQL服務層記錄,無關儲存引擎
  • binlog的主要作用:
    • 基於備份恢復資料
    • 資料庫主從同步
    • 挖掘分析SQL語句

開啟binlog

  • 主要引數
log_bin = c:/tmp/mylog/mysql-bin
sql_log_bin = 1
sync_binlog = 1
  • 檢視binlog

show binary logs;

binlog管理

  • 主要引數
max_binlog_size = 100MB
expire_logs_days = 7
  • binlog始終生成新檔案,不會重用

  • 手工清理binlog

purge binary logs to 'mysql-bin.000009';
purge binary logs before '2016-4-2 21:00:40'

檢視binlog內容

  • 日誌
show binlog events in 'mysql-bin.000011';
show binlog events in 'mysql-bin.000011' from 60 limit 3;
  • mysqlbinlog工具
mysqlbinlog c:/tmp/mylog/mysql-bin.000001
--start-datetime | --stop-datetime
--start-position | --stop-position

binlog格式

  • 主要引數

binlog_format = {ROW|STATEMENT|MIXED}

  • 檢視row模式的binlog內容

mysqlbinlog --base64-output=decode-rows -v c:/tmp/mylpg/mysql-bin.000001

5.2-MySQL資料備份

基本指數 - 備份用途

  • 資料備災
    • 應對硬體故障資料丟失
    • 應對人為或程式bug導致資料刪除
  • 製作映象庫以供服務
    • 需要將資料遷移、統計分析等用處
    • 需要為線上資料建立一個映象

基本知識 - 備份內容

  • 資料
    • 資料檔案或文字格式資料
  • 操作日誌(binlog)
    • 資料庫變更日誌

基本知識 - 冷備份與熱備份

  • 冷備份
    • 關閉資料庫服務,完整拷貝資料檔案
  • 熱備份
    • 在不影響資料庫讀寫服務的情況下備份資料庫

基本知識 - 物理備份與邏輯備份

  • 物理備份
    • 以資料頁的形式拷貝資料
  • 邏輯備份
    • 匯出為裸資料或者SQL(insert)語句

基本知識 - 本地備份與遠端備份

  • 本地備份
    • 在資料庫伺服器本地進行備份
  • 遠端備份
    • 遠端連線資料庫進行備份

基本知識 - 全量備份與增量備份

  • 全量備份
    • 備份完整的資料庫
  • 增量備份
    • 只備份上一次備份以來發生修改的資料

基本知識 - 備份週期

考慮因素:
* 資料庫大小(決定備份時間)
* 恢復速度要求(快速or慢速)
* 備份方式(全量or增量)

常用工具及用法

  • mysqldump - 邏輯備份,熱備
  • xtrabackup - 物理備份, 熱備
  • Lvm/zfs snapshot - 物理備份
  • mydumper - 邏輯備份,熱備
  • cp - 物理備份,冷備

常用工具及用法 - mysqldump

MySQL官方自帶的命令列工具

主要示例:

  • 演示使用mysqldump備份表、庫、例項
# 備份所有資料庫
mysqldump -uroot -p123456 --socket=/var/run/mysqld/mysqld.sock --all-databases > /dbbackup/all_db.sql
# 備份指定的資料庫
mysqldump -uroot -p123456 --socket=/var/run/mysqld/mysqld.sock --databases db2 > /dbbackup/db2.sql
# 備份單個表
mysqldump -uroot -p123456 --socket=/var/run/mysqld/mysqld.sock db2 t1 >/dbbackup/db2_t1.sql
# 還原表
mysql > source /dbbackup/db2_t1.sql
  • 演示使用mysqldump製作一致性備份
mysqldump --single-transaction -uroot -p123456 --all-databases > /dbbackup/add_db_2.sql
  • 演示使用mysqldump遠端備份一個數據庫
mysqldump -utest -ptest -h192.168.0.68 -P3306 --all-databases > /dbbackup/remote_bakall.sql
  • 演示使用mysqldump匯出資料為csv格式
mysqldump -uroot -p123456 --single-transaction --fields-terminated-by=, db1 -T /tmp

常用工具及用法 - xtrabackup

特點:
* 開源,線上備份InnoDB表
* 支援限速備份,避免對業務造成影響
* 支援流備
* 支援增量備份
* 支援備份檔案壓縮與加密
* 支援並行備份與恢復,速度快

xtrabackup備份原理

  • 基於InnoDB的crash-recovery功能
  • 備份期間允許使用者讀寫,寫請求產生redo日誌
  • 從磁碟上拷貝資料檔案
  • 從InnoDB redo log file實時拷貝走備份期間產生的所有redo日誌
  • 恢復的時候 資料檔案 + redo日誌 = 一致性資料

實用指令碼innobackupex

  • 開源Perl指令碼,封裝呼叫xtrabackup及一系列相關工具與OS操作,最終完成備份過程
  • 支援備份InnoDB和其他引擎的表
  • 備份一致性保證

innobackupex備份基本流程

start xtrabackup_log -> copy .ibd; ibdata1 -> FLUSH TABLE WITH READ LOCK -> copy .FRM; MYD; MYI; misc files -> Get binary log position -> UNLOCK TABLES -> stop and copy xtrabackup_log

innobackupex使用

主要示例:

  • 全量備份
innobackupex --user=root --password=123456 --defaults-file=/etc/mysql/my.cnf /dbbackup
  • 增量備份
innobackupex --user=root --password=123456 --defaults-file=/etc/mysql/my.cnf --incremental --incremental-dir /dbbackup/2016-4-3_13:24:32 /dbbackup
  • 流方式備份
innobackupex --user=root --password=123456 --defaults-file=/etc/mysql/my.cnf --stream=xbstream /dbbackup/ > /dbbackup/stream.bak
  • 並行備份
innobackupex --user=root --password=123456 --defaults-file=/etc/mysql/my.cnf --parallel=4 /dbbackup/
  • 限流備份
innobackupex --user=root --password=123456 --defaults-file=/etc/mysql/my.cnf --throttle=10 /dbbackup/
  • 壓縮備份
innobackupex --user=root --password=123456 --defaults-file=/etc/mysql/my.cnf --compress --compress-thread 4 /dbbackup/

如何制定備份策略

需要考慮的因素

  • 資料庫是不是都是innodb引擎表 -> 備份方式,熱備or冷備
  • 資料量大小 -> 邏輯備份or物理備份,全量or增量
  • 資料庫本地磁碟空間十分充足 -> 備份到本地or遠端
  • 需要多塊恢復 -> 備份頻率 小時or天

5.3-MySQL資料恢復

什麼時候需要恢復資料

  • 硬體故障(如磁碟損壞)
  • 人為刪除(如誤刪除資料、被黑)
  • 業務回滾(如遊戲bug需要回檔)
  • 正常需求(如部署映象庫、檢視歷史某時刻資料)

資料恢復的必要條件

  • 有效備份
  • 完整的資料庫操作日誌(binlog)

資料恢復思路

  • 最新一次備份 + binlog恢復到故障時間點(適用於各種資料丟失場景)
  • 挖掘最後一次備份到故障點之間的binlog獲取相關SQL語句,構造反轉SQL語句並應用到資料庫(只是用於記錄丟失,且binlog必須是row格式)

反轉SQL語句

例:

t1(id primary key, a int)

反轉SQL語句:

insert into t(id, a) values(1, 1) -> delete t1 where id=1 and a=1
update t1 set a=5 where id=1 -> update t1 set a=1 where id=1
delete from t1 where id=1 -> insert into t(id, a) values(1, 1)

資料庫恢復工具與命令

  • mysqldump備份 -> source恢復
  • xtrabackup備份 -> xtrabackup恢復
  • binlog備份 -> mysqlbinlog恢復

詳細示例講解

  • 恢復某幾條誤刪資料
  • 恢復誤刪表、庫
  • 將資料庫恢復到指定時間點

恢復誤刪除資料

case:誤操作,刪除資料忘記帶完整條件,執行delete from user where age > 30 [and sex=male]

需求:將被刪除的資料還原

恢復前提:完整的資料庫操作日誌(binlog)

delete from user where sex='female';
# 首先需要找到binlog裡的資訊
mysqlbinlog -vv mysql-bin.000001
# 找出sql語句,然後寫出反轉sql語句

恢復誤刪表、庫

case:業務被黑,表被刪除了(drop teble user)

需求:將表恢復

前提:備份 + 備份以來完整binlog

innobackupex --apply-log /dbbackup/filename
# 檢視binlog的位置點
cat xtrabackup_binlog_info
# 檢視結束點
mysqlbinlog -vv filename

mysqlbinlog -vv --start-position=2556990 -- stop-position=2776338
mysqlbinlog -vv --start-position=2556990 -- stop-position=2776338 | mysql -uroot -p123456 --sock=/dbbackup/mysql_3309/mysqld.sock

課程小結

  • 恢復是已經非常苦逼的差事,儘量避免做。我們要做資料衛士而不是救火隊員。(線上應該嚴格把控許可權,資料變更操作應事先測試,操作時做好備份)
  • 有效備份(+binlog)是重中之重,對資料庫定期備份是必須的
  • 備份是一切資料恢復的基礎

5.4-MySQL線上部署

MySQL線上部署

考慮因素:

  • 版本選擇, 5.1、5.5還是5.6?
  • 分支選擇,官方社群版? percona server? Mariadb?
  • 安裝方式,包安裝?二進位制包安裝?原始碼安裝?
  • 路徑配置,引數配置(儘量模板化、標準化)
  • 一個例項多個庫 or 多個例項單個庫?

二進位制安裝MySQL

  • 下載軟體包
  • 解壓放到指定目錄(比如/usr/local)
  • 將MySQL目錄放到PATH中
  • 初始化例項,編輯配置檔案並啟動
  • 賬戶安全設定

編譯安裝MySQL

  • 下載MySQL原始碼安裝包
  • 安裝必要包(make cmake bison-devel ncurses-devel build-essential)
  • Cmake配置MySQL編譯選項,可以定製需要安裝的功能
  • make && make install
  • 初始化例項,編輯配置檔案並啟動
  • 賬戶安全設定

MySQL升級

  • 下載MySQL5.6安裝包並配置MySQL5.6安裝包安裝路徑
  • 關閉MySQL5.5例項,修改部分引數,使用MySQL5.6軟體啟動
  • 執行MySQL5.6路徑下mysql_upgrade指令碼
  • 驗證是否成功升級

MySQL多例項安裝

  • 部署好mysql軟體
  • 編輯多個配置檔案,初始化多個例項
  • 啟動MySQL例項

MySQL多例項部署

為啥多例項部署?

  • 充分利用系統資源
  • 資源隔離
  • 業務、模組隔離

MySQL線上安裝小結

  • 根據需求選擇合適的版本以及分支,建議使用或升級到較高版本5.5或5.6
  • 如果需要定製MySQL功能的話,可以考慮編譯安裝,否則的話建議使用二進位制包安裝,比較省事
  • 根據機器配置選擇部署多個MySQL例項還是單個例項,機器配置非常好的話,建議部署多例項

5.5-MySQL主從複製

MySQL主從複製

  • 一主一從
  • 主主複製
  • 一主多從
  • 多主一從
  • 聯級複製

MySQL主從複製用途

  • 實時災備,用於故障切換
  • 讀寫分離,提供查詢服務
  • 備份,避免影響業務

MySQL主從複製部署

主從部署必要條件

  • 主庫開啟binlog日誌(設定log-bin引數)
  • 主從server-id不同
  • 從庫伺服器能連通主庫

主從部署步驟:

  • 備份還原(mysqldump或xtrabackup)
  • 授權(grant replication slave on .)
  • 配置複製,並啟動(change master to)
  • 檢視主從複製資訊(show slave status\G)

MySQL複製存在的問題

存在的問題

  • 主機宕機後,資料可能丟失
  • 從庫只有一個sql thread,主庫寫壓力大,複製很可能延時

解決方法:

  • 半同步複製
  • 並行複製

MySQL semi-sync(半同步複製)

半同步複製

  • 5.5整合到MySQL,以外掛形式存在,需要單獨安裝
  • 確保事務提交後binlog至少傳輸到一個從庫
  • 不保證從庫應用完這個事務的binlog
  • 效能有一定的降低,響應時間更長
  • 網路異常或從庫宕機,卡住主庫,直到超時或從庫恢復

MySQL非同步複製

非同步複製

MySQL semi-sync(半同步複製)

半同步複製

配置MySQL半同步複製

只需一次:

主庫:

INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

從庫:

INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

動態設定:

主庫:

SET GLOBAL rpl_semi_sync_master_enabled=1;
SET GLOBAL rpl_semi_sync_master_timeout=N; master 延遲切非同步

從庫:

SET GLOBAL rpl_semi_sync_slave_enabled=1;

配置MySQL並行複製

並行複製

  • 社群版5.6中新增
  • 並行是指從庫多執行緒apply binlog
  • 庫級別並行應用binlog,同一個資料庫更改還是序列的(5.7版並行複製基於事務組)

設定

set global slave_parallel_workers=10; 設定sql執行緒數為10

聯級複製

A -> B -> C

B中新增引數:
log_slave_updates
B將把A的binlog記錄到自己的binlog日誌中

複製監控

查詢從庫狀態:

show slave status\G

複製出錯處理

常見:1062(主鍵衝突) 1032(記錄不存在)
解決:手動處理
或:
跳過複製出錯
set global sql_slave_skip_counter=1

總結

  • MySQL主從複製是MySQL高可用性、高效能(負載均衡)的基礎
  • 簡單、靈活,部署方式多樣,可以根據不同業務場景部署不同複製結構
  • MySQL主從複製目前也存在一些問題,可以根據需要部署複製增強功能來解決問題
  • 複製過程中應該時刻監控複製狀態,複製出錯或延時可能給系統造成影響
  • MySQL複製是MySQL資料庫工程師必知必會的一項基本技能

5.6-MySQL日常運維

DBA運維工作

日常
* 導資料、資料修改、表結構變更
* 加許可權、問題處理
其他
* 資料庫選型部署、設計、監控、備份、優化等

導資料及注意事項

  • 資料最終形式(csv、sql文字 還是直接匯入某庫中)
  • 導資料方法(mysqldump、select into outfile)
  • 導資料注意事項
    • 匯出為csv格式需要file許可權,而且只能資料庫本地導
    • 避免鎖庫鎖表(mysqldump使用——single-transaction選項不鎖表)
    • 避免對業務造成影響,儘量在映象庫做

資料修改及注意事項

  • 修改前切記做好備份
  • 開事務做,修改完檢查好了再提交
  • 避免一次 修改大量資料,可以分批修改
  • 避免業務高峰期做

表結構變更注意事項

  • 在低峰期做
  • 表結構變更是否會有鎖?(5.6包含online ddl功能)
  • 使用pt-online-schema-change完成表結構變更
    • 可以避免主從延時
    • 可以避免負載過高,可以限速

加許可權及注意事項

  • 只給符合需求的最低許可權
  • 避免授權時修改密碼
  • 避免給應用賬號super許可權

問題處理(資料庫慢?)

  • 資料庫慢在哪?
  • show processlist檢視mysql連線資訊
  • 檢視系統狀態(iostat, top, vmstat)

小結

  • 日常工作比較簡單,但是任何一個操作都可能影響線上服務
  • 結合不同環境,不同要求選擇最合適的方法處理
  • 日常工作應該求穩不求快,保障線上穩定是DBA的最大責任

5.7-MySQL引數調優

為什麼要調整引數

  • 不同伺服器之間的配置、效能不一樣
  • 不同業務場景對資料的需求不一樣
  • MySQL的預設引數只是個參考值,並不適合所有的應用場合

優化之前我們需要知道什麼

  • 伺服器相關的配置
  • 業務相關的情況
  • MySQL相關的配置

伺服器上需要關注哪些

  • 硬體情況
  • 作業系統版本
  • CPU、網絡卡節電模式
  • 伺服器numa設定
  • RAID卡快取

磁碟排程策略-write back

  • 資料寫入cache既返回,資料非同步的從cache刷入儲存介質

磁碟排程策略-write through

  • 資料同時寫入cache和儲存介質才返回寫入成功

Write Back VS Write Through

  • write Back 效能優於 Write Through
  • Write Through 比 Write Back安全性高

RAID

  • RAID Redundant Array of Independent Disks
    • 生產環境裡一般不太會用裸裝置,通常會使用RAID卡對一塊盤或多塊盤做RAID
    • RAID卡會預留一塊記憶體,來保證資料高效儲存與讀取
    • 常見的RAID型別有:RAID1、RAID0、RAID10和RAID5

RAID0 VS RAID1

  • RAID 0 - Block Striped. No Mirror. No Parity.
  • RAID 1 - Block Mirrored. No Stripe. No Parity.

RAID5 VS RAID10

  • RAID 5 - Block Striped. Distributed Parity.(至少三塊盤,每塊裡有兩個資料塊和一個校驗塊)
  • RAID 10 - Block Mirrored.(每兩塊盤做RAID1,然後再按組做RAID0,至少四塊盤)

RAID如何保證資料安全

  • BBU(Backup Battery Unit)
    • BBU保證在WB策略下,即使伺服器發生掉電或者宕機,也能夠將快取資料寫入到磁碟,從而保證資料的安全

MySQL有哪些注意事項

  • MySQL的部署安裝
  • MySQL的監控
  • MySQL引數調優

部署MySQL的要求

  • 推薦的MySQL版本: >= MySQL5.5
  • 推薦的MySQL儲存引擎: InnoDB

系統調優的依據:監控

  • 實時監控MySQL的slow log
  • 實時監控資料庫伺服器的負載情況
  • 實時監控MySQL內部狀態值

通常關注哪些MySQL Status

  • Com_Select/Update/Delete/Insert
  • Bytes_received/Bytes_sent
  • Buffer Pool Hit Rate
  • Threads_connected/Threads_created/Threads_running

MySQL引數調優

  • 為什麼要調整MySQL的引數
    • MySQL是通用資料庫,但業務是多變的,預設引數無法滿足所有業務需求
    • MySQL內部一些引數是在MySQL一些很老的版本時候做的,可能之前是做限流和保護用的,但隨著機器效能的提高,這些保護類的引數可能會成為效能瓶頸

讀優化

  • 合理利用索引對MySQL查詢效能至關重要
  • 適當的調整引數也能提升查詢效能

innodb_buffer_pool_size

  • InnoDB儲存引擎自己維護一塊記憶體區域完成新老資料的替換
  • 記憶體越大越能快取更多的資料

innodb_thread_concurrency

  • innoDB內部併發控制引數,設定為0代表不做控制
  • 如果併發請求較多,引數設定較小,後進來的請求將會排隊

寫優化

  • 表結構設計上使用自增欄位作為表的主鍵
  • 只對合適的欄位加索引,索引太多影響寫入效能
  • 監控伺服器磁碟IO情況,如果寫延遲較大則需要擴容
  • 選擇正確的MySQL版本,合理設定引數

哪些引數有助於提高寫入效能

  • innoDB_flush_log_at_trx_commit && sync_binlog
  • innodb log file size
  • innodb_io_capacity
  • innodb insert buffer

主要影響MySQL寫效能的兩個引數

  • innoDB_flush_log_at_trx_commit
  • sync_binlog

innoDB_flush_log_at_trx_commit

  • 控制InnoDB事務的重新整理方式,一共有三個值:0,1,2
    • N=0 - 每隔一秒,把事務日誌快取區的資料寫到日誌檔案中,以及把日誌檔案的資料重新整理到磁碟上(高效,但不安全)
    • N=1 - 每個事務提交時候,把事務日誌從快取區寫到日誌檔案中,並且重新整理日誌檔案的資料到磁碟上,優先使用此模式保障資料安全性(低效,非常安全)
    • N=2 - 每事務提交的時候,把事務日誌資料從快取區寫到日誌檔案中;每隔一秒,但不一定重新整理到磁碟上,而是取決於作業系統的排程(高效,但不安全)

sync_binlog

  • 控制每次寫入Binlog,是否都需要進行一次持久化

如何保證事務的安全

  • innoDB_flush_log_at_trx_commit 和 sync_binlog都設為1
  • 事務要和Binlog保證一致性

(加鎖)-> xa_prepare, Fsync -> Write And Fsync Binlog -> InnoDB Commit, Fsync ->(釋放鎖)

序列有哪些問題

  • SAS盤一般每秒只能有150~200個Fsync。
  • 換算到資料庫每秒只能執行50~60個事務

社群和官方的改進

  • MariaDB提出改進,即使這兩個引數都是1也能做到合併效果,效能得到了大幅提高。
  • 官方吸收了MariaDB的思想,並在此基礎上進行了改進,效能再次得到了提高

Tips:

  • 官方在MySQL5.6版本之後才做了這個優化
  • Percona和MariaDB版本在MySQL5.5已經包含了這個優化

InnoDB Redo log

  • Write ahead Log

Redo log的作用

  • Redo log用在資料庫崩潰會的故障恢復

Redo log有哪些問題

  • 如果寫入頻繁導致Redo log裡對應的最老的資料髒頁還沒有重新整理到磁碟,此時資料庫將卡住,強制重新整理髒頁到磁碟
  • MySQL預設配置兩個檔案才10M,非常容易寫滿,生產環境中應適當調整大小。

innodb_io_capacity

  • InnoDB每次刷多少個髒頁,決定InnoDB儲存引擎的吞吐能力。
  • 在SSD等高效能儲存介質下,應該提高該引數以提高資料庫的效能。

Insert Buffer

  • 順序讀寫 VS 隨機讀寫
  • 隨機請求效能遠小於順序請求

儘可能多的隨機請求合併為順序請求才是提高資料庫效能的關鍵

  • MySQL從5.1版本開始支援Insert Buffer
  • MySQL5.5版本之後同時支援update和delete的merge
  • Insert Buffer只對二級索引且非唯一索引有效

總結

  • 伺服器配置要合理(核心版本、磁碟排程策略、RAID卡快取)
  • 完善的監控系統,提前發現問題
  • 資料庫版本要跟上,不要太新,也不要太老
  • 資料庫效能優化:
    • 查詢優化:索引優化為主,引數優化為輔
    • 寫入優化:業務優化為主,引數優化為輔