パスマンパーティションテーブルツールの使用

I.概要

PG <= 10のバージョンでは、すべてのパーティションがテーブル継承によってパーティション化されます。各パーティションをサブテーブルとして作成するには、CHECKCONSTRAINTを使用する必要があります。

PostgreSQL 10は、暗黙的な制約によって実現される、従来の方法と同じであるネイティブパーティショニングを提供し、その制限のほとんどは依然として関連しています。

2つの元のパーティションテーブルの実装は、select / delete / updateの実行時に実行されます。実行プランでは、制約やクエリ条件に従ってクエリを実行する必要のないパーティションテーブルは除外されます。COPYを呼び出すとき、またはデータを挿入するときにトリガーまたはルールを使用して、対応するパーティションテーブルにデータを挿入します。PLANは、すべてのパーティションに対してRangeTblEntryとRelOptInfoの結果を作成する必要があり、ロックも必要です。クエリであろうと挿入であろうと、パフォーマンスへの影響はより大きくなります。

PG 12バージョン以降、ネイティブパーティションテーブルが再び最適化され、リソースの消費とパフォーマンスが大幅に向上しました。

Pathmanは、一般的に使用されるパーティションテーブル管理プラグインです。パーティション構成をpathman_configテーブルに格納し、テーブル情報をメモリにキャッシュします。同時に、HOOKを使用してRELATION置換を実装するため、効率が非常に高くなります。 。現在、このツールはrangeとhashの2つのパーティション分割方法をサポートしています。Rangeはバイナリ検索を使用して対応するパーティションを検索し、hashはハッシュ検索を使用して対応するパーティションを検索します。

pg_pathmanが使用するフックは次のとおりです。

  • pg_pathmanは、ProcessUtility_hookフックを使用して、パーティションテーブルのCOPYクエリを処理します。
  • RuntimeAppend(追加プランノードを上書きします)
  • RuntimeMergeAppend(MergeAppendプランノードをオーバーライドします)
  • PartitionFilter(INSERTトリガーのドロップイン置換)

pg_pathmanの機能:

  • 現在、HASHパーティションとRANGEパーティションをサポートしています。
  • 自動パーティション管理(関数インターフェイスを介してパーティションを作成する、メインテーブルデータをパーティションテーブルに自動的に移行する)、または手動パーティション管理(関数を介して実装する、既存のテーブルをパーティションテーブルにバインドする、またはパーティションテーブルから削除する)をサポートします。 。
  • サポートされているパーティションフィールドタイプには、int、float、date、およびカスタムドメインを含むその他の一般的なタイプが含まれます。
  • パーティションテーブル(JOIN、副選択など)の効果的なクエリプラン。
  • RuntimeAppendおよびRuntimeMergeAppendカスタムプランノードを使用して、動的パーティション選択を実現します。
  • PartitionFilter:挿入トリガーの効果的な置換方法。
  • パーティションの自動追加のサポート(現在、RANGEパーティションテーブルのみをサポートしています)。
  • 効率を向上させるために、パーティションテーブルの直接読み取りまたは書き込みへのコピーから/へのコピーをサポートします。
  • パーティションフィールドの更新をサポートするには、トリガーを追加する必要があります。パーティションフィールドを更新する必要がない場合は、このトリガーを追加することはお勧めしません。これにより、パフォーマンスに一定の影響があります。
  • ユーザーがコールバック関数をカスタマイズできるようにします。コールバック関数は、パーティションの作成時に自動的にトリガーされます。
  • パーティションテーブルのノンブロッキング作成、およびメインテーブルデータのバックグラウンドでのパーティションテーブルへの自動ノンブロッキング移行。
  • FDWをサポートし、構成パラメーターpg_pathman.insert_into_fdw =(disabled | postgres | any_fdw)を介してpostgres_fdwまたは任意のFDWをサポートします。

2、インストールと展開

1.ソースインストールパッケージをダウンロードし、コンパイルしてインストールします

# git clone https://github.com/postgrespro/pg_pathman
# cd /usr/local/pg_pathman
# make USE_PGXS=1
# make USE_PGXS=1 install

2.データベース構成ファイルを変更して有効にします

## 配置文件修改
$ vi postgres.conf
shared_preload_libraries = 'pg_pathman'

## 重启数据库服务,使配置文件生效
$ pg_ctl start

