1
- <sect1 id="pathman">
2
- <title>pathman </title>
1
+ <sect1 id="pg- pathman">
2
+ <title>pg_pathman </title>
3
3
<para>
4
- The <literal>pathman </literal> module provides optimized
4
+ The <literal>pg_pathman </literal> module provides optimized
5
5
partitioning mechanism and functions to manage partitions.
6
6
</para>
7
- <sect2 id="pathman-concepts">
8
- <title>pathman Concepts</title>
7
+ <sect2 id="pg- pathman-concepts">
8
+ <title>pg_pathman Concepts</title>
9
9
<para>
10
10
Partitioning refers to splitting one large table into smaller
11
11
pieces. Each row in such table assigns to a single partition based
36
36
For example:
37
37
</para>
38
38
<programlisting>
39
- CHECK ( id >= 100 AND id < 200 )
40
- CHECK ( id >= 200 AND id < 300 )
39
+ CREATE TABLE test (id SERIAL PRIMARY KEY, title TEXT);
40
+ CREATE TABLE test_1 (CHECK ( id >= 100 AND id < 200 )) INHERITS (test);
41
+ CREATE TABLE test_2 (CHECK ( id >= 200 AND id < 300 )) INHERITS (test);
41
42
</programlisting>
42
43
<para>
43
44
Despite the flexibility of this approach it has weakness. If query
@@ -47,15 +48,15 @@ CHECK ( id >= 200 AND id < 300 )
47
48
partitions is large the overhead may be significant.
48
49
</para>
49
50
<para>
50
- The <literal>pathman </literal> module provides functions to manage
51
- partitions and partitioning mechanism optimized based on knowledge
52
- of the partitions structure. It stores partitioning configuration
53
- in the <literal>pathman_config</literal> table, each row of which
54
- contains single entry for partitioned table (relation name,
55
- partitioning key and type). During initialization the
56
- <literal>pathman </literal> module caches information about child
57
- partitions in shared memory in form convenient to perform rapid
58
- search. When user executes SELECT querypathman analyzes
51
+ The <literal>pg_pathman </literal> module provides functions to
52
+ manage partitions and partitioning mechanism optimized based on
53
+ knowledge of the partitions structure. It stores partitioning
54
+ configuration in the <literal>pathman_config</literal> table, each
55
+ row of which contains single entry for partitioned table (relation
56
+ name, partitioning key and type). During initialization the
57
+ <literal>pg_pathman </literal> module caches information about
58
+ child partitions in shared memory in form convenient to perform
59
+ rapid search. When user executes SELECT querypg_pathman analyzes
59
60
conditions tree looking for conditions like:
60
61
</para>
61
62
<programlisting>
@@ -72,32 +73,34 @@ WHERE id = 150
72
73
</programlisting>
73
74
<para>
74
75
Based on partitioning type and operator the
75
- <literal>pathman </literal> searches corresponding partitions and
76
- builds the plan.
76
+ <literal>pg_pathman </literal> searches corresponding partitions
77
+ and builds the plan.
77
78
</para>
78
79
</sect2>
79
- <sect2 id="pathman-installation">
80
+ <sect2 id="pg- pathman-installation">
80
81
<title>Installation</title>
81
82
<para>
82
83
To install pathman run:
83
84
</para>
84
85
<programlisting>
85
- CREATE EXTENSION pathman;
86
+ CREATE SCHEMA pathman;
87
+ CREATE EXTENSION pg_pathman SCHEMA pathman;
86
88
</programlisting>
87
89
<para>
88
- in your database Then modify shared_preload_libraries parameter
89
- in postgresql.conf as following:
90
+ Then modify <literal>shared_preload_libraries</>
91
+ parameter in postgresql.conf as
92
+ following:
90
93
</para>
91
94
<programlisting>
92
- shared_preload_libraries = 'pathman '
95
+ shared_preload_libraries = 'pg_pathman '
93
96
</programlisting>
94
97
<para>
95
- Then restart the &productname; instance.
98
+ It will require to restart of the &productname; instance.
96
99
</para>
97
100
</sect2>
98
- <sect2 id="pathman-functions">
101
+ <sect2 id="pg- pathman-functions">
99
102
<title>FUNCTIONS</title>
100
- <sect3 id="partitions-creation">
103
+ <sect3 id="pg-pathman- partitions-creation">
101
104
<title>Partitions Creation</title>
102
105
<programlisting>
103
106
create_hash_partitions(
@@ -143,16 +146,30 @@ create_range_partitions(
143
146
<literal>TIMESTAMP</literal> partitioning keys.
144
147
</para>
145
148
</sect3>
146
- <sect3 id="data-migration">
149
+ <sect3 id="pg-pathman- data-migration">
147
150
<title>Data migration</title>
148
151
<programlisting>
149
152
partition_data(parent text)
150
153
</programlisting>
151
154
<para>
152
155
Copies data from parent table to its partitions.
153
156
</para>
157
+ <programlisting>
158
+ create_hash_update_trigger(parent TEXT)
159
+ </programlisting>
160
+ <para>
161
+ Creates the trigger on UPDATE for HASH partitions. The UPDATE
162
+ trigger isn't created by default because of overhead. It is
163
+ useful in cases when key attribute could be changed.
164
+ </para>
165
+ <programlisting>
166
+ create_hash_update_trigger(parent TEXT)
167
+ </programlisting>
168
+ <para>
169
+ Same as above for RANGE sections.
170
+ </para>
154
171
</sect3>
155
- <sect3 id="partitions-management">
172
+ <sect3 id="pg-pathman- partitions-management">
156
173
<title>Partitions management</title>
157
174
<programlisting>
158
175
split_range_partition(partition TEXT, value ANYELEMENT)
@@ -188,15 +205,15 @@ prepend_partition(p_relation TEXT)
188
205
disable_partitioning(relation TEXT)
189
206
</programlisting>
190
207
<para>
191
- Disables <literal>pathman </literal> partitioning mechanism for
192
- the specified parent table and removes an insert trigger.
208
+ Disables <literal>pg_pathman </literal> partitioning mechanism
209
+ for the specified parent table and removes an insert trigger.
193
210
Partitions itself remain unchanged.
194
211
</para>
195
212
</sect3>
196
213
</sect2>
197
- <sect2 id="examples">
214
+ <sect2 id="pg-pathman- examples">
198
215
<title>Examples</title>
199
- <sect3 id="hash">
216
+ <sect3 id="pg-pathman-example- hash">
200
217
<title>HASH</title>
201
218
<para>
202
219
Consider an example of HASH partitioning. First create a table
@@ -222,9 +239,36 @@ SELECT create_hash_partitions('hash_rel', 'value', 100);
222
239
</para>
223
240
<programlisting>
224
241
SELECT partition_data('hash_rel');
242
+ </programlisting>
243
+ <para>
244
+ Here is an example of the query with filtering by partitioning
245
+ key and its plan:
246
+ </para>
247
+ <programlisting>
248
+ SELECT * FROM hash_rel WHERE value = 1234;
249
+ id | value
250
+ ------+-------
251
+ 1234 | 1234
252
+
253
+ EXPLAIN SELECT * FROM hash_rel WHERE value = 1234;
254
+ QUERY PLAN
255
+ -----------------------------------------------------------------
256
+ Append (cost=0.00..2.00 rows=0 width=0)
257
+ -> Seq Scan on hash_rel_34 (cost=0.00..2.00 rows=0 width=0)
258
+ Filter: (value = 1234)
259
+ </programlisting>
260
+ <para>
261
+ Note that pg_pathman exludes parent table from the query plan.
262
+ To access parent table use ONLY modifier:
263
+ </para>
264
+ <programlisting>
265
+ EXPLAIN SELECT * FROM ONLY hash_rel;
266
+ QUERY PLAN
267
+ --------------------------------------------------------
268
+ Seq Scan on hash_rel (cost=0.00..0.00 rows=1 width=8)
225
269
</programlisting>
226
270
</sect3>
227
- <sect3 id="range">
271
+ <sect3 id="pg-pathman-example- range">
228
272
<title>RANGE</title>
229
273
<para>
230
274
Consider an example of RANGE partitioning. Create a table with
@@ -270,15 +314,93 @@ SELECT split_range_partition('range_rel_1', '2010-02-15'::date);
270
314
</para>
271
315
<programlisting>
272
316
SELECT append_partition('range_rel');
273
- SELECT append_partition('range_rel');
317
+ </programlisting>
318
+ <para>
319
+ Here is an example of the query with filtering by partitioning
320
+ key and its plan:
321
+ </para>
322
+ <programlisting>
323
+ SELECT * FROM range_rel WHERE dt >= '2012-04-30' AND dt <= '2012-05-01';
324
+ id | dt
325
+ -----+---------------------
326
+ 851 | 2012-04-30 00:00:00
327
+ 852 | 2012-05-01 00:00:00
328
+
329
+ EXPLAIN SELECT * FROM range_rel WHERE dt >= '2012-04-30' AND dt <= '2012-05-01';
330
+ QUERY PLAN
331
+ ----------------------------------------------------------------------------
332
+ Append (cost=0.00..60.80 rows=0 width=0)
333
+ -> Seq Scan on range_rel_28 (cost=0.00..30.40 rows=0 width=0)
334
+ Filter: (dt >= '2012-04-30 00:00:00'::timestamp without time zone)
335
+ -> Seq Scan on range_rel_29 (cost=0.00..30.40 rows=0 width=0)
336
+ Filter: (dt <= '2012-05-01 00:00:00'::timestamp without time zone)
337
+ </programlisting>
338
+ </sect3>
339
+ <sect3 id="disable-pg-pathman">
340
+ <title>Disable pg_pathman</title>
341
+ <para>
342
+ To disable pg_pathman for some previously partitioned table use
343
+ disable_partitioning() function:
344
+ </para>
345
+ <programlisting>
346
+ SELECT disable_partitioning('range_rel');
347
+ </programlisting>
348
+ <para>
349
+ All sections and data will stay available and will be handled by
350
+ standard PostgreSQL partitioning mechanism. ### Manual
351
+ partitions management It is possible to manage partitions
352
+ manually. After creating or removing child tables it's necessary
353
+ to invoke function:
354
+ </para>
355
+ <programlisting>
356
+ on_update_partitions(oid),
357
+ </programlisting>
358
+ <para>
359
+ which updates internal structures in memory of
360
+ <literal>pg_pathman module</literal>. For example, let's create
361
+ new section for the <literal>range_rel</literal> from above:
362
+ </para>
363
+ <programlisting>
364
+ CREATE TABLE range_rel_archive (CHECK (dt >= '2000-01-01' AND dt < '2010-01-01')) INHERITS (range_rel);
365
+ SELECT on_update_partitions('range_rel'::regclass::oid);
366
+ </programlisting>
367
+ <para>
368
+ CHECK CONSTRAINT must have the exact format: * (VARIABLE >=
369
+ CONST AND VARIABLE < CONST) for RANGE partitioned tables; *
370
+ (VARIABLE % CONST = CONST) for HASH partitioned tables.
371
+ </para>
372
+ <para>
373
+ It is possible to create partition from foreign table as well:
374
+ </para>
375
+ <programlisting>
376
+ CREATE FOREIGN TABLE range_rel_archive (
377
+ id INTEGER NOT NULL,
378
+ dt TIMESTAMP)
379
+ SERVER archive_server;
380
+ ALTER TABLE range_rel_archive INHERIT range_rel;
381
+ ALTER TABLE range_rel_archive ADD CHECK (dt >= '2000-01-01' AND dt < '2010-01-01');
382
+ SELECT on_update_partitions('range_rel'::regclass::oid);
383
+ </programlisting>
384
+ <para>
385
+ Foreign table structure must exactly match the parent table.
386
+ </para>
387
+ <para>
388
+ In case when parent table is being dropped by DROP TABLE, you
389
+ should invoke on_remove_partitions() function and delete
390
+ particular entry from <literal>pathman_config</literal> table:
391
+ </para>
392
+ <programlisting>
393
+ SELECT on_remove_partitions('range_rel'::regclass::oid);
394
+ DROP TABLE range_rel CASCADE;
395
+ DELETE FROM pathman_config WHERE relname = 'public.range_rel';
274
396
</programlisting>
275
397
</sect3>
276
398
</sect2>
277
- <sect2 id="author">
399
+ <sect2 id="pg-pathman- author">
278
400
<title>Author</title>
279
401
<para>
280
402
Ildar Musin <email>i.musin@postgrespro.ru</email> Postgres
281
- Professional Ltd., Russia
403
+ Professional Ltd., Russia
282
404
</para>
283
405
</sect2>
284
406
</sect1>