• [其他问题] 【数仓GaussDB(DWS)】【bytea类型】使用postgresql.jar驱动包解析出错
    【功能模块】数据库中 bytea类型字段【操作步骤&问题现象】1、使用postgresql.jar驱动包解析出错2. 请问是否有提供专属驱动包可以解决这个问题【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [最佳实践] 创建Flink OpenSource作业从Postgres CDC源表读取数据写入到DWS
    场景描述CDC是变更数据捕获(Change Data Capture)技术的缩写,它可以将源数据库的增量变动记录,同步到一个或多个数据目的中。CDC在数据同步过程中,还可以对数据进行一定的处理,例如分组(GROUP BY)、多表的关联(JOIN)等。本示例通过创建Postgres CDC源表来监控Postgres的数据变化,并将变化的数据信息插入到DWS数据库中。前提条件已创建RDS Postgres实例,具体步骤可参考:RDS PostgreSQL快速入门。本示例创建的RDS Postgres数据库版本选择为:11。说明:创建的RDS Postgres数据库版本不能低于11。已创建DWS实例,具体创建DWS集群的操作可以参考创建DWS集群。本示例创建的DWS集群版本为:8.1.1.205。整体作业开发流程整体作业开发流程参考图1。图1 作业开发流程步骤1:创建队列:创建DLI作业运行的队列。步骤2:创建RDS Postgres数据库:创建RDS Postgres的数据库和表。步骤3:创建DWS数据库和表:创建用于接收数据的DWS数据库和表。步骤4:创建增强型跨源连接:DLI上创建连接RDS和DWS的跨源连接,打通网络。步骤5:运行作业:DLI上创建和运行Flink OpenSource作业。步骤6:发送数据和查询结果:RDS Postgres的表上插入数据,在DWS上查看运行结果。步骤1:创建队列登录DLI管理控制台,在左侧导航栏单击“资源管理 > 队列管理”,可进入队列管理页面。在队列管理界面,单击界面右上角的“购买队列”。在“购买队列”界面,填写具体的队列配置参数,具体参数填写参考如下。计费模式:选择“包年/包月”或“按需计费”。本示例选择“按需计费”。区域和项目:保持默认值即可。名称:填写具体的队列名称。说明:新建的队列名称,名称只能包含数字、英文字母和下划线,但不能是纯数字,且不能以下划线开头。长度限制:1~128个字符。队列名称不区分大小写,系统会自动转换为小写。类型:队列类型选择“通用队列”。“按需计费”时需要勾选“专属资源模式”。AZ策略、CPU架构、规格:保持默认即可。企业项目:当前选择为“default”。高级选项:选择“自定义”。网段:配置队列网段。例如,当前配置为10.0.0.0/16。注意:队列的网段不能和DMS Kafka、RDS MySQL实例的子网网段有重合,否则后续创建跨源连接会失败。其他参数根据需要选择和配置。图2 创建队列参数配置完成后,单击“立即购买”,确认配置信息无误后,单击“提交”完成队列创建。步骤2:创建RDS Postgres数据库登录RDS管理控制台,在“实例管理”界面,选择已创建的RDS Postgres实例,选择操作列的“更多 > 登录”,进入数据管理服务实例登录界面。输入实例登录的用户名和密码。单击“登录”,即可进入RDS Postgres数据库并进行管理。在数据库实例界面,单击“新建数据库”,数据库名定义为:testrdsdb,字符集保持默认即可。在testrdsdb数据库下,单击“新建Schema”,Schema名称输入为:test。在test的Schema所在行,单击“操作”列的“打开Schema”。单击“SQL查询”,输入以下创建表语句,创建RDS Postgres表。create table test.cdc_order( order_id VARCHAR, order_channel VARCHAR, order_time VARCHAR, pay_amount FLOAT8, real_pay FLOAT8, pay_time VARCHAR, user_id VARCHAR, user_name VARCHAR, area_id VARCHAR, primary key(order_id));在Postgre中执行下列SQL语句。ALTER TABLE test.cdc_order REPLICA IDENTITY FULL;步骤3:创建DWS数据库和表参考使用gsql命令行客户端连接DWS集群连接已创建的DWS集群。执行以下命令连接DWS集群的默认数据库“gaussdb”:gsql -d gaussdb -h DWS集群连接地址 -U dbadmin -p 8000 -W password -rgaussdb:DWS集群默认数据库。DWS集群连接地址:请参见获取集群连接地址进行获取。如果通过公网地址连接,请指定为集群“公网访问地址”或“公网访问域名”,如果通过内网地址连接,请指定为集群“内网访问地址”或“内网访问域名”。如果通过弹性负载均衡连接,请指定为“弹性负载均衡地址”。dbadmin:创建集群时设置的默认管理员用户名。-W:默认管理员用户的密码。在命令行窗口输入以下命令创建数据库“testdwsdb”。CREATE DATABASE testdwsdb;执行以下命令,退出gaussdb数据库,连接新创建的数据库“testdwsdb”。\q gsql -d testdwsdb -h DWS集群连接地址 -U dbadmin -p 8000 -W password -r执行以下命令创建表。create schema test; set current_schema= test; drop table if exists dws_order; CREATE TABLE dws_order ( order_id VARCHAR, order_channel VARCHAR, order_time VARCHAR, pay_amount FLOAT8, real_pay FLOAT8, pay_time VARCHAR, user_id VARCHAR, user_name VARCHAR, area_id VARCHAR );步骤4:创建增强型跨源连接创建DLI连接RDS的增强型跨源连接在RDS管理控制台,选择“实例管理”,单击对应的RDS实例名称,进入到RDS的基本信息页面。在“基本信息”的“连接信息”中获取该实例的“内网地址”、“数据库端口”、“虚拟私有云”和“子网”信息,方便后续操作步骤使用。单击“连接信息”中的安全组名称,在“入方向规则”中添加放通队列网段的规则。例如,本示例队列网段为“10.0.0.0/16”,则规则添加为:优先级选为:1,策略选为:允许,协议选择:TCP,端口值不填,类型:IPV4,源地址为:10.0.0.0/16,单击“确定”完成安全组规则添加。登录DLI管理控制台,在左侧导航栏单击“跨源管理”,在跨源管理界面,单击“增强型跨源”,单击“创建”。在增强型跨源创建界面,配置具体的跨源连接参数。具体参考如下。连接名称:设置具体的增强型跨源名称。本示例输入为:dli_rds。弹性资源池:选择步骤1:创建队列中已经创建的队列。虚拟私有云:选择RDS的虚拟私有云。子网:选择RDS的子网。其他参数可以根据需要选择配置。参数配置完成后,单击“确定”完成增强型跨源配置。单击创建的跨源连接名称,查看跨源连接的连接状态,等待连接状态为:“已激活”后可以进行后续步骤。单击“队列管理”,选择操作的队列,本示例为步骤1:创建队列中创建的队列,在操作列,单击“更多 > 测试地址连通性”。在“测试连通性”界面,根据2中获取的RDS连接信息,地址栏输入“RDS内网地址:RDS数据库端口”,单击“测试”测试DLI到RDS网络是否可达。创建DLI连接DWS的增强型跨源连接在DWS管理控制台,选择“集群管理”,单击已创建的DWS集群名称,进入到DWS的基本信息页面。在“基本信息”的“数据库属性”中获取该实例的“内网IP”、“端口”,“基本信息”页面的“网络”中获取“虚拟私有云”和“子网”信息,方便后续操作步骤使用。单击“连接信息”中的安全组名称,在“入方向规则”中添加放通队列网段的规则。例如,本示例队列网段为“10.0.0.0/16”,则规则添加为:优先级选为:1,策略选为:允许,协议选择:TCP,端口值不填,类型:IPV4,源地址为:10.0.0.0/16,单击“确定”完成安全组规则添加。登录DLI管理控制台,在左侧导航栏单击“跨源管理”,在跨源管理界面,单击“增强型跨源”,单击“创建”。说明:本示例默认RDS和DWS实例分别在两个VPC和子网下,所以要分别创建增强型跨源连接打通网络。如果RDS和DWS实例属于同一VPC和子网下,则创建增强型跨源一次即可,4和5不需要再执行。在增强型跨源创建界面,配置具体的跨源连接参数。具体参考如下。连接名称:设置具体的增强型跨源名称。本示例输入为:dli_dws。弹性资源池:选择步骤1:创建队列中已经创建的队列。虚拟私有云:选择DWS的虚拟私有云。子网:选择DWS的子网。其他参数可以根据需要选择配置。参数配置完成后,单击“确定”完成增强型跨源配置。单击创建的跨源连接名称,查看跨源连接的连接状态,等待连接状态为:“已激活”后可以进行后续步骤。单击“队列管理”,选择操作的队列,本示例为步骤1:创建队列中创建的队列,在操作列,单击“更多 > 测试地址连通性”。在“测试连通性”界面,根据2中获取的DWS连接信息,地址栏输入“DWS内网IP:DWS端口”,单击“测试”测试DLI到DWS网络是否可达。步骤5:运行作业在DLI管理控制台,单击“作业管理 > Flink作业”,在Flink作业管理界面,单击“创建作业”。在创建队列界面,类型选择“Flink OpenSource SQL”,名称填写为:FlinkCDCPostgreDWS。单击“确定”,跳转到Flink作业编辑界面。在Flink OpenSource SQL作业编辑界面,配置如下参数。所属队列:选择步骤1:创建队列中创建的队列。Flink版本:选择1.12。保存作业日志:勾选。OBS桶:选择保存作业日志的OBS桶,根据提示进行OBS桶权限授权。开启Checkpoint:勾选。Flink作业编辑框中输入具体的作业SQL,本示例作业参考如下。SQL中加粗的参数需要根据实际情况修改。说明:本示例使用的Flink版本为1.12,故Flink OpenSource SQL语法也是1.12。本示例数据源是Kafka,写入结果数据到Elasticsearch,故请参考Flink OpenSource SQL 1.12创建Postgres CDC源表和Flink OpenSource SQL 1.12创建DWS结果表。create table PostgreCdcSource( order_id string, order_channel string, order_time string, pay_amount double, real_pay double, pay_time string, user_id string, user_name string, area_id STRING, primary key (order_id) not enforced ) with ( 'connector' = 'postgres-cdc', 'hostname' = '192.168.15.153',--IP替换为RDS Postgres的实例IP 'port' = '5432',--端口替换为RDS Postgres的实例端口 'username' = 'xxxxx',--RDS Postgres实例的数据库用户名 'password' = 'xxxxx',-RDS Postgres实例的数据库用户密码 'database-name' = 'testrdsdb',--RDS Postgres实例的数据库名 'schema-name' = 'test',--RDS Postgres数据库下的schema 'table-name' = 'cdc_order'--RDS Postgres数据库下的表名 ); create table dwsSink( order_id string, order_channel string, order_time string, pay_amount double, real_pay double, pay_time string, user_id string, user_name string, area_id STRING, primary key(order_id) not enforced ) with ( 'connector' = 'gaussdb', 'driver' = 'com.huawei.gauss200.jdbc.Driver', 'url' = 'jdbc:gaussdb://192.168.168.16:8000/testdwsdb', ---192.168.168.16:8000替换为DWS的内网IP和端口,testdwsdb为创建的DWS数据库名 'table-name' = 'test\".\"dws_order', ---test为创建的DWS表的schema,dws_order为对应的DWS表名 'username' = 'xxxxx',--替换为DWS实例的用户名 'password' = 'xxxxx',--替换为DWS实例的用户密码 'write.mode' = 'insert' ); insert into dwsSink select * from PostgreCdcSource where pay_amount > 100;单击“语义校验”确保SQL语义校验成功。单击“保存”,保存作业。单击“启动”,启动作业,确认作业参数信息,单击“立即启动”开始执行作业。等待作业运行状态变为“运行中”。步骤6:发送数据和查询结果登录RDS管理控制台,在“实例管理”界面,选择已创建的RDS Postgres实例,选择操作列的“更多 > 登录”,进入数据管理服务实例登录界面。输入实例登录的用户名和密码。单击“登录”,即可进入RDS Postgres数据库并进行管理。在已创建的数据库的操作列,单击“SQL查询”,输入以下创建表语句,插入测试数据。insert into test.cdc_order values ('202103241000000001','webShop','2021-03-24 10:00:00','50.00','100.00','2021-03-24 10:02:03','0001','Alice','330106'), ('202103251606060001','appShop','2021-03-24 12:06:06','200.00','180.00','2021-03-24 16:10:06','0002','Jason','330106'), ('202103261000000001','webShop','2021-03-24 14:03:00','300.00','100.00','2021-03-24 10:02:03','0003','Lily','330106'), ('202103271606060001','appShop','2021-03-24 16:36:06','99.00','150.00','2021-03-24 16:10:06','0001','Henry','330106');参考使用gsql命令行客户端连接DWS集群连接已创建的DWS集群。执行以下命令连接DWS集群的默认数据库“testdwsdb”:gsql -d testdwsdb -h DWS集群连接地址 -U dbadmin -p 8000 -W password -r执行以下语句,查询DWS的表数据。select * from test.dws_order;查询结果参考如下:order_channel order_channel order_time pay_amount real_pay pay_time user_id user_name area_id 202103251606060001 appShop 2021-03-24 12:06:06 200.0 180.0 2021-03-24 16:10:06 0002 Jason 330106 202103261000000001 webShop 2021-03-24 14:03:00 300.0 100.0 2021-03-24 10:02:03 0003 Lily 330106
  • [其他] 升级前巡检发现to_clob函数存在元数据不一致,如何整改
    【问题现象】C80->8.0.0.2升级前巡检发现to_clob函数存在元数据不一致,部分dn或CN上有该函数,部分DN上没有,需要进行升级前整改,否则升级过程中必然出现问题:cid:link_0cid:link_1【解决方法】1.对于C80版本,可以直接drop:可以在升级前将该函数drop掉,升级过程中会自动重建该函数:(1)业务库、postgres库和template1库下可以直接drop该函数:分别连接业务库、postgres库和template1库,执行:drop function if exists pg_catalog.to_clob(bpchar) cascade;drop function if exists pg_catalog.to_clob(varchar) cascade;drop function if exists pg_catalog.to_clob(nvarchar2) cascade;(2)template0库需要单独处理:(25308/25330/25332为同一个节点上CN、DN的端口号,如果一个节点上有多个DN,可以参考该方式增加)gs_ssh -c "gsql -d postgres -p25308 -c \"start transaction read write;update pg_database set datallowconn = true where datname = 'template0';commit; \""  >> clob.0528gs_ssh -c "gsql -d postgres -p25330 -c \"start transaction read write;update pg_database set datallowconn = true where datname = 'template0';commit; \"" >> clob.0528gs_ssh -c "gsql -d postgres -p25332 -c \"start transaction read write;update pg_database set datallowconn = true where datname = 'template0';commit; \"" >> clob.0528gsql -d template0 -p25308 -c "select p.oid, n.nspname,p.* from pg_proc p inner join pg_namespace n on p.pronamespace=n.oid where proname = 'to_clob' order by 1,2;"gs_ssh -c "gsql -d template0 -p25308 -c \"start transaction read write;drop function if exists pg_catalog.to_clob(bpchar) cascade;drop function if exists pg_catalog.to_clob(varchar) cascade;drop function if exists pg_catalog.to_clob(nvarchar2) cascade;commit; \""  >> clob.0528gs_ssh -c "gsql -d template0 -p25330 -c \"start transaction read write;drop function if exists pg_catalog.to_clob(bpchar) cascade;drop function if exists pg_catalog.to_clob(varchar) cascade;drop function if exists pg_catalog.to_clob(nvarchar2) cascade;commit; \"" >> clob.0528gs_ssh -c "gsql -d template0 -p25332 -c \"start transaction read write;drop function if exists pg_catalog.to_clob(bpchar) cascade;drop function if exists pg_catalog.to_clob(varchar) cascade;drop function if exists pg_catalog.to_clob(nvarchar2) cascade;commit; \"" >> clob.0528gsql -d template0 -p25308 -c "select p.oid, n.nspname,p.* from pg_proc p inner join pg_namespace n on p.pronamespace=n.oid where proname = 'to_clob' order by 1,2;"gs_ssh -c "gsql -d postgres -p25308 -c \"start transaction read write;update pg_database set datallowconn = false where datname = 'template0';commit; \"" >> clob.0528gs_ssh -c "gsql -d postgres -p25330 -c \"start transaction read write;update pg_database set datallowconn = false where datname = 'template0';commit; \"" >> clob.0528gs_ssh -c "gsql -d postgres -p25332 -c \"start transaction read write;update pg_database set datallowconn = false where datname = 'template0';commit; \"" >> clob.0528grep -E 'ERROR|FATAL' clob.05282. 对于高版本,存在元数据不一致时drop可能会报错:这时可以使用CREATE OR REPLACE FUNCTION对函数进行补齐后重新drop或使用-m参数在所有节点drop
  • [行业资讯] 2021年七个优秀的PostgreSQL GUI软件
    51CTO.com快译】什么是PostgreSQL GUI?它如何帮助企业管理PostgreSQL数据库?人们需要了解2021年一些优秀的PostgreSQL GUI软件。PostgreSQL是一种先进的开源对象关系数据库管理系统,可以支持SQL和JSON查询。根据Stack Overflow公司的一项调查,PostgreSQL是目前仅次于MySQL的第二大常用数据库。在对7万多名受访者的调查中,超过40%的人表示更喜欢采用PostgreSQL,而不是SQLite、MongoDB、Redis等其他数据库。作为Postgres用户,有两种方法来管理数据库:通过命命令行界面(CLI)编写查询(并非所有人都喜欢)。使用Postgres GUI,该界面由PostgreSQL管理工具之一构建。Postgres GUI比命令行界面(CLI)方便得多。此外,它还可以提高企业的工作效率。以下了解一下Postgres GUI和最常用的PostgreSQL GUI工具。什么是PostgreSQL GUI?PostgreSQL GUI是PostgreSQL数据库的管理工具。它允许企业或数据库用户查询、可视化、操作、分析其Postgres数据。还可以通过Postgres GUI访问数据库服务器。很多用户更喜欢Postgres GUI而不是CLI的主要原因是:漫长的学习曲线和复杂的使用流程。CLI界面不便于使用。控制台提供的信息不足。难以通过控制台浏览和监控数据库。反过来,使用Postgres GUI可为企业提供以下优势:快捷方式可用于更快、更简单的工作。丰富的数据可视化机会。可以访问远程数据库服务器。轻松地访问操作系统。优秀的PostgreSQL GUI软件对于某些用户来说,以Postgres为中心的pgAdmin并不是目前唯一可用的Postgres GUI工具,这可能出乎人们的意料。以下了解一下如今流行的一些PostgreSQL GUI管理工具。也许其中之一将会显著简化Postgres数据库管理。1.pgAdminpgAdmin是一个开源的跨平台PostgreSQL GUI工具。优点:与Linux、Windows、macOS兼容。允许同时使用多个服务器。CSV文件导出。查询计划功能。能够通过仪表板监控会话、数据库锁定。SQL编辑器中的快捷方式,使工作更方便。内部程序语言调试器旨在帮助代码调试。完整的文档和充满活力的社区。缺点:与一些付费的工具相比,其用户界面运行缓慢且不直观。笨重。不易上手。企业需要高级技能才能同时使用多个数据库。2.DBeaver这是一个支持多数据库的开源PostgreSQL管理工具。优点:跨平台。支持80多个数据库。作为可视化查询生成器,允许企业在没有SQL技能的情况下添加SQL查询。具有多个数据视图。CSV、HTML、XML、JSON、XLS、XLSX中的数据导入/导出。高级数据安全性。全文数据搜索和将搜索结果显示为表格/视图的能力。提供免费计划。缺点:与竞争对手相比运行速度较慢。更新过于频繁,令人烦恼。在闲置一段时间后,DBeaver会断开与企业的数据库的连接。企业需要重新启动应用程序。3.Navicat这是一个非常直观的Postgres数据库管理图形工具。Navicat并不是开源的工具。优点:非常容易和快速安装。获得Windows、Linux、macOS、iOS支持。方便快捷的可视化SQL构建器。具有代码自动完成功能。数据建模工具:操作企业的数据库对象、设计模式。作业调度程序:运行作业,在作业完成时获得通知。内置团队协作。数据源同步。以Excel、Access、CSV和其他格式导入/导出数据。通过SSH隧道和SSL确保数据保护。与亚马逊、谷歌和其他公司的云计算服务商合作。缺点:GUI工具性能不高。与竞争对手相比价格偏高。一个许可证只限于一个平台(用户需要PostgreSQL和MySQL两个单独的许可证)。许多高级功能需要时间来学习如何使用。使用不方便:添加行时需要更新应用程序。4.DataGrip由JetBrains构建的支持多个数据库的高级IDE。优点:跨平台(Windows、macOS、Linux支持)。简单的架构导航。带有查询控制台的可自定义用户界面(UI),可确保企业的工作进度安全。提示错误检测。内置版本控制系统。MySQL、SQLite、MariaDB、Cassandra和其他数据库支持。清晰的报告,能够将它们与图表和图形集成。强大的自动完成功能,建议相关代码完成。缺点:相当昂贵。消耗内存。复杂的错误调试过程。DataGrip和JetBrains具有长期的学习曲线。难以用作基于云计算的管理Web应用程序。不适合同时管理多个数据库。5.HeidiSQL这是一个开源Postgres(不仅仅是)GUI工具。现在仅支持Windows。优点:易于安装,与竞争对手相比非常轻巧。PostgreSQL、MySQL、Microsoft SQL Server、MariaDB支持。能够在一个窗口中连接和管理多个数据库服务器。从一个数据库或服务器到另一个数据库或服务器的直接SQL导出。通过简单易用的网格进行批量表格浏览和编辑。代码完成和语法突出显示功能。活跃的支持社区定期增强这个GUI工具。网格和数据导出为Excel、HTML、JSON、PHP文件。100%加密数据连接。缺点:不能跨平台使用(仅支持Windows)。问题频繁出现。没有程序语言调试器来简单地进行代码调试。6.TablePlus用于管理SQL和NoSQL数据库的原生GUI软件。TablePlus并不是开源的工具。优点:根据用户的反馈提供高性能和速度。高度可定制的用户界面:根本无需求助于Mojave。支持语法突出显示。快捷方式可以节省时间并提高效率。由于客户端-服务器连接的端到端加密,确保了更高级别的数据安全。缺点:当企业使用PostgreSQL以外的其他数据库时,经常出现用户体验不佳的问题。价格昂贵。而免费试用的功能进行严格限制。客户支持还有很多需要改进的地方。7.OmniDB这是一个简单的PostgreSQL开源GUI管理工具。优点:跨平台(获得Windows、Linux、macOS支持)。获得PostgreSQL、Oracle、MySQL、MariaDB支持。与某些替代品相比,响应速度快且更加轻巧。SQL自动完成功能。具有语法高亮显示功能。能够创建可定制的图表以显示相关的数据库指标。内置调试​​功能。缺点:如果同时使用多个数据库,则不是很适合。缺乏支持和学习文件。结语当企业选择GUI软件时,应该基于以下几个方面做出最终决定:团队规模。操作系统。数据库类型。计划使用的多个数据库。DBeaver、DataGrp和HeidiSQL更适合个人使用的数据库。由于具有GUI工具协作功能,Navicat是团队的最佳选择。除了支持Windows的HeidiSQL之外,几乎所有提到的工具都是跨平台的。pgAdmin以PostgreSQL为中心,作为PostgreSQL GUI工具的功能相当强大。但是采用可视化的内部工具构建器有UI Bakery。如果需要将多个不同的数据源集成在一起,那么这个低代码开发平台非常有用——无论是数据库、第三方工具还是API。而企业不必只局限在一个生态系统中。UI Bakery不是Postgres原生的。但是,它的数据可视化功能允许企业根据从PostgreSQL、MySQL、MS SQL Server、MongoDB、Redis、Salesforce和一系列其他数据库和应用程序中提取的数据,构建真正美观、易懂的图表、表格和图形。企业还可以使用预构建的用户界面(UI)组件和模板,避免从头开始构建,并节省更多的时间。如果企业不确定内部工具构建器适合自己的特定需求,可以继续进行尝试。整个GUI工具开发过程可能需要数小时的时间,有时甚至低至数分钟,具体取决于企业的开发经验。pgAdmin和其他经典的GUI软件似乎正在失去吸引力。Postgres和其他数据库管理的低代码方法使企业可以在更短的时间内获得更好的结果。原文标题:Top 8 PostgreSQL GUI Software in 2021,作者:Ilon Adams【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】
  • [行业资讯] 分布式 PostgreSQL之Citus 架构
    节点Citus 是一种 PostgreSQL 扩展,它允许数据库服务器(称为节点)在“无共享(shared nothing)”架构中相互协调。这些节点形成一个集群,允许 PostgreSQL 保存比单台计算机上更多的数据和使用更多的 CPU 内核。这种架构还允许通过简单地向集群添加更多节点来扩容数据库。扩展https://www.postgresql.org/docs/current/external-extensions.htmlCoordinator 与 Worker每个 cluster 都有一个称为 coordinator(协调器) 的特殊节点(其他节点称为 worker 节点)。应用程序将它们的查询发送到 coordinator 节点,coordinator 节点将其转发给相关的 worker 并累积结果。对于每个查询,coordinator 要么将其路由到单个 worker 节点,要么将其并行化到多个节点,具体取决于所需数据是位于单个节点上还是多个节点上。coordinator 通过查阅其元数据表知道如何做到这一点。这些 Citus 特定表跟踪 worker 节点的 DNS 名称和运行状况,以及跨节点数据的分布情况。分布式数据表类型Citus 集群中有三种类型的表,每种表都以不同方式存储在节点中,并且用于不同的目的。类型 1:分布式表第一种类型,也是最常见的,是分布式表。对于 SQL 语句而言,它们看似是普通的表,但在 worker 节点之间水平分区。这里 table 的行存储在 worker 的表 table_1001、table_1002 等中。组件 worker 表称为分片(shards)。分布列Citus 使用使用分片算法将行分配到分片。基于表列(称为分布列(distribution column))的值执行分配,此分配具有确定性。集群管理员在分布表时必须指定此列。做出正确的选择,这一点对于性能和功能有重要影响。类型 2:引用表引用表 是一种分布式表,其全部内容都集中到单个分片中,并在每个 worker 上复制。因此,对任何 worker 的查询都可以在本地访问 引用 信息,无需从另一个节点请求行,因此也不会产生此类网络开销。引用表没有分布列,因为无需区分每行的各个分片。引用表 通常很小,用于存储与在任何工作节点上运行的查询相关的数据。例如,订单状态或产品类别等枚举值。当与 引用表 交互时,我们会自动对事务执行两阶段提交 (2PC)。这意味着 Citus 确保您的数据始终处于一致状态,无论您是在写入、修改还是删除它。2PChttps://en.wikipedia.org/wiki/Two-phase_commit_protocol类型 3:本地表当您使用 Citus 时,您连接并与之交互的 coordinator 节点是安装了 Citus 扩展的常规 PostgreSQL 数据库。因此,您可以创建普通表并选择不对其进行分片。这对于不参与连接查询的小型管理表很有用。一个示例是用于应用程序登录和身份验证的用户表。创建标准 PostgreSQL 表很容易,因为它是默认值。这是你运行 CREATE TABLE 时得到的。在几乎每个 Citus 部署中,我们都会看到标准 PostgreSQL 表与 distributed 和 reference 表共存。事实上,如前所述,Citus 本身使用本地表来保存集群元数据。Shards上一节将分片描述为在 worker 节点内的较小表中包含分布式表的行的子集。本节详细介绍了技术细节。协调器上的 pg_dist_shard 元数据表包含系统中每个分布式表的每个分片的行。该行与分片 ID 相匹配,分片 ID 的范围是一组哈希整数 (shardminvalue, shardmaxvalue)。SELECT * from pg_dist_shard; logicalrelid | shardid | shardstorage | shardminvalue | shardmaxvalue ---------------+---------+--------------+---------------+--------------- github_events | 102026 | t | 268435456 | 402653183 github_events | 102027 | t | 402653184 | 536870911 github_events | 102028 | t | 536870912 | 671088639 github_events | 102029 | t | 671088640 | 805306367 (4 rows)如果 coordinator 节点要确定哪个分片包含 github_events 行,它将对行中分布列的值执行哈希算法。然后此节点检查哪个分片的范围包含此哈希值。定义范围后,哈希函数的image(图像)就是两者的并查。分片放置假设分片 102027 与相应的行关联。在某个 worker 中的 github_events_102027 表中读取或写入此行。是哪个 worker?这完全由元数据表确定。分片映射到 worker 的过程称为分片放置(shard placement)。coordinator 节点将查询重写为引用特定表(例如 github_events_102027)的片段,并对相应 worker 运行这些片段。下面的查询示例在后台运行,旨在查找分片 ID 为 102027 的节点。SELECT shardid, node.nodename, node.nodeport FROM pg_dist_placement placement JOIN pg_dist_node node ON placement.groupid = node.groupid AND node.noderole = 'primary'::noderole WHERE shardid = 102027; ┌─────────┬───────────┬──────────┐ │ shardid │ nodename │ nodeport │ ├─────────┼───────────┼──────────┤ │ 102027 │ localhost │ 5433 │ └─────────┴───────────┴──────────┘在 github_events 示例中,有四个分片。每个表的分片数量在其在集群中分布时是可配置的。最后请注意,Citus 允许复制分片以防止数据丢失。有两种复制“模式”:Citus 复制和流复制。前者创建额外的备份分片放置并针对所有更新它们的所有它们运行查询。后者效率更高,利用 PostgreSQL 的流式复制将每个节点的整个数据库备份到一个 follower 数据库。这是透明的,不需要 Citus 元数据表的参与。共置由于可以根据需要将分片及其副本放置在节点上,因此将包含相关表的相关行的分片放在同一节点上是有意义的。这样,它们之间的连接查询可以避免通过网络发送尽可能多的信息,并且可以在单个 Citus 节点内执行。一个示例是包含商店、产品和购买的数据库。如果所有三个表都包含 - 并且由 - store_id 列分布,那么限制在单个存储中的所有查询都可以在单个工作节点上高效运行。即使查询涉及这些表的任意组合也是如此。并行性跨多台机器分散查询允许一次运行更多查询,并允许通过向集群添加新机器来扩展处理速度。此外,如上一节所述,将单个查询拆分为片段可以提高专用于它的处理能力。后一种情况实现了最大的并行性,这意味着 CPU 内核的利用率。读取或影响均匀分布在多个节点上的分片的查询能够以“实时”速度运行。请注意,查询的结果仍然需要通过协调器节点传回,因此当最终结果紧凑时(例如计数和描述性统计等聚合函数),加速效果最为明显。查询执行在执行多分片查询时,Citus 必须平衡并行性的收益与数据库连接的开销(网络延迟和工作节点资源使用)。要配置 Citus 的查询执行以获得最佳的数据库工作负载结果,它有助于了解 Citus 如何管理和保存协调节点和工作节点之间的数据库连接。Citus 将每个传入的多分片查询会话转换为称为任务的每个分片查询。它将任务排队,并在能够获得与相关工作节点的连接时运行它们。对于分布式表 foo 和 bar 的查询,下面是连接管理图:coordinator 节点为每个会话都有一个连接池。每个查询(例如图中的 SELECT * FROM foo)仅限于为每个 worker 的任务打开最多 citus.max_adaptive_executor_pool_size(整数)个同时连接。该设置可在会话级别进行配置,以进行优先级管理。在同一连接上按顺序执行短任务比为它们并行建立新连接更快。另一方面,长时间运行的任务受益于更直接的并行性。为了平衡短任务和长任务的需求,Citus 使用 citus.executor_slow_start_interval(整数)。该设置指定多分片查询中任务的连接尝试之间的延迟。当查询首先对任务进行排队时,这些任务只能获取一个连接。在每个有待处理连接的时间间隔结束时,Citus 会增加它将打开的同时连接数。通过将 GUC 设置为 0,可以完全禁用慢启动行为。当任务完成使用连接时,会话池将保持连接打开以供以后使用。缓存连接避免了 coordinator 和 worker 之间重新建立连接的开销。但是,每个池一次打开的空闲连接不超过 citus.max_cached_conns_per_worker(整数)个,以限制 worker 中空闲连接资源的使用。最后,设置 citus.max_shared_pool_size (integer) 充当故障保险。它限制了所有任务之间每个 worker 的总连接数。
  • [技术干货] PostgreSQL-14.3稳定版SQL语法
    先聊聊Postgre的词汇结构1.词汇结构1.1标识符和关键字SQL 输入由一系列命令组成。命令由一系列标记组成,以分号 (“;”) 结尾。输入流的末尾也会终止命令。哪些关键字有效取决于特定命令的语法。标记可以是关键字、标识符、带引号的标识符、文本(或常量)或特殊字符符号。标记通常由空格(空格,制表符,换行符)分隔,但如果没有歧义,则不需要这样(通常只有在特殊字符与其他标记类型相邻时才会出现这种情况)。举个栗子  select * from s_student ;   update s_student set age =1 where name ='xiaoming'; insert  into student  values ("liming' ,25);以上是有效的 SQL 输入这是一个由三个命令组成的序列,每行一个命令(尽管这不是必需的;一行上可以有多个命令,并且可以有效地跨行拆分命令)。此外,注释可以出现在 SQL 输入中。它们不是标记,它们实际上等同于空格。标记(如 、或上面的示例中)是关键字的示例,即在 SQL 语言中具有固定含义的单词。令牌 和 是标识符的示例。它们标识表、列或其他数据库对象的名称,具体取决于使用它们的命令。因此,它们有时被简单地称为“名称”。关键字和标识符具有相同的词汇结构,这意味着如果不了解语言,就无法知道令牌是标识符还是关键字。SQL 标识符和关键字必须以字母(-,但也包括带有变音符号和非拉丁字母的字母)或下划线 () 开头。标识符或关键字中的后续字符可以是字母、下划线、数字 (-) 或美元符号 ()。请注意,根据 SQL 标准的字母,标识符中不允许使用美元符号,因此使用它们可能会使应用程序的可移植性降低。SQL标准不会定义包含数字或以下划线开头或结尾的关键字,因此这种形式的标识符是安全的,不会与标准的未来扩展发生冲突。az_09$系统使用不超过 -1 个字节的标识符;较长的名称可以写在命令中,但它们将被截断。默认情况下,为 64,因此最大标识符长度为 63 个字节。如果此限制有问题,可以通过更改 中的常量来提高它。关键字和未加引号的标识符不区分大小写。因此:select * from s_student ;  写成seLEct * from s_student ; 也不是不可以,不过这个就是个人习惯,轻度强迫症 必须全部大写或者小写 。经常使用的惯例是用大写字母写关键词,用小写字母写名字,例如:UPDATE student SET age =‘5’;还有第二种标识符:分隔标识符或带引号的标识符。它是通过将任意字符序列括在双引号 () 中而形成的。分隔标识符始终是标识符,而不是关键字。因此,可用于引用名为“select”的列或表,而未加引号将被视为关键字,因此在需要表或列名称时使用时会引起解析错误。该示例可以使用带引号的标识符编写,如下所示:UPDATE “student” SET "age"=‘5’;带引号的标识符可以包含任何字符,但代码为零的字符除外。(要包含双引号,请写两个双引号。这允许构造原本不可能实现的表名或列名,例如包含空格或 & 符号的表名或列名。长度限制仍然适用。引用标识符也会使其区分大小写,而未引用的名称始终折叠为小写。例如,PostgreSQL 认为标识符 、 和 是相同的,但与这三者不同。(在PostgreSQL中将未引用的名称折叠为小写与SQL标准不兼容,SQL标准规定未引用的名称应折叠为大写。因此,应等同于不按标准。如果你想编写可移植的应用程序,建议你总是引用一个特定的名字,或者永远不要引用它。STU"stu""Stu""STU"stu带引号的标识符的变体允许包括由其码位标识的转义 Unicode 字符。此变体以(大写或小写 U 后跟 & 符号)开头,紧挨着开始的双引号,中间没有任何空格,例如 。(请注意,这会与运算符 产生歧义。在运算符周围使用空格以避免此问题。在引号内,可以通过编写反斜杠后跟四位十六进制码位号或反斜杠后跟加号后跟六位十六进制码位号来以转义形式指定 Unicode 字符。例如,标识符可以写为U&U&"foo"&"data"转义字符可以是除十六进制数字、加号、单引号、双引号或空格字符以外的任何单个字符。请注意,转义字符写在 单引号中,而不是双引号,位于 之后。UESCAPE若要在标识符中按字面意思包含转义字符,请将其写入两次。4 位或 6 位转义形式可用于指定 UTF-16 代理项对,以组合代码点大于 U+FFFF 的字符,尽管 6 位格式的可用性在技术上使这变得不必要。(代理项对不直接存储,而是合并到单个代码点中。如果服务器编码不是 UTF-8,则由这些转义序列之一标识的 Unicode 码位将转换为实际的服务器编码;如果无法做到这一点,则会报告错误。1.2常量常量里面又分为字符串常量,带有C风格转移的字符串常量,带UNICODE风格转义字符的常量,带有美元字符的字符串常量,位字符串常量,数字常量,其他类型的常量。下来一一做一个简单的讨论。SQL 中的字符串常量是由单引号 () 限定的任意字符序列,例如 。要在字符串常量中包含单引号字符,请编写两个相邻的单引号,例如 。请注意,这与双引号字符 () 不同。''This is a string''Dianne''s horse'"仅由至少一个换行符的空格分隔的两个字符串常量将被串联并有效地处理,就好像字符串已编写为一个常量一样。PostgreSQL还接受“转义”字符串常量,这是SQL标准的扩展。转义字符串常量是通过在开始单引号之前写入字母(大写或小写)来指定的,例如.(跨行继续转义字符串常量时,请仅在第一个开头引号之前写入。在转义字符串中,反斜杠字符 () 开始一个类似 C 的反斜杠转义序列,其中反斜杠和后续字符的组合表示一个特殊的字节值,如下表\b退格\f进纸\n换行符\r回车\t标签\o, , (o = 0–7)\oo\ooo八进制字节值\xh, (h = 0–9, A–F)\xhh十六进制字节值\uxxxx, (x = 0–9, A–F)\Uxxxxxxxx16 位或 32 位十六进制 Unicode 字符值PostgreSQL还支持另一种类型的字符串转义语法,允许按码位指定任意Unicode字符。Unicode 转义字符串常量以(大写或小写字母 U 后跟与号)开头,紧跟在左引号之前,中间没有任何空格,例如 。(请注意,这会与运算符 产生歧义。在运算符周围使用空格以避免此问题。在引号内,可以通过编写反斜杠后跟四位十六进制码位号或反斜杠后跟加号后跟六位十六进制码位号来以转义形式指定 Unicode 字符。虽然用于指定字符串常量的标准语法通常很方便,但当所需的字符串包含许多单引号或反斜杠时,可能很难理解,因为每个单引号或反斜杠都必须加倍。为了允许在这种情况下进行更具可读性的查询,PostgreSQL提供了另一种称为“美元报价”的方法来编写字符串常量。以美元报价的字符串常量由美元符号 ()、零个或多个字符的可选“标记”、另一个美元符号、组成字符串内容的任意字符序列、美元符号、以此美元报价开头的相同标记以及美元符号组成。位字符串常量看起来像常规字符串常量,在开头引号之前有一个(大写或小写)(没有中间空格)其中数字是一个或多个十进制数字(0 到 9)。如果使用小数点,则必须至少有一个数字位于小数点之前或之后。指数标记 () 后面必须至少有一个数字(如果存在)。常量中不能嵌入任何空格或其他字符。
  • [数据库] 【第42课】RDS for PostgreSQL插件介绍
    本文介绍RDS for PostgreSQL支持的插件及不同插件的创建、删除或使用方法。PostgreSQL插件简介PostgreSQL是开源数据库中经典的大型关系型数据库之一,它不仅具备经典关系型数据库的功能,而且在不断发展。PostgreSQL的发展不仅受到了很多基于PostgreSQL外部应用的影响,而且发展出了更多基于PostgreSQL的应用,例如PostGIS(GIS领域中重要组件)。从技术角度讲,PostGIS是PostgreSQL的一个扩展(extension),即插件。像PostGIS这样的插件已经在计算机相关的领域中都得到不同程度的应用,它成为PostgreSQL功能延展性的主要特点。PostgreSQL插件的功能不仅体现在新增复杂的数据类型、索引等数据的基本功能上,这些基本功能也是GIS领域所特别需要的,并且PostgreSQL的插件可以完成包括分布式、异构数据访问等的各种高级功能。这使得PostgreSQL数据库不仅仅是一个传统的经典关系型数据库,并且通过插件的扩展功能,它完全可以满足今天互联网对于大数据应用的需求。RDS for PostgreSQL插件列表RDS for PostgreSQL和社区版PostgreSQL一样,也支持通过插件,实现更多的扩展功能。当前RDS for PostgreSQL支持的插件如下表所示:插件名称PostgreSQL 9.5PostgreSQL 9.6PostgreSQL 10PostgreSQL 11PostgreSQL 增强版PostgreSQL 12PostgreSQL 13address_standardizer2.5.12.5.12.5.12.5.12.5.13.0.03.1.0address_standardizer_data_us2.5.12.5.12.5.12.5.12.5.13.0.03.1.0amcheck无无无1.11.11.21.2auto_explain2222222bloom无无无1.01.01.01.0btree_gin1.01.01.21.31.31.31.3btree_gist1.11.21.51.51.51.51.5citext1.11.31.41.51.51.61.6cube1.01.21.21.41.41.41.4dblink1.11.21.21.21.21.21.2dict_int1.01.01.01.01.01.01.0dict_xsyn1.01.01.01.01.01.01.0earthdistance1.01.11.11.11.11.11.1fuzzystrmatch1.01.11.11.11.11.11.1hll2.122.122.122.122.122.142.15.1hstore1.31.41.41.51.51.61.7icu无无无1.01.01.01.0intagg1.01.11.11.11.11.11.1intarray1.01.21.21.21.21.21.3isn1.01.11.11.21.21.21.2ltree1.01.11.11.11.11.11.2mysql_fdw无无无2.5.52.5.52.5.52.5.5oracle_fdw无无2.1.02.1.02.1.02.2.02.3.0orafce3.8.03.8.03.8.03.8.003.8.03.14.0pageinspect1.31.51.61.71.71.71.8passwordcheck2222222pg_bigm无无无1.2_202002281.2_202002281.2_202002281.2_20200228pg_buffercache1.11.21.31.31.31.31.3pg_cron无无无无无1.2.01.3.0pg_freespacemap1.01.11.21.21.21.21.2pg_hint_plan1.1.51.2.01.3.01.3.51.3.51.3.71.3.7pg_jieba1.1.01.1.01.1.01.1.01.1.01.1.02.0.1pg_pathman1.5.81.5.81.5.81.5.81.5.81.5.121.5.12pg_prewarm1.01.11.11.21.21.21.2pg_repack1.4.61.4.61.4.61.4.61.4.61.4.61.4.6pg_roaringbitmap无无无0.5.20.5.20.5.20.5.2pg_stat_statements1.31.41.61.61.61.71.8pg_trgm1.11.31.31.41.41.41.5pg_visibility无无无1.21.21.21.2pgcrypto1.21.31.31.31.31.31.3pglogical无无无2.3.32.3.32.3.32.3.3pg_profile_pro无无无无无1.0无pgrouting无无无3.1.03.1.03.1.03.1.3pgrowlocks1.11.21.21.21.21.21.2pg_sql_history1.01.01.01.01.01.01.0pgsql-ogr-fdw无无无1.0.121.0.121.0.121.0.12pgstattuple1.31.41.51.51.51.51.5plpgsql1.01.01.01.01.01.01.0plperl无无无1.01.01.01.0plproxy无无无2.10.02.10.02.10.02.10.0plv8无无无2.3.152.3.152.3.152.3.15postgis2.5.12.5.12.5.12.5.12.5.13.0.03.1.0postgis_raster集成到postgis集成到postgis集成到postgis集成到postgis集成到postgis3.0.03.1.0postgis_sfcgal2.5.12.5.12.5.12.5.12.5.13.0.03.1.0postgis_tiger_geocoder2.5.12.5.12.5.12.5.12.5.13.0.03.1.0postgis_topology2.5.12.5.12.5.12.5.12.5.13.0.03.1.0postgres_fdw1.01.01.01.01.01.01.0postgres-decoderbufs无无无1.3.11.3.11.3.11.3.1postgresql_anonymizer无无无0.7.10.7.10.7.10.7.1q3c无无无2.0.02.0.02.0.02.0.0rum无无无1.3.701.3.71.3.7sslinfo无无无1.21.21.21.2tablefunc1.01.01.01.01.01.01.0tds_fdw无无2.0.12.0.12.0.12.0.12.0.2test_decoding2222222timescaledb01.3.21.3.21.3.21.3.21.7.02.1.0tsm_system_rows1.01.01.01.01.01.01.0tsm_system_time1.01.01.01.01.01.01.0unaccent1.01.11.11.11.11.11.1uuid-ossp1.01.11.11.11.11.11.1wal2json无无无2.32.32.32.3xml2无无无1.11.11.11.1zhparser1.01.01.01.01.01.01.0表中的数据均来源于PostgreSQL引擎各个版本,最新小版本支持的插件列表。您可以通过SELECT name FROM pg_available_extensions;查看当前实例支持的插件列表。如果当前实例的版本不支持某个插件,您可以将当前实例迁移至新版本实例,迁移方法请参考迁移方案概览。使用mysql_fdw、oracle_fdw、pgsql-ogr-fdw、postgres_fdw和tds_fdw等需要跨数据库实例访问的插件时,需确保两个数据库实例的服务端IP必须在同一个VPC和子网内。具有公测权限的用户才可使用RDS for PostgreSQL 13,您可以提交工单申请。创建RDS for PostgreSQL插件RDS for PostgreSQL插件是数据库级生效,并不是全局生效。因此创建插件时需要在业务所在数据库上进行手动创建。RDS for PostgreSQL的以下插件不需要通过手动创建或删除:auto_explainpasswordcheckpg_profile_propg_sql_historyplpgsqlwal2jsontest_decodingRDS for PostgreSQL 11、RDS for PostgreSQL 增强版、RDS for PostgreSQL 12和RDS for PostgreSQL 13的最新小版本,支持以root用户通过社区的方式来创建(create extension)、删除(drop extension)插件。1.  执行如下命令,以root用户连接数据库,以database1为例,并使用模板库template1创建需要支持插件的数据库。# psql --host=RDS_ADDRESS --port=DB_PORT --dbname=database1 --username=root -c "create database DB_NAME template template1;"RDS_ADDRESS为RDS实例的IP地址。DB_PORT为RDS数据库实例的端口。DB_NAME为需要创建插件的数据库名称。回显如下信息,请输入root用户的密码。Password for user root:如果执行操作为:由普通用户user1创建的数据库db1,您需要先使用普通用户user1登录数据库db1(登录方式参考上述内容),然后执行如下命令将数据库db1的权限授予root用户。GRANT ALL ON DATABASE db1 TO root;示例:创建需要支持插件的数据库my_extension_db# psql --host=192.168.6.141 --port=5432 --dbname=database1 --username=root -c "create database my_extension_db template template1;"Password for user root: CREATE DATABASE2.   以root用户连接需要支持插件的数据库,并创建插件。# psql --host=RDS_ADDRESS --port=DB_PORT --dbname=DB_NAME --username=root -c "select control_extension('create','EXTENSION_NAME');"RDS_ADDRESS为RDS实例的IP地址。DB_PORT为RDS数据库实例的端口。DB_NAME为需要创建插件的数据库名称。EXTENSION_NAME为插件名称,请参见上表。回显如下信息,请输入root用户的密码。Password for user root:示例:在数据库my_extension_db中创建postgis插件# psql --host=192.168.6.141 --port=5432 --dbname=my_extension_db --username=root -c "select control_extension('create','postgis');"Password for user root: control_extension ------------------------------ create postgis successfully. (1 row)删除RDS for PostgreSQL插件RDS for PostgreSQL插件是数据库级生效,并不是全局生效。因此创建插件时需要在业务所在数据库上进行手动创建。RDS for PostgreSQL的以下插件不需要通过手动创建或删除:auto_explainpasswordcheckpg_profile_propg_sql_historyplpgsqlwal2jsontest_decodingRDS for PostgreSQL 11、RDS for PostgreSQL 增强版、RDS for PostgreSQL 12和RDS for PostgreSQL 13的最新小版本,支持以root用户通过社区的方式来创建(create extension)、删除(drop extension)插件。执行如下命令,以root用户连接已创建插件的数据库,并删除插件。# psql --host=RDS_ADDRESS --port=DB_PORT --username=root --dbname=DB_NAME -c "select control_extension ('drop','EXTENSION_NAME');"RDS_ADDRESS为RDS实例的IP地址。DB_PORT为RDS数据库实例的端口。DB_NAME为需要创建插件的数据库名称。EXTENSION_NAME为插件名称,请参见上表。回显如下信息,请输入root用户的密码。Password for user root:示例:# psql --host=192.168.6.141 --port=5432 --dbname=my_extension_db --username=root -c "select control_extension('drop','postgis');"Password for user root: control_extension ---------------------------- drop postgis successfully. (1 row)RDS for PostgreSQL插件说明插件名称插件说明postgis创建postgis插件时,会同步创建以下插件:postgis、postgis_topology、fuzzystrmatch、postgis_tiger_geocoder、address_standardizer及address_standardizer_data_us。创建的postgis插件版本如果大于等于3.0.0,创建postgis插件时会同步创建postgis_raster插件。创建postgis插件时,主备实例的主机创建插件后,请先断开备机已经建立的连接,备机需要重新建立连接更新search_path设置。对于PostgreSQL增强版实例,创建postgis插件前,需要在控制台上将实例参数“empty_is_null”设置为“OFF”。plpgsqlplpgsql 1.0插件支持提供SQL过程语言,默认内置安装,无需手动创建该插件。earthdistance安装earthdistance插件前,请先安装cube插件。cube如果已安装earthdistance插件,删除cube插件会导致earthdistance插件不可用。timescaledbRDS for PostgreSQL的timescaledb插件不支持tsl协议的特性,具体如下:add_compress_chunks_policyadd_drop_chunks_policyadd_reorder_policyalter_job_schedulecompress_chunkdecompress_chunkdrop_chunksinterpolatelocfmove_chunkremove_compress_chunks_policyremove_drop_chunks_policyremove_reorder_policyreorder_chunkset_integer_now_functime_bucket_gapfillwal2json该插件是逻辑复制插件,您可以直接使用该插件,不需要通过control_extension安装。pg_profile_pro因发现插件存在缺陷,现暂时关闭支持,我们会在缺陷修复后重新开放,给您造成不便敬请谅解。pg_repackpg_repack可以使用最小的锁资源来重新整理表和索引的物理页面,从而实现物理页面的碎片整理。相较于使用cluster和vacuumn full重写表,pg_repack不需要在整个处理期间持有表级排他锁,因此能提供近似的在线服务。具体操作请参考使用pg_repack插件。
  • [问题求助] 【opengauss】【表结构迁移】Postgresql 迁移至Opengauss 遇到字符类型等问题
    计划把Postgresql 迁移到Opengauss,遇到如下问题:1. 某些数据库对象不支持,比如:jsonb xml2. 某些列名与数据库关键字冲突。ERROR:  column name "tid" conflicts with a system column name3. 迁移之后,数据导入opengauss报字符错误gsql:/tmp/iot.sql:18610: ERROR:  value too long for type character varying(32)CONTEXT:  COPY sys_sec_org, line 5, column name: "深圳迅远城智南山分公司"4.  PG支持这种语法,opengauss 该如何应对CREATE TABLE iot.v_ship_destination (    "?column?" unknown);
  • [问题求助] 【PostgreSQL】【绑核功能】PostgreSQL 13.3如何绑核
    【功能模块】PostgreSQL 13.3【操作步骤&问题现象】1、如何给postgresql 13.3版本绑核,使用numactl -C 32-63 测试不生效,还运行在别的cpu上【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [技术干货] 常用 PostgreSQL 预防数据丢失解决方案
    PostgreSQL是一种特性非常齐全的自由软件的对象-关系型数据库管理系统(ORDBMS),是以加州大学计算机系开发的POSTGRES,4.2版本为基础的对象关系型数据库管理系统。POSTGRES的许多领先概念只是在比较迟的时候才出现在商业网站数据库中。PostgreSQL支持大部分的SQL标准并且提供了很多其他现代特性,如复杂查询、外键、触发器、视图、事务完整性、多版本并发控制等。同样,PostgreSQL也可以用许多方法扩展,例如通过增加新的数据类型、函数、操作符、聚集函数、索引方法、过程语言等。另外,因为许可证的灵活,任何人都可以以任何目的免费使用、修改和分发PostgreSQL。下面看下常用 PostgreSQL 预防数据丢失解决方案。PostgreSQL 本身不具备数据闪回和数据误删除保护功能,但在不同场景下也有对应的解决方案。本文由作者在 2021 PCC 大会的演讲主题《PostgreSQL 数据找回》整理而来,上一篇《盘点 | 常用 PG 数据恢复方案概览》 介绍了 PostgreSQL 常见的 数据恢复方案。本篇将介绍 预防数据丢失方案的实现原理及使用示例。预防数据丢失方案前文提到数据丢失的主要操作为 DDL 和 DML 。本篇主要介绍关于 DDL 和 DML 操作,如何预防数据丢失的方案。DDL 操作事件触发器当事件以其定义的方式在数据库中相关的发生时,触发事件触发器。主要可预防以下四种 DDL 事件。事件说明ddl_command_startDDL 执行前执行ddl_command_endDDL 执行后执行, 通过 pg_event_trigger_ddl_commands() 可以获取操作的对象sql_dropDDL 执行后执行, 通过 pg_event_trigger_dropped_objects() 可以获取所有被删除的对象table_rewriteDDL 执行前执行, 例如 ALTER TABLE、ALTER TYPE 等当表被删除后,可以通过 ddl_command_start 事件组织删除操作。12345678910CREATE OR REPLACE FUNCTION disable_drops()    RETURNS event_trigger LANGUAGE plpgsql AS $$BEGIN     RAISE EXCEPTION 'drop table denied';END$$; -- 创建事件触发器函数  CREATE EVENT TRIGGER event_trigger_disable_drops    ON ddl_command_start WHEN TAG in('drop table')    EXECUTE PROCEDURE disable_drops(); -- 创建事件触发器,禁止drop table操作事件触发器,无法修改 drop 的任何行为,因此只能拒绝,来确保数据不被删除,由其他拥有更高权限的数据库管理员删除。12345678910test=# \dy                                        事件触发器列表            名称             |       Event       | 拥有者  | 使能 |     函数      |    标签    -----------------------------+-------------------+---------+------+---------------+------------ event_trigger_disable_drops | ddl_command_start | lzzhang | 启用 | disable_drops | DROP TABLE(1 行记录)  test=# drop table lzzhang;ERROR:  drop table deniedCONTEXT:  PL/pgSQL function disable_drops() line 3 at RAISE删除表的操作由拥有更高级权限的数据库管理员操作。12345BEGIN;ALTER EVENT TRIGGER event_trigger_disable_drops DISABLE;DROP TABLE lzzhang;ALTER EVENT TRIGGER event_trigger_disable_drops ENABLE;COMMIT;回收站DDL 会将文件从操作系统中完全删除,因此唯一的办法是将删除改为换一个"位置",类似 Windows 中回收站。pgtanshscan[1] 便是一种回收站工具,并且只能通过插件采用 hook 的方式来实现。123456if (nodeTag(parsetree) == T_DropStmt){                if (stmt->removeType == OBJECT_TABLE){AlterObjectSchemaStmt *newstmt = makeNode(AlterObjectSchemaStmt);newstmt->newschema = pstrdup(trashcan_nspname);通过其代码示例可以看出, DROP TABLE 操作被转换成了 ALTER 操作。由于 pgtrashcan 代码陈旧,已经有 8 年未更新,不适配新版本 PG。且仅支持移动功能,并不支持彻底清除功能。由此,pgtrashcan 做了很多优化。• 支持新版本 PG 14/13/12• 通过插件的 depend 功能,依赖 pg_cron• 自动设置 pg_cron 将其回收站中超过 1 天的数据清除DML 操作通过参数 vacuum_defer_cleanup_age 来调整 Dead 元组在数据库中的量,以便恢复误操作的数据。接下来将根据 流复制延迟恢复和 备份恢复两种设计方案来具体介绍:流复制延迟恢复PostgreSQL 流复制时可以通过 recovery_min_apply_delay 设置相应的延迟时间。例如设置 5 小时,备库可以延迟应用最近 5 小时的日志,提供最多 5 小时的数据恢复窗口,延迟的应用日志的同时并不影响日志的接受,源库的日志仍然是实时的被延迟恢复节点接受。找回数据的具体操作步骤如下:• 暂停延迟恢复 pg_wal_replay_pause() ;• 通过 pg_dump 或 copy 操作将其需要的数据找出来;• 通过 psql、copy、pg_restore 等操作将数据导入源库中;• 继续延迟 pg_wal_replay_resume() 。备份恢复从备份模式的角度来说,备份主要包括以下两种:• 逻辑备份不能进行实时备份,因此不太适用于数据找回,会丢失很多数据。• 物理备份物理备份拥有与源集群完全一致的数据,因此可以持续使用源集群的 WAL 日志,达到数据找回的目标,原理上也是延迟恢复。物理备份与 PITR 结合,可恢复数据到任意时间点。可选用工具有很多,如下几种是常用的恢复工具。• pg_basebackup[2]• pg_probackup[3]• pgbackrest[4]• barman[5]• pg_rman[6]总结• 注意权限划分。危险操作或是 DDL 等影响大的操作,一定要由第二个数据库管理员操作。• 提前做好数据找回和数据安全的方案规划。• 流复制延迟恢复,同样需要设置 recovery_target_xid 、recovery_target_time 或recovery_target_lsn 来精准的定位到完整的数据集。• pg_waldump 是数据找回必备的一个功能。• 如果方案是重型的,轻型的插件有时会是更好的选择。• 若无任何准备,且不能安装任何插件,可第一时间将数据库关机!!!防止 Dead 元组被清理,拷贝整个集群,使用拷贝后的集群用 pg_resetwal 进行数据恢复。参考引用[1] :pgtrashcan:https://github.com/petere/pgtrashcan [2]:pg_basebackup:https://www.postgresql.org/docs/10/app-pgbasebackup.html 转载自https://www.jb51.net/article/235029.htm
  • [技术干货] 将PostgreSQL插件移植到openGauss指导
    1 概述PostgreSQL社区提供了丰富的插件,但由于openGauss和PostgreSQL存在一定的差异,如线程/进程模型、系统表和视图等,无法直接为openGauss所用,不可避免的需要在插件上做整改。本文档主要对PostgreSQL插件移植到openGauss的过程提供指导说明,旨在让开发人员对PG插件所需要的修改有一个具体的了解,基于该文档,可基本实现PG插件移植到openGauss。2 约束由于openGauss与PostgreSQL在内核上存在不少差异,这篇文档未能覆盖所有这些差异,因此仅依赖该文档有可能无法实现PG插件的完全迁移,部分差异需要开发者深入内核源码识别,然后可将识别出来的差异补充到该博客的第9章对应小节的表格中(博客对应的gitee地址: https://gitee.com/opengauss/blog/blob/master/content/zh/post/chenxiaobin/,具体操作可见blog仓库的将PostgreSQL插件移植到openGauss指导.md ),有任何问题可在博客下方留言讨论。3 移植步骤1) 将PG插件的代码拷贝到openGauss源码的contrib目录下2) 配置环境变量,需要将数据库的bin和lib加在操作系统的环境变量PATH和LD_LIBRARY_PATH中3) 到插件目录下,执行make && make install,编译安装插件。4) 编译成功后,到数据库中执行create extension extension_name即可使用。通常步骤3和4不会直接成功,需要一些必须的修改。下面分类别说明移植PG插件所需要做的修改。4 Makefile文件1) 当前有两种方式支持插件编译,一种是依赖源码编译,一种是用pgxs的方式编译,支持插件在一个已经安装的数据库服务上进行编译。建议选择前者的方式,如果采用后者,需要定义USE_PGXS,但是可能出现部分头文件找不到的问题,这时候需要到源码拷贝头文件到目标目录。ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) else subdir = contrib/pg_freespacemap top_builddir = ../.. include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif2) -fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code)。使用-fPIC,可以使得动态库可以被多个程序共享。不加fPIC加载的so,要在加载时根据加载到的位置再次重定位。override CPPFLAGS :=$(filter-out -fPIE, $(CPPFLAGS)) -fPIC5 类型转换1) ANSI C规定,void指针可以复制给其他任意类型的指针,其他任意类型的指针也可以复制给void指针,他们之间复制不需要强制类型转换。但是c++不支持,需要做强制类型转换。buffer = palloc(MAX_LINESIZE); -> buffer = (char*)palloc(MAX_LINESIZE);2) 部分c++编译器不支持const char*到char*的隐式转换,需要做强制类型转换。6 函数声明1) C语言中并没有重载和类这些特性,编译出的符号与C++不同,例如print(int i),不会被编译为_print_int,而是直接编译为_print等。因此如果直接在C++中调用C的函数会失败,例如调用print(3),c++中实际上会去找_print_int(3),这样就会找不到。加上extern “C”,指示编译器这部分代码按C语言来进行编译,而不是C++。extern PGDLLEXPORT Datum orafce_to_char_timestamp(PG_FUNCTION_ARGS); -> extern "C" PGDLLEXPORT Datum orafce_to_char_timestamp(PG_FUNCTION_ARGS);可以通过nm -D so文件查看生成的符号。7 安全函数整改1) 推荐使用安全函数(可见securec.h),并对安全函数的返回值作检查,openGauss定义了几个常用的检查宏,如下。#define check_memcpy_s(r) securec_check_c((r), "", "") #define check_memmove_s(r) securec_check_c((r), "", "") #define check_memset_s(r) securec_check_c((r), "", "") #define check_strcpy_s(r) securec_check_c((r), "", "") #define check_strncpy_s(r) securec_check_c((r), "", "") #define check_strcat_s(r) securec_check_c((r), "", "") #define check_strncat_s(r) securec_check_c((r), "", "") #define check_gets_s(r) securec_check_ss_c((r), "", "") #define check_sprintf_s(r) securec_check_ss_c((r), "", "") #define check_snprintf_s(r) securec_check_ss_c((r), "", "") #define check_scanf_s(r) securec_check_ss_c((r), "", "")下面是安全函数整改的示例。memcpy(d, u, clen); -> check_memcpy_s(memcpy_s(d, strlen(d), u, clen));为了方便和完全地作安全函数整改,这里提供一个查找危险函数的正则表达式。(wmemcpy\()|(wmemove\()|(memmove\()|(wcscpy\()|(wcsncpy\()|(strcat\()|(wcscat\()|(strncat\()|(wcsncat\()|(strtok\()|(wcstok\()|(sprintf\()|(swprintf\()|(vsprintf\()|(vswprintf\()|(snprintf\()|(vsnprintf\()|(vsnprintf_truncated\()|(snprintf_truncated\()|(scanf\()|(wscanf\()|(vscanf\()|(vwscanf\()|(fscanf\()|(fwscanf\()|(vfscanf\()|(vfwscanf\()|(sscanf\()|(swscanf\()|(vsscanf\()|(vswscanf\()|(gets\()|(strcpy\()|(strcpy\()|(strncpy\()|(strncpy\()|(strcat\()|(strncat\()|(memcpy\()|(memcpy\()|(memset\()|(memset\()8 变量转换1) 对比PostgreSQL,openGauss收集了原有的全局变量,将其收集在了g_instance、t_thrd、u_sess(分别是全局变量、线程变量和会话变量)等结构体内,因此需要作相应替换(通过编译报错体现,需要到内核代码层面查看变量具体存放位置)。插件的全局变量可通过nm -D so | grep ‘B’排查。(具体见7.7)econtext = error_context_stack; -> econtext = t_thrd.log_cxt.error_context_stack;2) PG采用进程模型,用户会话进来时会创建一个独立的进程去处理,此时插件定义的全局变量在该进程内就是唯一的会话变量。而openGauss采用线程模型,所有会话共享同一份全局变量,因此需要将全局变量修改为会话变量。对于只读的全局变量,保持原样即可,而对于多次修改的变量,需要作如下修改。a. 如果不考虑在线程池模式下使用插件,将全局变量修改为THR_LOCAL变量,即线程变量,因为用户会话进来会创建一个独立的线程。b. 如果需要线程池,就需要作额外的修改。线程池模式下,一个用户会话可能会切换多个线程,单纯的将全局变量改为线程变量,在切换线程时会丢失对该变量的修改。openGauss提供了插件自定义会话变量的方式,具体实现如下。(以dblink为例)内核侧在u_sess中定义一个指针数组extension_session_vars_array,和标识数组大小的变量extension_session_vars_array_size,数组用于存放插件会话变量的结构体。   typedef struct knl_session_attr_common { … uint32 extension_session_vars_array_size; void** extension_session_vars_array; } knl_session_attr_common;插件侧需定义一个全局的下标变量,用于获取数组元素,并且提供set_extension_index函数,内核侧会调用该函数来设置下标。示例如下。static uint32 dblink_index; void set_extension_index(uint32 index) { dblink_index = index; }此外,插件侧还需要定义步骤1提到的会话变量结构体,存放该插件自身所有的会话变量,以及提供函数init_session_vars,主要是初始化该结构体,并把指针存放在数组的对应下标位置。示例如下。#include "commands/extension.h" typedef struct dblink_session_context { remoteConn* pconn; HTAB* remoteConnHash; } dblink_session_context; void init_session_vars(void) { RepallocSessionVarsArrayIfNecessary(); dblink_session_context* psc = (dblink_session_context*)MemoryContextAllocZero(u_sess->self_mem_cxt, sizeof(dblink_session_context)); u_sess->attr.attr_common.extension_session_vars_array[dblink_index] = psc; psc->pconn = NULL; psc->remoteConnHash = NULL; }最终,在插件使用会话变量时,根据下标到数组中获取对应的结构体指针即可。dblink_session_context* get_session_context() { if (u_sess->attr.attr_common.extension_session_vars_array[dblink_index] == NULL) { init_session_vars(); } return (dblink_session_context*)u_sess->attr.attr_common.extension_session_vars_array[dblink_index]; } void example() { remoteConn* pconn = get_session_context()->pconn; }具体方案实现可见社区PR(https://gitee.com/opengauss/openGauss-server/pulls/1101),插件整改可参考其中对dblink的整改。9 其他除了上述修改点,还存在很多一些较为细节的地方,其中包括有C和C++的差异,例如在C++中new关键字不能作标识符等;大多数还是openGauss和PostgreSQL内核上的差异,下文会对这些差异作详细说明。此外,有些插件可能是基于PG内核新特性开发的,openGauss并不支持,可以考虑将特性整合到插件,必要时修改内核。下面列举openGauss和PostgreSQL(REL_13_STABLE)内核上的差异,第2章中提到该部分需要不断更新完善,目前仅列出极少部分。9.1 API序号API_01PostgreSQLvoid table_close(Relation relation, LOCKMODE lockmode);openGauss#define heap_close(r,l) relation_close(r,l) void relation_close(Relation relation, LOCKMODE lockmode);作用close any relation差异名称不同序号API_02PostgreSQLRelation table_open(Oid relationId, LOCKMODE lockmode)openGaussRelation heap_open(Oid relationId, LOCKMODE lockmode, int2 bucketid=-1);作用open a heap relation by relation OID差异名称不同;openGauss的heap_open增加了一个可选参数bucketid9.2 系统表序号SYSTAB_01系统表pg_class差异openGauss新增字段:reltoastidxid, reldeltarelid, reldeltaidx, relcudescrelid, relcudescidx, relhasoids, relhaspkey, relcmprs, relhasclusterkey, relrowmovement, parttype, relfrozenxid64, relbucket, relbucketkeyPostgreSQL 新增字段:relrowsecurity, relforcerowsecurity, relispopulated, relispartition, relrewrite , relminmxid , relpartbound relkind字段可选值差异:PostgreSQL中用p和I表示分区表和分区索引,openGauss用字段parttype表示。备注具体描述可见《开发者指南》-系统表和系统视图-系统表-PG_CLASS9.3 系统视图序号SYSVIEW_01系统表pg_tables差异openGauss新增字段:tablecreator, created, last_ddl_time PostgreSQL 新增字段:rowsecurity备注具体描述可见《开发者指南》-系统表和系统视图-系统视图-PG_TABLES9.4 系统函数9.5 LOCK9.6 Memory Context9.7 全局变量PostgreSQLopenGauss作用域error_context_stackt_thrd.log_cxt.error_context_stackThreadWalSndCaughtUpt_thrd.walsender_cxt.walSndCaughtUpThreaddisable_costg_instance.cost_cxt.disable_costInstancecpu_tuple_costu_sess->attr.attr_sql.cpu_tuple_costcpu_tuple_cost10 常见错误信息1) 编译安装时报错:dangerous relocation: unsupported relocation解决方法:参考4.2,在Makefile中添加下面一句。override CPPFLAGS :=$(filter-out -fPIE, $(CPPFLAGS)) -fPIC2) 编译安装时报错:error: invalid conversion from ‘void’ to ‘char’ [-fpermissive]解决方法:参考5类型转换3) create extension时报错:could not find function “xxx” in file “xxx.so”解决方法:参考6函数声明。
  • [技术干货] 直播预告 | 12月30日,openGauss与PostgreSQL核心技术解读及优势对比
    直播时间 12月30日 14:00—15:30 由Gauss松鼠会联合墨天轮、openGauss社区共同主办的专题分享之:“openGauss与PostgreSQL核心技术解读及优势对比” 将于本周四(12月30日)震撼登场。活动详情PostgreSQL 全球开发组于 2021-05-20 发布了 PostgreSQL 14 的第一个 beta 版本且目前已经提供了下载。最新版本的PostgreSQL的更新主要体现在负载情况下的性能优化,增加了数据类型和SQL,增强信息监控能力,逻辑复制的性能以及安全方面的强化。而作为基于PostgreSQL而开发的国产数据库领军产品openGauss也在今年9月30日发布了2.1.0的最新版本。市面上对于PostgreSQL及openGauss之间的对比及讨论一直非常热烈。openGauss毫无疑问在很多方面,尤其是内核增强上,规避了PostgreSQL出现的很多问题,但是相比较老牌的数据库产品,也有很多不足和需要继续进步的地方。活动主题本次直播将针对openGauss及PostgreSQL 进行核心技术的解读与对比,从专业的角度来分析双方产品的核心技术以及自身优势,同时也包括对于数据库国产化发展及生态构建的展望。直播福利本次直播给大家准备了超多精美礼物!届时进入直播间即有机会领取!礼物包括:墨天轮定制黑胶晴雨伞墨天轮定制款蓝牙耳机Gauss松鼠会保温杯Gauss松鼠会无线充电宝套装《openGauss数据库核心技术》 活动嘉宾大会议程扫码立即报名扫描二维码或点击文末“阅读原文”即可报名小伙伴们行动起来吧与大咖对话的机会千万别错过~- END -阅读原文
  • [问题求助] Postgresql性能优化求指点
    有进展了,谢谢。
  • [技术干货] 我使用DRS同步MySQL Float类型数据到PostgreSQL,为什么两边数据"不一致"
    最近收到一个客户反馈使用DRS同步后,源库和目标库的数据不一致。数据一致性是DRS的生存之本,团队上下非常重视,收到反馈后马上联系客户了解情况排查原因,最终发现原来是虚惊一场。那么这个“不一致”是怎么产生的?它底层的根本原因又是什么呢?接下来我们一起来挖一挖。 ### 问题现象 客户使用DRS创建了MySQL到PostgreSQL的同步任务,MySQL表中存在一个FLOAT类型的列,DRS任务启动后会在PostgreSQL中对应创建一个FLOAT4的列。同步过程中在MySQL中插入一条FLOAT列值为3.1415926的数据,同步后在源库MySQL中SELECT出来的数据是3.14159,而在目标库PostgrSQL中SELECT出来却是3.1415925。 ### 复现步骤: 1. 在源库建表: ``` CREATE TABLE `float_test` ( `id` int(11) primary key, `id2` float ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ``` 2. 创建DRS任务,同步这张表的数据到PostgreSQL。目标库会自动创建下表: ``` CREATE TABLE "root"."float_test" ( "id" int PRIMARY KEY, "id2" FLOAT4 ) ``` 3. 在源库insert数据: ``` insert into `float_test` values (1, 3.1415926); ``` 4. 数据同步之后 通过mysql客户端查询: ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202110/30/212544xwlhjzvltsvzwq3e.png) 通过postgresql客户端查询: ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202110/30/220225tpxlepjbgjhm6sgi.png) 而通过jdbc查询: mysql: ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202110/30/220318ok6xwp6d82fzlwr3.png) postgresql: ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202110/30/220331oolheuirfknpihww.png) ### 问题原因: mysql底层存储3.1415926的时候,binlog中记录的数据为3.1415925,DRS从binlog中解析出来数据,同步到PostgrSQL的也是3.1415925。 而通过mysql的driver进行select的时候,mysql driver对数据进行了截断,所以查出来是3.14159,而PostgrSQL的driver没有进行截断,导致通过两种driver select出的数据不一致。 如果不想让driver截断,可以在jdbc的url中增加useServerPrepStmts=true的option。
  • [问题求助] 【鲲鹏920产品】【Postgresql功能调优】性能问题分析热点函数
    运行TPCC,perf top 发现热点函数为tts_buffer_heap_getsomeattrs10%ExecInterpExpr 7%ExecParallelHashTableInsert 6%网上未找到相关联的参数能将热点函数消掉,特来鲲鹏论坛求助解答谢谢