このパラメータ設定について注意すべきことの1つは、データベースに同じフック関数を使用するツールがある場合、フック関数の呼び出しで競合が発生する可能性があることです。それらは構成ファイルで標準化する必要があります。一般的なシナリオは、pg_stat_statementsがデータベースにインストールされている場合、構成順序はshared_preload_libraries = 'pg_stat_statements、pg_pathman'です。

3.データベース読み込み拡張パッケージ

postgres=# CREATE EXTENSION pg_pathman;
CREATE EXTENSION
postgres=# \dx
                     List of installed extensions
    Name    | Version |   Schema   |           Description
------------+---------+------------+----------------------------------
 pg_pathman | 1.5     | public     | Partitioning tool for PostgreSQL
 plpgsql    | 1.0     | pg_catalog | PL/pgSQL procedural language
(2 rows)

4.拡張パックのアップグレード

## 下载安装最新版本的源码包
## 重启数据库服务
## 执行以下命令
ALTER EXTENSION pg_pathman UPDATE;
SET pg_pathman.enable = t;

5.インストールされているプラ​​グインを表示する

postgres=# \dx
                     List of installed extensions
    Name    | Version |   Schema   |           Description
------------+---------+------------+----------------------------------
 pg_pathman | 1.5     | public     | Partitioning tool for PostgreSQL
 plpgsql    | 1.0     | pg_catalog | PL/pgSQL procedural language
(2 rows)

3つの基本的なコマンド

3.1関連するビューと表

1.パーティションテーブルのメタデータ情報pathman_config

db1=# \d+ pathman_config
                                   Table "public.pathman_config"
     Column     |   Type   | Collation | Nullable | Default | Storage  | Stats target | Description
----------------+----------+-----------+----------+---------+----------+--------------+-------------
 partrel        | regclass |           | not null |         | plain    |              |主表oid
 expr           | text     |           | not null |         | extended |              |分区字段
 parttype       | integer  |           | not null |         | plain    |              |分区类型,hash或range
 range_interval | text     |           |          |         | extended |              |range分区的interval
Indexes:
    "pathman_config_pkey" PRIMARY KEY, btree (partrel)
Check constraints:
    "pathman_config_interval_check" CHECK (validate_interval_value(partrel, expr, parttype, range_interval))
    "pathman_config_parttype_check" CHECK (parttype = ANY (ARRAY[1, 2]))
Policies:
    POLICY "allow_select" FOR SELECT
      USING (true)
    POLICY "deny_modification"
      USING (check_security_policy(partrel))
Triggers:
    pathman_config_trigger AFTER INSERT OR DELETE OR UPDATE ON pathman_config FOR EACH ROW EXECUTE FUNCTION pathman_config_params_trigger_func()
Access method: heap


db1=# select * from  pathman_config;
    partrel     |   expr   | parttype | range_interval
----------------+----------+----------+----------------
 part_test      | crt_time |        2 | 1 mon               //主表为part_test、分区字段为crt_time,分区类型2表示range分区,range的interval为1个月
 part_hash_test | crt_time |        1 |                     //主表为part_hash_test,分区字段为crt_time,分区类型1表是hash分区
(2 rows)

2.パーティションテーブルのメタデータ情報pathman_config_params

db1=# \d+ pathman_config_params
                                Table "public.pathman_config_params"
     Column      |   Type   | Collation | Nullable | Default | Storage  | Stats target | Description
-----------------+----------+-----------+----------+---------+----------+--------------+-------------
 partrel         | regclass |           | not null |         | plain    |              |主表oid
 enable_parent   | boolean  |           | not null | false   | plain    |              |是否在优化器中过滤主表
 auto            | boolean  |           | not null | true    | plain    |              |insert时是否自动扩展不存在的分区
 init_callback   | text     |           |          |         | extended |              |create partition时的回调函数oid
 spawn_using_bgw | boolean  |           | not null | false   | plain    |              |
Indexes:
    "pathman_config_params_pkey" PRIMARY KEY, btree (partrel)
Check constraints:
    "pathman_config_params_init_callback_check" CHECK (validate_part_callback(
CASE
    WHEN init_callback IS NULL THEN 0::regprocedure
    ELSE init_callback::regprocedure
END))
Policies:
    POLICY "allow_select" FOR SELECT
      USING (true)
    POLICY "deny_modification"
      USING (check_security_policy(partrel))
