简介

gogudb是一个基于FDW技术的分库分表中间件,主要采用了分区管理技术(pg_pathman)和外部数据源(postgres_fdw)的技术。支持以extension的方式加载到PG数据库上运行,支持以透明的方式访问其他PG数据库上的表。支持常见的SQL操作,支持触发器,支持跨节点的连接、排序、聚集操作等。
代码目前公开在github上面:https://github.com/hangzhou-cstech/gogudb
gogudb支持 PG9.6 10 11,支持X86_64的操作系统。

编译

目前,gogudb支持两种方式来进行编译:

  1. 一种是使用PG源码的方式来进行安装,
  2. 一种是使用安装之后的PG来进行编译,安装PG的方式不限,但是需要设置环境变量,使得在在shell中能直接使用pg_config来获取PG的相关文件路径。

    gogudb在PG源码下进行编译

  3. 下载PG源码(9.6 10 11版本),使用tar解压缩
  4. 使用configure进行配置,生成makefile
  5. 使用git将代码获取,放置到contrib下的gogudb目录下面
  6. 在gogudb的目录下面,执行make,即可获得gogudb的动态库文件和sql文件,完成使用版的编译。

gogudb在安装PG之后进行编译

  1. 安装PG,可以使用源码安装或是使用yum或是rpm来进行安装,PG的版本同上。注意设置环境变量,使得shell中可以直接使用pg_config
  2. 使用git获取gogudb源码
  3. 在gogudb的源码目录下执行make USE_PGXS=1命令来编译,获得使用版的动态库文件和sql文件。

安装

在gogudb的目录下执行安装gogudb:

  1. sudo make install

配置

在当前PG的实例的配置文件中增加:

  1. shared_preload_libraries='gogudb'

这个配置项需要数据重启才能生效。

使用

创建 extension

使用有相应权限的用户执行:

  1. create externsion gogudb

创建数据源

  • 使用create server语句创建数据源,例如:
    1. CREATE SERVER server_remote1 FOREIGN DATA WRAPPER gogudb_fdw OPTIONS(host '192.168.2.2',port '5432',dbname 'postgres');

创建了一个名为server_remote1的数据源,远程数据源的IP是192.168.2.2,端口是5432,数据库名是postgres,使用的是gogudb内置的fdw:gogudb_fdw

  • 使用create user mapping语句来配置数据源的访问用户信息,例如:
  1. create user mapping for current_user server server_remote1 options(user 'pgsql',password '');

设置当前用户访问server_remote1时,使用的登录用户是pgsql,密码为空。

配置表的分表规则

gogudb中有一张表 table_partition_rule(1.0版本在pg_catalog这个schema下,而1.1移到了_gogu这个schema下)定义了用户分表的规则,在创建分区表之前,用户需要在表中插入数据。在创建表的时候,gogudb会根据改变预先定义的规则,来创建分区表。该表主要包括下列字段:

  • schema_name 类型TEXT NOT NULL,指定即将创建的父表所在的schema
  • table_name 类型TEXT NOT NULL,指定即将创建的父表的名称,
  • part_expr 类型TEXTTEXT NOT NULL,指定分表时使用的表达式(最简单的就是列名)
  • part_type 类型INTEGER NOT NULL,分区类型,只能选择1或是2,1表示hash分区,2表示range分区
  • range_interval 类型TEXT DEFAULT NULL, range分区时使用的间隔。
  • range_start 类型TEXT DEFAULT NULL,range分区时使用起始值。
  • part_dist 类型INTEGER,子表的总数量,最终创建远程子表时,子表会逐一分布到每个远程数据源上数量,尽量保证每个数据源上的子表数据量均匀一致。
  • remote_schema 类型 TEXT DEFAULT NULL,子表在远程数据源上的schema,默认为public
  • servers 类型TEXT[] DEFAULT NULL,子表分布的远程数据源名称列表,默认是系统内所有使用gogudb_fdw的远程的数据源列表。

配置远程数据源的HASH值区间

gogudb中有一张表 server_map(1.0版本在pg_catalog这个schema下,而1.1移到了_gogu这个schema下)定义了做hash值的范围和远程数据源的关系,这张表主要有下面三个字段:

  • server_name, TEXT NOT NULL类型,子表分布的远程数据源名称列表,默认是系统内所有使用gogudb_fdw的远程的数据源列表。
  • range_start,smallint NOT NULL类型,hash值范围的起始值(包括该值),最小为0;
  • range_end,smallint NOT NULL类型,hash值范围的结束值(不包括该值),不小于range_start,不大于128;
    用户向 pg_catalog.server_map插入数据源以及范围之后,需要执行
  1. select reload_range_server_set()

