看了這篇MySQL,開發功力再升級

1、查詢截取分析

1)慢查詢日誌

  
  • MySQL 的慢查詢日誌是MySQL提供的一種日誌記錄,它用來記錄在MySQL中響應時間超過閥值的語句,具體指運行時間超過long_query_time值的SQL,則會被記錄到慢查詢日誌中。mysql

  • 具體指運行時間超過long_query_time值的SQL,則會被記錄到慢查詢日誌中。long_query_time的默認值爲10,意思是運行10秒以上的語句。sql

  • 咱們能夠查看哪些SQL超出了咱們的最大忍耐時間值,好比一條SQL執行超過5秒鐘,咱們就算慢SQL,但願能收集超過5秒的sql,能夠結合以前explain進行全面分析。數據庫

開始使用:
默認狀況下,MySQL數據庫沒有開啓慢查詢日誌,須要咱們手動來設置這個參數。
經過show variables like '%slow_query_log' 查看是否開啓了慢查詢日誌
windows

圖片
設置方法:緩存

# 如下方式只對當前數據庫有效,MySQL重啓後失效
set global slow_query_log = 1;
set global long_query_time = 1.0;
# 主要從新鏈接或者新開一個會話才能看到修改值
set session long_query_time = 1.0;

永久生效就得修改 my.cnf服務器

slow_query_log = 1

#指定生成位置,若是沒有指定默認生成 host_name-slow.log
slow_query_log_file=/var/lib/mysql/cbuc_slow.log

開啓後若是long_query_time沒有指定,默認爲10秒,那麼假如運行時間正好等於long_query_tie的狀況,並不會被記錄下來,也就是說在mysql源碼裏面的判斷是大於long_query_time,而非大於等於
實驗:session

# 手動製造一條慢SQL
select sleep(9)

跟蹤日誌文件 :tail -50f cbuc_slow.log
數據結構

圖片
查詢當前系統中有多少條慢查詢:併發

show global status like '%Slow_queries%'

【配置小結】
在 my.ini或者my.cnf配置文件下的配置異步

show_query_log = 1;
show_query_log_file = /var/lib/mysql/cbuc_slow.log
long_query_time = 3;
log_output = FILE

日誌分析工具mysqldumpslow
查看mysqldumpslow的幫助信息:

  1. s:是表示按照何種方式排序;

  2. c:訪問次數

  3. l:鎖定時間

  4. r:返回記錄

  5. t:查詢行數

  6. al:平均鎖定時間  

  7. ar:平均返回記錄數

  8. at:平均查詢時間

  9. t:即爲返回前面多少條的數據

  10. g:後邊搭配一個正則匹配模式,大小寫不敏感

【使用參考】
一、 獲得返回記錄集最多的10個SQL

mysqldumpslow -s -t 10 /var/lib/mysql/cbuc_slow.log

二、 獲得訪問次數最多的10個SQL

mysqldumpslow -s -c -t 10 /var/lib/mysql/cbuc_slow.log

三、 獲得按照時間排序的前10條裏面含有左鏈接的查詢語句

mysqldumpslow -s -t -t 10 -g "left join"  /var/lib/mysql/cbuc_slow.log

四、 另外建議在使用這些命令是結合 | 和 more使用, 不然有可能出現爆屏的狀況

mysqldumpslow -s r -t 10 /var/lib/mysql/cbuc_slow.log | more

2)Show Profile

  
  • 是mysql提供能夠用來分析當前會話中語句執行的資源消耗狀況,能夠用於SQL的調優的測量

  • 默認狀況下,參數處於關閉狀態,並保存最近15次的運行結果

【分析步驟】

  • 查看是否支持

# 默認是關閉,使用前須要開啓
show variables like 'profiling';

圖片

  • 開啓

set profiling = 1;


  • 測試

# 運行兩個SQL查看
select * from tbl_emp a left join tbl_dept b on a.deptId = b.id
select * from tbl_emp a right join tbl_dept b on a.deptId = b.id

查看結果 :

圖片
圖片
參數說明:

  • ALL:顯示全部的開銷信息

  • BLOCK IO :顯示塊 IO 相關開銷

  • CONTEXT SWITCHES :上下文切換相關開銷

  • CPU :顯示CPU相關開銷信息

  • IPC :顯示發送和接收相關開銷信息

  • MEMORY :顯示內存相關開銷信息

  • PAGE FAULTS :顯示頁面錯誤相關開銷信息

  • SOURCE :顯示和Source_function,Source_file,Source_line 相關的開銷信息

  • SWAPS :顯示交換次數相關開銷的信息

