Vertica分區

本文翻譯整理自:https://www.vertica.com/docs/9.2.x/HTML/Content/Authoring/AdministratorsGuide/Partitions/PartitioningTables.htm?tocpath=Administrator%27s%20Guide%7CPartitioning%20Tables%7C_____0

基礎知識

vertica的分區方法與目的與其他數據庫沒有區別,都是爲了更高效的對數據進行管理。

vertica中有一個活動分區的概念,特指最新創建的那個分區。非活動分區包含可能不需要經常訪問的數據。在執行合併時,對於非活動分區,Tuple Mover將所有ROS容器組合到一個ROS容器中。在活動分區中,Tuple Mover使用基於分層的算法來組合ROS容器。(一個ROS(讀取優化存儲器)容器是一組存儲在文件中的一組特定的行。ROS容器是通過Moveout或COPY DIRECT等操作創建的。您可以查詢STORAGE_CONTAINERS系統表以查看ROS 容器。由於數據差異,ROS容器佈局在各個節點上可能會有所不同。分段可以向一個節點傳遞比另一節點更多的行。兩個數據負載可能適合一個節點上的WOS,而溢出到另一個節點上。)數據分區被定義爲表屬性,並在該表的所有投影上實現。在所有加載,刷新和恢復操作中,Vertica Tuple Mover會自動將數據分區到單獨的ROS容器中。每個ROS容器包含一個分區或分區組的數據 ; 根據空間要求,一個分區或分區組可以跨越多個ROS容器。

可以通過更改ActivePartitionCount配置參數來更改每個表的活動分區數,默認值爲1。
如果經常將數據加載到最後兩個分區,請將ActivePartitionCount更改爲2。這是一個全局配置參數,會影響每個表。如果將其設置爲2,則Tuple Mover將分層算法應用於最後兩個創建的分區。
增加ActivePartitionCount可減少Tuple Mover操作的數量。但是,您的投影中可能會有太多的ROS容器。

Vertica建議您僅分區大型事實表,不要對小表或維度表進行分區,這樣做會創建大量的ROS容器,這會快速增加目錄大小並影響查詢性能。

爲表定義分區表達式時,請考慮以下事項:

  • 數據保留政策
  • 經常使用的查詢謂詞
  • 分區粒度可能對每個節點的每個投影的ROS容器數量和每個節點的ROS文件總數產生的影響

分區和存儲修剪

分區如何影響數據生命週期管理?

在Vertica數據庫中對大型事實表進行分區可以簡化數據生命週期管理並提高查詢性能。

Vertica提供以下功能:

  • 從表中刪除分區。(DROP_PARTITION函數)
  • 將很少使用的分區移動到存檔表。(MOVE_PARTITIONS_TO_TABLE函數)
  • 將很少使用的分區移動到較便宜的存儲。
  • 從存檔還原分區。

vertica的一些分區函數可以參考:
https://www.vertica.com/docs/9.2.x/HTML/Content/Authoring/SQLReferenceManual/Functions/VerticaFunctions/PartitionManagement/PartitionManagementFunctions.htm?tocpath=SQL Reference Manual|SQL Functions|Vertica Meta-Functions|Partition Management Functions|_____0
vertica的存儲策略可以參考:
https://www.vertica.com/docs/9.2.x/HTML/Content/Authoring/AdministratorsGuide/StorageLocations/CreatingStoragePolicies.htm

什麼是存儲修剪以及它與分區有什麼關係?

分區數據被分隔到各個存儲容器中。因此,在分區列上使用謂詞的查詢可以從Vertica存儲修剪功能中獲益。
在查詢規劃階段,數據庫優化器會識別不包含該查詢所需數據的存儲容器。在查詢處理期間,Vertica執行引擎省略了不存儲適用值的存儲容器,從而減少了I / O並提高了查詢性能。

如何判斷我的查詢是否利用了分區和存儲修剪?

1.配置查詢以獲取transaction_id和statement_id

SELECT * FROM <table_name> WHERE <column_name> BETWEEN 5 AND 7;
NOTICE 4788:  Statement is being profiled
HINT:  Select * from v_monitor.execution_engine_profiles where 
transaction_id=54043195528458555 and statement_id=1;
NOTICE 3557:  Initiator memory for query: [on pool general: 19543 KB, minimum: 19543 KB]
NOTICE 5077:  Total memory required by query: [19543 KB]

2.檢查QUERY_EVENTS系統表中的該事務,並確定查詢計劃指示在執行該查詢時從處理中消除分區的位置:

SELECT node_name , event_details FROM query_events WHERE 
   event_type = 'PARTITIONS_ELIMINATED' AND transaction_id = 54043195528458555
   AND statement_id=1;
    node_name     |                       event_details
------------------+-----------------------------------------------------------
v_vmart_node0003  | Using only 1 stores out of 3 for projection public.tab_b0
v_vmart_node0002  | Using only 1 stores out of 5 for projection public.tab_b0
v_vmart_node0001  | Using only 1 stores out of 2 for projection public.tab_b0
(3 rows)