Triggers:
    pathman_config_params_trigger AFTER INSERT OR DELETE OR UPDATE ON pathman_config_params FOR EACH ROW EXECUTE FUNCTION pathman_config_params_trigger_func()
Access method: heap


db1=# select * from pathman_config_params;
    partrel     | enable_parent | auto | init_callback | spawn_using_bgw
----------------+---------------+------+---------------+-----------------
 part_test      | f             | t    |               | f                  //主表为part_test,数据无法写入到主表,自动扩展分区
 part_hash_test | t             | t    |               | f                  //主表为part_hash_test,允许数据写入到主表,自动扩展分区
(2 rows)

3.パーティションテーブルのバックグラウンドデータ移行タスク情報pathman_concurrent_part_tasks

db1=# \d+ pathman_concurrent_part_tasks
                  View "public.pathman_concurrent_part_tasks"
  Column   |   Type   | Collation | Nullable | Default | Storage  | Description
-----------+----------+-----------+----------+---------+----------+-------------
 userid    | regrole  |           |          |         | plain    |
 pid       | integer  |           |          |         | plain    |
 dbid      | oid      |           |          |         | plain    |
 relid     | regclass |           |          |         | plain    |
 processed | bigint   |           |          |         | plain    |
 status    | text     |           |          |         | extended |
View definition:
 SELECT show_concurrent_part_tasks.userid,
    show_concurrent_part_tasks.pid,
    show_concurrent_part_tasks.dbid,
    show_concurrent_part_tasks.relid,
    show_concurrent_part_tasks.processed,
    show_concurrent_part_tasks.status
   FROM show_concurrent_part_tasks() show_concurrent_part_tasks(userid, pid, dbid, relid, processed, status);

db1=#
db1=#
db1=# select * from pathman_concurrent_part_tasks;
 userid | pid | dbid | relid | processed | status
--------+-----+------+-------+-----------+--------
(0 rows)

4.パーティションテーブルpathman_partition_listのパーティションフィールド情報

db1=# \d+ pathman_partition_list
                      View "public.pathman_partition_list"
  Column   |   Type   | Collation | Nullable | Default | Storage  | Description
-----------+----------+-----------+----------+---------+----------+-------------
 parent    | regclass |           |          |         | plain    |主表oid
 partition | regclass |           |          |         | plain    |子分区表
 parttype  | integer  |           |          |         | plain    |分区表类型,1表示range,2表示hash
 expr      | text     |           |          |         | extended |分区字段
 range_min | text     |           |          |         | extended |range的左边界
 range_max | text     |           |          |         | extended |range的右边界
View definition:
 SELECT show_partition_list.parent,
    show_partition_list.partition,
    show_partition_list.parttype,
    show_partition_list.expr,
    show_partition_list.range_min,
    show_partition_list.range_max
   FROM show_partition_list() show_partition_list(parent, partition, parttype, expr, range_min, range_max);

db1=# select * from pathman_partition_list;
     parent     |    partition     | parttype |   expr   |      range_min      |      range_max