3)全局查詢日誌

  • 配置啓用
    在 mysql 的my.cnfmy.ini中設置

# 開啓
general_log = 1

# 記錄日誌文件的路徑
general_log_file = /path/logfile

# 輸出格式
log_output = FILE
  • 編碼啓用
    命令:set global general_log = 1;
    全局日誌能夠存放在日誌文件文件中,也能夠存放在MySQL系統表中。存放在日誌中性能會更好一些,存儲到表中:
    set global log_output = 'TABLE'
    此後,你所編寫的sql 語句,將會記錄到mysql 庫裏的 general_log 表,能夠用下面的命令查看
    select * from mysql.general_log

2、Mysql鎖機制

1)概述

鎖是計算機協調多個進程或線程併發訪問某一資源的機制。
在數據庫中,除傳統的計算資源(如CPU、RAM、I/O等)的爭用之外,數據也是一種供許多用戶共享的資源。如何保證數據併發訪問的一致性,有效性是全部數據庫必須解決的一個問題,鎖衝突也是影響數據庫併發訪問性能的一個重要因素。從這個角度來講,鎖對數據庫而言顯的尤爲重要,也更加複雜。

【案例理解】
一件商品這個時候只有一件庫存,可是同時用A、B兩我的要下單,那麼是A下單成功仍是B下單成功。
這種時候就要使用到事務,咱們要先從庫存表中取出物品數量,而後生成訂單,付款成功後生成付款信息,再更新商品數量。這個流程中,咱們須要使用到鎖對有限的資源進行保護,解決隔離和併發問題。
【鎖的分類】

  • 從數據操做的類型劃分 (讀/寫鎖)

  1. 讀鎖(共享鎖): 針對同一份數據,多個讀操做能夠同時進行而不會互相影響。

  2. 寫鎖(排它鎖): 當前寫操做沒有完成前,它會阻斷其餘寫鎖和讀鎖。

  • 從數據操做的顆粒度劃分

  1. 表鎖

  2. 行鎖

2)三級鎖

【表鎖】
特色:(偏讀)

偏向MyISAM存儲引擎,開銷小,加鎖快; 無死鎖; 鎖定粒度大; 發生鎖衝突的機率高,併發度最低。
  • 手動加鎖:

lock table <table_name1> <read/write>,<table_name2> <read/write>
  • 查看錶上加過的鎖:

show open tables;


  • 釋放表鎖

unlock tables;

讀鎖說明:
新建兩個session會話,session1 和session2
此時在session1中對mylock表進行read 鎖定,狀況以下:

  1. session1能夠查詢該表的信息,session2也能夠查詢該表的記錄

  2. session1中不能查詢其餘沒有鎖定的表,session2能夠查詢和更新其它沒有鎖定的表

  3. session1插入或更新鎖定的表都會提示錯誤,session2插入或更新鎖定的表會一直等待。

  4. 當session1釋放鎖後,session2以前插入或更新執行完成。

寫鎖說明:
一樣新建兩個session會話,session1 和session2
此時在session1中對mylock表進行write 鎖定,狀況以下:

  1. session1 對鎖定表的查詢+更新+插入操做均可以執行,session2 對鎖定表的查詢 被阻塞,須要等待鎖的釋放。可是若是session2以前有數據緩存,則能夠讀出緩存數據,一旦數據發生改變,緩存將失效,操做將被阻塞。

【小結】
MyISAM在執行查詢語句的前,會自動給涉及的全部表加讀鎖,在執行增刪改操做前,會自動給涉及的表加寫鎖。

鎖類型 他人可讀 他人可寫
讀鎖
寫鎖

一、 對MyISAM表的讀操做(加讀鎖),不會阻塞其餘進程對同一表的讀請求,但會阻塞對同一表的寫請求,只有當讀鎖釋放後,纔會執行其餘進程的寫操做。
二、 對MyISAM表的寫操做(加寫鎖),會阻塞其餘線程對同一表的讀和寫操做,只用當寫鎖釋放後,纔會執行其餘進程的讀寫操做。
總結:讀鎖會阻塞寫,可是不會阻塞讀。而寫鎖則會把讀和寫都阻塞
【行鎖】
特色:(偏讀)

