MySQL高級

MySQL高級

下載與安裝

MySQL下載地址
在這裏插入圖片描述
安裝

rpm -ivh MySQL-server-5.5.48-1.linux2.6.x86_64.rpm
rpm -ivh MySQL-client-5.5.48-1.linux2.6.x86_64.rpm

修改初始密碼

/usr/bin/mysqladmin -u root password 密碼

設置開機自啓

chkconfig mysql on

修改配置文件

設置字符集

將初始配置文件複製到/etc下命名爲my.cnf

cd /usr/share/mysql/
cp my-huge.cnf /etc/my.cnf

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

mysql架構

它的架構可以在多種不同的場景中應用併發揮良好的作用,插件式的存儲引擎架構將查詢處理和其它的系統任務以及數據庫的存儲提取分離
在這裏插入圖片描述

連接層

最上層的是一些客戶端和連接服務,包含本地sock通信和大多數基於客戶端/服務端工具實現的類似於TCP/IP的通信。主要完成一些類似於連接處理、授權認證及相關的安全方案。在該層引入了線程池的概念,爲通過認證安全接入的客戶端提供線程。同樣在該層上可以實現基於SSL的安全連接,服務器也會爲安全接入的每個客戶端驗證它所具有的操作權限

服務層

第二層架構主要完成大多數的核心服務功能,如SQL接口,並完成緩存的查詢,SQL的分析和優化及部分內置函數的執行,所有跨存儲引擎的功能也在這一層實現,如過程、函數等,在該層,服務器會解析查詢並創建相應的內部解析樹,並對完成相應的優化如確定查詢表的順序,是否利用索引等,最後生成相應的執行操作。如果是select語句,服務器還會查詢內部的緩存,如果緩存的空間足夠大,這樣在解決大量的讀操作的環境中能夠很好地提升系統性能

引擎層

存儲引擎層,真正的負責了MySQL中數據的存儲和提取,服務器通過API與存儲引擎進行通信。不同的存儲引擎具有的功能不同,這樣我們可以根據自己的實際需要進行選取

存儲層

主要講數據存儲在運行與裸設備的文件系統之上,並完成與存儲引擎的交互

存儲引擎

MyISAM和InnoDB

在這裏插入圖片描述

索引

MySQL官方對索引的定義:索引是幫助MySQL高效獲取數據的數據結構,索引的本質:索引是數據結構
索引可以理解爲:排好序的快速查找數據結構
索引本身也很大,所以索引以文件的形式存儲在磁盤上
平常所說的索引,一般是指B樹結構組織的索引。其中聚集索引,次要索引、複合索引、前綴索引、唯一索引默認都是使用B+樹索引,除了B+樹索引,還有哈希索引等

索引優勢

提高數據檢索的效率,降低數據庫的IO成本
通過索引列對數據進行排序,降低數據排序的成本,降低了CPU消耗

索引劣勢

索引也是一張表,該表保存了主鍵與索引字段,並指向實體表的記錄,所以索引也要佔空間
雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,調整因爲更新所帶來的鍵值變化後的索引信息
索引只是提高效率的一個因素,如果MySQL有大量的數據,就需要花時間研究建立最優秀的索引

索引分類

  • 單值索引:即一個索引只包含單個列,一個表可以有多個單值索引
  • 唯一索引:索引列的值必須唯一,但允許有null值
  • 複合索引:即一個索引包含多個列

基本語法

創建

create 【unique】index indexName on mytable(columnName(length));

alter mytable add [unique] index [indexName] on (columnName(length));

刪除

drop index [indexName] on mytable;

查看

show index from tableName\G;

索引結構

BTree索引

  • 一顆B+樹真實的數據存在於葉子節點
  • 非葉子節點不存儲真實數據,只存儲指引搜索方向的數據項
  • 3層的B+樹可以表示上百萬的數據,如果上百萬的數據查找只需要三次IO性能提高將是巨大的
    Hash索引
    full-text全文索引
    R-Tree索引

需要創建索引的條件

  • 主鍵自動建立唯一索引
  • 頻繁作爲查詢條件的字段
  • 查詢中與其它表關聯的字段,外鍵關係建立索引
  • where條件裏用到的字段
  • 在高併發下傾向創建組合索引
  • 查詢中排序的字段,排序字段通過索引訪問將大大提高排序速度
  • 查詢中統計或者分組的字段