分區和ROS文件以及ROS容器

ROS文件和ROS容器有什麼區別?

當用戶使用DIRECT發出COPY語句時,Vertica會爲每列創建一個ROS文件。ROS容器是ROS文件的邏輯分組。由於COPY DIRECT或Tuple Mover操作,Vertica創建了ROS容器。

爲什麼我要考慮每個節點每個投影的ROS容器數量?

Vertica將分區數據隔離到不同的存儲容器中。由於Vertica不會跨分區合併數據,因此擁有太多小分區可能會使存儲容器的數量接近最大ROS容器數:1024。

如果達到特定投影的此限制,並嘗試將新數據加載到該投影中,則加載會因“太多ROS容器”錯誤而失敗。如果您有此錯誤,請執行以下操作之一:

  • 使用ALTER_PARTITION將分區表達式更改爲更精細的分區方案。
  • 使用MOVE_PARTITION將舊分區移動到存檔表。
每個節點的ROS容器總數如何影響我的數據庫?

每個節點的ROS文件數量爲:

(storage containers)x(每個投影的列數)

ROS文件的數量可能是catalog目錄大小的主要貢獻者。擁有大catalog目錄會佔用系統內存並降低其他數據庫操作的速度,例如系統表查詢,數據庫啓動,數據庫備份和臨時恢復。

如果每個節點都有一個包含100萬個ROS文件的目錄,則目錄大小約爲3-4GB。如果在你進行控制之前ROS文件的數量一直在增加,則可能不會釋放catalog目錄內存。在Vertica重新獲取已釋放的catalog目錄內存後,內存可供將來使用。但是,在重啓該節點之前,節點實際上不會釋放該內存。

兩個例子
大的catalog目錄

你有一個數據庫

  • 1,000個 table
  • 每個table 2個投影
  • 每個table 50列(平均)
  • 每個節點50個ROS容器

所以,每個節點大約有500萬個ROS文件。

(1000表)x(每個表2個投影)= 2000個投影
(50列)x(2000個投影)= 10,0000 x(每個投影50個ROS)= 5,000,000個ROS文件
  • 1
  • 2

您可以按日期對300個表進行分區,並將數據保留一年。這樣做可以使用Vertica分區管理功能管理單個日期的數據。然而,這使得ROS數量增加了大約1000萬,使目錄的大小翻了一番:

300個表)x(2個投影)= 600個投影
(365天)x 600 = 219,000 x(50列)= 10,900,000個ROS文件

在這種情況下,您有兩種選擇:

  • 按天分區每個節點每個投影至少添加365個ROS容器,因此您只需要對少量表按天分區。避免對小表進行分區,如果可能,請對大多數表按周或按月進行分區。
  • 如果需要按天進行分區,請通過將類似的表組合到單個表中來確定可以減少ROS容器數量的位置。schema通常繼承自傳統OLTP系統,後者根據地理位置將表拆分爲多個表,以提高查詢性能。爲獲得最佳結果,請將這些表組合到一個表中。
每個投影的ROS容器太多

你有一個數據庫:

  • 100個 table
  • 每個table 2個投影
  • 每個table 50列
  • 每個節點50個ROS容器

所以,您有200個投影和500,000個ROS文件:

100個表)x(每個表2個投影)= 200個投影
(50列平均值)x(200個投影)=  10,000 x(每個節點50個ROS容器)=  500,000個ROS文件

假設您希望按天對10個表進行分區,並將數據保留三年。這樣做允許您使用分區管理功能管理每天的數據。在這種情況下,您可能不會累積大量的ROS文件。但是,在達到第三年加載數據時,你會遇到ROS pushback(1024個ROS容器)。