----------------+------------------+----------+----------+---------------------+---------------------
 part_test      | part_test_1      |        2 | crt_time | 2020-09-01 00:00:00 | 2020-10-01 00:00:00
 part_test      | part_test_2      |        2 | crt_time | 2020-10-01 00:00:00 | 2020-11-01 00:00:00
 part_test      | part_test_3      |        2 | crt_time | 2020-11-01 00:00:00 | 2020-12-01 00:00:00
 part_test      | part_test_4      |        2 | crt_time | 2020-12-01 00:00:00 | 2021-01-01 00:00:00
 part_test      | part_test_5      |        2 | crt_time | 2021-01-01 00:00:00 | 2021-02-01 00:00:00
 part_test      | part_test_6      |        2 | crt_time | 2021-02-01 00:00:00 | 2021-03-01 00:00:00
 part_test      | part_test_7      |        2 | crt_time | 2021-03-01 00:00:00 | 2021-04-01 00:00:00
 part_test      | part_test_8      |        2 | crt_time | 2021-04-01 00:00:00 | 2021-05-01 00:00:00
 part_test      | part_test_9      |        2 | crt_time | 2021-05-01 00:00:00 | 2021-06-01 00:00:00
 part_test      | part_test_10     |        2 | crt_time | 2021-06-01 00:00:00 | 2021-07-01 00:00:00
 part_test      | part_test_11     |        2 | crt_time | 2021-07-01 00:00:00 | 2021-08-01 00:00:00
 part_test      | part_test_12     |        2 | crt_time | 2021-08-01 00:00:00 | 2021-09-01 00:00:00
 part_test      | part_test_13     |        2 | crt_time | 2021-09-01 00:00:00 | 2021-10-01 00:00:00
 part_test      | part_test_14     |        2 | crt_time | 2021-10-01 00:00:00 | 2021-11-01 00:00:00
 part_test      | part_test_15     |        2 | crt_time | 2021-11-01 00:00:00 | 2021-12-01 00:00:00
 part_test      | part_test_16     |        2 | crt_time | 2021-12-01 00:00:00 | 2022-01-01 00:00:00
 part_test      | part_test_17     |        2 | crt_time | 2022-01-01 00:00:00 | 2022-02-01 00:00:00
 part_test      | part_test_18     |        2 | crt_time | 2022-02-01 00:00:00 | 2022-03-01 00:00:00
 part_test      | part_test_19     |        2 | crt_time | 2022-03-01 00:00:00 | 2022-04-01 00:00:00
 part_test      | part_test_20     |        2 | crt_time | 2022-04-01 00:00:00 | 2022-05-01 00:00:00
 part_test      | part_test_21     |        2 | crt_time | 2022-05-01 00:00:00 | 2022-06-01 00:00:00
 part_test      | part_test_22     |        2 | crt_time | 2022-06-01 00:00:00 | 2022-07-01 00:00:00
 part_test      | part_test_23     |        2 | crt_time | 2022-07-01 00:00:00 | 2022-08-01 00:00:00
 part_test      | part_test_24     |        2 | crt_time | 2022-08-01 00:00:00 | 2022-09-01 00:00:00
 part_test      | part_test_25     |        2 | crt_time | 2022-09-01 00:00:00 | 2022-10-01 00:00:00
 part_hash_test | part_hash_test_0 |        1 | crt_time |                     |
 part_hash_test | part_hash_test_1 |        1 | crt_time |                     |
 part_hash_test | part_hash_test_2 |        1 | crt_time |                     |
 part_hash_test | part_hash_test_3 |        1 | crt_time |                     |
(29 rows)

3.2パーティション管理機能

1.範囲パーティション

1)範囲パーティションを作成しますcreate_range_partitions

create_range_partitions(relation       REGCLASS,  -- 主表OID
                        attribute      TEXT,      -- 分区列名
                        start_value    ANYELEMENT,  -- 开始值
                        p_interval     ANYELEMENT,  -- 间隔;任意类型,适合任意类型的分区表
                        p_count        INTEGER DEFAULT NULL,   --  分多少个区
                        partition_data BOOLEAN DEFAULT TRUE)   --  是否立即将数据从主表迁移到分区, 不建议这么使用

2)範囲パーティションを作成しますcreate_partitions_from_range

create_partitions_from_range(relation       REGCLASS,  -- 主表OID
                             attribute      TEXT,      -- 分区列名
                             start_value    ANYELEMENT,  -- 开始值
                             end_value      ANYELEMENT,  -- 结束值
                             p_interval     ANYELEMENT,  -- 间隔;任意类型,适合任意类型的分区表
                             partition_data BOOLEAN DEFAULT TRUE)   --  是否立即将数据从主表迁移到分区, 不建议这么使用

RANGEパーティションテーブルの使用に関する提案:

  • パーティション列には、非NULL制約が必要です。
  • パーティションの数は、既存のすべてのレコードをカバーできる必要があります。
  • パーティションテーブルを作成するときは、partition_dataをfalseに設定し、非ブロッキング移行インターフェイスを使用することをお勧めします。データ移行が完了したら、メインテーブルを無効にすることをお勧めします。

2.ハッシュパーティション

1)ハッシュパーティションを作成しますcreate_hash_partitions

create_hash_partitions(relation         REGCLASS,  -- 主表OID
                       attribute        TEXT,      -- 分区列名
                       partitions_count INTEGER,   -- 打算创建多少个分区
                       partition_data   BOOLEAN DEFAULT TRUE)   --  是否立即将数据从主表迁移到分区, 不建议这么使用

