Blog Postgresql Range Partition ve Default Partition

Postgresql Range Partition ve Default Partition

Sizlere “Range Partition” oluşturmak ve “Defult Partition” yaratarak, bunun üzerine Default Partition’dan nasıl kurtulanabilir aktarılacaktır.

Aşağıdaki komutlar ile “Range Partitionlu” bir tablo oluşturup, ardından onun “Partition”ları oluşturulacaktır.

CREATE TABLE deneme (

    ldate         date not null,

    sayi        int,

    sayi2      int

) PARTITION BY RANGE (ldate);

CREATE TABLE deneme_y2016 PARTITION OF deneme FOR VALUES FROM ('2016-01-01') TO ('2017-01-01');

CREATE TABLE deneme_y2017 PARTITION OF deneme FOR VALUES FROM ('2017-01-01') TO ('2018-01-01');

CREATE TABLE deneme_y2018 PARTITION OF deneme FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');

CREATE TABLE deneme_y2019 PARTITION OF deneme FOR VALUES FROM ('2019-01-01') TO ('2020-01-01');

CREATE TABLE deneme_y2020 PARTITION OF deneme FOR VALUES FROM ('2020-01-01') TO ('2021-01-01');

Tabloya data nasıl atılacağı aşağıda gösterilmektedir:

INSERT INTO deneme (ldate, sayi, sayi2)  VALUES ('2016-07-10', 66, 100); 

Aşağıdaki “İnsert” ilgili tarihi kapsayacak bir “partition” olmadığı için hata verecektir.

INSERT INTO deneme (ldate, sayi, sayi2) VALUES ('2021-07-10', 66, 100);

ERROR:  no partition of relation "deneme" found for row

DETAIL:  Partition key of the failing row contains (ldate) = (2021-07-10).

Bu tabloya ilgili yıl ile alakalı değil “Default Partition” tanımlanır. Performans açısından problem oluşturacağı için “Default Partition” kesinlikle önerilmemektedir.

CREATE TABLE deneme_default PARTITION OF deneme DEFAULT;

Bu “Partition” oluşturulduktan sonra aynı “Insert” çalıştırıldığında “Insert”ler hata vermeyecektir.

INSERT INTO deneme (ldate, sayi, sayi2) VALUES ('2021-07-10', 66, 100);        

INSERT INTO deneme (ldate, sayi, sayi2) VALUES ('2022-07-10', 66, 100);

 

“Default Partition”, tablonuzda var ise nasıl kurtulabilirsiniz?

“Default Partition” oluşturulduktan sonra farklı bir “Partition” yaratmaya izin vermemektedir. “Postgresql” denenir;

CREATE TABLE deneme_y2021 PARTITION OF deneme FOR VALUES FROM ('2021-01-01') TO ('2022-01-01');

ERROR:  updated partition constraint for default partition "deneme_default" would be violated by some row

CREATE TABLE deneme_y2022 PARTITION OF deneme FOR VALUES FROM ('2022-01-01') TO ('2022-01-01'); 

ERROR:  updated partition constraint for default partition "deneme_default" would be violated by some row

“Default Partition”u “Detach” edilir sonrasında yeni “Partition”lar oluşturulur ve “Detach” edilen “Default Partition”dan da data aktarılır.

postgres=# alter table deneme detach partition deneme_default;

postgres=# CREATE TABLE deneme_y2021 PARTITION OF deneme FOR VALUES FROM ('2021-01-01') TO ('2022-01-01');

CREATE TABLE

postgres=# CREATE TABLE deneme_y2022 PARTITION OF deneme FOR VALUES FROM ('2022-01-01') TO ('2023-01-01'); 

CREATE TABLE

postgres=# insert into deneme select * from deneme_default ;

INSERT 0 4

postgres=# dt

                    List of relations

 Schema |      Name       |       Type        |  Owner   

--------+-----------------+-------------------+----------

 public | deneme          | partitioned table | postgres

 public | deneme_default  | table             | postgres

 public | deneme_y2016    | table             | postgres

 public | deneme_y2017    | table             | postgres

 public | deneme_y2018    | table             | postgres

 public | deneme_y2019    | table             | postgres

 public | deneme_y2020    | table             | postgres

 public | deneme_y2021    | table             | postgres

 public | deneme_y2022    | table             | postgres

(9 rows)

 

postgres=# select * from deneme_y2021

postgres-# ;

   ldate    | sayi | sayi2 

------------+------+-------

 2021-07-10 |   66 |   100

 2021-07-10 |   66 |   100

(2 rows)

postgres=# 

postgres=# 

postgres=# select * from deneme_y2022;

   ldate    | sayi | sayi2 

------------+------+-------

 2022-07-10 |   66 |   100

 2022-07-10 |   66 |   100

(2 rows)

“Default Partition”u drop edilebilir.

postgres=# drop table deneme_default ;

DROP TABLE

Yazar: Engin Yılmaz