来重新加载server_map表的数据,使之生效。

使用案例

准备测试环境的数据库实例

环境如下:

主机名 IP 数据库端口 数据目录
gogu01 192.168.3.46 5432 /home/postgres/pgdata
pg01 192.168.3.41 5432 /home/postgres/pgdata
pg02 192.168.3.42 5432 /home/postgres/pgdata

其中gogu01作为gogudb的运行实例,pg01和pg02作为gogudb的远程数据源。

配置gogudb

编辑gogu01机器上(即gogudb)数据库的配置文件: vi /data/pgdata/postgresql.conf 在配置文件中增加一行:

  1. shared_preload_libraries='gogudb'

安装gogudb

使用前面描述的方法,编译gogudb之后使用make install安装

启动数据库:

启动gogudb数据库:

  1. pg_ctl start -D /data/pgdata

创建extension

需要在gogudb的数据库中创建gogudb的extension

  • 连接gogudb数据库:
    psql -d postgres
  • 在连接会话中创建gogudb:
  1. create extension gogudb;

创建远程数据源

创建两个数据源,分别指向拍pg01和pg02:

  • 连接gogudb数据库: psql -d postgres
  • 创建名为server_remote1的数据源:CREATE SERVER server_remote1 FOREIGN DATA WRAPPER gogudb_fdw OPTIONS(host ‘192.168.3.41’,port ‘5432’,dbname ‘postgres’);
  • 创建名为server_remote2的数据源:CREATE SERVER server_remote2 FOREIGN DATA WRAPPER gogudb_fdw OPTIONS(host ‘192.168.3.42’,port ‘5432’,dbname ‘postgres’);
  • 为server_remote1设置用户名密码:create user mapping for current_user server server_remote1 options(user ‘pgsql’,password ‘’);
  • 为server_remote2设置用户名密码:create user mapping for current_user server server_remote1 options(user ‘pgsql’,password ‘’);

配置远程数据源的hash值分区

执行下列操作:

  1. insert into _gogu.server_map values('server_remote1', 0, 64), ('server_remote2', 64, 128);
  2. select reload_range_server_set();

这就配置并生效了两台远程数据源server_remote1和server_remote2,server_remote1接受的hash值范围是[0,64), server_remote2接受的范围是[64,128)。

使用hash方式创建分区表

主要是先在table_partition_rule中插入表的分区规则,然后使用普通SQL来创建表。

  • 连接gogudb数据库: psql -d postgres
  • 插入分区规则:
  1. insert into _gogu.table_partition_rule(schema_name, table_name, part_expr, part_type, part_dist, remote_schema) values('public', 'part_hash_test', 'id', 1,4,'public');

插入的记录指定了:将会在public的schema下创建一张表,表的分布字段是id,采用hash分区,总共4个分片,分片将分布到所有的gogudb_fdw的远程的数据源列表上,所在的schema为public

  • 创建分区表:
  1. postgres=# CREATE TABLE part_hash_test(id INT NOT NULL, payload REAL);
  2. CREATE TABLE

*可以查看生成的分区表:

  1. postgres=# \d+ part_hash_test
  2. Table "public.part_hash_test"
  3. Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
  4. ---------+---------+-----------+----------+---------+---------+--------------+-------------
  5. id | integer | | not null | | plain | |
  6. payload | real | | | | plain | |
  7. Child tables: gogudb_partition_table._public_0_part_hash_test,
  8. gogudb_partition_table._public_1_part_hash_test,
  9. gogudb_partition_table._public_2_part_hash_test,
  10. gogudb_partition_table._public_3_part_hash_test
  11. postgres=# \dES gogudb_partition_table.*
  12. List of relations
  13. Schema | Name | Type | Owner
  14. ------------------------+------------------------+---------------+-------
  15. gogudb_partition_table | _public_0_part_hash_test | foreign table | pgsql
  16. gogudb_partition_table | _public_1_part_hash_test | foreign table | pgsql
  17. gogudb_partition_table | _public_2_part_hash_test | foreign table | pgsql
  18. gogudb_partition_table | _public_3_part_hash_test | foreign table | pgsql

