mysql資料庫並發
mysql資料庫超過並發量會pengding mysql資料庫超過並發量會
主要是針對數據量很大,和並發訪問量高的時候
經驗一:
在開發過程中,我們經常會寫
SELECT * FROM table WHERE 1 ORDER BY xxx DESC LIMIT 0,10
這樣的語句用來分頁
在有完美索引的情況 對xxx建立索引
前面幾頁會很快,但如果數據量達到100萬級以後,我們查詢最後一頁
SELECT * FROM table WHERE 1 ORDER BY xxx DESC LIMIT 999990,10
這句執行就會很慢,同時有多人訪問伺服器就會掉 (這里不考慮緩存,因為內容更新太快,有時候緩存了達不到數據的更新的要求)
但如果我們把
SELECT * FROM table WHERE 1 ORDER BY xxx DESC LIMIT 999990,10
換成
SELECT * FROM table WHERE 1 ORDER BY xxx ASC LIMIT 0,10
這兩個的MYSQL執行時間可是大大的不一樣 當然要注意把這樣取出來的結果用php重新排序一下
取得的一樣是最後一頁的數據,當然最中間的兩頁有部分數據一樣
這時候最慢的只是最中間的部分,相對而言,訪問最中間的人還是很少的
經驗二:
例如論壇帖子列表的顯示:
一般是SELECT * FROM table ORDER BY is_top DESC ,post_time DESC LIMIT 0,10這樣的分頁
兩個order by 的執行是非常慢的,哪怕你有再好的索引,
我們的處理辦法是 把is_top的數據CACHE住,畢竟is_top的數據量有限,更新這個緩存也容易
然後SQL一樣是SELECT * FROM table ORDER BY post_time DESC LIMIT {$num},{$num2}
注意這個$num2 是減掉is_top的數量後的一個值,$num是is_top的數量
當然還要考慮is_top的數據量是不是有好幾頁,當前頁的值是不是都在cache裡面
經驗三:
SELECT * FROM table ORDER BY RAND() LIMIT 100 這個ORDER BY RAND() 是非常慢的 能不用盡量不要用
處理辦法是
1.用PHP生成數組後,然後用SELECT * FROM table WHERE id IN() WHERE IN 也比這個order by rand()快的多
2.如果數量信息不太重多,就用SELECT * FROM table WHERE 1 LIMIT 500 多取點數據,然後用php 處理數組
B. mysql鎖能控制並發嗎
可以的,mysql中典型的是mvcc協議:
MVCC是為了實現資料庫的並發控制而設計的一種協議。從直觀理解上來看,要實現資料庫的並發訪問控制,最簡單的做法就是加鎖訪問,即讀的時候不能寫(允許多個西線程同時讀,即共享鎖,S鎖),寫的時候不能讀(一次最多隻能有一個線程對同一份數據進行寫操作,即排它鎖,X鎖)。這樣的加鎖訪問,其實並不算是真正的並發,或者說它只能實現並發的讀,因為它最終實現的是讀寫串列化,這樣就大大降低了資料庫的讀寫性能。加鎖訪問其實就是和MVCC相對的LBCC,即基於鎖的並發控制(Lock-Based Concurrent Control),是四種隔離級別中級別最高的Serialize隔離級別。為了提出比LBCC更優越的並發性能方法,MVCC便應運而生。
C. mysql並發數是什麼意思
可能影響,並可能影響。這就是所謂的「一個老鼠屎壞了一鍋湯。」許多DBA都遇到類似的問題,即一台伺服器上,在伺服器上的所有應用程序的應用程序編程問題,導致多個應用程序的數據都受到牽連。但是,根據你的描述,如果唯一的A1死鎖,然後A2是不是一個問題。但是,如果的A1表掃描或復雜的計算,導致太多的資源,這將影響到A2的壓力。
資料庫的並發性通常指的是整個伺服器的並發性,無論資料庫伺服器的幾個庫
D. 如何增加mysql資料庫並發數
現象
Sysbench對MySQL進行壓測, 並發數過大(>5k)時, Sysbench建立連接的步驟會超時.
猜想
猜想: 直覺上這很簡單, Sysbench每建立一個連接, 都要消耗一個線程, 資源消耗過大導致超時.
驗證: 修改Sysbench源碼, 調大超時時間, 仍然會發生超時.
檢查環境
猜想失敗, 回到常規的環境檢查:
MySQL error log 未見異常.
syslog 未見異常.
tcpmp 觀察網路包未見異常, 連接能完成正常的三次握手; 只觀察到在出問題的連接中, 有一部分的TCP握手的第一個SYN包發生了重傳, 另一部分沒有發生重傳.
自己寫一個簡單的並發發生器, 替換sysbench, 可重現場景. 排除sysbench的影響
檢查MySQL堆棧未見異常, 彷彿MySQL在應用層沒有看到新連接進入.
通過strace檢查MySQL, 發現accept()調用確實沒有感知到新連接.
Client 向 Server 發起連接請求, 發送SYN.
Server 預留連接資源, 向 Client 回復SYN-ACK.
Client 向 Server 回復ACK.
Server 收到 ACK, 連接建立.
在業務層上, Client和Server間進行通訊.
Client 向 Server 發起連接請求, 發送SYN.
Server 不預留連接資源, 向 Client 回復SYN-ACK, 包中附帶有簽名A.
Client 向 Server 回復ACK, 附帶 f(簽名A) (對簽名進行運算的結果).
Server 驗證簽名, 分配連接資源, 連接建立.
在業務層上, Client和Server間進行通訊.
從Client的視角, 連接已經建立.
從Server的視角, 連接並不存在, 既沒有建立, 也沒有」即將建立」 (若不啟用SYN-cookie, Server會知道某個連接」即將建立」)
若業務層的第一個包應是從 Client 發往 Server, 則會進行重發或拋出連接錯誤
若業務層的第一個包應是從 Server 發往 Client的, Server不會發出第一個包. MySQL的故障就屬於這種情況.
- Some of these packets get lost because some buffer somewhere overflows.
probe kernel.function("cookie_v4_check").return
{
source_port = @cast($skb->head + $skb->transport_header, "struct tcphdr")->source
printf("source=%d, return=%d ",readable_port(source_port), $return)
}
function readable_port(port) {
return (port & ((1<<9)-1)) << 8 | (port >> 8)
}
- static inline bool sk_acceptq_is_full(const struct sock *sk){ return sk->sk_ack_backlog > sk- >sk_max_ack_backlog;}
if (!queue->synflood_warned &&
sysctl_tcp_syncookies != 2 &&
xchg(&queue->synflood_warned, 1) == 0)
pr_info("%s: Possible SYN flooding on port %d. %s.
Check SNMP counters. ",
proto, ntohs(tcp_hdr(skb)->dest), msg);
猜想2
懷疑 MySQL 在應用層因為某種原因, 沒有發送握手包, 比如卡在某一個流程上:
懷疑是OS的原因, Google之, 得到參考文檔:A TCP 「stuck」 connection mystery【http://www.evanjones.ca/tcp-stuck-connection-mystery.html】
分析
參考文檔中的現象跟目前的狀況很類似, 簡述如下:
正常的TCP連接流程:
當發生類似SYN-flood的現象時, TCP連接的流程會使用SYN-cookie, 變為:
當啟用SYN-cookie時, 第3步的ACK包因為某種原因丟失, 那麼:
發生這種情況時:
TCP握手的第三步ACK包為什麼丟失
參考文檔中, 對於TCP握手的第三步ACK包的丟失原因, 描述為:
我們可以通過Systemtap進一步探究原因.通過一個簡單的腳本:
觀察結果, 可以確認cookie_v4_check(syn cookie機制進行包簽名檢查的函數)會返回 NULL(0). 即驗證是由於syn cookie驗證不通過, 導致TCP握手的第三步ACK包不被接受.
之後就是對其中不同條件進行觀察, 看看是哪個條件不通過. 最終原因是accept隊列滿(sk_acceptq_is_full):
恢復故障與日誌的正關聯
在故障處理的一開始, 我們就檢查了syslog, 結論是未見異常.
當整個故障分析完成, 得知了故障與syn cookie有關, 回頭看syslog, 裡面是有相關的信息, 只是和故障發生的時間不匹配, 沒有正關聯, 因此被忽略.
檢查linux源碼:
可以看到日誌受到了抑制, 因此日誌與故障的正關聯被破壞.
粗看源碼, 每個listen socket只會發送一次告警日誌, 要獲得日誌與故障的正關聯, 必須每次測試重啟MySQL.
解決方案
這種故障一旦形成, 難以檢測; 系統日誌中只會出現一次, 在下次重啟MySQL之前就不會再出現了; Client如果沒有合適的超時機制, 萬劫不復.
解決方案:
1. 修改MySQL的協議, 讓Client先發握手包. 顯然不現實.
2. 關閉syn_cookie. 有安全的人又要跳出來了.
3. 或者調高syn_cookie的觸發條件 (syn backlog長度). 降低系統對syn flood的敏感度, 使之可以容忍業務的syn波動.
有多個系統參數混合影響syn backlog長度, 參看【http://blog.bbelboer.com/2012/04/09/syn-cookies.html】
下圖為精華總結
E. 如何使用mysql資料庫解決高並發
使用mysql非同步查詢,需要使用mysqlnd作為PHP的MySQL資料庫驅動。 使用MySQL非同步... 如果創建的線程過多,則會造成線程切換引起系統負載過高。Swoole中的非同步MySQL其...
F. mysql資料庫怎麼解決高並發問題
通常情況下在PHP中MySQL查詢是串列的,如果能實現MySQL查詢的非同步化,就能實現多條SQL語句同時執行,這樣就能大大地縮短MySQL查詢的耗時,提高資料庫查詢的效率。目前MySQL的非同步查詢只在MySQLi擴展提供,查詢方法分別是:
1、使用MYSQLI_ASYNC模式執行mysqli::query
2、獲取非同步查詢結果:mysqli::reap_async_query
使用mysql非同步查詢,需要使用mysqlnd作為PHP的MySQL資料庫驅動。
使用MySQL非同步查詢,因為需要給所有查詢都創建一個新的連接,而MySQL服務端會為每個連接創建一個單獨的線程進行處理,如果創建的線程過多,則會造成線程切換引起系統負載過高。Swoole中的非同步MySQL其原理是通過MYSQLI_ASYNC模式查詢,然後獲取mysql連接的socket,加入到epoll事件循環中,當資料庫返回結果時會回調指定函數,這個過程是完全非同步非阻塞的。
G. 如何處理mysql資料庫並發更新問題
mysql的最大連接數默認是100, 這個數值對於並發連接很多的資料庫應用是遠遠不夠的,當連接請求大於默認連接數後,就會出現無法連接資料庫的錯誤,因此我們需要把它適當調大一些。 調節方法為: 1.linux伺服器中:改my中國f中的值就行了 2.Windows伺服器中(我用的): 在文件「my.ini」中找到段 [mysqld],在其中添加一行 max_connections=200 ### 200可以更改為想設置成的值. 然後重啟"mysql"服務。 /mysqladmin所在路徑/mysqladmin -uroot -p variables 輸入root資料庫賬號的密碼後可看到 | max_connections | 1000 | 其他需注意的: 在編程時,由於用mysql語句調用資料庫時,在每次之執行語句前,會做一個臨時的變數用來打開資料庫,所以你在使用mysql語句的時候,記得在每次調用完mysql之後就關閉mysql臨時變數。 另外對於訪問量大的,可以考慮直接寫到文本中,根據預測的訪問量,先定義假若是100個文件文件名依次為1.txt,2.txt...100.txt。需要的時候,再對所有文本文件中的數據進行分析,再導入資料庫