mysql併發操作引發的一些思考

2021-08-15 09:34:11 字數 3174 閱讀 6379

最近公司專案中用到了關係型資料庫mysql,其中會涉及到併發操作,之前也用過mysql,但是只是停在了簡單的用上面(老大搭好架子、寫好demo,我模仿),趁放假好好看看相關的資料,解決一下我一直以來的疑惑。

在網上查閱文章的過程中,我對mysql有了新的認識,對鎖、事務等有了了解。感覺要深入理解mysql鎖還是需要花費很多時間的,在這裡我先淺嘗輒止,只記錄一下自己的理解。

我的疑惑:

一、應用程式層如何在高併發下保證資料一致性?

二、資料庫層(mysql)是否已經保證了高併發下的資料一致性?如果是,如何實現的?

三、分布式時如何在高併發下保證資料一致性?

四、sqlalchemy如何保證高併發下的資料一致性?

這個還是比較好解決的。不管是多執行緒還是多程序只要用鎖就能保證資料一致性,當然這樣會損失效率。

使用innodb在特定隔離級別下時可以保證高併發下的資料一致性的,具體看下面:

1、mysql是支援多種儲存型別的,現在用的最多的是innodb(後續分析都是圍繞innodb)

通過查資料,我對mysql有了新的認識:

mysql是開源的關係型資料庫,它提供了很多種型別的儲存引擎,我們可以根據對資料處理的需求,選擇不同的儲存引擎,從而最大限度的利用mysql強大的功能。

這是介紹mysql engines的文章,現在主要用的是innodb,之前公司用過myisam。

innodb

innodb是乙個健壯的事務型儲存引擎,為使用者操作非常大的資料儲存提供了乙個強大的解決方案。

innodb還引入了行級鎖定和外來鍵約束,在以下場合下,使用innodb是最理想的選擇:

1.更新密集的表。innodb儲存引擎特別適合處理多重併發的更新請求。

2.事務。innodb儲存引擎是支援事務的標準mysql儲存引擎。

3.自動災難恢復。與其它儲存引擎不同,innodb表能夠自動從災難中恢復。

4.外來鍵約束。mysql支援外來鍵的儲存引擎只有innodb。

5.支援自動增加列auto_increment屬性。

一般來說,如果需要事務支援,並且有較高的併發讀取頻率,innodb是不錯的選擇。

myisam

據說已經被淘汰了,現在用的很少。支援選擇密集或者插入密集的場景。

myisam表無法處理事務,這就意味著有事務處理需求的表,不能使用myisam儲存引擎。myisam儲存引擎特別適合在以下幾種情況下使用:

1.選擇密集型的表。myisam儲存引擎在篩選大量資料時非常迅速,這是它最突出的優點。

2.插入密集型的表。myisam的併發插入特性允許同時選擇和插入資料。例如:myisam儲存引擎很適合管理郵件或web伺服器日誌資料。

2、innodb自己對sql進行加鎖,我們要做的選擇合適的隔離級別和避免死鎖

參考文章:

innodb中的事務隔離級別和鎖的關係-美團技術分享

mysql 加鎖處理分析-阿里資料庫專家寫的

(1) 資料庫遵循的是兩段鎖協議,將事務分成兩個階段,加鎖階段和解鎖階段(所以叫兩段鎖)

(2)在資料庫操作中,為了有效保證併發讀取資料的正確性,提出的事務隔離級別。我們的資料庫鎖,也是為了構建這些隔離級別存在的。

(3)innodb通過樂觀鎖(實現方式是mvcc)在rr級別中,解決了快照讀時出現幻讀的問題。

快照讀:就是select

當前讀:特殊的讀操作,插入/更新/刪除操作,屬於當前讀,處理的都是當前的資料,需要加鎖。

(4)行鎖防止別的事務修改或刪除,gap鎖防止別的事務新增,行鎖和gap鎖結合形成的的next-key鎖共同解決了rr級別在寫資料(即當前讀)時的幻讀問題。

(5)綜上:在innodb的rr隔離級別下,基本不需要自己加鎖,因為innodb本身都幫著幹了,除非你在資料時效特別敏感的業務中需要當前讀,比如select * from table where ? for update。

我覺得有兩種方式:

1、使用自身支援分布式的資料庫

2、使用資料庫中介軟體,比如360開源的atlas,阿里雲的drds服務(現在的雲服務特別的方便,大大減小了小公司的運維成本,但是還是需要懂相關的基礎知識才行)

sqlalchemy使用session的時候,大多數情況都是不需要自己加鎖的。如果需要當前讀則可以呼叫函式with_for_update。

2017.01.04更新

補充其他一些概念:

1、髒讀、不重複讀、幻讀:

(1)髒讀,最容易理解。另乙個事務修改了資料,但尚未提交,而本事務中的select會讀到這些未被提交的資料。 (2)不重複讀。解決了髒讀後,會遇到,同乙個事務執行過程中,另外乙個事務提交了新資料,因此本事務先後兩次讀到的資料結果會不一致。 (3)幻讀。解決了不重複讀,保證了同乙個事務裡,查詢的結果都是事務開始時的狀態(一致性)。但是,如果另乙個事務同時提交了新資料,本事務再更新時,就會「驚奇的」發現了這些新資料,貌似之前讀到的資料是「鬼影」一樣的幻覺。

2、主鍵:

參考網頁

主鍵,是索引的一種,並且是唯一性索引的一種。 (1)主鍵是not null和unique的 (2)主鍵可以是聯合主鍵 (3)無特殊需求下innodb建議使用與業務無關的自增id作為主鍵(走過彎路) (4)主鍵可以,但是mysql官方建議有

3、外來鍵:

參考網頁

外來鍵的使用條件: (1)兩個表必須是innodb表,myisam表暫時不支援外來鍵(據說以後的版本有可能支援,但至少目前不支援); (2)外來鍵列必須建立了索引,mysql 4.1.2以後的版本在建立外來鍵時會自動建立索引,但如果在較早的版本則需要顯示建立; (3)外來鍵關係的兩個表的列必須是資料型別相似,也就是可以相互轉換型別的列,比如int和tinyint可以,而int和char則不可以; 外來鍵的好處:可以使得兩張表關聯,保證資料的一致性和實現一些級聯操作;

MySql一些操作

一.mysql修改使用者密碼 1.直接在資料庫中修改記錄 mysql use mysql mysql update user set password password new password where user user name mysql flush privileges 其實這種方法就是...

mysql一些操作

13 1.複製表結構及資料到新錶 create table 新錶 select from 舊表 2.只複製表結構到新錶 create table 新錶 select from 舊表 where 1 2 即 讓where條件不成立.create table 新錶 like 舊表 tianshibao ...

MySql 的一些操作

default 預設 1.distinct 去重 2.desc 描述 3.select 選擇 4.insert into 表名 co1,col2,col3 values 英文翻譯 insert 插入 v1,v2,v3 v1,v2,v3 v1,v3,v3 5.alter 改變 資料庫mysql的基本操...