MYSQL 一個特殊需求在不同的MYSQL配置產生不同的結果 與 update 0 是否需要應用程式判斷
來源:AustinDatabases
最近有一個需求關於資料的清理的需求,但是這個需求裡面有一個部分有一個部分是特殊,也就是在資料清理中,是需要進行資料的匯出和匯入的,並確定在匯入和匯出的過程中,匯出資料在匯出到清理的整個過程中中不能被改變,不能進行commited這些資料需要具有獨佔性 。
這裡要完成這個事情,可以採用對於要遷移的行進行鎖定的方法來進行,但鎖定的方法可以用 select * from table where 條件 for update; 但問題的重點是, 在不同的MYSQL配置中會產生什麼樣的結果,不同的結果開發是否能接受的問題。
這裡有一個相關的說明和測試的大綱
1 MYSQL innodb_lock_wait_timeout = 更長的時間如 86400 和 innodb_deadlock_detect =ON
2 MYSQL innodb_lock_wait_timeout =3 和 innodb_deadlock_detect = OFF 的情況
在不同場合下,MySQL 在這兩邊有不同的設定可能性,在一些早期的MYSQL 和網際網路的情況下,innodb_deadlock_detect 是為OFF的,並且在 innodb_lock_wait_timeout = 3 也就是不管怎麼樣,只要出現互斥的狀態下,鎖超時為3秒,當然這裡也包含了死鎖的情況,死鎖不超過3秒,這裡是透過系統鎖超時來進行判斷的,當然blocked 的情況也是3秒內解決。
但在一些傳統性的單位,也有另外的一種配置,innodb_deadlock_detect =ON 並且因為程式編制和需求的原因blocked 的時間都設定的較長並不和網際網路設定的相同。
這裡需要在不同的情況下來分析,同樣的設定給應用程式帶來的不同的問題。
這裡先從網際網路的方案來說,死鎖探測為0 innodb_lock_wait_timeout = 3 當然有的地方更短設定成1秒。具體什麼成因這裡就不討論了,同時這裡還有一個不同就是隔離級別,我們在每次測試使用不同的隔離級別來看看會有什麼影響。
編號 | 資料庫引數 | session 隔離 | 操作型別 |
1 | 不探測死鎖 3秒解鎖 | read commit | 更新 |
2 | 不探測死鎖 3秒解鎖 | repeatable read | 更新 |
3 | 不探測死鎖 3秒解鎖 | read commit | 刪除 |
4 | 不探測死鎖 3秒解鎖 | repeatable read | 刪除 |
5 | 探測死鎖,不解鎖 | read commit | 更新 |
6 | 探測死鎖,不解鎖 | repeatable read | 更新 |
7 | 探測死鎖,不解鎖 | read commit | 刪除 |
8 | 探測死鎖,不解鎖 | repeatable read | 刪除 |
1 innodb_lock_wait_timeout = 3 and innodb_deadlock_detect = OFF
innodb_deadlock_detect = OFF
innodb_lock_wait_timeout = 3
表的狀態
mysql> select * from read_table;
+----+------+
| id | name |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 7 |
| 8 | 8 |
| 9 | 9 |
+----+------+
9 rows in set (0.00 sec)
1
2
3
4
這裡我們可以看到,整體的操作中,隔離級別對於操作是沒有任何影響的,結果都是一樣,對於表中的鎖定的資料更新失敗。
innodb_deadlock_detect = ON
innodb_lock_wait_timeout = 86400
5
6
7
8
透過上面的幾個實驗,我們可以總結出以下一些結論
在MYSQL 配置中如果使用的 innodb_lock_wait_timeout =3 的配置的情況下,在很短的時間資料庫就能判斷出BLOCKED 或死鎖,在這樣的情況下,無論使用什麼隔離級別,那麼結果都是一樣的,都會是鎖超時的報錯和讓你重試的資訊。
或者你使用了自動檢測死鎖,同時將innodb_lock_wait_timeout = 更大的數值,那麼你得到的結果就與隔離級別有關了,如果是RR 的情況,你將會獲得 update 0 的結果,如果是RC 資料還在的情況下,你會獲得update 對應結果的結果,如果相關的行不在的情況下,獲得結果也是UPDATE 0 的結果。
另這裡也需要注意,在設定 innodb_lock_wait_timeout = 3 的情況下如果blocked 的情況不超過3秒,那麼結果還是和 innodb_lock_wait_time=無限大的情況類似。
最終基於以上的結果,應用程式是需要針對程式最終在執行語句後的結果進行判斷,到底是 update 0 還是 非0,並根據結果做出相關後續的操作。
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70027826/viewspace-3005051/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql 兩個表結果合拼到一個表,用常量區別不同的表MySql
- 突然斷電,是否會影響Mysql的執行結果MySql
- mysql如何判斷是否存在某個欄位MySql
- mysql如何判斷是否為空MySql
- MySQL判斷表名是否存在MySql
- oracle sqr之不同判斷寫入不同的.LIS檔案Oracle
- 理解:MySQL的null與空字串的不同MySqlNull字串
- 怎麼判斷mysql表是否存在MySql
- PHP 判斷一個字元是否在字串中PHP字元字串
- MySQL 更新同一個表不同欄位MySql
- 如何判斷一個連結地址是否有效
- 怎樣判斷mysql是否安裝成功MySql
- java判斷mysql中資料庫是否存在JavaMySql資料庫
- MySQL:一個特殊的問題MySql
- 判斷一個物件是否為空物件,判斷一個物件中是否有空值物件
- golang中判斷兩個slice是否相等與判斷值下的 陣列是否相等Golang陣列
- C#中模運算子(%)在不同的.NET版本為什麼會有不同結果?C#
- 相同update語句在MySQL,Oracle的不同表現(r12筆記第30天)MySqlOracle筆記
- 如何判斷一個物件是否在指定物件的原型鏈中物件原型
- 判斷一個檔案是否在IE的快取中 (轉)快取
- MySQL與SQL的觸發器的不同寫法MySql觸發器
- javascript 判斷括號是否配對。JavaScript
- 用JS判斷一個html元素是否存在的五種方法JSHTML
- Mysql 分頁效率不同的SQLMySql
- 判斷一個字串是否包含一個子串的方法字串
- 判斷一個數是否為質數(程式碼)
- 如何判斷一個元素是否在可視範圍
- 如何判斷一個元素是否在可視區域中?
- 判斷ABAP程式碼是否處於update模式下執行的工具類模式
- 判斷 Eloqument 模型查詢資料結果是否為空模型
- 選擇排序中交換資料的不同方式出現的不同結果排序
- 解鎖「SOAR」在不同場景下的應用與實踐
- 如果精確判斷一個IP是否被佔用
- Laravel 不同生產環境伺服器的判斷Laravel伺服器
- 如何判斷一個元素在億級資料中是否存在?
- 在Oracle中,如何判斷一個字串是否為數字?Oracle字串
- js的特殊結果JS
- IBM WorkFlow可以呼叫不同的應用(程式)IBM