不需要創建索引的情況

  • 頻繁更新的索引不適合創建索引
  • 表記錄太少
  • 數據重複且分佈平均的表字段,如果某個數據列包含許多重複的內容,爲它建立索引就沒有實際效果

性能分析

MySQL Query Optimizer

MYSQL會按自己的優化策略檢索,但不見得是DBA認爲最優的

MySQL常見瓶頸

  • CPU:CPU在飽和的時候一般發生在數據裝入內存或從磁盤上讀取數據的時候
  • IO:磁盤I/O瓶頸發生在裝入數據遠大於內存容量的時候
  • 服務器硬件性能瓶頸:top,free,iostat和vmstat 來查看系統的性能狀態

Explain

使用EXplain關鍵字可以模擬優化器執行SQL查詢語句,從而知道MySQL是如何處理SQL語句的
用法:

Explain SQL語句

可以獲取的信息:

  • 表的讀取順序
  • 數據讀取操作的操作類型
  • 那些索引可以使用
  • 那些索引被實際使用
  • 表之間的引用
  • 每張表有多少行被優化器查詢
explain字段解釋

id:

  • select查詢的序列號,包含一組數字,表示查詢中執行select子句或操作表的順序
  • 兩種情況:
    id相同,執行順序由上至下
    id不同,如果是子查詢,id的序號會遞增,id值越大優先級越高

select_type
查詢的類型,主要是用於區別普通查詢、聯合查詢、子查詢等的複雜查詢

關鍵字 解釋
SIMPLE 簡單的select查詢,查詢中不包含子查詢或者UNION
PRIMARY 查詢中若包含任何複雜的子部分,最外層查詢則被標記
SUBQUERY 在select或where列表中包含子查詢
DERIVED 在from列表中包含的子查詢被標記爲DERIVED(衍生)MySQL會遞歸執行這些子查詢,把結果放在臨時表裏
UNION 若第二個select出現在UNION之後,則被標記爲UNION,若UNION包含在FROM子句的子查詢中,外層SELECT將被標記爲UNION
UNION RESULT 從UNION表獲取結果的SELECT

table:數據來自哪張表
type

  • 顯示查詢使用了何種類型,從好到差依次是:system>const>eq_ref>ref>range>index>ALL
關鍵字 解釋
system 表中只有一行數據(等於系統表),這是const類型的特例,一般不會出現
const 表示通過索引一次就找到了,const用於比較primary key或者unique索引,因爲只匹配一行數據,所以很快,如將主鍵置於where列表中,MySQL就能將查詢轉換爲一個常量
eq_ref 唯一性索引掃描,對於每個索引鍵,表中只有一條數據與之匹配,常見於主鍵或唯一性索引掃描
ref 非唯一性索引掃描,返回匹配某個單獨值的所有行,本質上也是一種索引訪問,它返回所有匹配某個單獨值的行
range 只檢索給定範圍的行,使用一個索引來選擇行,key列顯示使用了哪個索引一般就是在你的where語句中出現between、<、>、in等查詢
index Full Index Scan,index與ALL區別爲類型只遍歷索引樹,這通常比ALL快,因爲索引文件通常比數據文件小
all Full Table Scan,將遍歷全表以找到匹配的行

一般來說,得保證查詢至少達到range級別,最好能達到ref

key

  • 實際使用的索引,如果爲null,則沒有使用索引

  • 查詢中若使用了覆蓋索引,則該索引僅出現在key列表中
    possible_key

  • 顯示可能應用在這張表中的索引,一個或多個

  • 查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢實際使用

key_len

  • 表示索引中使用的字節數,可通過該列計算查詢中使用的索引長度。在不損失精確度的情況下,長度越短越好
  • key_len顯示的值爲索引字段的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的

ref

  • 顯示索引的那一列被使用了,如果可能,是一個常數,哪些列或常量被用於查找索引列上的值

rows

  • 根據表統計信息及索引選用情況,大致估算出找到所需要的記錄需要讀取的行數
    Extra

  • 包含不適合在其它列中顯示但十分重要的額外信息

關鍵字 解釋
Using filesort 說明MySQL會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取,MySQL中無法利用索引完成的排序操作稱爲"文件排序"
Using temporary 使用了臨時表保存中間結果,MySQL在對查詢結果排序時使用臨時表。常見於排序order by和分組查詢group by
Using Index 表示相應的select操作使用了覆蓋索引,避免訪問表的數據行,如果同時出現using where,表明索引被用來執行索引鍵值的查找,如果沒有同時出現using where,表明索引用來讀取數據而非執行查找操作
using where 使用了where過濾
using join buffer 使用了連接緩存
impossible where where子句的值總是false,不能來獲取任何元組
select tables optimized away 在沒有group by子句的情況下,基於索引優化min/max操作或者對於MyISAM存儲引擎優化count(*),不必等到執行階段再進行計算,查詢執行計劃生成的階段即完成優化
distinct 優化distinct操作,在找到第一匹配的元組後即停止找同樣值的動作

索引優化

  • 全值匹配我最愛,最左前綴要遵守
  • 帶頭大哥不能死,中間兄弟不能斷
  • 索引列上少計算,範圍之後全失效
  • like百分寫最右,覆蓋索引不寫星
  • 不等空值還有or,索引失效要少用
  • var引號不可丟,SQL高級也不難

索引分析

單表

  • 覆蓋索引中,範圍查詢會導致後面的索引失效
EXPLAIN select id
from article
where category_id=1
and comments=1
ORDER BY views
limit 0,1;

show index from article;

CREATE index idx_article_ccv on article(category_id,comments,views);

DROP index idx_article_ccv on article;

CREATE index idx_article_cv on article(category_id,views);

兩表

  • 左連接右表建索引
  • 右連接左表建索引
ALTER TABLE book ADD INDEX Y(card);
EXPLAIN select * from class left join book on class.card=book.card;

三表

alter table phone add index z(card);
alter table book add index Y(card);

EXPLAIN select * from class 
left join book on class.card=book.card
left join phone on book.card=phone.card;

在這裏插入圖片描述

  • 後兩行的type都是ref,因此索引最好設置在需要經常查詢的字段中

join語句的優化

  • 儘可能減少join語句中的NestedLoop的循環總次數:“永遠用小結果集驅動大結果集”
  • 優先優化NestedLoop的內層循環
  • 保證join語句中被驅動表上join條件字段已經被索引
  • 當無法保證被驅動表的join條件字段被索引且內存資源充足前提下,不要太吝嗇joinbuffer的設置

索引失效

1、全值匹配
2、左前綴法則:如果索引了多列,要遵守最左前綴法則,指的是查詢從索引的最左前列開始並且不跳過索引中的列
3、不在索引列上做任何操作(計算、函數、類型轉換),會導致索引失效而轉向全表掃描
4、存儲引擎不能使用索引中範圍條件範圍條件右邊的列
**5、儘量使用覆蓋索引(只訪問索引的查詢,索引列和查詢列一致,減少select ***
6、MySQL在使用不等於的時候無法使用索引會導致全表掃描
7、is null,is not null 也無法使用索引
8、like以通配符開頭MySQL索引失效變成全表掃描

  • 使用覆蓋索引解決通配符開頭索引失效的問題
    9、字符串不加單引號索引失效
    10、少用or,用它來連接時會索引失效

定值、範圍還是排序,一般order by是給個範圍,group by 基本上都需要排序,會有臨時表產生

注意

對於單鍵索引,儘量選擇針對當前query過濾性更好的索引
在選擇組合索引時,當前query中過濾性最好的字段在索引字段順序中,位置越靠左越好
在選擇組合索引時,儘量選擇可以包含當前query中的where子句中更多字段的索引
儘可能通過分析統計和調整query的寫法來達到選擇合適索引的目的

查詢截取分析

  • 慢查詢的開啓並捕獲
  • explain+慢SQL分析
  • show profile查詢SQL在MySQL服務器裏面的執行細節和生命週期
  • SQL數據庫服務器的參數調優

查詢優化

  • 優化原則:小表驅動大表,即小的數據集驅動大的數據集
select * from A where id in (select id from B)
等價於
for select id from  B
for select * from A where A.id=B.id

當B表的數據集小於A表的時候,用in優於exists

select * from A where exists (select 1 from B where B.id=A.id)
等價於
for select * from A
for select * from B where B.id=A.id

當A表的數據集小於B表的數據集,用exists優於in

order by關鍵字優化
  • order by子句,儘量使用index方式排序,避免使用filesort方式排序
  • 儘可能在索引列上完成排序操作,遵照索引建的最佳左前綴
  • 如果不在索引列上,filesort有兩種算法:MySQL就要啓動雙路排序和單路排序
    雙路排序
    MySQL4.1之前是使用雙路排序,字面意思是兩次掃描磁盤,最終的導數據,讀取行指針和order by列,對它們進行排序,然後掃描已經排好序的列表,按照列表中的值重新從列表中讀取
    從磁盤取排序字段,在buffer進行排序,再從磁盤取其它字段
    取一批數據,要對磁盤進行兩次掃描,I\O很耗時,4.1之後出現了第二種改進算法,單路排序
    單路排序
    從磁盤讀取查詢需要的所有列,按照order by列在buffer對它們進行排序,然後掃描排序後的列表進行輸出,它的效率更快,避免了第二次讀取數據。並且把隨機IO變成了順序IO,但它會使用更多的空間,因爲它把每一行都保存在內存中了
    緩存問題
    在sort_buffer中,單路比雙路佔用很多的空間,因爲單路是把所有字段都取出,所以有可能取出的數據總大小超出了sort_buffer的容量,導致每次只能取sort_buffer容量大小的數據,進行排序(創建tmp文件,多路合併),排完再取sort_buffer容量的大小,出現多次I\O
  • 優化策略

增大sort_buffer_size參數的設置
增大max_length_for_sort_data的參數

group by關鍵字優化
  • group by實質是先排序後進行分組,遵照索引建的最佳左前綴
  • 當無法使用索引列,增大max_length_for_sort_data參數和sort_buffer_size
  • where高於having,能在where限定的條件就不要去having限定了

慢查詢日誌

  • MySQL的慢查詢日誌是MySQL提供的一種日誌記錄,它用來記錄在MySQL中相應時間超過閾值的語句,具體指運行時間超過long_query_time值得SQL,則會被記錄在慢查詢日誌中
  • long_query_time的默認值爲10,也就是10秒
  • 結合explain進行全面分析
慢查詢日誌查看與開啓
  • MySQL默認情況下沒開啓慢查詢日誌
  • 一般不建議開啓,會影響性能

查看

show variables like '%slow_query_log%';

開啓

set global slow_query_log=1;

設置慢的閾值時間

set global long_query_time=3;
修改後需要重新連接或新開一個會話才能看到修改值

查看閾值時間

show global variables like 'long_query_time';

查詢當前系統中有多少條慢查詢記錄

show global status like '%slow_queries%';

如果要永久生效,必須修改配置文件my.cnf

【mysqld】下配置
slow_query_log=1;
slow_query_log_file=/var/lib/mysql/slow.log
long_query_time=3;
log_output=FILE
日誌分析工具mysqldumpslow
命令 含義
s 表示按照何種方式排序
c 訪問次數
l 鎖定時間
r 返回記錄
t 查詢時間
al 平均鎖定時間
ar 平均返回記錄數
at 平均查詢時間
t 返回前面多少條數據
g 後邊搭配一個正則匹配模式,大小寫不敏感

得到返回記錄集最多的10個SQL

mysqldumpslow -s r -t 10 /var/lib/mysql/localhost-slow.log

得到訪問次數最多的10個SQL

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

得到按照時間排序的前10條裏含有左連接的查詢語句

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

建議在使用這些命令時結合| 和more使用

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

批量數據腳本

創建函數,假如報錯:this function has none of determini…

#由於開啓了慢查詢日誌,必須爲function指定一個參數
show variables like 'log_bin_trust_function_creators';
set global log_bin_trust_function_creators=1;
隨機產生字符串
set global log_bin_trust_function_creators=1;
delimiter $$
create FUNCTION rand_string(n int) returns varchar(255)
BEGIN
	DECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
	DECLARE return_str varchar(255) DEFAULT '';
	DECLARE i int DEFAULT 0;
	WHILE i<n do
	set return_str=CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1));
	set i=i+1;
	end WHILE;
	return return_str;
END $$

select rand_string(20);
隨機產生範圍數字
delimiter $$
create function rand_num() RETURNS int(5)
begin 
	DECLARE i int DEFAULT 0;
	set i=FLOOR(100+RAND()*10);
	RETURN i;
END $$

select rand_num();

存儲過程批量插入數據
delimiter $$
create PROCEDURE insert_emp(in start int(10),in max_num int(10))
begin 
DECLARE i int DEFAULT 0;
set autocommit=0;
repeat
set i=i+1;
INSERT into emp(empno,ename,job,mgr,hiredate,sal,comm,deptno)
VALUES((start+i),rand_string(6),'salesman',0001,curdate(),2000,400,rand_num());
UNTIL i=max_num
end repeat;
commit;
end $$

