「
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的幫助信息:
s:是表示按照何種方式排序;
c:訪問次數
l:鎖定時間
r:返回記錄
t:查詢行數
al:平均鎖定時間
ar:平均返回記錄數
at:平均查詢時間
t:即爲返回前面多少條的數據
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
「
是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 :顯示交換次數相關開銷的信息
配置啓用
在 mysql 的my.cnf
或my.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
「鎖是計算機協調多個進程或線程併發訪問某一資源的機制。
在數據庫中,除傳統的計算資源(如CPU、RAM、I/O等)的爭用之外,數據也是一種供許多用戶共享的資源。如何保證數據併發訪問的一致性,有效性是全部數據庫必須解決的一個問題,鎖衝突也是影響數據庫併發訪問性能的一個重要因素。從這個角度來講,鎖對數據庫而言顯的尤爲重要,也更加複雜。
【案例理解】
一件商品這個時候只有一件庫存,可是同時用A、B兩我的要下單,那麼是A下單成功仍是B下單成功。
這種時候就要使用到事務,咱們要先從庫存表中取出物品數量,而後生成訂單,付款成功後生成付款信息,再更新商品數量。這個流程中,咱們須要使用到鎖對有限的資源進行保護,解決隔離和併發問題。【鎖的分類】
從數據操做的類型劃分 (讀/寫鎖)
讀鎖(共享鎖): 針對同一份數據,多個讀操做能夠同時進行而不會互相影響。
寫鎖(排它鎖): 當前寫操做沒有完成前,它會阻斷其餘寫鎖和讀鎖。
從數據操做的顆粒度劃分
表鎖
行鎖
【表鎖】
特色:(偏讀)
「 偏向MyISAM存儲引擎,開銷小,加鎖快; 無死鎖; 鎖定粒度大; 發生鎖衝突的機率高,併發度最低。
手動加鎖:
lock table <table_name1> <read/write>,<table_name2> <read/write>
查看錶上加過的鎖:
show open tables;
釋放表鎖
unlock tables;
讀鎖說明:
新建兩個session會話,session1 和session2
此時在session1中對mylock表進行read 鎖定,狀況以下:
session1能夠查詢該表的信息,session2也能夠查詢該表的記錄
session1中不能查詢其餘沒有鎖定的表,session2能夠查詢和更新其它沒有鎖定的表
session1插入或更新鎖定的表
都會提示錯誤,session2插入或更新鎖定的表
會一直等待。
當session1釋放鎖後,session2以前插入或更新執行完成。
寫鎖說明:
一樣新建兩個session會話,session1 和session2
此時在session1中對mylock表進行write 鎖定,狀況以下:
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執行過程當中經過範圍查找的話,他會鎖定整個範圍內全部的索引鍵值,即便這個鍵值並不存在,間隙鎖有一個比較致命的弱點,就是當鎖定一個範圍鍵值以後,即便某些不存在的鍵值也會被無辜的鎖定,而形成在鎖定的時候沒法插入鎖定鍵值範圍內的任何數據。在某些場景下這可能會對性能形成很大的危害優化建議:
儘量讓給全部數據檢索都經過索引來完成,避免無索引行鎖升級爲表鎖。
儘量較少檢索條件,避免間隙鎖。
儘可能控制事務大小,減小鎖定資源量和時間長度。
鎖住某行後,儘可能不要去調別的行或表,趕忙處理被鎖住的行而後釋放掉鎖。
涉及相同表的事務,對於調用表的順序儘可能保持一致。
在業務環境容許的狀況下,儘量低級別事務隔離。【頁鎖】
開銷和加鎖時間介於表鎖和行鎖之間,會出現死鎖;鎖定粒度介於表鎖和行鎖之間,併發度通常。
「 slave 會從 master 讀取binlog來進行數據同步
【三個步驟】
master將改變記錄到二進制日誌(binary log)。這些記錄過程叫作二進制日誌時間,binary log events
slave將master的binary log events拷貝到它的中繼日誌中(relay log)
slave重作中繼日誌中的事件,將改變應用到本身的數據庫中,mysql複製是異步的且串行化的。
每一個slave 只有一個master
每一個slave只能有一個惟一的服務器ID
每一個master能夠有多個slave
複製的最大問題: 延遲
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