HASHパーティションテーブルでの使用に関する提案:

  • パーティション列には、非NULL制約が必要です。
  • パーティションテーブルを作成するときは、partition_dataをfalseに設定し、ノンブロッキング移行インターフェイスを使用して移行することをお勧めします。データ移行が完了したら、メインテーブルを無効にすることをお勧めします。
  • pg_pathmanは式によって制限されないため、* from part_test where crt_time = '2016-10-25 00:00:00' :: timestamp;を選択します。この書き込み方法はHASHパーティションにも使用できます。
  • HASHパーティション列はint型の列に限定されず、HASH関数を使用して自動的に変換されます。

3.パーティションの移行

パーティションテーブルの作成時にメインテーブルのデータがパーティションに移行されない場合は、ノンブロッキング移行インターフェイスを使用して、データを対応するパーティションに移行できます。

1)メインテーブルデータをサブパーティションテーブルpartition_table_concurrentlyに移行します

partition_table_concurrently(relation   REGCLASS,              -- 主表OID
                             batch_size INTEGER DEFAULT 1000,  -- 一个事务批量迁移多少记录
                             sleep_time FLOAT8 DEFAULT 1.0)    -- 获得行锁失败时,休眠多久再次获取,重试60次退出任务。

2)移行タスクを停止します

stop_concurrent_part_task(relation REGCLASS)    -- 主表OID

4.パーティションの分割と統合

1)範囲パーティション分割

パーティションが大きすぎて2つのパーティションに分割する場合は、パーティションを2つのサブパーティションテーブル(現在はRANGEパーティションテーブルのみをサポート)に分割するように指定できます。データは自動的に別のパーティションに移行されます。

split_range_partition(partition      REGCLASS,            -- 分区oid
                      split_value    ANYELEMENT,          -- 分裂值
                      partition_name TEXT DEFAULT NULL)   -- 分裂后新增的分区表名

2)複数のパーティションの組み合わせ

2つのサブパーティションテーブルがマージされ、サブパーティションテーブル2のデータが自動的にサブパーティションテーブル1に移行されてから、サブパーティションテーブル2が削除されます。(現在、RANGEパーティションテーブルのみをサポートしています)

指定两个需要合并分区,必须为相邻分区  
merge_range_partitions(partition1 REGCLASS,               -- 子分区表1
                        partition2 REGCLASS)              -- 相邻的子分区表2

5.新しいパーティション

各パーティションテーブルは、デフォルトで自動的にパーティションを作成できます。

1)範囲パーティションを後方に追加する

append_range_partition(parent         REGCLASS,            -- 主表OID
                       partition_name TEXT DEFAULT NULL,   -- 新增的分区表名, 默认不需要输入
                       tablespace     TEXT DEFAULT NULL)   -- 新增的分区表放到哪个表空间, 默认不需要输入

2)範囲パーティションを前方に追加します

prepend_range_partition(parent         REGCLASS,
                        partition_name TEXT DEFAULT NULL,
                        tablespace     TEXT DEFAULT NULL)

4)パーティションを追加します

add_range_partition(relation       REGCLASS,    -- 主表OID
                    start_value    ANYELEMENT,  -- 起始值
                    end_value      ANYELEMENT,  -- 结束值
                    partition_name TEXT DEFAULT NULL,  -- 分区名
                    tablespace     TEXT DEFAULT NULL)  -- 分区创建在哪个表空间下

6、パーティションを削除します

## 删除指定子分区
drop_range_partition(partition TEXT,   -- 子分区名称
                    delete_data BOOLEAN DEFAULT TRUE)  -- 是否删除分区数据,如果false,表示分区数据迁移到主表。  

## 批量删除全部子分区
drop_partitions(parent      REGCLASS,       -- 主表oid
                delete_data BOOLEAN DEFAULT FALSE) -- 是否删除分区数据,如果false,表示分区数据迁移到主表。

7.パーティションのバインド/バインド解除

1)パーティションをバインドします(既存のテーブルがパーティションテーブルに追加されます)

既存のテーブルを既存のパーティションマスターテーブルにバインドします。既存のテーブルとメインテーブルは、削除された列を含め、同じ構造を維持する必要があります(pg_attributeの整合性を確認してください)

