文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (美式信紙尺寸) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 參考手冊  /  ...  /  NDB Cluster 中與交易處理相關的限制

25.2.7.3 NDB Cluster 中與交易處理相關的限制

NDB Cluster 在處理交易方面存在一些限制。這些限制包括以下幾點:

  • 交易隔離等級。  NDBCLUSTER 儲存引擎僅支援 READ COMMITTED 交易隔離等級。(例如,InnoDB 支援 READ COMMITTEDREAD UNCOMMITTEDREPEATABLE READSERIALIZABLE。)您應該記住,NDB 會針對每一列實作 READ COMMITTED;當讀取請求到達儲存該列的資料節點時,所返回的是該列當時最後一次提交的版本。

    永遠不會返回未提交的資料,但是當修改多列的交易與讀取相同列的交易同時提交時,執行讀取的交易可能會觀察到這些列的之前值、之後值或兩者兼具,這是因為給定的列讀取請求可能會在其他交易提交之前或之後處理。

    為了確保給定的交易僅讀取之前或之後的值,您可以使用 SELECT ... LOCK IN SHARE MODE 來強制列鎖定。在這種情況下,鎖定會一直保留到擁有該鎖定的交易提交為止。使用列鎖定還可能導致以下問題:

    • 鎖定等待逾時錯誤的頻率增加,以及並行性降低

    • 由於讀取需要提交階段,因此交易處理額外負擔增加

    • 可能會耗盡可用的並行鎖定數量,此數量受限於 MaxNoOfConcurrentOperations

    NDB 對所有讀取都使用 READ COMMITTED,除非使用 LOCK IN SHARE MODEFOR UPDATE 等修改子。 LOCK IN SHARE MODE 會導致使用共用列鎖定;FOR UPDATE 會導致使用獨佔列鎖定。唯一的索引鍵讀取會由 NDB 自動升級其鎖定,以確保自我一致的讀取;BLOB 讀取也會採用額外的鎖定來確保一致性。

    請參閱 第 25.6.8.4 節「NDB Cluster 備份疑難排解」,以瞭解 NDB Cluster 的交易隔離等級實作如何影響 NDB 資料庫的備份和還原。

  • 交易與 BLOB 或 TEXT 欄位。  NDBCLUSTER 僅將使用任何 MySQL BLOBTEXT 資料類型的欄位值部分儲存在 MySQL 可見的資料表中;BLOBTEXT 的剩餘部分儲存在 MySQL 無法存取的單獨內部資料表中。這會產生兩個相關的問題,您在對包含這些類型欄位的資料表執行 SELECT 陳述式時應注意這些問題:

    1. 針對任何來自 NDB Cluster 資料表的 SELECT:如果 SELECT 包含 BLOBTEXT 欄位,則 READ COMMITTED 交易隔離等級會轉換為帶有讀取鎖定的讀取。這樣做的目的是為了保證一致性。

    2. 對於任何使用唯一索引鍵查詢來擷取任何使用 BLOBTEXT 資料類型之任何欄位的 SELECT,且該查詢在交易內執行,則會在該資料表上保留共用讀取鎖定,直到交易提交或中止為止。

      即使針對具有 BLOBTEXT 欄位的 NDB 資料表,使用索引或資料表掃描的查詢也不會發生此問題。

      例如,考慮由以下 CREATE TABLE 陳述式定義的資料表 t

      CREATE TABLE t (
          a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
          b INT NOT NULL,
          c INT NOT NULL,
          d TEXT,
          INDEX i(b),
          UNIQUE KEY u(c)
      ) ENGINE = NDB,

      以下在 t 上的查詢會導致共用讀取鎖定,因為它使用唯一索引鍵查詢:

      SELECT * FROM t WHERE c = 1;

      但是,這裡顯示的四個查詢都不會導致共用讀取鎖定:

      SELECT * FROM t WHERE b = 1;
      
      SELECT * FROM t WHERE d = '1';
      
      SELECT * FROM t;
      
      SELECT b,c WHERE a = 1;

      這是因為在這四個查詢中,第一個查詢使用索引掃描,第二個和第三個查詢使用資料表掃描,而第四個查詢雖然使用主索引鍵查詢,但不擷取任何 BLOBTEXT 欄位的值。

      您可以避免使用會擷取 BLOBTEXT 欄位的唯一索引鍵查詢,或者在無法避免此類查詢的情況下,儘快提交交易,以協助將共用讀取鎖定的問題降至最低。

  • 唯一索引鍵查詢和交易隔離。  唯一索引會在 NDB 中使用內部維護的隱藏索引表來實作。當使用唯一索引存取使用者建立的 NDB 資料表時,會先讀取隱藏的索引表以尋找主索引鍵,然後再使用該索引鍵來讀取使用者建立的資料表。為了避免在此雙重讀取作業期間修改索引,會鎖定在隱藏索引表中找到的列。當更新使用者建立的 NDB 資料表中由唯一索引參照的列時,執行更新的交易會對隱藏的索引表加上獨佔鎖定。這表示同一(使用者建立的)NDB 資料表上的任何讀取作業都必須等待更新完成。即使讀取作業的交易等級為 READ COMMITTED,情況也是如此。

    一種可以用來繞過潛在封鎖讀取的解決方法,是強制 SQL 節點在執行讀取時忽略唯一索引。這可以使用 SELECT 陳述式中作為一部分的 IGNORE INDEX 索引提示來完成(請參閱第 10.9.4 節「索引提示」)。由於 MySQL 伺服器會為在 NDB 中建立的每個唯一索引建立陰影順序索引,因此可以使用讀取順序索引來代替,並避免唯一索引存取鎖定。產生的讀取與依主索引鍵提交的讀取一致,並傳回讀取該列時最後一次提交的值。

    透過順序索引讀取會降低叢集中資源的使用效率,並可能具有更高的延遲。

    也可以透過查詢範圍而不是唯一值來避免使用唯一索引進行存取。

  • 復原。  沒有部分交易,也沒有部分交易復原。重複索引鍵或類似錯誤會導致整個交易復原。

    此行為與其他交易式儲存引擎(例如 InnoDB)的行為不同,InnoDB 可能會復原個別陳述式。

  • 交易與記憶體使用。 如本章其他地方所述,NDB Cluster 不擅長處理大型交易;執行多次每次包含少量操作的小型交易,會比嘗試執行包含大量操作的單一大型交易來得好。除此之外,大型交易需要非常大量的記憶體。因此,許多 MySQL 陳述式的交易行為會受到影響,如下列清單所述:

    • 當在 NDB 資料表上使用 TRUNCATE TABLE 時,它不具有交易性。如果 TRUNCATE TABLE 無法清空資料表,則必須重新執行直到成功。

    • DELETE FROM (即使沒有 WHERE 子句) 具有交易性的。對於包含大量資料列的資料表,您可能會發現使用多個 DELETE FROM ... LIMIT ... 陳述式來將刪除操作「分塊」可提高效能。如果您的目標是清空資料表,則您可能希望改用 TRUNCATE TABLE

    • LOAD DATA 陳述式。 LOAD DATANDB 資料表上使用時不具有交易性。

      重要事項

      當執行 LOAD DATA 陳述式時,NDB 引擎會以不規則的間隔執行 commit,以更好地利用通訊網路。無法事先得知這些 commit 何時發生。

    • ALTER TABLE 和交易。 當複製 NDB 資料表作為 ALTER TABLE 的一部分時,複製的建立不具有交易性。(無論如何,當複製被刪除時,此操作將會回滾。)

  • 交易與 COUNT() 函式。 使用 NDB Cluster 複寫時,無法保證副本上 COUNT() 函式的交易一致性。換句話說,當在來源上執行一系列陳述式 (INSERTDELETE 或兩者),在單一交易中變更資料表中的資料列數目時,在副本上執行 SELECT COUNT(*) FROM table 查詢可能會產生中繼結果。這是因為 SELECT COUNT(...) 可能會執行髒讀,而不是 NDB 儲存引擎中的錯誤。(如需更多資訊,請參閱 Bug #31321。)