偏向InnoDB存儲引擎,開銷大,加鎖慢; 會出現死鎖; 鎖定粒度最小,發生鎖衝突的機率最低,併發度也最高。

InnoDB與MyISAM的最大不一樣有兩點:

  • 支持事務(TRANSACTION)

  • 採用了行級鎖

事務複習:
事務是由一組SQL語句組成的邏輯處理單元,事務具備如下4個屬性,一般簡稱爲事務的ACID屬性。

  • 原子性(Atomicity): 事務是一個原子操做的單元,其對數據的修改,要麼所有執行,要麼全都不執行。

  • 一致性(Consistent):在事務開始和完成時候,數據都必須保持一致狀態。這意味着全部相關的數據規則都必須應用於事務的修改,以保持數據的完整性;事務結束時,全部內部的數據結構(如B樹索引或雙向鏈表)也都必須是正確的。

  • 隔離性(Isolation):數據庫系統提供必定的隔離機制        ,保證事務在不受外部併發操做影響的「獨立」環境執行。這意味着事務處理過程當中的中間狀態對外部是不可見的,反之亦然。

  • 持久性(Durable):事務完成以後,它對於數據的修改是永久性的,即便出現系統故障也可以保持。

併發事務處理帶來的問題:

  • 更新丟失(Lost Update)
    當兩個或多個事務選擇同一行,而後基於最初選定的值更新該行是,因爲每一個事務都不知道其餘事務的存在,就會發生丟失更新的問題 -- 最後的更新覆蓋了由其餘事務所作的更新。

  • 髒讀(Dirty Reads)
    事務A讀取到了事務B已修改但還沒有提交的數據,還在這個數據基礎上作了操做。此時,若是B事務回滾,A讀取的數據無效,不符合一致性要求。

  • 不可重複讀(Non-Repeatable Reads)
    一個事務範圍內兩個相同的查詢卻返回了不一樣數據。

  • 幻讀(Phantom Reads)
    一個事務按相同的查詢從新讀取之前檢索過的數據,卻發現其餘事務插入了知足其查詢條件的新數據,這種現象就稱爲「幻讀」。也就是說事務A讀取到了事務B提交的新增數據,不符合隔離性。

事務隔離級別:

# 查看事務的隔離級別
show variable like 'tx_isolate'
隔離級別 讀數據一致性 髒讀 不可重複讀 幻讀
未提交讀(Read uncommitted) 最低級別,只能保證不讀取物理上損壞的數據
已提交讀(Read committed) 語句級
可重複讀(Repeatable read) 事務級
可序列化(Serializable) 最高級別,事務級

數據庫的事務隔離越嚴格,併發反作用越小,但付出的代價也就越大,由於事務隔離實質上就是使事務在必定程度上「串行化」進行,這顯然與「併發」是矛盾的。同時,不一樣的應用對讀一致性和事務隔離程度的要求也是不一樣的,好比許多應用對「不可重複讀」和「幻讀」並不敏感,可能更關心數據併發訪問的能力。
無索引時行鎖會升級爲表鎖
經過select加鎖:
讀鎖(共享鎖):
加上讀鎖後,其餘事務能夠併發讀取數據,但任何事務都不能對數據進行修改(獲取數據上的排它鎖),直到已釋放全部共享鎖。
若是事務T對數據A加上共享鎖後,則其餘事務只能對A再加共享鎖,不能加排他鎖。獲准共享鎖的事務只能讀數據,不能修改數據。

# 經過這段加鎖,Mysql會對查詢結果中的每行都加共享鎖
select ... <lock in share mode>

寫鎖(排他鎖):
加上排它鎖後,其餘事務不能再對A加任何類型的鎖。已獲取到排它鎖的事務既能讀數據,又能修改數據。

# 經過這段加鎖,mysql會對查詢結果中的每行都加排他鎖
select ... for update;