attach_range_partition(relation    REGCLASS,    -- 主表OID
                       partition   REGCLASS,    -- 分区表OID
                       start_value ANYELEMENT,  -- 起始值
                       end_value   ANYELEMENT)  -- 结束值

2)パーティションのバインドを解除します(パーティションを通常のテーブルに変換します)

メインテーブルの継承関係からパーティションを削除します。データは削除せず、継承関係を削除し、制約を削除します。インターフェイスは次のとおりです。

detach_range_partition(partition REGCLASS)  -- 指定分区名,转换为普通表

8.メインテーブルを無効にします

メインテーブルのすべてのデータがパーティションに移行されると、メインテーブルを無効にすることができます。インターフェイス機能は次のとおりです。

set_enable_parent(relation REGCLASS,      -- 主表名称
                    value BOOLEAN)        -- true/false

9.パーティションを自動的に拡張します

範囲パーティションテーブル。パーティションの自動拡張を可能にします。新しく挿入されたデータが既存のパーティション範囲にない場合、パーティションは自動的に作成されます。

set_auto(relation REGCLASS,         -- 主表名称
            value BOOLEAN)          -- true/false

4、例

1.範囲パーティションの基本的な使用法

postgres=# \c db1
You are now connected to database "db1" as user "postgres".

## 创建分区主表
db1=# create table part_test(id int, info text, crt_time timestamp not null);
CREATE TABLE
db1=# insert into part_test select id,md5(random()::text),clock_timestamp() + (id||' hour')::interval from generate_series(1,10000) t(id);
INSERT 0 10000
db1=# select * from part_test limit 10;
 id |               info               |          crt_time
----+----------------------------------+----------------------------
  1 | d31dbb7672abc7aac781d30f1e6fd707 | 2020-09-24 18:51:37.784476
  2 | 97d807b7e5b7438904338b12e66519d0 | 2020-09-24 19:51:37.784566
  3 | c332436057ed3e43d56c2702ae66477c | 2020-09-24 20:51:37.78457
  4 | 9973d6f7c3ba75c14ebfcae16ef5081d | 2020-09-24 21:51:37.784572
  5 | dd377f7d8ff7a78f64f1155b071837eb | 2020-09-24 22:51:37.784575
  6 | 5bf2c97d421602ba7821da5059b13225 | 2020-09-24 23:51:37.784577
  7 | 82fca34052d64defaec7ac2d59961934 | 2020-09-25 00:51:37.784578
  8 | edf9cb3eb950a4f2efbab3bd52fbef79 | 2020-09-25 01:51:37.78458
  9 | 1e263054325dfcb6d82980c595fea977 | 2020-09-25 02:51:37.784581
 10 | 77b7c4f7660e23d241af6a226cea147f | 2020-09-25 03:51:37.784582
(10 rows)


## 创建range分区子分区表
db1=# select create_range_partitions('part_test'::regclass,'crt_time','2020-09-01 00:00:00'::timestamp,interval '1 month',24,false) ;
 create_range_partitions
-------------------------
                      24
(1 row)


db1=# \d+ part_test
                                            Table "public.part_test"
  Column  |            Type             | Collation | Nullable | Default | Storage  | Stats target | Description
----------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
 id       | integer                     |           |          |         | plain    |              |
 info     | text                        |           |          |         | extended |              |
 crt_time | timestamp without time zone |           | not null |         | plain    |              |
Child tables: part_test_1,
              part_test_10,
              part_test_11,
              part_test_12,
              part_test_13,
              part_test_14,
              part_test_15,
              part_test_16,
              part_test_17,
              part_test_18,
              part_test_19,
              part_test_2,
              part_test_20,
              part_test_21,
              part_test_22,
              part_test_23,
              part_test_24,
              part_test_3,
              part_test_4,
              part_test_5,
              part_test_6,
              part_test_7,
              part_test_8,
              part_test_9
Access method: heap

## 使用非阻塞方式迁移主表数据到子分区表
db1=# select partition_table_concurrently('part_test'::regclass,10000,1.0);
NOTICE:  worker started, you can stop it with the following command: select public.stop_concurrent_part_task('part_test');
 partition_table_concurrently
------------------------------

(1 row)

db1=# select count(*) from only part_test;
 count
-------
     0
(1 row)

## 禁用主表
db1=# select set_enable_parent('part_test'::regclass, false);
 set_enable_parent