show profile

  • mysql提供可以用來分析當前會話中語句執行的資源消耗情況,可以用於SQL調優的測量
  • 默認情況下,參數處於關閉狀態,並保存最近15次的運行結果
分析步驟

1、查看是否支持

show global variables like 'profiling';

2、開啓,默認是關閉

set global profiling=on;

3、運行SQL

select * from emp group by id%10 limit 150000;
select * from emp group bu id%20 order by 5;

4、查看結果

show profiles;

5、診斷SQL

show profiles cpu,block io for query n;
  • 參數
type 含義
ALL 顯示所有的開銷信息
BLOCK IO 顯示塊IO相關開銷
CONTEXT SWITCHES 上下文切換相關開銷
CPU 顯示CPU相關開銷
IPC 顯示發送和接受相關開銷信息
MEMORY 顯示內存相關開銷信息
PAGE FAULTS 顯示頁面錯誤相關開銷信息
SOURCE 顯示和Source_function,Source_file,Source_line相關的開銷信息
SWAPS 顯示交換次數相關開銷信息

6、日常開發需要注意的結論

  • coverting HEAP to MyISAM:查詢結果太大,內存都不夠用了往磁盤上搬了
  • Creating tmp table:創建臨時表-拷貝數據到臨時表,用完再刪除
  • Coping to tmp table on disk:把內存中臨時文件複製到磁盤,危險
  • locked

全局查詢日誌

不要在生產環境開啓這個功能
配置啓用

在my.cnf中
#開啓
general_log=1
#記錄日誌文件路徑
general_log_file=/path/logfile
#輸出格式
log_output=FILE

編碼啓用

set global general_log=1;
set global log_output='TABLE';

編寫的SQL語句,會記錄到mysql庫裏的general_log表,使用如下命令查看

select * from mysql.general_log;

mysql鎖機制

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

鎖的分類

按數據操作的類型(讀\寫)
讀鎖(共享鎖):對同一份數據,多個讀操作可以同時進行二不會互相影響
寫鎖(排它所):當前寫操作沒完成,會阻斷其它寫鎖和讀鎖
按數據操作的粒度分
表鎖
行鎖

三鎖(表、行、頁)

開銷、加鎖速度、死鎖、粒度、併發性能只能就具體應用特點來說哪種鎖更合適
InnoDB存儲引擎由於實現了行級鎖,雖然在鎖機制的實現方面所帶來的性能損耗可能比表鎖高一些,但是在整體併發處理能力方面遠遠優於MyISAM的表級鎖,當系統併發量較高的時候,InnoDB的整體性能有較大優勢。
InnoDB的行級鎖同樣也有脆弱的一面,當使用不當時(行鎖升級爲表鎖),會讓InnoDB的整體性能表現比MyISAM差

表鎖(偏讀)

偏向MyISAM存儲引擎,開銷小,加鎖快,無死鎖,鎖粒度大,發生鎖衝突的概率最高,併發度低
讀阻塞寫

建表

CREATE TABLE mylock(
	id int not null PRIMARY KEY auto_increment,
	name varchar(20)
)ENGINE myisam;

INSERT INTO mylock(name)VALUES('a'),('b'),('c'),('d'),('e');

select * from mylock;

手動加鎖

lock table 表名 read|write;

查看錶的加鎖情況

show open tables;
表鎖分析

通過檢查table_locks_waited和table_locks_immediate狀態變量萊分析系統上的表鎖定

show status like 'table%';

在這裏插入圖片描述
table_locks_immediate:產生表級鎖定的次數,表示可以立即獲取鎖的查詢次數,每立即獲取鎖值加1
table_locks_waited:出現表級鎖定爭用而發生等待的次數,此值高說明嚴重的表級爭用情況
此外,MyISAM的讀寫鎖調度是寫優先,這也是MyISAM不適合做寫爲主的引擎。因爲寫鎖後,其它線程不能做任何操作,大量的更新會使查詢很難得到鎖,從而造成永遠阻塞

行鎖(偏寫)

偏向InnoDB存儲引擎,開銷大,加鎖慢,會出現死鎖,鎖粒度小,發生鎖衝突的概率最低,併發度也最高
InnoDB與MyISAM的最大不同有兩點:一是支持事務,二是採用了行級鎖

併發事務處理的問題
  • 更新丟失:兩個進程併發更新數據,數據被覆蓋
  • 髒讀:事務A讀取到事務B未提交的數據
  • 不可重複讀:事務A讀取到事務B已經提交的修改數據
  • 幻讀:事務A讀取到事務B提交的新增數據,不符合隔離性
