1. 程式人生 > >Mysql監控調優

Mysql監控調優

pda ini 刪除數據 創建索引 是我 connected 自己 如果 直接

關系型數據庫概念,有啥?

非關系型數據庫概念,有啥?

要對表操作,是有權限控制的,我們自動會忽略這個權限問題

查詢走硬盤的話,硬盤會影響性能。ssd>hdd

存儲引擎:innerdb

首先,讓我們來看一下SQL語句執行的過程,下面這個是我們平時寫的SQL語句。

SELECT DISTINCT
    < select_list >
FROM
    < left_table > < join_type >
JOIN < right_table > ON < join_condition >
WHERE
    < where_condition >
GROUP BY
    
< group_by_list > HAVING < having_condition > ORDER BY < order_by_condition > LIMIT < limit_number >

然而當數據庫接收到查詢請求以後會先對數據進行解析,解析後查詢順序就變成了下面這樣

FROM <left_table>
ON <join_condition>
<join_type> JOIN <right_table>
WHERE <where_condition>
GROUP BY 
<group_by_list> HAVING <having_condition> SELECT DISTINCT <select_list> ORDER BY <order_by_condition> LIMIT <limit_number>

sql語法的順序:

1、from……where之間,是取表,取庫,去磁盤裏面把數據加載到內存裏面,也就是磁盤的io會影響性能,讀磁盤操作(整表全部放內存)

2、where,group by,having之後是條件,where實現的是篩選功能。這一步是在哪操作的?是在內存裏面操作的(分組占用 cpu 特別高),這裏對 cpu 的性能影響很大

  假設 where 之後篩選出 1W 數據,在 group by 後剩下 3000 ,having 後剩 1000 數據

3、order by 也是很耗費 cpu 的,排序算法,肯定很耗費 cpu

可以看到整個邏輯:取數據,選數據,排數據(取選排)伴隨著的性能問題:io,內存和 cpu

搶 cpu 是怎麽造成的?

進程都在占用 cpu ,突然一個 A 進程搶 cpu 暴增,那麽其他的也會搶。比如說 a 進程要 10 m內存,內存 1%,那麽沒幹完,被其他的搶走了,就會再要內存,內存就變成 2%,就這麽其他的搶占也會一點一點增起來。一個高,另外的也會高,互相神仙打架。死的最多的是 tomcat ,java進程

DDL (Data Definition Language 數據定義語言)

技術分享圖片
create table 創建表     
alter table  修改表   
drop table 刪除表   
truncate table 刪除表中所有行(把自增id清零)     
create index 創建索引   
drop index  刪除索引
技術分享圖片

DML (Data Manipulation Language 數據操作語言)

insert 將記錄插入到數據庫 
update 修改數據庫的記錄 
delete 刪除數據庫的記錄

4、Mysql連接數

線程的連接數,比如 A 用戶連一個, B用戶連一個。

這裏有個三次握手的概念,比如說客戶端a問服務端b,我能打你麽?b說,可以。那麽a就去打b了,在他們沒有說再見的狀況下,b是一直等待被a打的,不會等其他的人來打

比如說我連上了 一個 mysql ,我不告訴 mysql 斷開。是不會斷開的,在我們一定的連接時間內(時間可配置)假設 30s,30s 內及時沒有數據操作,這個數據庫連接就是被占用的。影響:如果用戶訪問多,我們的連接數滿了,其他的用戶就連不上了。

那麽我們引入連接池連接的方法。連接池,比如說最大連接數 100個,我設連接池 50 個,我設置的 50 為啥不設為 100 呢?為啥只設置 50?

  這麽想,比如我最大連接數 100 ,連接池如果也設置 100 ,其他人連接就肯定連不上了。連接池這個 50 是在哪設置?其實是在代碼裏面,是應用服務自己創建的連接池,是比如說我現在建立一個 50 個連接的連池,應用服務會一直跟 mysql 去溝通:嘿,我還要用這 50 個連接池呢 ,在超時之前,每隔一段時間,跟 mysql 絮叨一回,我還占著呢,你別讓別人進來。mysql 接收到這消息之後,就把這50個連接就一直留給這個應用服務。剩下的 50 個連接閑置,誰想用,誰想連就連。

  那麽連接池這邊,我去傳給連接池 一個 SQL 語句,執行了,返回正確結果了。那麽下一個 SQL 語句過來,就不用管連接池是否還在等待鏈接,因為只要返回正確結果了,代表這個操作完成了。就相當於一條隊列,我給你 10 條 sql 語句,按照順序執行就好了,而不是說給你 10 條 sql ,你建立 10 次連接,等 30s 斷開,再執行第二條,依次執行到第 10 條,這樣效率肯定低。但是如果我通過代碼的連接池,我相當於是調用一個功能,我給你 10 條sql ,你給我返回回來結果,返回回來後,你就給我閑置。你就可以開始接下來的操作。

  那麽為啥這個連接池要設置 50 ?如果設置成 100 ,結果會怎樣?第一個問題,假設數據庫掛了,管理員怎麽連?所以肯定不能設定為 100 。可以去找找這種連接池的代碼,看一看,玩一玩

  

MYSQL數據庫默認最大連接數是100,然而對於流量稍微大一點的論壇或網站這個連接數是遠遠不夠的,當並發數過大的時候會出現連接數不夠用,使得很多線程在等待其他連接釋放,會直接導致導致數據庫連接超時或者響應時間過長,所以需要調整最大連接數。

技術分享圖片
# 重新設置數據庫最大連接數
set global max_connections=1000 

# 查詢數據庫當前設置的最大連接數
show variables like %max_connections%; 
MariaDB [(none)]> show variables like %max_connections%; 
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| extra_max_connections | 1     |    # extra_port可以接受的最大連接數
| max_connections       | 151   |    # 最大連接數
+-----------------------+-------+
2 rows in set (0.00 sec)

# extra_port是之前5.6版本開始新增的,指定了可以使用的端口


# 服務器響應的最大連接數
show global status like Max_used_connections; 
MariaDB [(none)]> show global status like Max_used_connections; 
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| Max_used_connections | 4     |
+----------------------+-------+
1 row in set (0.00 sec)

# 服務器線程方面的
show status like Threads%;
MariaDB [(none)]> show status like Threads%;
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_cached    | 0     |    # mysql管理的線程池中還有多少可以被復用的資源
| Threads_connected | 3     |    # 打開的連接數
| Threads_created   | 226   |    # 表示創建過的線程數
| Threads_running   | 1     |    # 激活的連接數,這個數值一般遠低於connected數值,
                                # 準確的來說,Threads_running是代表當前並發數
+-------------------+-------+
4 rows in set (0.00 sec)
技術分享圖片

Mysql監控調優