1個表x(365 x 3= 1095個ROS容器用於非活動分區 

結果,在活動分區中沒有剩餘空間來接收數據。

或者,如果按周劃分:

1個表x(52 x 3= 156個ROS容器用於非活動分區 

這種替代方案可以顯著減少ROS容器。在這種情況下,請考慮按周而不是按天對數據進行分區。

在規劃未來數據增長時,請考慮這些問題。

補充:對於vertica,還有一種方法去解決上述問題。就是採用分層分區,分層分區是一種可以靈活進行分區的方式。比如說,可以針對近一個月的數據按天分區,大於一個月到一年的數據按月分區,大於一年的數據按照年進行分區。這樣既可以減少分區的數量,又可以確保近期使用的數據有更細化的分區。
關於分層分區,可參考:https://www.vertica.com/docs/9.2.x/HTML/Content/Authoring/AdministratorsGuide/Partitions/HierarchicalPartitioning.htm?tocpath=Administrator's Guide|Partitioning Tables|_____2
以及
https://www.vertica.com/blog/hierarchical-partitioning/

重新分區及重新組織

您可以使用以下內容對現有表進行分區或更改表的分區表達式:

 ALTER TABLE < table_name > PARTITION BY < partition_expression >

運行此語句時,將立即擦除存儲容器的任何現有分區鍵信息。您必須使用REORGANIZE關鍵字根據新的分區表達式重建此信息。
注意:節點關閉時,請勿更改表分區。

使用REORGANIZE關鍵字時會發生什麼?

分別或一起使用PARTITION BY和REORGANIZE關鍵字對錶進行分區或重新分區,如下所示:

=> ALTER TABLE <table_name> PARTITION BY <partition_expression> REORGANIZE;
  • 1

運行此語句時,Vertica會刪除所有現有分區鍵,重新分區表並重新組織表。

REORGANIZE操作是在後臺運行的Tuple Mover操作的變體。重組操作以塊的形式讀取數據,以免影響數據庫性能。然後,REORGANIZE根據新的分區方案將數據寫入ROS容器,並將分區鍵添加到ROS容器對象。

可以推遲REORGANIZE嗎?這種延遲有什麼影響?

爲了最小化正在運行的數據庫的性能,REORGANIZE一次只能處理一部分ROS容器。

重新分區後延遲REORGANIZE操作會導致以下限制:

  • 您無法在分區表達式已更改但未REORGANIZE的表上運行分區函數。
  • 對於分區表,沒有分區鍵的ROS容器不參與Tuper Mover合併。這可能導致ROS的pushback。

重新分區後儘快REORGANIZE。監視REORGANIZE操作的進度,直到完成更改表上的所有投影。

如何監控REORGANIZE流程的狀態?

使用以下系統表監視重組後臺進度:

VS_TUPLE_MOVER_OPERATIONS
PARTITION_STATUS
PARTITION_REORGANIZE_ERRORS

要查看給定表的分區歷史記錄,請查詢系統表CATALOG_EVENTS。

如何刪除表分區?

要更改表以使其不再分區,請使用以下語句:

=> ALTER TABLE <table_name> REMOVE PARTITIONING;
  • 1

從表中刪除分區後,Vertica會像處理任何其他非分區表一樣處理該表。Vertica使用分層算法合併ROS容器。

分區限制注意事項

每個表的分區數量是否有限制?

每個表的分區數沒有限制。但是,分區的數據被分隔爲ROS容器。Vertica將每個節點的每個投影的ROS容器數限制爲1024,因此每個表的限制基本上是1024個分區。

Vertica可防止單個COPY DIRECT語句加載超過1024個分區。

如果您有超過365個分區(約爲限制的三分之一),請按投影計數觀察ROS容器並監視Tuple Mover合併操作。如果有超過365個分區,則可能需要重新考慮該表的分區方案,或將未查詢的分區移動到歸檔表。

如何確定內存中數據庫目錄的大小?

以下查詢返回數據庫目錄的大小:

SELECT node_name,MAX(ts)AS ts,MAX(catalog_size_in_MB)
   AS catlog_size_in_MB 
   FROMSELECT node_name,
    TRUNC((dc_allocation_pool_statistics_by_second。“time”):: TIMESTAMP'SS':: VARCHAR2))AS ts,
    SUM ((dc_allocation_pool_statistics_by_second.total_memory_max_value 
    -  dc_allocation_pool_statistics_by_second.free_memory_min_value))/1024 * 1024AS catalog_size_in_MB from dc_allocation_pool_statistics_by_second GROUP BY 1,
    TRUNC((dc_allocation_pool_statistics_by_second。“time”):: TIMESTAMP'SS':: VARCHAR2))
    )
    subquery_1 GROUP BY 1 ORDER BY 1 LIMIT 50;
如何檢查分區是否有助於大型目錄?

有幾種情況可能導致大型數據庫目錄。大型目錄是10 GB或更大的目錄。

以下查詢返回具有最大ROS容器的前50個投影。如果您看到結果中的表已分區且分區計數很高,請考慮修改分區方案,以便Vertica創建更少的分區。

SELECT s.node_name,p.table_schema,s.projection_name,
   COUNT(DISTINCT s.storage_oid)storage_container_count,
   COUNT(DISTINCT partition_key)partition_count,
   COUNT(r.rosid)ros_file_count 
   FROM storage_containers s LEFT OUTER JOIN PARTITIONS p 
   ON s.storage_oid = p.ros_id JOIN vs_ros r 
   ON r.delid = s.storage_oid 
   GROUP BY 1,2,3 ORDER BY 4 DESC LIMIT 50;

關於分區,更多內容可參考:https://www.vertica.com/docs/9.2.x/HTML/Content/Authoring/AdministratorsGuide/Partitions/PartitioningTables.htm

參考:https://blog.csdn.net/hmxz2nn/article/details/95526904 vertica的分區

後記:DROP_PARTITION函數和MOVE_PARTITIONS_TO_TABLE函數用於管理分區。在大表(數據量超幾十億)進行備份和臨時表入庫正式表的操作中,比insert into 要快很多。上億數據insert into 大概近一個小時的操作,用MOVE_PARTITIONS_TO_TABLE會快很多。vertica 中insert into select * from tmp是非常慢的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章