簡體   English   中英

MySQL 如何處理並發插入?

[英]How does MySQL handle concurrent inserts?

我知道 MySQL 中存在一個並發 SELECT 和 INSERT 的問題。 但是,我的問題是,如果我打開與 MySQL 的兩個連接並繼續使用它們加載數據,MySQL 是並發獲取數據還是等待一個完成后再加載另一個?

我想知道 MySQL 在這兩種情況下的行為。 就像我嘗試在打開單獨的連接時同時加載同一個表或不同表中的數據一樣。

如果您將創建一個到數據庫的新連接並從兩個鏈接執行插入,那么從數據庫的角度來看,它仍然是順序的

MySQL 文檔頁面上的 並發插入文檔說:

如果有多個 INSERT 語句,它們將與 SELECT 語句同時排隊並按順序執行。

請注意,無法控制兩個並發插入的順序。 這種並發中的順序受許多不同因素的支配。 為了確保順序,默認情況下您將不得不犧牲並發性。

MySQL 確實支持將數據並行插入到同一個表中。

但是並發讀/寫的方法取決於您使用的存儲引擎。

數據庫

MySQL 對 InnoDB 表使用行級鎖定以支持多個會話的同時寫入訪問,使其適用於多用戶、高並發和 OLTP 應用程序。

我的ISAM

MySQL 對 MyISAM、MEMORY 和 MERGE 表使用表級鎖定,一次只允許一個會話更新這些表,使它們更適合只讀、多讀或單用戶應用程序

但是,上面提到的 MyISAM 表的行為可以通過concurrent_insert系統變量來改變,以實現並發寫入。 詳情請參閱此鏈接

因此,事實上,MySQL 確實支持 InnoDB 和 MyISAM 存儲引擎的並發插入。

您詢問死鎖檢測、ACID 和特別是 MVCC、鎖定和事務:

死鎖檢測和回滾

InnoDB 自動檢測事務死鎖並回滾一個或多個事務以打破死鎖。 InnoDB 嘗試選擇小事務進行回滾,其中事務的大小由插入、更新或刪除的行數決定。 當 InnoDB 執行一個事務的完全回滾時,該事務設置的所有鎖都會被釋放。 但是,如果由於錯誤而僅回滾單個 SQL 語句,則可能會保留該語句設置的某些鎖。 發生這種情況是因為 InnoDB 以一種格式存儲行鎖,以至於它之后無法知道哪個語句設置了哪個鎖。

https://dev.mysql.com/doc/refman/5.6/en/innodb-deadlock-detection.html

鎖定

保護事務免於查看或更改其他事務正在查詢或更改的數據的系統。 鎖定策略必須在數據庫操作的可靠性和一致性(ACID 哲學的原則)與良好並發性所需的性能之間取得平衡。 微調鎖定策略通常涉及選擇隔離級別並確保所有數據庫操作對於該隔離級別都是安全可靠的。

http://dev.mysql.com/doc/refman/5.5/en/glossary.html#glos_locking

代表原子性、一致性、隔離性和持久性的首字母縮寫詞。 這些屬性在數據庫系統中都是可取的,並且都與事務的概念密切相關。 InnoDB 的事務特性遵循 ACID 原則。 事務是可以提交或回滾的原子工作單元。 當一個事務對數據庫進行多次更改時,要么在提交事務時所有更改都成功,要么在回滾事務時撤消所有更改。 數據庫始終保持一致的狀態——在每次提交或回滾之后,以及在事務進行時。 如果跨多個表更新相關數據,查詢會看到所有舊值或所有新值,而不是舊值和新值的混合。 交易在進行中時相互保護(隔離); 他們不能相互干擾或看到彼此未提交的數據。 這種隔離是通過鎖定機制實現的。 有經驗的用戶可以調整隔離級別,以減少保護以提高性能和並發性為代價,當他們可以確定事務確實不會相互干擾時。

http://dev.mysql.com/doc/refman/5.5/en/glossary.html#glos_acid

MVCC

InnoDB 是一個多版本並發控制 (MVCC) 存儲引擎,這意味着單行的多個版本可以同時存在。 事實上,可能有大量這樣的行版本。 根據您選擇的隔離模式,InnoDB 可能必須讓所有行版本回到最早的活動讀取視圖,但至少它必須讓所有版本回到當前正在運行的 SELECT 查詢的開頭

https://www.percona.com/blog/2014/12/17/innodbs-multi-versioning-handling-can-be-achilles-heel/

這取決於。

這取決於客戶端——有些客戶端允許並發訪問; 有些會序列化訪問,從而失去預期的收益。 您甚至沒有指定 PHP vs Java vs ... 或 Apache vs ... 或 Windows vs ... 許多組合根本不提供任何並行性。

如果不同的表,則只有 I/O、CPU、buffer_pool 上的互斥體等的一般爭用。合理的並行度是可能的。

如果是同一個表,則取決於索引和訪問模式。 在某些情況下,線程會相互阻塞。 在某些情況下,它甚至會“死鎖”並回滾其中一項事務。 死鎖不僅會減慢你的速度,還會讓你重試插入。

如果您正在尋找大量行的高速攝取,請參閱我的博客 它列出了一些技術,並指出了一些后果,例如復制、引擎選擇、多線程。

多個線程插入同一個表——這在很大程度上取決於您為任何PRIMARYUNIQUE鍵提供的值。 這取決於是否在同一事務中采取了其他操作。 這取決於涉及多少 I/O。 這取決於您是進行單行插入還是批處理。 這取決於......(抱歉含糊不清,但您的問題不是很具體。)

如果您想介紹兩個或三個設計的細節,我們可以討論這些細節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM