當前位置:首頁 » 數據倉庫 » 資料庫並發時間段
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

資料庫並發時間段

發布時間: 2023-01-07 13:06:56

『壹』 資料庫死鎖,並發問題

補充樓主:
其實我沒什麼經驗,只不過是了解一些基礎的東西罷了。
一樓的 一朵瘩紅花 實際經驗很豐富,你可以向她咨詢一下。

你問的問題挺好得。三個概念緊密聯系在一起。
這樣說吧:並發的幾個事務同時發生,不加鎖控制的話數據就會亂套了,而加了鎖後,又是並發訪問會出現死鎖,所以就會出現避免死鎖的一些措施。
首先談並發:理論指的是在一段時間同時對某件事進行操作。 注意精度問題,修改資料庫是在一段時間內操作,不是在某個時刻,而日誌則會從 時刻 開始記錄你的操作。

造成死鎖的原因是為了防止 不同的用戶同時間(不是時刻)都對某個數據修改,造成訪問不一致的問題。
比如你讀了資料庫的一個數據然後把它修改了並存回去,是需要時間的(假如是student表中的有個grade屬性,你改了一條記錄的一個值)在這個過程當中,有人又訪問了資料庫並且恰恰訪問的是存回去之前的數據,然後他要進行操作,過了一段時間,此時你已經存回去了數據。會發現原來的數據被改動了。這時數據就亂套了。(專業術語叫讀臟數據,其實還有很多其他類似這種導致前後數據不一致的問題)所以為了限定這種操作,資料庫設計了-----鎖---來鎖定這種操作。就是你正在操作某個數據的時候----通常之前會先鎖定這個數據,這樣別人就不能對此數據操作了(嚴格來說就是只能讀,不能改),必須等你操作完才能對此數據修改等操作,這就在一定程度上避免了前後操作數據不一致的問題。

但是有了鎖後,新問題出現了,就是死鎖:

簡單解釋死鎖:進程A等待進程B釋放他的資源,B又等待A釋放他的資源,這樣就互相等待就形成死鎖

官方解釋死鎖
死鎖,根本原因在於對共享存儲區的訪問。在資料庫中也一樣,如果需要「修改」一條數據,首先資料庫管理系統會在上面加鎖,以保證在同一時間只有一個事務能進行修改操作。鎖有多種實現方式,比如意向鎖,共享-排他鎖,鎖表,樹形協議,時間戳協議等等。鎖還有多種粒度,比如可以在表上加鎖,也可以在記錄上加鎖。

在並發控制中,鎖是非常重要的。
至於在Oracle還是別的資料庫管理系統中,死鎖產生的原因沒有不同,不同的頂多是鎖的實現或者死鎖的恢復等罷了

再來說說事務:
事務簡單來說就是 一系列的對資料庫的操作揉在一起,要麼同時完成,要麼就都不完成。
比如---你要取錢的過程就可以當成是一個小的事務: 插卡,輸入取錢金額,取走錢,拿出來卡。此過程缺一不可。把所有這些過程細節封裝起來就成為一個事務。
以oracle資料庫為例:
一個事務(你可以認為是一系列業務的操作)起始於dml語句(insert、update、delete)
即一條dml語句就做為一個事務的起始,然後根據業務需要,進行其他的dml操作都算是事務的一部分。
最後碰到commit。或者rollback,或者其他意外什麼的都算作一個事務的結束。
整個過程就是一個事務。
事務的理論解釋就是那四個什麼特性:什麼原子性、一致性、隔離性和持久性
簡稱ACID

剩下的:資料庫是建立在操作系統之上的一個層次。
你問的是資料庫的存儲機制??工作機制??還是什麼的??
資料庫就是存數據的。資料庫管理系統是 對存的數據進行高效率的管理
大的結構分物理數據跟邏輯數據。
物理數據就是數據在存儲設備上的存儲方式,什麼物理聯系,物理結構,物理記錄等 術語。
邏輯數據就是程序員和用戶看到的數據形式。什麼邏輯聯系,邏輯結構==同上
資料庫管理類系統就是把這些邏輯跟物理相互轉換。 好比你輸入的叫邏輯數據存儲在磁碟上叫物理數據。等等。

