Mysql

將具有許多表的大型數據庫從 latin1 轉換為 utf8mb4

  • June 15, 2022

所以這不是關於“如何將表格從 latin1 轉換為 utf8?”的問題。我完全知道並明白這一點。我想問的問題是,“我怎樣才能讓這種轉變在過渡期間盡可能少地痛苦?” 我知道我需要轉換每個表上的列,然後在某個時候將 PHP MySQL 連接從 latin1 更改為 UTF8,如果我的數據庫是 1 GB 而不是 1 TB,我可以輕鬆完成所有這些。

使用 MariaDB 10.3,數據庫中有大約 600 個表都在 InnoDB 儲存引擎下,我想說其中可能有 50 個在 1gb 以北,大約 20 個在 10 或 100 gb 中。這 20 個表的問題在於它們是應用程序本身的核心,而這 20 個表中的 1 個表是很多 UTF8 問題發生的地方(目前為 66gb)。

因此,處理約 90% 的表基本上不會有停機時間,但最後 10% 將是一個笨蛋。關於我應該採取哪些步驟以及以什麼順序進行的任何建議?以下是我一般的想法……

  1. 將 90% 轉換為 utf8mb4
  2. 將 PHP MySQL 連接字元集從 latin1 設置為 utf8mb4
  3. 使用我建構的腳本將剩餘表的每一列從 latin1 轉換為二進制,然後將二進制轉換為 utf8mb4。留出大概…… 3-4 小時的停機時間???我們的應用程序是一個非常繁忙的應用程序,3-4 小時的停機時間很多。

有沒有人成功地嘗試過 Percona 的pt-online-schema-change,你認為它在這種情況下會有所幫助嗎?

我能想到的唯一另一件事是啟動並執行一個新的從屬伺服器,它是主伺服器的新副本,對該從屬伺服器進行所有 utf8mb4 更改,然後將該從屬伺服器提升到主數據庫。我想我也可以事先轉換所有的奴隸,只是在我這樣做的時候將它們輪換使用或停止使用。唯一未知的是 latin1 主伺服器會發生什麼,而從伺服器都是 utf8mb4。所有轉換後的數據都可以,但我認為新數據可能是 binlog 中的 latin1 而不是 charset 不可知的?

在我的上一份工作中,我們使用 pt-online-schema-change 進行此類更改或任何其他 ALTER TABLE 更改,每週在比您大得多的表上進行數百次。我從事內部服務和儀表板工作,以允許開發人員*自行執行架構更改。*我知道——這太瘋狂了!


對於如此大的表,您必須小心重啟。如果數據庫發生故障轉移事件,或者執行 pt-online-schema-change 的主機重新啟動,那麼您必須重新開始。實際上,我們為 pt-online-schema-change 開發了更新檔來保存它的狀態,所以如果腳本被中斷,我們可以從中斷的地方繼續。不幸的是,這些更新檔不是公開的,我已經離開了那份工作。

至少在screenortmux會話中執行 pt-online-schema-change,這樣您就不必依賴不間斷的 ssh 會話。


一張非常大的桌子需要多少時間?它會有所不同,因為 pt-online-schema-change 監控幾個性能指標,如果它認為表複製工作負載導致性能下降,它會動態降低自身速度。因此,如果您的數據庫通常服務於高流量級別,則 pt-online-schema-change 將比數據庫空閒時花費更多的時間。因此,如果可能的話,在下班時間安排您的架構更改是值得的。

大型表可能需要 24 小時以上才能完成架構更改。我想我看到的最長的是4週。在非常繁忙的數據庫伺服器上,這可能是一個超過 1TB 的表。很不幸,因為我記得在那種情況下,開發人員認為他們可以刪除索引。一旦他們放棄它,事實證明他們確實確實需要該索引來進行某些查詢。但是用了 4 週的時間來執行 alter table 以重新創建刪除的索引。由於使用了 pt-online-schema-change,在這 4 週內仍然可以查詢該表,但是在沒有所需索引的情況下某些查詢的性能很差。那很痛苦。

我一直告訴開發人員,允許表變得如此大是自找麻煩,出於這樣的原因。但他們不聽。


pt-online-schema-change 的另一個警告是,由於它必須在開始時創建觸發器並在結束時進行重命名,因此它必須在開始和結束時短暫地對錶具有獨占訪問權。這意味著它等待一個獨占的元數據鎖,如果有針對錶的任何未完成的事務。因此,如果您有長時間執行的查詢,甚至是未送出事務的短查詢,它將阻止啟動或最後的重命名。雖然 pt-online-schema-change 在等待元數據鎖時被阻塞,但它會阻塞所有其他查詢。這可能會導致嚴重的問題。

所以我們找到了一種方法來呼叫 pt-online-schema-change 並在元數據鎖定上設置 2 秒超時。如果它不能在 2 秒內完成它的工作,它會停止等待,並且必須重試。這可以防止像我描述的那樣長時間的僵局。有時這意味著 pt-online-schema-change 必須重試多次才能開始或結束。但這總比停電好。

理想情況下,您不會有如此長時間執行的事務,但這取決於您的應用程式碼。可能很難知道您是否有這種情況,或者哪些程式碼對它們負責。


我現在能想到的最後一個警告是,如果您在任何地方對字元串列進行連接,更改字元集,因此排序規則意味著如果這些連接之前依賴於索引,那麼它們現在不能。在您可以將連接表更改為兼容之前,此類連接可能對性能有很大的不利影響。這與 pt-online-schema-change 無關,但適用於您用來更改字元集的任何方法。


我希望你升級到 utf8mb4,而不僅僅是 utf8。utf8mb4 正在成為首選字元集,而 utf8(3 字節類型)正在被棄用。


我不確定您提到的複制問題。我建議您測試它,而不是使用您的生產數據庫,而是在測試環境中。我懷疑基於語句的複制會起作用,但我不確定基於行的複制是否會起作用。

引用自:https://dba.stackexchange.com/questions/313404