将另一个数据库的分区添加到 Postgres 12 中的现有分区 table
Adding a partition from another DB to existing partitioned table in Postgres 12
问题的简短描述
我需要构建一个分区 table“用户”,其中 2 个分区位于不同的服务器(莫斯科和汉堡),每个分区 table 列:
id
- 自动递增的整数主键
region
- smallint 分区键,汉堡为 100,莫斯科为 200
login
- 长度为 100 的唯一字符。
我打算将 id
的序列作为汉堡的 n*1000 + 100
和莫斯科的 n*1000 + 200
,所以只需查看主键我就会知道它属于哪个分区。
region
旨在只读且创建后永不更改,因此不会在分区之间移动任何记录。
SELECT
查询必须能够 return 来自所有分区的记录并且 UPDATE
查询必须能够修改所有分区上的记录,INSERT
/DELETE
查询必须能够 add/delete 只记录到本地分区,因此存储在其中的数据不是完全隔离的。
做了什么
使用 pgAdmin4
- 我在汉堡服务器上创建了一个“测试”table,添加了所有列信息,将其标记为已分区 table,分区键
region
和分区类型 List
.
- 我在此 table 中创建了一个“汉堡”分区,将主键约束添加为
id
、region
并将唯一键约束添加为 login
、region
.
- 我在莫斯科服务器上创建了一个“moscow”table,其列信息与“test”相同
- 我向汉堡服务器添加了
postgres_fdw
扩展,创建了指向莫斯科服务器和用户映射上的数据库的外国服务器。
- 我在汉堡服务器上添加了“moscow”外国 table 指向莫斯科服务器上的“moscow”table。
我的问题是什么
我不知道如何将这个外部 table 作为第二个分区附加到“测试”table。
当我试图通过“测试”table 分区属性中的 pgAdmin 对话框 attach
分区时,它向我显示了一个错误:cannot unpack non-iterable Response object
当我尝试使用查询添加分区时:
ALTER TABLE public.test ATTACH PARTITION public.moscow FOR VALUES IN (200);
显示错误:
ERROR: cannot attach foreign table "moscow" as partition of partitioned table "test"
DETAIL: Table "test" contains unique indexes.
SQL state: 42809
我从 login
列中删除了唯一约束,但它显示相同的错误。
当我使用相同的属性对 table 进行分区并且最初位于同一台服务器上的两个分区都运行良好时,除了 postgres 监视 login
每个分区的唯一性而不是整个 table,但我认为这是它的局限性。
那么,如何将位于第二台服务器上的 table 作为分区附加到位于第一台服务器上的分区 table?
错误信息很清楚:因为你不能在分区table上创建索引,PostgreSQL 不能创建唯一索引的分区。但是需要唯一索引来实现约束。
查看此来源评论:
/*
* If we're attaching a foreign table, we must fail if any of the indexes
* is a constraint index; otherwise, there's nothing to do here. Do this
* before starting work, to avoid wasting the effort of building a few
* non-unique indexes before coming across a unique one.
*/
要么放弃唯一约束,要么不使用外部 table 作为分区。
好的,我终于可以添加一个外部 table 作为分区到分区 table。
- 有必要在
id
上删除 primary key
属性,在 的 login
列上删除 unique
属性分区 table
- 之后我能够将外部 table 作为分区附加到分区 table
- 后来我在
id
上添加了 primary key
属性,在每个 的 login
列上添加了 unique
属性本地分区.
所以最后我得到了唯一的全局 id
,因为它是由每个数据库的序列生成的,值从不相交。对于 login
唯一性,我必须在插入之前手动检查全局 table 是否有任何记录。
P.S。希望 postgres 中的这种分区机制适用于地理上遥远的区域。
问题的简短描述
我需要构建一个分区 table“用户”,其中 2 个分区位于不同的服务器(莫斯科和汉堡),每个分区 table 列:
id
- 自动递增的整数主键
region
- smallint 分区键,汉堡为 100,莫斯科为 200
login
- 长度为 100 的唯一字符。
我打算将 id
的序列作为汉堡的 n*1000 + 100
和莫斯科的 n*1000 + 200
,所以只需查看主键我就会知道它属于哪个分区。
region
旨在只读且创建后永不更改,因此不会在分区之间移动任何记录。
SELECT
查询必须能够 return 来自所有分区的记录并且 UPDATE
查询必须能够修改所有分区上的记录,INSERT
/DELETE
查询必须能够 add/delete 只记录到本地分区,因此存储在其中的数据不是完全隔离的。
做了什么
使用 pgAdmin4
- 我在汉堡服务器上创建了一个“测试”table,添加了所有列信息,将其标记为已分区 table,分区键
region
和分区类型List
. - 我在此 table 中创建了一个“汉堡”分区,将主键约束添加为
id
、region
并将唯一键约束添加为login
、region
. - 我在莫斯科服务器上创建了一个“moscow”table,其列信息与“test”相同
- 我向汉堡服务器添加了
postgres_fdw
扩展,创建了指向莫斯科服务器和用户映射上的数据库的外国服务器。 - 我在汉堡服务器上添加了“moscow”外国 table 指向莫斯科服务器上的“moscow”table。
我的问题是什么
我不知道如何将这个外部 table 作为第二个分区附加到“测试”table。
当我试图通过“测试”table 分区属性中的 pgAdmin 对话框 attach
分区时,它向我显示了一个错误:cannot unpack non-iterable Response object
当我尝试使用查询添加分区时:
ALTER TABLE public.test ATTACH PARTITION public.moscow FOR VALUES IN (200);
显示错误:
ERROR: cannot attach foreign table "moscow" as partition of partitioned table "test"
DETAIL: Table "test" contains unique indexes.
SQL state: 42809
我从 login
列中删除了唯一约束,但它显示相同的错误。
当我使用相同的属性对 table 进行分区并且最初位于同一台服务器上的两个分区都运行良好时,除了 postgres 监视 login
每个分区的唯一性而不是整个 table,但我认为这是它的局限性。
那么,如何将位于第二台服务器上的 table 作为分区附加到位于第一台服务器上的分区 table?
错误信息很清楚:因为你不能在分区table上创建索引,PostgreSQL 不能创建唯一索引的分区。但是需要唯一索引来实现约束。
查看此来源评论:
/*
* If we're attaching a foreign table, we must fail if any of the indexes
* is a constraint index; otherwise, there's nothing to do here. Do this
* before starting work, to avoid wasting the effort of building a few
* non-unique indexes before coming across a unique one.
*/
要么放弃唯一约束,要么不使用外部 table 作为分区。
好的,我终于可以添加一个外部 table 作为分区到分区 table。
- 有必要在
id
上删除primary key
属性,在 的login
列上删除unique
属性分区 table - 之后我能够将外部 table 作为分区附加到分区 table
- 后来我在
id
上添加了primary key
属性,在每个 的login
列上添加了unique
属性本地分区.
所以最后我得到了唯一的全局 id
,因为它是由每个数据库的序列生成的,值从不相交。对于 login
唯一性,我必须在插入之前手动检查全局 table 是否有任何记录。
P.S。希望 postgres 中的这种分区机制适用于地理上遥远的区域。