-------------------

(1 row)


## 分区表查询执行计划
db1=# explain select * from part_test where crt_time = '2020-10-25 00:00:00'::timestamp;
                                QUERY PLAN
---------------------------------------------------------------------------
 Seq Scan on part_test_2  (cost=0.00..13.30 rows=1 width=45)
   Filter: (crt_time = '2020-10-25 00:00:00'::timestamp without time zone)
(2 rows)

2.ハッシュパーティションテーブルの使用例


## 创建区分主表
db1=# create table part_hash_test(id int, info text, crt_time timestamp not null);
CREATE TABLE
db1=# insert into part_hash_test select id,md5(random()::text),clock_timestamp() + (id||' hour')::interval from generate_series(1,10000) t(id);
INSERT 0 10000
db1=# select * from part_hash_test limit 10;
 id |               info               |          crt_time
----+----------------------------------+----------------------------
  1 | 5a178885f00e94d93fbe25b3ebf78cdb | 2020-09-25 11:16:09.032447
  2 | dc1c362db8122b42262e76375d4fb266 | 2020-09-25 12:16:09.032583
  3 | bb9fc8da485d9085d4c91f4e3ec86478 | 2020-09-25 13:16:09.032588
  4 | 1f503196e4337ebb9a98500ada99cf66 | 2020-09-25 14:16:09.03259
  5 | 5fa2fc57bf309cd84bc8a2a88b8a8c7e | 2020-09-25 15:16:09.032591
  6 | 9a8c7b178826466f4c32a70c84b242bc | 2020-09-25 16:16:09.032593
  7 | f6b5a272d3214a1fda9b45fdc38a457d | 2020-09-25 17:16:09.032594
  8 | 5747a82d95a026530c0dbcf42f7dcb2b | 2020-09-25 18:16:09.032595
  9 | 3d4dae8e6b5d093ed5c000d0a8348b4f | 2020-09-25 19:16:09.032597
 10 | dff90345635e9757d91f6ce8908012ea | 2020-09-25 20:16:09.032598
(10 rows)

## 创建hash分区子表
db1=# select create_hash_partitions('part_hash_test'::regclass,'crt_time',4,false) ;
 create_hash_partitions
------------------------
                      4
(1 row)

## 查看分区表定义
db1=# \d+ part_hash_test
                                          Table "public.part_hash_test"
  Column  |            Type             | Collation | Nullable | Default | Storage  | Stats target | Description
----------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
 id       | integer                     |           |          |         | plain    |              |
 info     | text                        |           |          |         | extended |              |
 crt_time | timestamp without time zone |           | not null |         | plain    |              |
Child tables: part_hash_test_0,
              part_hash_test_1,
              part_hash_test_2,
              part_hash_test_3
Access method: heap

db1=# select count(*) from only part_hash_test;
 count
-------
 10000
(1 row)

## 使用非阻塞方式迁移主表数据到分区子表
db1=# select partition_table_concurrently('part_hash_test'::regclass,10000,1.0);
NOTICE:  worker started, you can stop it with the following command: select public.stop_concurrent_part_task('part_hash_test');
 partition_table_concurrently
------------------------------

(1 row)

db1=# select count(*) from only part_hash_test;
 count
-------
     0
(1 row)

db1=# \d+ part_hash_test_0
                                         Table "public.part_hash_test_0"
  Column  |            Type             | Collation | Nullable | Default | Storage  | Stats target | Description
----------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
 id       | integer                     |           |          |         | plain    |              |
 info     | text                        |           |          |         | extended |              |
 crt_time | timestamp without time zone |           | not null |         | plain    |              |
Check constraints:
    "pathman_part_hash_test_0_check" CHECK (get_hash_part_idx(timestamp_hash(crt_time), 4) = 0)
Inherits: part_hash_test
Access method: heap

3.パーティション列の分割

db1=# \d+ part_test_1
                                           Table "public.part_test_1"
  Column  |            Type             | Collation | Nullable | Default | Storage  | Stats target | Description
----------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
 id       | integer                     |           |          |         | plain    |              |
 info     | text                        |           |          |         | extended |              |
 crt_time | timestamp without time zone |           | not null |         | plain    |              |
Check constraints:
    "pathman_part_test_1_check" CHECK (crt_time >= '2020-09-01 00:00:00'::timestamp without time zone AND crt_time < '2020-10-01 00:00:00'::timestamp without time zone)
