PostgreSQL sharding for Oracle, SQL Server, DB2, Sybase

本文涉及的产品
RDS Agent(兼容OpenClaw),2核4GB
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
PolarClaw,2核4GB
简介:

Oracle 12c支持sharding,但是对于低版本,如何实现水平分库呢?
在写PostgreSQL 水平分库方案时,想到一招。何不利用PostgreSQL的分片技术来实现对Oracle的分片呢?
分库技术架构和实践请参考:
http://blog.163.com/digoal@126/blog/static/16387704020161239252998/

如果要做到对Oracle用户完全透明,需要满足几个条件:

  1. PostgreSQL必须支持Oracle的SQL语法,这一点 EnterpriseDB 可以满足需求。
  2. PostgreSQL必须支持Oracle的存储过程和函数,以及包。这一点 EnterpriseDB 可以满足需求。
    如果用户愿意修改不兼容的SQL和函数,使用社区版本的 PostgreSQL 就能满足分片需求了。

分片架构如下:
可以支持几乎任何数据库的分片。
_2
分为两层:

  1. 上层为PostgreSQL 或 EnterpriseDB(如果需要兼容Oracle特殊语法),在上层节点中,需要存储表的定义,路由算法,函数,存储过程,视图,序列等全局数据。
    上层的PostgreSQL数据库可以有1个或者多个,最少1个。
  2. 下层为数据分片节点,可以是任何数据库品种,譬如图中所述的Oracle, DB2, Sybase, SQL Server。在分片节点中,存储数据分片,维度表(用户可以自定义维度表的副本数)。