廢話了一堆,也不知道回答對你的問題沒~~

『貳』 如何處理資料庫並發問題

想要知道如何處理數據並發,自然需要先了解數據並發。

什麼是數據並發操作呢?
就是同一時間內,不同的線程同時對一條數據進行讀寫操作。

在互聯網時代,一個系統常常有很多人在使用,因此就可能出現高並發的現象,也就是不同的用戶同時對一條數據進行操作,如果沒有有效的處理,自然就會出現數據的異常。而最常見的一種數據並發的場景就是電商中的秒殺,成千上萬個用戶對在極端的時間內,搶購一個商品。針對這種場景,商品的庫存就是一個需要控制的數據,而多個用戶對在同一時間對庫存進行重寫,一個不小心就可能出現超賣的情況。

針對這種情況,我們如何有效的處理數據並發呢?

第一種方案、資料庫鎖
從鎖的基本屬性來說,可以分為兩種:一種是共享鎖(S),一種是排它鎖(X)。在Mysql的資料庫中,是有四種隔離級別的,會在讀寫的時候,自動的使用這兩種鎖,防止數據出現混亂。

這四種隔離級別分別是:

讀未提交(Read Uncommitted)
讀提交(Read Committed)
可重復讀(Repeated Read)
串列化(Serializable)
當然,不同的隔離級別,效率也是不同的,對於數據的一致性保證也就有不同的結果。而這些可能出現的又有哪些呢?

臟讀(dirty read)

當事務與事務之間沒有任何隔離的時候,就可能會出現臟讀。例如:商家想看看所有的訂單有哪些,這時,用戶A提交了一個訂單,但事務還沒提交,商家卻看到了這個訂單。而這時就會出現一種問題,當商家去操作這個訂單時,可能用戶A的訂單由於部分問題,導致數據回滾,事務沒有提交,這時商家的操作就會失去目標。

不可重復讀(unrepeatable read)

一個事務中,兩次讀操作出來的同一條數據值不同,就是不可重復讀。

例如:我們有一個事務A,需要去查詢一下商品庫存,然後做扣減,這時,事務B操作了這個商品,扣減了一部分庫存,當事務A再次去查詢商品庫存的時候,發現這一次的結果和上次不同了,這就是不可重復讀。

幻讀(phantom problem)

一個事務中,兩次讀操作出來的結果集不同,就是幻讀。

例如:一個事務A,去查詢現在已經支付的訂單有哪些,得到了一個結果集。這時,事務B新提交了一個訂單,當事務A再次去查詢時,就會出現,兩次得到的結果集不同的情況,也就是幻讀了。

那針對這些結果,不同的隔離級別可以干什麼呢?

「讀未提(Read Uncommitted)」能預防啥?啥都預防不了。

「讀提交(Read Committed)」能預防啥?使用「快照讀(Snapshot Read)」方式,避免「臟讀」,但是可能出現「不可重復讀」和「幻讀」。

「可重復讀(Repeated Red)」能預防啥?使用「快照讀(Snapshot Read)」方式,鎖住被讀取記錄,避免出現「臟讀」、「不可重復讀」,但是可能出現「幻讀」。

「串列化(Serializable)」能預防啥?有效避免「臟讀」、「不可重復讀」、「幻讀」,不過運行效率奇差。

好了,鎖說完了,但是,我們的資料庫鎖,並不能有效的解決並發的問題,只是盡可能保證數據的一致性,當並發量特別大時,資料庫還是容易扛不住。那解決數據並發的另一個手段就是,盡可能的提高處理的速度。

因為數據的IO要提升難度比較大,那麼通過其他的方式,對數據進行處理,減少資料庫的IO,就是提高並發能力的有效手段了。

最有效的一種方式就是:緩存
想要減少並發出現的概率,那麼讀寫的效率越高,讀寫的執行時間越短,自然數據並發的可能性就變小了,並發性能也有提高了。