Inherits: part_test
Access method: heap

db1=# select count(*) from part_test_2;
 count
-------
   744
(1 row)

db1=# \d+ part_test_2
                                           Table "public.part_test_2"
  Column  |            Type             | Collation | Nullable | Default | Storage  | Stats target | Description
----------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
 id       | integer                     |           |          |         | plain    |              |
 info     | text                        |           |          |         | extended |              |
 crt_time | timestamp without time zone |           | not null |         | plain    |              |
Check constraints:
    "pathman_part_test_2_check" CHECK (crt_time >= '2020-10-01 00:00:00'::timestamp without time zone AND crt_time < '2020-11-01 00:00:00'::timestamp without time zone)
Inherits: part_test
Access method: heap


## 子分区表的分裂
db1=# select split_range_partition('part_test_2'::regclass,'2020-10-15 00:00:00'::timestamp,'part_test_2_1');
 split_range_partition
-----------------------
 part_test_2_1
(1 row)


## 分裂后的子分区表
db1=# select count(*) from part_test_2;
 count
-------
   336
(1 row)

db1=# select count(*) from part_test_2_1;
 count
-------
   408
(1 row)

4.サブパーティションテーブルのマージ

db1=# \d+ part_test_2
                                           Table "public.part_test_2"
  Column  |            Type             | Collation | Nullable | Default | Storage  | Stats target | Description
----------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
 id       | integer                     |           |          |         | plain    |              |
 info     | text                        |           |          |         | extended |              |
 crt_time | timestamp without time zone |           | not null |         | plain    |              |
Check constraints:
    "pathman_part_test_2_check" CHECK (crt_time >= '2020-10-01 00:00:00'::timestamp without time zone AND crt_time < '2020-10-15 00:00:00'::timestamp without time zone)
Inherits: part_test
Access method: heap

db1=# \d+ part_test_2_1
                                          Table "public.part_test_2_1"
  Column  |            Type             | Collation | Nullable | Default | Storage  | Stats target | Description
----------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
 id       | integer                     |           |          |         | plain    |              |
 info     | text                        |           |          |         | extended |              |
 crt_time | timestamp without time zone |           | not null |         | plain    |              |
Check constraints:
    "pathman_part_test_2_1_check" CHECK (crt_time >= '2020-10-15 00:00:00'::timestamp without time zone AND crt_time < '2020-11-01 00:00:00'::timestamp without time zone)
Inherits: part_test
Access method: heap


## 子分区表的合并
db1=# select merge_range_partitions('part_test_2'::regclass, 'part_test_2_1'::regclass) ;
 merge_range_partitions
------------------------
 part_test_2
(1 row)

db1=# \d+ part_test_2_1
Did not find any relation named "part_test_2_1".
db1=# \d+ part_test_2
                                           Table "public.part_test_2"
  Column  |            Type             | Collation | Nullable | Default | Storage  | Stats target | Description
----------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
 id       | integer                     |           |          |         | plain    |              |
 info     | text                        |           |          |         | extended |              |
 crt_time | timestamp without time zone |           | not null |         | plain    |              |
Check constraints:
    "pathman_part_test_2_check" CHECK (crt_time >= '2020-10-01 00:00:00'::timestamp without time zone AND crt_time < '2020-11-01 00:00:00'::timestamp without time zone)
Inherits: part_test
Access method: heap

## 子分区表合并后,数据自动迁移到分区表1中
db1=# select count(*) from part_test_2;
 count
-------
   744
(1 row)

このドキュメントでは、pathmanツール
基本的なコマンドと例
を参照しています:https://www.alibabacloud.com/help/zh/doc-detail/140900.htm?spm = a2c63.p38356.a1.2.2865177fPTXTBA DeGeブログの紹介パスマンツールへ:https://github.com/digoal/blog/blob/master/201610/20161024_01.md
パスマンgithub公式ドキュメント:https ://github.com/postgrespro/pg_pathman?spm = a2c6h.12873639.0.0.2 b50419eBaxd7C
PG 12パーティションテーブルパフォーマンスの向上:https://github.com/digoal/blog/blob/master/201903/20190331_01.md

おすすめ

転載: blog.csdn.net/weixin_37692493/article/details/109053005