本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 InnoDB 資料表空間來改善 My RDS 的當機復原時間SQL
MySQL 中的每個資料表都包含資料表定義、資料和索引。MySQL 儲存引擎 InnoDB 會將資料表資料和索引存放在資料表空間中。InnoDB 會建立全域共用的資料表空間,其中包含資料字典和其他相關中繼資料,而且它可以包含資料表資料和索引。InnoDB 也可以針對每個資料表和分割區建立個別的資料表空間。這些個別的資料表空間會儲存在副檔名為 .ibd 的檔案中,而且每個資料表空間的標題都包含一個專門識別它的數字。
Amazon RDS 在名為 的 MySQL 參數群組中提供參數innodb_file_per_table
。此參數會控制 InnoDB 是否將新的資料表資料和索引加入至共用的資料表空間 (方法為將參數值設為 0) 或加入至個別的資料表空間 (方法為將參數值設為 1)。Amazon RDS會將 innodb_file_per_table
參數的預設值設定為 1,這可讓您捨棄個別的 InnoDB 資料表,並回收這些資料表用於資料庫執行個體的儲存體。在大部分使用案例中,將 innodb_file_per_table
參數設為 1 是建議的設定。
當您有大量資料表時,您應該將 innodb_file_per_table
參數設定為 0,例如在使用標準 (磁性) 或一般用途SSD儲存時超過 1000 個資料表,或使用佈建IOPS儲存時超過 10,000 個資料表。將此參數設為 0 時,不會建立個別資料表空間,而且這樣做可縮短資料庫損毀復原所需的時間。
在當機復原週期期間,我的SQL 會處理每個中繼資料檔案,包括資料表空間。與在有多個資料表空間時處理數千個資料表空間檔案所需的時間相比,處理SQL共用資料表空間中中繼資料資訊所需的時間可忽略。因為資料表空間號碼會儲存在每個檔案的標題內,所以讀取所有資料表空間檔案的合計時間可能高達七小時。例如,標準儲存體上的一百萬個 InnoDB 資料表空間在損毀復原週期可能需要五到八小時的處理時間。在某些情況下,InnoDB 可以判斷在損毀復原週期之後是否需要額外清除,以便它將開始另一個損毀復原週期,這將延長復原時間。請記住,除了處理資料表空間資訊外,損毀復原週期也會包含轉返交易、修正中斷的頁面,以及其他操作。
因為 innodb_file_per_table
參數位於常數群組中,所以您可以變更參數值,方法為編輯資料庫執行個體所使用的參數群組,而不必重新啟動資料庫執行個體。例如,在將設定從 1 (建立個別資料表) 變更為 0 (使用共用的資料表空間) 之後,當現有的資料表繼續具有個別資料表空間時,新的 InnoDB 資料表將新增至共用的資料表空間。若要將 InnoDB 資料表移至共用的資料表空間,您必須使用 ALTER TABLE
命令。
將多個資料表空間遷移至共用的資料表空間
您可以將 InnoDB 資料表的中繼資料移至它自己的資料表空間,這將根據 innodb_file_per_table
參數設定,重建資料表中繼資料。請先連線至您的 MySQL 資料庫執行個體,然後發出適當的命令,如下所示。如需詳細資訊,請參閱連線至 MySQL 資料庫執行個體。
ALTER TABLE
table_name
ENGINE = InnoDB, ALGORITHM=COPY;
例如,以下查詢會針對不在共用的資料表空間中的每一個 InnoDB 資料表傳回 ALTER TABLE
陳述式。
對於 MySQL 5.7 資料庫執行個體:
SELECT CONCAT('ALTER TABLE `', REPLACE(LEFT(NAME , INSTR((NAME), '/') - 1), '`', '``'), '`.`', REPLACE(SUBSTR(NAME FROM INSTR(NAME, '/') + 1), '`', '``'), '` ENGINE=InnoDB, ALGORITHM=COPY;') AS Query FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE SPACE <> 0 AND LEFT(NAME, INSTR((NAME), '/') - 1) NOT IN ('mysql','');
對於 MySQL 8.4 和 8.0 資料庫執行個體:
SELECT CONCAT('ALTER TABLE `', REPLACE(LEFT(NAME , INSTR((NAME), '/') - 1), '`', '``'), '`.`', REPLACE(SUBSTR(NAME FROM INSTR(NAME, '/') + 1), '`', '``'), '` ENGINE=InnoDB, ALGORITHM=COPY;') AS Query FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE SPACE <> 0 AND LEFT(NAME, INSTR((NAME), '/') - 1) NOT IN ('mysql','');
重建 MySQL 資料表以將資料表的中繼資料移至共用資料表空間需要暫時額外的儲存空間才能重建資料表,因此資料庫執行個體必須具有可用的儲存空間。重建期間,會鎖定資料表,而且查詢無法存取它。對於不經常存取的小型表格或表格,可能不需要擔心此問題。對於在大量並行環境中經常存取的大型表格或表格,您可以在僅供讀取複本上重建資料表。
您可以建立僅供讀取複本,並將資料表中繼資料遷移至僅供讀取複本上共用的資料表空間。雖然ALTERTABLE陳述式會封鎖僅供讀取複本上的存取,但來源資料庫執行個體不會受到影響。在資料表重建過程中,當僅供讀取複本延遲時,來源資料庫執行個體將繼續產生其二進位記錄。由於重建需要額外的儲存空間,重播日誌檔案可能因此變大,所以您應該建立其配置的儲存體大於來源資料庫執行個體的僅供讀取複本。
若要建立僅供讀取複本並重建 InnoDB 資料表,以使用共用的資料表空間,請採取以下步驟:
-
確保已在來源資料庫執行個體上啟用備份保留,以便啟用二進位記錄。
-
使用 AWS Management Console 或 AWS CLI 為來源資料庫執行個體建立僅供讀取複本。因為建立僅供讀取複本涉及許多與損毀復原相同的程序,所以如果有大量 InnoDB 資料表空間,則建立程序可能需要一些時間。在僅供讀取複本上配置更多的儲存空間,超過目前在來源資料庫執行個體上使用的儲存空間。
-
建立僅供讀取複本後,請使用參數設定
read_only = 0
和innodb_file_per_table = 0
建立參數群組。接著請將參數群組與僅供讀取複本產生關聯。 -
針對您想要在複本上遷移的所有資料表,發出下列SQL陳述式:
ALTER TABLE
name
ENGINE = InnoDB -
在僅供讀取複本上完成了所有
ALTER TABLE
陳述式時,請驗證僅供讀取複本是否連線至來源資料庫執行個體,以及這兩個執行個體是否同步。 -
使用 主控台或 CLI 將僅供讀取複本提升為執行個體。確定用於新獨立資料庫執行個體的參數群組已將
innodb_file_per_table
參數設為 0。變更新獨立資料庫執行個體的名稱,並將任何應用程式指向新的獨立資料庫執行個體。