還是用剛才的秒殺舉例,我們為的就是保證庫存的數據不出錯,賣出一個商品,減一個庫存,那麼,我們就可以將庫存放在內存中進行處理。這樣,就能夠保證庫存有序的及時扣減,並且不出現問題。這樣,我們的資料庫的寫操作也變少了,執行效率也就大大提高了。

當然,常用的分布式緩存方式有:Redis和Memcache,Redis可以持久化到硬碟,而Memcache不行,應該怎麼選擇,就看具體的使用場景了。

當然,緩存畢竟使用的范圍有限,很多的數據我們還是必須持久化到硬碟中,那我們就需要提高資料庫的IO能力,這樣避免一個線程執行時間太長,造成線程的阻塞。

那麼,讀寫分離就是另一種有效的方式了
當我們的寫成為了瓶頸的時候,讀寫分離就是一種可以選擇的方式了。

我們的讀庫就只需要執行讀,寫庫就只需要執行寫,把讀的壓力從主庫中分離出去,讓主庫的資源只是用來保證寫的效率,從而提高寫操作的性能。

『叄』 在資料庫中如何將時間段做為欄位保存

你這個只能用字元串類型保存!!
建議你用兩個datetime欄位來分別保存起始時間和結束時間!!

『肆』 怎麼提高資料庫高峰時訪問的並發能力

1:首先需要有非常良好的網路帶寬,若有上萬人同時錄入數據的普通的Web信息管理系統,至少需要10M左右的網路帶寬,而且網通、電信的主幹網都有接入比較好,否則全國各地的網路情況都不太一樣,有的城市錄入數據時可能會遇到網路非常緩慢的情況,甚至到無法忍受的程度。

2:須有一台牛X的Web伺服器 + 一台牛X的資料庫伺服器(備注接近頂配的奢侈硬體伺服器非個人PC),由於是需要錄入1000萬條以上數據,最好採用Oracle資料庫比較理想一些,經得起考驗一些。

3:需要進行適當的內存緩存優化策略,不能所有的資料庫都依靠SQL資料庫的方式把壓力放在資料庫伺服器上,盡量多使用內存的方式處理數據。

4:需要一個牛X的,經得起考驗的資料庫訪問層,因為每秒都有可能成千上萬的人在訪問,若是質量不良好的資料庫訪問組件、或者不穩定的資料庫訪問組件,更容易導致系統崩潰、或者佔用非常龐大的內存,最後容易導致整個系統的崩潰。

5:需要優化分頁存取數據功能,應為有可能會有1000萬條數據,若分頁讀取數據的功能沒能優化到最高,也很容易導致系統的崩潰,因為上萬人萬一在同一時間,或者接近同一時間點了查詢某頁數據時,那系統就真崩潰了,分頁存取數據一定需要做到極致才可以。

6:需要進行資料庫索引優化,有索引和沒索引的性能差距有時候會是100倍,大數據量時可能會有1000倍都有可能,資料庫索引優化到極致了更容易得到運行順暢的信息管理系統。

7:嚴謹高效的資料庫事務處理,由於高並發,並且有些單據是需要同時寫入多個表,需要保證資料庫的一致性,要麼全部成功,要麼全部失敗重新錄入數據,所以需要一個高效的資料庫事務處理機制的配合。

8:所有的系統的操作日誌、異常信息都需要完整的記錄下來,當系統發生一些故障時,可以快速排查問題,對正確診斷系統發生的故障的原因做分析參考用。

9:需要經常檢測系統的各項指標、例如各伺服器的內存使用情況、CPU使用情況、網路帶寬使用情況,高峰時的各個參數是什麼情況、系統不繁忙時的情況等,若伺服器快承受不了壓力了,就得馬上增加負載均衡的伺服器,網路帶寬不夠了需要增加等等,總不能等系統崩潰了再去做這些事情。

10:每個頁面的HTML、JS都進行優化,若某個頁面多餘發了100個字元的垃圾HTML代碼,那1萬人每天獲得100次,那得佔用多少網路帶寬,100×100×1萬個字元的多餘HTML被網路上傳輸了,要知道接入主幹網的網路資源是多麼寶貴,費用是多麼昂貴。

11:HTML、JS等都可以考慮用壓縮模式傳輸,那樣網路傳輸效率會更高一些。