間隙鎖:
當咱們用範圍條件而不是相等條件檢索數據,並請求共享或排他鎖時,InnoDB會給符合條件的已有數據記錄的索引項加鎖;對於鍵值在條件範圍內但並不存在的記錄,叫作「間隙(GAP)」
InnoDB也會對這個「間隙」加鎖,這種鎖機制就是所謂的間隙鎖(GAP Lock)
危害:
由於Query執行過程當中經過範圍查找的話,他會鎖定整個範圍內全部的索引鍵值,即便這個鍵值並不存在,間隙鎖有一個比較致命的弱點,就是當鎖定一個範圍鍵值以後,即便某些不存在的鍵值也會被無辜的鎖定,而形成在鎖定的時候沒法插入鎖定鍵值範圍內的任何數據。在某些場景下這可能會對性能形成很大的危害
優化建議:

  1. 儘量讓給全部數據檢索都經過索引來完成,避免無索引行鎖升級爲表鎖。

  2. 儘量較少檢索條件,避免間隙鎖。

  3. 儘可能控制事務大小,減小鎖定資源量和時間長度。

  4. 鎖住某行後,儘可能不要去調別的行或表,趕忙處理被鎖住的行而後釋放掉鎖。

  5. 涉及相同表的事務,對於調用表的順序儘可能保持一致。

  6. 在業務環境容許的狀況下,儘量低級別事務隔離。
    【頁鎖】
    開銷和加鎖時間介於表鎖和行鎖之間,會出現死鎖;鎖定粒度介於表鎖和行鎖之間,併發度通常。

3、主從複製

1)複製的基本原理

slave 會從 master 讀取binlog來進行數據同步

【三個步驟】

  • master將改變記錄到二進制日誌(binary log)。這些記錄過程叫作二進制日誌時間,binary log events

  • slave將master的binary log events拷貝到它的中繼日誌中(relay log)

  • slave重作中繼日誌中的事件,將改變應用到本身的數據庫中,mysql複製是異步的且串行化的。

    圖片

2)複製的基本原則

  • 每一個slave 只有一個master

  • 每一個slave只能有一個惟一的服務器ID

  • 每一個master能夠有多個slave

複製的最大問題: 延遲

3)主從常見配置

mysql 版本一致且後臺以服務運行,主從配置都在[mysqld]結點下,都是小寫
【主機修改my.ini配置文件】

  • [必須] 主服務器惟一ID

server-id = 1
  • [必須] 啓用二進制文件

log-bin = 本身本地的路徑/data/mysqlbin
log-bin = D:/devSoft/MySQLServer5.5/data/mysqlbin
  • [可選] 啓用錯誤日誌

log-err = 本身本地的路徑/data/mysqlerr
log-err = D:/devSoft/MySQLServer5.5/data/mysqlerr
  • [可選] 根目錄

basedir = "本身本地路徑"
basedir = D:/devSoft/MySQLServer5.5/
  • [可選] 臨時目錄

tmpdir = "本身本地路徑"
tmpdir =  D:/devSoft/MySQLServer5.5/
  • [可選] 數據目錄

datadir = "本身本地路徑"
datadir =  D:/devSoft/MySQLServer5.5/data/
  • read-only = 0
    主機讀寫均可以

  • [可選] 設置不要複製的數據庫

binlog-ignore-db = mysql
  • [可選] 設置須要複製的數據庫

binlog-do-db = 須要複製的數據庫的名字

【從機修改my.ini配置文件】

  • [必須] 從服務器惟一ID

  • [可選] 啓用二進制文件

    【修改後,主從機都須要重啓後臺mysql服務】
    【主從機都須要關閉防火牆】
    【在windows主機上創建帳戶並受權slave】

  • 步驟1:

GRANT REPLICATION SLAVE ON *.* TO 'zhangsan'@'從機的數據庫IP'INDETIFIED BY '123456'
  • 步驟2:

flush privileges;
  • 查看master狀態

show master status;
# 記錄File和Position 的值

圖片

  • 執行完以上步驟便不要再操做,防止主服務器狀態值發生改變

【在Linux從機上配置須要複製的主機】

  • 步驟1

change master to master_host = '主機IP',master_user='zhangsan',master_password = '123456',master_log_file='file名字',master_log_pos=position數字

圖片

  • 步驟2:
    啓動從服務器複製功能

start slave;
  • 步驟3:

show slave status
#下面兩個參數都是Yes,便說明主從配置成功Slave_IO_Running:YesSlave_SQL_running:Yes
相關文章
相關標籤/搜索