注意,如果要支持函数,必须将原数据库的函数转换为PostgreSQL的函数,在PostgreSQL中可以使用plpgsql语言来实现,包括自治事务也能实现
(参考 http://blog.163.com/digoal@126/blog/static/163877040201613982063/ )。
如果使用EnterpriseDB,则大多数的Oracle函数语法都兼容,用户可以不需要修改,直接使用。

以Oracle为例,介绍实施步骤:
.1. 安装Oracle数据节点,这里假设有4台Oracle数据库,分别为db0,db1,db2,db3。
.2. 安装一台PostgreSQL 9.5+ 以及 oracle_fdw插件。

插件位置:http://pgxn.org/dist/oracle_fdw/  
内含详细说明,推荐阅读。  
http://blog.163.com/digoal@126/blog/static/163877040201181505331588/  
安装好后,设置正确的 NLS_LANG 环境变量(<language>_<territory>.<charset> (for example  AMERICAN_AMERICA.AL32UTF8)),重启数据库。  

.3. 配置oracle数据库监听,以及主机防火墙,允许PostgreSQL数据库访问Oracle数据库。
.4. 在PostgreSQL数据库中创建所有数据节点的foreign server, 本例需要4个foreign server, user mapping。
例如 (请使用正确的 IP,端口和sid, username, password替换) :

master=# create extension oracle_fdw;    
master=# create server db0 foreign data wrapper oracle_fdw OPTIONS (dbserver '//ip:port/sid');    
master=# create server db0 foreign data wrapper oracle_fdw OPTIONS (dbserver '//ip:port/sid');    
master=# create server db0 foreign data wrapper oracle_fdw OPTIONS (dbserver '//ip:port/sid');    
master=# create server db0 foreign data wrapper oracle_fdw OPTIONS (dbserver '//ip:port/sid');    
master=# create user mapping for postgres server db0 options (user 'username', password 'pwd');    
master=# create user mapping for postgres server db1 options (user 'username', password 'pwd');    
master=# create user mapping for postgres server db2 options (user 'username', password 'pwd');    
master=# create user mapping for postgres server db3 options (user 'username', password 'pwd');    

.5. 规划表分区的分布列,如果分布列不是INT类型,可以使用hash函数转换为INT。按abs(mod(column,4))的值计算分布规则。
.6. 在所有的数据节点db[0-3],创建需要分片的表,以及分布列的 check 约束。
例如:

on db0:  
create table tbl ( id int primary key , info varchar2(32), crt_time date, check (abs(mod(id,4))=0));  
on db1:  
create table tbl ( id int primary key , info varchar2(32), crt_time date, check (abs(mod(id,4))=1));  
on db2:  
create table tbl ( id int primary key , info varchar2(32), crt_time date, check (abs(mod(id,4))=2));  
on db3:  
create table tbl ( id int primary key , info varchar2(32), crt_time date, check (abs(mod(id,4))=3));  

.7. 规划维度表的副本数,本文例子假设维度表有2个副本,分别放在db0, db1。
.8. 在数据节点db0, db1创建维度表。
例如:

on db0:  
create table test ( id int primary key, info varchar2(32), crt_time date);  
on db1:  
create table test ( id int primary key, info varchar2(32), crt_time date);  

.9. 在PostgreSQL节点,创建分片表的外部表,必须包含CHECN约束。必须制定KEY,否则不能写。

create FOREIGN table tbl0 (id int OPTIONS (key 'true') , info varchar(32), crt_time timestamp without time zone) server db0 options (table 'tbl', schema 'username');  
create FOREIGN table tbl1 (id int OPTIONS (key 'true') , info varchar(32), crt_time timestamp without time zone) server db1 options (table 'tbl', schema 'username');  
create FOREIGN table tbl2 (id int OPTIONS (key 'true') , info varchar(32), crt_time timestamp without time zone) server db2 options (table 'tbl', schema 'username');  
create FOREIGN table tbl3 (id int OPTIONS (key 'true') , info varchar(32), crt_time timestamp without time zone) server db3 options (table 'tbl', schema 'username');  
alter foreign table tbl0 add constraint ck_tbl0 check (abs(mod(id,4))=0);    
alter foreign table tbl1 add constraint ck_tbl1 check (abs(mod(id,4))=1);    
alter foreign table tbl2 add constraint ck_tbl2 check (abs(mod(id,4))=2);    
alter foreign table tbl3 add constraint ck_tbl3 check (abs(mod(id,4))=3);    

.10. 在PostgreSQL节点,创建维度表的外部表

 create FOREIGN table test0 (id int OPTIONS (key 'true'), info varchar(32), crt_time timestamp without time zone) server db0 options (table 'test', schema 'username');  
 create FOREIGN table test1 (id int OPTIONS (key 'true'), info varchar(32), crt_time timestamp without time zone) server db1 options (table 'test', schema 'username');  

.11. 在PostgreSQL节点,创建分片表的父表,设置继承关系,触发器函数,触发器。

create table tbl (id int primary key, info varchar(32), crt_time timestamp without time zone);  
alter foreign table tbl0 inherit tbl;    
alter foreign table tbl1 inherit tbl;    
alter foreign table tbl2 inherit tbl;    
alter foreign table tbl3 inherit tbl;    
create or replace function f_tbl_ins() returns trigger as 
$$
    
declare    
begin    
  case abs(mod(NEW.id, 4))     
    when 0 then    
      insert into tbl0 (id, info, crt_time) values (NEW.*);    
    when 1 then    
      insert into tbl1 (id, info, crt_time) values (NEW.*);    
    when 2 then    
      insert into tbl2 (id, info, crt_time) values (NEW.*);    
    when 3 then    
      insert into tbl3 (id, info, crt_time) values (NEW.*);    
    else    
      return null;    
  end case;    
    return null;    
end;    

$$
 language plpgsql;    
create trigger tg1 before insert on tbl for each row execute procedure f_tbl_ins();    

.12. 在PostgreSQL节点,创建维度表的父表,设置继承关系,触发器函数,触发器。

create table test (id int primary key, info varchar(32), crt_time timestamp without time zone);  
alter foreign table test0 inherit test;    
-- 在不同的master节点,设置不同的继承,从而实现均衡查询的目的,目前PG内核还不支持维度表的负载均衡。  
create or replace function f_test_iud() returns trigger as 
$$
    
declare    
begin    
  case TG_OP  
    when 'INSERT' then  
      insert into test0 (id, info, crt_time) values (NEW.*);    
      insert into test1 (id, info, crt_time) values (NEW.*);    
    when 'UPDATE' then  
      update test0 set id=NEW.id,info=NEW.info,crt_time=NEW.crt_time where id=OLD.id and info=OLD.info and crt_time=OLD.crt_time;  
      update test1 set id=NEW.id,info=NEW.info,crt_time=NEW.crt_time where id=OLD.id and info=OLD.info and crt_time=OLD.crt_time;  
    when 'DELETE' then  
      delete from test0 where id=OLD.id and info=OLD.info and crt_time=OLD.crt_time;  
      delete from test1 where id=OLD.id and info=OLD.info and crt_time=OLD.crt_time;  
  end case;  
    return null;    
end;    

$$
 language plpgsql;    
create trigger tg1 before insert or update or delete on test for each row execute procedure f_test_iud();    

现在,你可以测试这些表的插入,查询,更新,删除,JOIN。以及分布式事务。
插入tbl这个分片表时,会根据ID计算一个模值,插入到对应的分片节点。
更新,删除,查询时,如果提供了ID的模值,则会选择对应的子节点查询。
对于维度表test,查询时会自动查询test0, 更新,删除,插入则会在test0,test1同时操作 (非并行)。

使用这种方法给其他数据库做sharding, 除了EDB对Oracle兼容性比较好,其他的兼容性都需要用户去验证。
但是不管怎么样,用户可以获得如下好处:
ACID
分布式事务
跨库JOIN
主节点和数据节点都支持水平扩展
prepared statement
支持存储过程和函数

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
8月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
1335 152
|
8月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
968 156
|
8月前
|
关系型数据库 分布式数据库 数据库
阿里云数据库收费价格:MySQL、PostgreSQL、SQL Server和MariaDB引擎费用整理
阿里云数据库提供多种类型,包括关系型与NoSQL,主流如PolarDB、RDS MySQL/PostgreSQL、Redis等。价格低至21元/月起,支持按需付费与优惠套餐,适用于各类应用场景。
|
8月前
|
SQL Oracle 关系型数据库
Oracle数据库创建表空间和索引的SQL语法示例
以上SQL语法提供了一种标准方式去组织Oracle数据库内部结构,并且通过合理使用可以显著改善查询速度及整体性能。需要注意,在实际应用过程当中应该根据具体业务需求、系统资源状况以及预期目标去合理规划并调整参数设置以达到最佳效果。
533 8
|
12月前
|
Oracle 关系型数据库 数据库
【赵渝强老师】在PostgreSQL中访问Oracle
本文介绍了如何在PostgreSQL中使用oracle_fdw扩展访问Oracle数据库数据。首先需从Oracle官网下载三个Instance Client安装包并解压,设置Oracle环境变量。接着从GitHub下载oracle_fdw扩展,配置pg_config环境变量后编译安装。之后启动PostgreSQL服务器,在数据库中创建oracle_fdw扩展及外部数据库服务,建立用户映射。最后通过创建外部表实现对Oracle数据的访问。文末附有具体操作步骤与示例代码。
1089 6
【赵渝强老师】在PostgreSQL中访问Oracle
|
SQL Oracle 关系型数据库
解决大小写、保留字与特殊字符问题!Oracle双引号在SQL中的特殊应用
在Oracle数据库开发中,双引号的使用是一个重要但易被忽视的细节。本文全面解析了双引号在SQL中的特殊应用场景,包括解决标识符与保留字冲突、强制保留大小写、支持特殊字符和数字开头标识符等。同时提供了最佳实践建议,帮助开发者规避常见错误,提高代码可维护性和效率。
507 6
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
|
SQL Oracle 关系型数据库
【YashanDB知识库】yashandb执行包含带oracle dblink表的sql时性能差
【YashanDB知识库】yashandb执行包含带oracle dblink表的sql时性能差
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
本文来自YashanDB官网,介绍如何处理Oracle客户端sql*plus中使用@@调用同级目录SQL脚本的场景。崖山数据库23.2.x.100已支持@@用法,但旧版本可通过Python脚本批量重写SQL文件,将@@替换为绝对路径。文章通过Oracle示例展示了具体用法,并提供Python脚本实现自动化处理,最后调整批处理脚本以适配YashanDB运行环境。
|
SQL Oracle 关系型数据库
如何在 Oracle 中配置和使用 SQL Profiles 来优化查询性能?
在 Oracle 数据库中,SQL Profiles 是优化查询性能的工具,通过提供额外统计信息帮助生成更有效的执行计划。配置和使用步骤包括:1. 启用自动 SQL 调优;2. 手动创建 SQL Profile,涉及收集、执行调优任务、查看报告及应用建议;3. 验证效果;4. 使用 `DBA_SQL_PROFILES` 视图管理 Profile。

相关产品

  • 云原生数据库 PolarDB
  • 推荐镜像

    更多