12:由於全國各地上萬人,會有各種各樣的人,這些人也未必全是好人,可能某些人心情不好,或者其他什麼的,可能就會攻擊我們的軟體系統破壞數據,這些也可能是由於好奇心導致的,所以系統需要有嚴格的許可權管理控制,不應該進入的頁面絕對不能進入,不應該看的數據絕對不讓看,不能操作的功能絕對不讓多操作,一方面防止沒必要的多餘的麻煩,另一方面也可以減少系統被攻擊破壞的可能性。

『伍』 如何處理mysql資料庫並發更新問題

現象

Sysbench對MySQL進行壓測, 並發數過大(>5k)時, Sysbench建立連接的步驟會超時.

猜想

猜想: 直覺上這很簡單, Sysbench每建立一個連接, 都要消耗一個線程, 資源消耗過大導致超時.

驗證: 修改Sysbench源碼, 調大超時時間, 仍然會發生超時.

檢查環境

猜想失敗, 回到常規的環境檢查:

  • MySQL error log 未見異常.

  • syslog 未見異常.

  • tcpmp 觀察網路包未見異常, 連接能完成正常的三次握手; 只觀察到在出問題的連接中, 有一部分的TCP握手的第一個SYN包發生了重傳, 另一部分沒有發生重傳.

  • 自己寫一個簡單的並發發生器, 替換sysbench, 可重現場景. 排除sysbench的影響

  • 猜想2

    懷疑 MySQL 在應用層因為某種原因, 沒有發送握手包, 比如卡在某一個流程上:

  • 檢查MySQL堆棧未見異常, 彷彿MySQL在應用層沒有看到新連接進入.

  • 通過strace檢查MySQL, 發現accept()調用確實沒有感知到新連接.

  • 懷疑是OS的原因, Google之, 得到參考文檔:A TCP 「stuck」 connection mystery【http://www.evanjones.ca/tcp-stuck-connection-mystery.html】

    分析

    參考文檔中的現象跟目前的狀況很類似, 簡述如下:

    正常的TCP連接流程:

  • Client 向 Server 發起連接請求, 發送SYN.

  • Server 預留連接資源, 向 Client 回復SYN-ACK.

  • Client 向 Server 回復ACK.

  • Server 收到 ACK, 連接建立.

  • 在業務層上, Client和Server間進行通訊.

  • 當發生類似SYN-flood的現象時, TCP連接的流程會使用SYN-cookie, 變為:

  • Client 向 Server 發起連接請求, 發送SYN.

  • Server 不預留連接資源, 向 Client 回復SYN-ACK, 包中附帶有簽名A.

  • Client 向 Server 回復ACK, 附帶 f(簽名A) (對簽名進行運算的結果).

  • Server 驗證簽名, 分配連接資源, 連接建立.

  • 在業務層上, Client和Server間進行通訊.

  • 當啟用SYN-cookie時, 第3步的ACK包因為某種原因丟失, 那麼:

  • 從Client的視角, 連接已經建立.

  • 從Server的視角, 連接並不存在, 既沒有建立, 也沒有」即將建立」 (若不啟用SYN-cookie, Server會知道某個連接」即將建立」)

  • 發生這種情況時:

  • 若業務層的第一個包應是從 Client 發往 Server, 則會進行重發或拋出連接錯誤

  • 若業務層的第一個包應是從 Server 發往 Client的, Server不會發出第一個包. MySQL的故障就屬於這種情況.

  • TCP握手的第三步ACK包為什麼丟失

    參考文檔中, 對於TCP握手的第三步ACK包的丟失原因, 描述為:

  • Some of these packets get lost because some buffer somewhere overflows.

  • 我們可以通過Systemtap進一步探究原因.通過一個簡單的腳本:

  • 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)

  • }

  • 觀察結果, 可以確認cookie_v4_check(syn cookie機制進行包簽名檢查的函數)會返回 NULL(0). 即驗證是由於syn cookie驗證不通過, 導致TCP握手的第三步ACK包不被接受.

    之後就是對其中不同條件進行觀察, 看看是哪個條件不通過. 最終原因是accept隊列滿(sk_acceptq_is_full):

  • static inline bool sk_acceptq_is_full(const struct sock *sk){ return sk->sk_ack_backlog > sk- >sk_max_ack_backlog;}

  • 恢復故障與日誌的正關聯

    在故障處理的一開始, 我們就檢查了syslog, 結論是未見異常.

    當整個故障分析完成, 得知了故障與syn cookie有關, 回頭看syslog, 裡面是有相關的信息, 只是和故障發生的時間不匹配, 沒有正關聯, 因此被忽略.

    檢查Linux源碼:

  • 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);

  • 可以看到日誌受到了抑制, 因此日誌與故障的正關聯被破壞.

    粗看源碼, 每個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】

    下圖為精華總結

