本文匯總了PolarDB MySQL版分區表相關的常見問題。
PolarDB MySQL版是否支援表分區?
支援。目前PolarDB MySQL版100%相容MySQL,同時做了功能和效能的增強,詳情請參考分區表概述。
PolarDB MySQL版普通表如何轉換為分區表?
普通錶轉換分區表分為以下三種方法:
建立一個分區表,通過DTS線上遷移在同執行個體內把普通表的資料移轉到分區表,資料追齊之後,rename切換表名。
在切換之前需要短暫的業務暫停確保增量資料追平後,切換表名。
例如:普通表t1轉分區表, 建立分區表t1_partition, DTS增量遷移t1到t1_partition, 切換表名語句如下:
rename table t1 to t1_bak, t1_partition to t1;使用COPY DDL轉分區表,
alter table ... partition by,DDL執行期間會阻塞業務寫入。ALTER TABLE t1 PARTITION BY RANGE COLUMNS(create_time) ( PARTITION p0 VALUES LESS THAN ('2025-01-01'), PARTITION p1 VALUES LESS THAN ('2025-02-01'), PARTITION p2 VALUES LESS THAN ('2025-03-01') );普通錶快速轉換為分區表時,僅需修改中繼資料,將所有歷史資料放置於第一個分區內。此過程中不進行資料校正,也不進行資料重分布,因此請務必正確定義分區邊界。
相對於COPY DDL文法, 增加了WITHOUT VALIDATION選項。
ALTER TABLE t1 PARTITION BY RANGE COLUMNS(create_time) ( PARTITION p0 VALUES LESS THAN ('2025-01-01'), PARTITION p1 VALUES LESS THAN ('2025-02-01'), PARTITION p2 VALUES LESS THAN ('2025-03-01') ) WITHOUT VALIDATION;
PolarDB MySQL版一張表最多支援多少個分區?
最多支援8192個分區。如果定義了二級分區,則是所有二級分區的總和最多支援8192個。
資料量有多大適合使用分區表?
資料量下限:使用分區表對資料量的下限沒有要求,空表也可以建分區表,但資料量太少沒必要分區。
資料量上限:當資料量超過64 TB時必須進行分區,因為PolarDB MySQL版單表的最巨量資料容量為64 TB。
其他:與傳統的MySQL資料庫不同,PolarDB MySQL版對大表的支援做了很多最佳化,線上叢集有超過40 TB大小的單表(單表指非分區表),訪問效能沒有明顯的下降。目前,對於64 TB以下的資料量也沒有絕對要求必須要分區,您可以綜合考慮資料的增長和如何管理資料庫比較方便來選擇是否建立分區表。
資料增長
資料增長需要考慮單錶轉分區表(單錶快速轉RANGE分區表情境除外)的時間。目前,一般是通過DTS在遷移前全量讀取和重寫資料(1 TB資料大約需要5.8小時)的方式線上轉分區表,然後再追齊增量資料。或者通過DDL操作轉分區表,但DDL執行期間會阻塞該表線上的寫操作。所以,在轉分區表之前,需要提前規劃分區。例如,預計未來的資料量較大需要分區,建議不要等到資料量增長到大於10 TB時才轉分區表,您可以提前規劃分區(5 TB的資料量線上轉分區表大概需要1天多時間)。
資料管理要求
對於主要用於資料管理需求情境的分區表,以下情境可以不考慮資料量。
按照月份刪除或老化資料,增加新月份的資料,線上始終保持12個月份的資料。如果使用單表,需要從一張大表中按照時間條件通過一個DELETE大事務來清理掉一個月的資料,然後通過
OPTIMIZER TABLE來釋放刪除資料的空間。而按照月份建立RANGE分區表,可以秒級DROP掉一個分區,清理資料非常方便。同理,需要按天、周、季度以及年份管理資料的業務情境使用分區表時也可以不考慮資料量。SaaS客戶按照租戶進行HASH分區或LIST DEFAULT HASH分區等情境下使用分區表也易於管理資料。
是否需要進行分區主要看資料所佔的空間大小,但是業務上更多按照超過多少資料量(行數)進行分區,資料量跟資料單行的長度有關,具體情況具體計算。一般10億行(單行1K位元組)估算成1 TB,建議分區資料量可以參考10億行(PolarDB MySQL版線上叢集有百億級資料量的單表,沒有效能問題)。
分區表建立多少個分區比較合適?
在滿足分區不超過8192個的前提下,根據業務情境和資料量決定分區數。
如何使用分區表?
通常分區和業務有很大關係。如果業務資料和時間相關,建議使用時間定界分割,如果業務資料與地區和租戶相關,可以使用List分區或者Hash分區,或者LIST DEFAULT HASH分區。如果一級分區資料過多,可以使用二級分區。具體請參考分區選擇策略。
使用PolarDB MySQL版資料庫是否需要分庫分表?
不需要。考慮使用分區表代替分庫分表。PolarDB MySQL版是基於共用儲存和一寫多讀的計算儲存分離架構的集中式資料庫,單分區或單表資料量最大64 TB,不必過早考慮分庫分表。
使用PolarDB MySQL版資料庫,單張表資料量太大 ,想使用分表,如何使用?
建議使用分區表。分區表的更多介紹請參見分區表概述。
使用PolarDB MySQL版資料庫進行分區後,是將分區片段儲存於不同的節點上,還是同一個節點上?
分區表把資料切分成小的分區獨立管理,資料會儲存在同一節點上。分區表的更多介紹請參見分區表概述。
PolarDB MySQL版中如果單表資料記錄條數達到億級,是否需要做分庫分表?還是選擇分區表?
建議使用分區表。分區表的更多介紹請參見分區表概述。
PolarDB MySQL版資料庫支援對錶進行分區的操作嗎?在PolarDB MySQL版中對錶進行分區是否有意義?
是的,分區表把資料切分成小的分區獨立管理,從而使得擁有巨量資料量的表仍然擁有高效能和高可用。分區表的更多介紹請參見分區表概述。
業務上估算單張表的資料量為2 TB,選擇使用PolarDB MySQL版還是PolarDB-X?
PolarDB MySQL版單表最大支援到64 TB, 2 TB的資料量相對較小,所以推薦使用PolarDB MySQL版。因為資料量超過1 TB,建議使用分區表。
PolarDB MySQL版分區表支援本地索引嗎?是否支援給指定的一級分區或二級分區添加二級索引?
支援。具體請參見部分索引。
分區表是否支援FULLTEXT全文索引?
不支援
分區表是否支援空間類型,如POINT或者GEOMETRY?
不支援
分區表是否支援使用者暫存資料表?
不支援
分區表是否支援外鍵?
不支援
二級分區是否支援Range和List?
支援。具體請參考分區表類型和使用說明。
分區表是否支援列存索引?
支援
分區表是否支援X-Engine?
支援
建立和刪除分區表時,是否會鎖表?
PolarDB MySQL版8.0.2版本支援分區粒度鎖,只鎖住當前操作的分區,避免了大事務阻塞DDL,從而不影響其他分區的DML操作。具體請參考線上分區維護。
如何刪除不帶名字的分區?
RANGE-LIST或LIST分區建議先通過
SHOW CREATE TABLE語句查看分區結構,再使用ALTER TABLE ... DROP PARTITION命令移除。HASH建議先通過
EXPLAIN SELECT * FROM ***語句查看分區名稱。HASH分區不支援DROP PARTITION。需重新分區調整HASH桶個數位置ALTER TABLE XXX PARTITION BY HASH(XXX) PARTITIONS NUM;調整HASH桶NUM個數。說明該操作需等待時間較長,建議您在業務低峰期運行。
使用PolarDB MySQL版分區,會不會導致效能下降?
與單表相比,掃描相同的資料量,分區表的掃描有分區間切換的代價,會存在效能損耗。相同資料量的情況下,單表只有一個B+樹,分區表是每個分區一個B+樹,樹的層級相對較低,insert效能會更好;分區表能使用where條件進行分區剪枝的查詢情境可以減少資料的掃描和計算,效能也會更優;相對於分庫分表,使用分區表在做JOIN、DDL時,效能上也有優勢。
PolarDB MySQL版的分區表功能會單獨收費嗎?
分區表能力是核心的內建能力,不收費。
使用分區表時,是否需要調整參數的設定?
建議開啟分區粒度的MDL鎖。具體請參見線上分區維護。
在源端的資料庫中某張表是不分區的,通過DTS遷移到目標資料庫中,需要對該表進行分區,是否支援?
支援。在資料同步任務中手動建立好分區表的結構,然後配置映射關係進行資料同步即可。
大版本升級過程中,是否可以把普通單錶轉換為分區表?
可以。具體操作步驟如下:
需要先在源庫中添加一個無主鍵的輔助表,如
create table t1 (a int),這樣可以確保大版本升級過程中的預檢查失敗任務中斷;開始進行大版本升級任務,直到預檢查失敗;
在目標庫建立分區表(該步驟需要前往配額中心,在配額名稱PolarDB MySQL版大版本升級的操作列,單擊申請解決);
刪除輔助表,如
t1。單擊繼續升級(不跳過預檢查),DTS預檢查會再報目標庫有同名表的錯誤;在DTS控制台屏蔽掉該報錯,重新開始預檢查,預檢查成功後,任務正式開始同步;
只要保證分區表和普通單表的資料存放區格式完全一致,後續的同步任務都會順利完成。
設定分區表後,如何查看所有分區表資訊?
要查詢分區資訊,請在information_schema.PARTITIONS表中尋找對應的分區表資訊。
分區表只能對資料表的整型列進行分區嗎?
可以使用KEY、RANGE COLUMN和LIST COLUMN文法對非整型資料的列進行分區。具體請參考KEY、RANGE和LIST。您也可以通過分區函數把資料列轉化成整型列,來使用HASH/RANGE/LIST分區表。
分區表有什麼使用上的限制?
最大分區數不能超過8192個。
單分區資料量最大為64 TB。
不支援外鍵。
不支援全文索引(FULL TEXT)。
如何建立分區表?
在建立表時通過PARTITON BY文法來建立。不同類型分區表的建立方法,請參見分區表類型和使用說明。
如何指定分區鍵?
通過part_expr來指定分區鍵。具體請參見分區表類型和使用說明。
PolarDB MySQL版的分區支援是否和PolarDB PostgreSQL版一樣?
PolarDB PostgreSQL版分區表的分區是子表,每個分區是獨立的表,PolarDB MySQL版的分區是InnoDB表,從Server層看每個分區不是獨立的表。
對PolarDB MySQL版的資料表進行分區,效能提升是否明顯?
對於按照分區鍵過濾條件進行分區剪枝的查詢效能會有明顯提升,另外PolarDB MySQL版對分區表做了效能最佳化,具體請參見分區表概述。
對於大批量的資料,例如一張表一天有1000萬行新資料,一個月就3億行,PolarDB如何應對?
請參見文檔INTERVAL RANGE和自動化管理分區。可以開啟線上分區維護功能,在自動增加和刪除分區時不阻塞其他分區上的DML操作。
分區表支援事務嗎?
支援。
使用分區表是否需要分庫分表分散式交易?
不需要。
分區的寫入效能提升嗎?不同分區的資料寫入相互阻塞嗎?
在巨量資料量的情況下,是能夠提升寫入效能的。不同分區的寫入是完全不阻塞的。
增加分區會導致鎖逾時嗎?
使用線上分區維護功能可以避免這個情況的發生。
為什麼DROP分區會導致整個表的業務阻塞?
在原生MySQL中DROP分區會擷取整表的MDL鎖,導致所有寫入訪問被阻塞。PolarDB MySQL版支援分區粒度的MDL鎖。因此只會阻塞正在DROP的分區的DML,不阻塞其他分區的DML, 最大限度減少對業務的影響。
分區對查詢和讀寫效能有影響嗎?
建議在SQL語句中指定分區鍵,可以減少對效能的影響。
OPTIMIZE TABLE在分區表上是如何進行的?
OPTIMIZE TABLE會對整個分區表上MDL鎖,阻塞所有分區上的DML操作。建議您使用REBUILD PARTITION命令並結合線上分區維護功能,這樣只會阻塞當前重建分區的DML操作,不阻塞其他分區的DML操作, 最大限度減少對業務的影響。
分區表如果需要做資料刪除,如何操作比較安全?
您可以建立一個新的相同定義的臨時空表,然後將需要刪除資料的分區做EXCHANGE PARTITION,再將暫存資料表刪除。
為什麼分區表查詢計劃不準確?
分區表查詢計劃不準確主要的原因是統計資訊不準確,在8.0.2版本中已經針對這個問題做了分區層級統計資訊最佳化,建議您將版本升級到8.0.2。
分區時出現分區不均時應該怎麼處理?
請您重新執行普通錶轉換為分區表,但不要添加WITHOUT VALIDATION關鍵字。重新執行分區操作後,系統會自動對資料進行重新校正並完成分區調整。
如果您資料量較大,重新進行資料校正和分區設定所需時間較長,建議在業務低峰期進行操作。
PolarDB MySQL版的物理表如何分區?
一般情況下,每個分區是一個Innodb表, Hybrid分區可以放在其他儲存引擎上。
誤刪了一個表的分區資料,能否恢複?
目前僅支援庫表級的恢複,不支援分區級的資料恢複。
分區數太多,導致記憶體耗盡,如何解決這個問題?
在PolarDB MySQL版8.0.1和8.0.2版本中,不存在該問題,分區的記憶體都是共用的。建議您升級您的核心版本。
為什麼添加分區的(ADD PARTITION)操作耗時間長度,如何避免?
操作耗時間長度是因為在該分區表上有大事務進行中。PolarDB MySQL版8.0.2版本支援分區粒度的MDL鎖只會阻塞正在添加分區的DML操作,不阻塞其他分區的DML操作, 最大限度減少對業務的影響。
PolarDB可以自動建立表分區嗎?
可以。具體請參見INTERVAL RANGE簡介和自動化管理分區。
使用自動化分區管理功能時,在RW節點建立的event是否會在RO節點執行?
PolarDB MySQL版是共用儲存的架構,在RW節點上建立的event不會在RO節點執行,參數選擇ENABLE即可。
使用自動化分區管理功能時,叢集發生主備切換之後,新的RW節點是否可以繼續執行event?
發生HA之後,新的RW節點是可以繼續執行event的。
使用自動化管理分區時,參數event_scheduler是否需要在RW和RO節點都設定成ON?
RO節點不需要設定為ON,只需要設定RW節點為ON即可。
單錶轉分區表需要多長時間,以100 GB資料量的表為例?
如果使用普通錶快速轉換為RANGE分區表功能,可以秒級轉換;如果您的業務情境不符合普通錶快速轉分區表的情境,您可以使用ALTER TABLE PARTITION BY來重寫表中的全部資料,用時大約1~2個小時,實際用時與您的叢集規格和業務負載等有關。
LINEAR HASH分區和HASH分區有什麼差異?
HASH分區
即模數雜湊,是最常用的一種分區,按照分區數模數來路由分區。
LINEAR HASH分區是一種雜湊演算法,根據二次冪的特性進行計算。相對於HASH分區,優缺點如下:
優點:新增分區時,每個新分區只可能由前一個確定分區分裂得到,增刪分區時需要讀寫的資料比例很小。
缺點:映射均勻性較差。
按照租戶ID進行分區的情境,如何選擇分區類型和分區個數?
按照租戶ID進行分區的情境,可選擇的分區類型有以下兩種:
HASH分區
適用於隨機產生租戶ID的情境,資料分布相對比較離散。分區數量設定可參考以下3種情境:
隨機產生的租戶ID,一般是按照資料總量來計算單個分區的資料量,單個分區的資料量在500萬至5000萬之間。由於資料分布可能不均衡,所以單個分區的資料量也不是絕對的。
如果租戶ID有一定規律,如按照100、200和500這樣的分區數來拆分資料量,資料量在各個分區分布不均衡,則可以嘗試使用一些質數作為分區數。
如果有10億的資料量,則建議建立100至200個分區,單個分區的資料量平均大約為500萬至5000萬。
HASH分區有HASH和KEY兩個子類型,其原理相同,均採用模數雜湊演算法。
如果分區鍵租戶ID是數實值型別, 則選擇HASH分區;
如果分區鍵租戶ID是字元類型,則選擇KEY分區。
LIST DEFAULT HASH分區
適用於長尾業務情境,資料量分布不均衡,資料分布類似二八法則。如:大租戶的資料量多,但大租戶少;中小租戶多但資料量少;或者隨時會新增小租戶,無法在建表時全部枚舉出來。在這種情境下,您可以在一張分區表中同時使用兩種分區:大租戶單獨使用LIST分區,或多個大租戶組合使用一個LIST分區。分區個數取決於大租戶的個數和資料量。其他中小租戶使用HASH分區,HASH分區的分區個數確定方法同HASH分區表。
使用分區表時,如何選擇索引?
針對PolarDB MySQL版分區表,您可以選擇以下幾種索引:
您可以根據實際業務情境,在分區表的不同分區上建立不同的索引,以滿足不同分區上的查詢需求。
針對查詢條件中不包含分區鍵的等值查詢情境,您可以使用全域二級索引。
如何將分區表中歷史分區的資料移轉到該庫的另一張新分區表的分區中?
假設分區表t1的歷史分區為p0和p1,需要將這兩個歷史分區中的資料移轉到新分區表t2的p0和p1分區中。操作步驟如下:
建立新的分區表
t2,表結構與t1保持一致,且包含p0和p1分區。建立普通表
temp,表結構與需要遷移的分區表的表結構相同。使用EXCHANGE PARTITION將
t1表中歷史分區p0中的資料移轉至temp表。ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE temp;如果
t1中p0的資料範圍與t2中p0的資料範圍完全一致,您可以在資料移轉的SQL語句中使用WITHOUT VALIDATION選項來加快遷移速度。如:ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE temp WITHOUT VALIDATION;使用EXCHANGE PARTITION將
temp表中的資料移轉至分區表t2的p0分區中。ALTER TABLE t2 EXCHANGE PARTITION p0 WITH TABLE temp;或使用如下SQL語句:
ALTER TABLE t2 EXCHANGE PARTITION p0 WITH TABLE temp WITHOUT VALIDATION;遷移完成後,
t1表歷史分區p0中的資料已經遷移至新的分區表t2的p0分區中。使用步驟3~步驟4的方法將
t1表歷史分區p1中的資料移轉至t2的p1分區中。全部遷移完成後,刪除表
temp。若後續
t1表中還有其他的分區需要遷移至t2中,您可以在t2表中使用ADD PARTITION添加新的空分區,再按照上述步驟進行資料移轉。
分區表或單表執行過INSTANT添加列或修改列操作後,再執行EXCHANGE PARTITION操作時報錯,應該如何處理?
執行過INSTANT添加列或修改列的分區表或單表,再執行EXCHANGE PARTITION操作時,報錯資訊如下:
ERROR 1731 (HY000): Non matching attribute 'INSTANT COLUMN(s)' between partition and table解決辦法:重寫單表或分區表,消除INSTANT資訊後再進行交換。重寫命令如下:
位於InnoDB引擎下的單表或分區表,重寫命令如下:
ALTER TABLE table_name ENGINE=InnoDB;位於X-Engine引擎下的單表或分區表,重寫命令如下:
ALTER TABLE table_name ENGINE=xengine;
重寫操作是online DDL,不影響DML和Query操作,但會佔用資源。如果表的資料量很大,則需要在業務低峰期執行重寫操作。您可以通過以下SQL語句來查詢重寫DDL的執行進度和預估剩餘時間:
SELECT
pl.ID,
pl.INFO,
esc.THREAD_ID,
esc.EVENT_NAME,
(esc.WORK_COMPLETED / esc.WORK_ESTIMATED) * 100 as PROGRESS,
pl.TIME / 60 AS `EXECUTED TIME(min)`,
ROUND(
(
esc.WORK_ESTIMATED * pl.TIME / esc.WORK_COMPLETED - pl.TIME
) / 60,
2
) AS `ESTIMATED REMAINING TIME(min)`
FROM
performance_schema.events_stages_current esc
LEFT JOIN performance_schema.threads th ON esc.thread_id = th.thread_id
LEFT JOIN information_schema.PROCESSLIST pl ON th.PROCESSLIST_ID = pl.ID;分區表如何指定分區名查詢資料?
在PolarDB MySQL版中支援通過指定分區名稱進行資料查詢的文法格式如下:
文法格式:
PARTITION (partition_names)其中,partition_names表示一個或多個分區名稱的列表,具體格式為:
partition_name, partition_name, ...樣本說明:
查詢特定分區的資料
要查詢表
t1中p0分區的資料,可以使用以下語句:SELECT * FROM t1 PARTITION (p0);
查詢多個分區的資料
如果需要同時查詢多個分區的資料,可以將多個分區名稱用逗號分隔:
SELECT * FROM t1 PARTITION (p0, p1, p2);
在執行分區查詢時,必須確保指定的分區名稱與實際表結構中的分區名稱完全一致。
分區查詢文法適用於支援分區表的表類型,且需要資料庫版本支援相應功能。