事務隔離級別
隔離級別 讀數據一致性 髒讀 不可重複讀 幻讀
未提交讀(read uncommitted) 最低級別,只能保證不讀取物理損壞的數據
已提交讀(read committed) 語句級
可重複讀(repeatable read) 事務級
可序列化(serializable) 最高級別,事務級

查看當前數據庫的事務隔離級別

show variables like 'tx_isolation';

建表SQL

CREATE TABLE test_innodb_lock(a int(11),b varchar(16))ENGINE=INNODB;

INSERT INTO test_innodb_lock values(1,'b1');
INSERT INTO test_innodb_lock values(2,'b2');
INSERT INTO test_innodb_lock values(3,'300');
INSERT INTO test_innodb_lock values(4,'4000');
INSERT INTO test_innodb_lock values(5,'5000');
INSERT INTO test_innodb_lock values(6,'600');
INSERT INTO test_innodb_lock values(7,'700');

CREATE INDEX test_innodb_a_ind on test_innodb_lock(a);
CREATE INDEX test_innodb_lock_b_ind on test_innodb_lock(b);
無索引行鎖升級爲表鎖

在這裏插入圖片描述
字段b爲varchar 類型,類型轉換導致索引失效,行鎖升級爲表鎖,並且只是當前索引的鎖變爲表鎖
在這裏插入圖片描述

間隙鎖的危害

間隙鎖:當我們用範圍條件而不是相等條件檢索數據時,InnoDB會給符合條件的已有數據記錄的索引項加鎖,對於鍵值在條件範圍內但並不存在的記錄,叫做“間隙(GAP)”,InnoDB也會對這個間隙加鎖,這種鎖機制就是所謂的間隙鎖(Next-Key鎖)
危害:因爲Query執行過程中通過範圍查找,會鎖定整個範圍內所有的索引鍵值,即使這個鍵值不存在,造成在鎖定的時候無法插入鎖定鍵值範圍內的任何數據。

如何鎖定一行
select * from 表名 where id=1 for update;
行鎖分析
show status like 'innodb_row_lock%';
變量 含義
Innodb_row_lock_current_waits 當前正在等待鎖定的數量
Innodb_row_lock_time 從系統啓動到現在鎖定總時長
Innodb_row_lock_time_avg 每次等待所花平均時間
Innodb_row_lock_time_max 從系統啓動到現在等待最長的一次時間
Innodb_row_lock_waits 系統啓動後到現在總共等待的次數

當等待次數很高時,而且每次等待時長也很大,就需要進行優化

優化建議
  • 儘可能讓所有數據檢索都通過索引來完成,避免無索引行鎖升級爲表鎖
  • 合理設計索引,儘量縮小鎖的範圍
  • 儘可能較少檢索條件,避免間隙鎖
  • 儘量控制事務大小,減少鎖定資源量和時間長度
  • 儘可能低級別事務隔離

頁鎖

  • 開銷和加鎖時間介於表鎖和行鎖之間,會出現死鎖,鎖定粒度介於表鎖與行鎖之間,併發度一般

主從複製

複製的最大問題-延遲

複製基本原理

在這裏插入圖片描述
MySQL複製分三步:

  • 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=自己本地路徑\mysqlbin
#啓動錯誤日誌
log-err=本地路徑\mysqlerr
#根目錄【可選】
basedir=自己本地路徑
#臨時目錄【可選】
tmpdir=自己本地路徑
#數據目錄【可選】
datadir=自己本地路徑\Data\
#主機,讀寫都可以
read-only=0
#設置不要複製的數據庫
binlog-ignore-db=mysql
#設置需要複製的數據庫【可選】
binlog-do-db=需要複製的主數據庫名字

從機修改my.cnf配置文件

找到
log-bin=mysql-bin
server-id=2

主從數據庫重啓
都關閉防火牆

service iptables stop

在Windows主機上建立賬戶並授權slave

CREATE USER 'slave123'@'192.168.103.%' IDENTIFIED BY '123456';#創建用戶
GRANT REPLICATION SLAVE ON *.* TO 'slave123'@'192.168.103.%';#授權
flush privileges; 
查看主機狀態
show master status;

從數據庫

change master to master_host='192.168.43.130',
master_user='slave123',
master_password='123456',
master_log_file='mysql-bin.000004',
master_log_pos=2315;

開啓從服務

start slave;

在這裏插入圖片描述
出現兩個Yes證明成功

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章