*删除表:

  1. postgres=# drop table part_hash_test cascade;
  2. NOTICE: drop cascades to 4 other objects
  3. DETAIL: drop cascades to foreign table gogudb_partition_table._public_0_part_hash_test
  4. drop cascades to foreign table gogudb_partition_table._public_1_part_hash_test
  5. drop cascades to foreign table gogudb_partition_table._public_2_part_hash_test
  6. drop cascades to foreign table gogudb_partition_table._public_3_part_hash_test
  7. DROP TABLE

使用range方式创建基于时间类型分区表

主要的步骤也是先向配置表中插入数据,然后使用普通的SQL来建表。

  • 向分区配置表插入数据:
    1. insert into _gogu.table_partition_rule(schema_name ,table_name ,part_expr ,part_type ,range_interval ,range_start ,part_dist, remote_schema) values('public', 'part_range_test', 'crt_time', 2, '2 month','2018-1-1 00:00:0', 6, 'public');

这个指定即将创建表的schema是pulic,表名是part_range_test,分表会使用的表达式是’crt_time,实际将会是一个timestamp类型的字段,分区的类型是range方式,分区间隔是’2 month’,起始值是’2018-1-1 00:00:0’,会创建6个分片,分片位于所有数据源上,schema为public。
*创建表:

  1. postgres=# create table part_range_test(id int, info text, crt_time timestamp not null);
  2. CREATE TABLE

*可以查看这个表由6个子表组成,实际是外部表,均分到2个外部数据源上:

  1. postgres=# \d+ part_range_test
  2. Table "public.part_range_test"
  3. Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
  4. ----------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
  5. id | integer | | | | plain | |
  6. info | text | | | | extended | |
  7. crt_time | timestamp without time zone | | not null | | plain | |
  8. Child tables: gogudb_partition_table._public_1_part_range_test,
  9. gogudb_partition_table._public_2_part_range_test,
  10. gogudb_partition_table._public_3_part_range_test,
  11. gogudb_partition_table._public_4_part_range_test,
  12. gogudb_partition_table._public_5_part_range_test,
  13. gogudb_partition_table._public_6_part_range_test
  14. postgres=# \dES gogudb_partition_table.*
  15. List of relations
  16. Schema | Name | Type | Owner
  17. ------------------------+-------------------------+---------------+-------
  18. gogudb_partition_table | _public_1_part_range_test | foreign table | pgsql
  19. gogudb_partition_table | _public_2_part_range_test | foreign table | pgsql
  20. gogudb_partition_table | _public_3_part_range_test | foreign table | pgsql
  21. gogudb_partition_table | _public_4_part_range_test | foreign table | pgsql
  22. gogudb_partition_table | _public_5_part_range_test | foreign table | pgsql
  23. gogudb_partition_table | _public_6_part_range_test | foreign table | pgsql
  24. (6 rows)

*使用普通SQL来删除表:

  1. postgres=# drop table part_range_test;
  2. DROP TABLE

使用range方式创建基于数值类型分区表

  • 向分区配置表插入数据:
  1. insert into _gogu.table_partition_rule(schema_name, table_name, part_expr, part_type, part_dist, remote_schema, range_interval,range_start) values('public','part_range_num_test', 'id', 2, 4, 'public', '100', '0');

注意对于1.0版本,上面的函数和表名前不需要加“_gogu.”

指定即将创建表的schema是pulic,表名是part_range_num_test,分表会使用的表达式是id,实际将会是一个int类型的字段,分区的类型是range方式,分区间隔是’100’,起始值是’0’,会创建4个分片,分片位于所有数据源上,schema为public。

  • 创建表:
  1. postgres=# CREATE TABLE part_range_num_test ( id integer NOT NULL, k integer DEFAULT 0 NOT NULL);、;
  2. CREATE TABLE
  • 可以查看这个表由4个子表组成:
  1. postgres=# \d+ part_range_num_test
  2. Table "public.part_range_num_test"
  3. Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
  4. --------+---------+-----------+----------+---------+---------+--------------+-------------
  5. id | integer | | not null | | plain | |
  6. k | integer | | not null | 0 | plain | |
  7. Child tables: gogudb_partition_table._public_1_part_range_num_test,
  8. gogudb_partition_table._public_2_part_range_num_test,
  9. gogudb_partition_table._public_3_part_range_num_test,
  10. gogudb_partition_table._public_4_part_range_num_test
  • 删除表
  1. postgres=# drop table part_range_num_test cascade;
  2. drop table part_hash_test;
0 评论  
添加一条新评论