『陸』 如何處理大量數據並發操作

處理大量數據並發操作可以採用如下幾種方法:

1.使用緩存:使用程序直接保存到內存中。或者使用緩存框架: 用一個特定的類型值來保存,以區別空數據和未緩存的兩種狀態。

2.資料庫優化:表結構優化;SQL語句優化,語法優化和處理邏輯優化;分區;分表;索引優化;使用存儲過程代替直接操作。

3.分離活躍數據:可以分為活躍用戶和不活躍用戶。

4.批量讀取和延遲修改: 高並發情況可以將多個查詢請求合並到一個。高並發且頻繁修改的可以暫存緩存中。

5.讀寫分離: 資料庫伺服器配置多個,配置主從資料庫。寫用主資料庫,讀用從資料庫。

6.分布式資料庫: 將不同的表存放到不同的資料庫中,然後再放到不同的伺服器中。

7.NoSql和Hadoop: NoSql,not only SQL。沒有關系型資料庫那麼多限制,比較靈活高效。Hadoop,將一個表中的數據分層多塊,保存到多個節點(分布式)。每一塊數據都有多個節點保存(集群)。集群可以並行處理相同的數據,還可以保證數據的完整性。

拓展資料:

大數據(big data),指無法在一定時間范圍內用常規軟體工具進行捕捉、管理和處理的數據集合,是需要新處理模式才能具有更強的決策力、洞察發現力和流程優化能力的海量、高增長率和多樣化的信息資產。

在維克托·邁爾-舍恩伯格及肯尼斯·庫克耶編寫的《大數據時代》中大數據指不用隨機分析法(抽樣調查)這樣捷徑,而採用所有數據進行分析處理。大數據的5V特點(IBM提出):Volume(大量)、Velocity(高速)、Variety(多樣)、Value(低價值密度)、Veracity(真實性)。

『柒』 資料庫原理並發控制問題

並發(concurrent)和並行(parallel)這兩個概念,在資料庫系統的資料中經常出現,然而有關它們的定義和區別卻沒有明確的說法。這里,我們根據這兩個概念在資料中的使用,對它們的不同做一個說明。

並發是指多個任務的同時執行,任務與任務之間沒有聯系。由於資料庫系統要同時為許多用戶提供服務,每個用戶都可以發出自己的訪問請求,一個請求就是一個任務。在一個時間點,資料庫系統可能要同時處理多個任務。因此,資料庫系統一定要具備並發處理能力。

並行是指將一個任務劃分為多個子任務,這些子任務同時執行。在所有子任務處理完成後,將它們的結果進行合並,就得到該任務的最終處理結果。在資料庫系統中,如果要執行一個大的數據查詢,為了提高速度、降低響應時間,用戶可以通過系統配置或者在命令中,要求對該大數據量查詢進行並行處理,將該查詢劃分成多個子查詢。這些子查詢同時執行,最後系統將所有子查詢的處理結果進行合並,作為該查詢處理的最終結果。現有的大型資料庫系統都支持並行處理。

需要說明的是,並發和並行與資料庫系統採用多進程還是多線程體系結構無關。對採用多進程結構的資料庫系統,所有的任務、子任務通過進程來處理;而對採用多線程結構的資料庫系統,這些工作是由線程來完成。

資料庫系統的並發控制,涉及到任務的調度、數據的一致性及可靠性等,而資料庫系統的並行處理,主要涉及任務的處理速度、系統性能等方面。