• [问题求助] 关于JDBC在不同场景下连接配置问题
    官方的容灾场景的架构配置为:A集群生产3节点 , B集群容灾3节点.如果B集群容灾为单节点JDBC在配置连接串时应如何进行配置  , 假设 node4 为容灾单节点为只读官方的介绍为 : jdbc:gaussdb://node1,node2,node3,node4/database?autoBalance=shuffle如果写成 : jdbc:gaussdb://node1,node2,node3,node4/database?autoBalance=true&priorityServers=3  需求为 : 在JDBC有连接池的情况下 ,优先连接主集群3节点 , 在发生主备切换后自动连接容灾单节点 , 等主集群修复后进行二次切换 , 通过 JDBC 连接串自动连接主集群3节点.
  • [技术解读] GaussDB多模数据库的设计思想
     GaussDB多模数据库的设计思想设计思想:在数据库系统之上提供统一的多模数据管理、处理能力,以及统一运维能力。 多模数据的存储:对于一个统一的多模数据库系统而言,需要提供多种数据模型的存储能力,包括关系、时序、流图、空间等。 多模数据的处理:对于一个统一的多模数据库系统而言,需要提供多种数据库模型的处理能力,包括关系、时序、流图、空间等。 多模数据之间的相关转换:大多数情况下,客户的数据产生源只有一个,即数据产生源的数据模型是单一的,但是后续处理可能需要使用多种模型来表征物理世界,进而进行数据处理,或者需要通过多种模型之间的相互协作来完成单一任务。因此,不同模型之间的数据转换也是极为重要的。 多模数据库系统架构 引入多模数据库统一框架(Multi–Model Database Uniform Framework),为用户提供关 系数据库、图数据库、时序数据库等多模数据库统一数据访问和维护接口,简化运维和应用开发人 员的学习和使用成本,提升了数据使用安全性(数据无须在多个系统之间进行倒换,减少了数据在 网络上暴露的时间)。 
  • [技术解读] GaussDB数据库语法及gsql入门
     一、GaussDB数据库语法入门 之前我们讲了如何连接数据库实例,那连接数据库后如何使用数据库呢?那么我们今天就带大家了解一下GaussDB,以下简称GaussDB的基本语法。  关于如何连接数据库,请戳这里。  学习本节课程之后,您将可以完成创建数据库、创建表及向表中插入数据和查询表中数据等操作。  1、前提条件 •   GaussDB实例正常运行。  •   已通过DAS或gsql连接数据库实例。  2、操作步骤 通过DAS或gsql连接数据库实例。 创建数据库用户。       默认只有创建实例时的管理员用户可以访问初始数据库,您还可以手动创建其他数据库用户帐号。  postgres=# CREATE USER joe WITH PASSWORD "xxxxxxxx";       xxxxxxxx需要替换为指定的密码,当结果显示为如下信息,则表示创建成功。  CREATE ROLE       如上创建了一个用户名为joe,密码为xxxxxxxxx的用户。        如下命令为设置joe用户为系统管理员。  postgres=# GRANT ALL PRIVILEGES TO joe;       使用GRANT命令进行相关权限设置,具体操作请参考GRANT。        引申信息:GaussDB对于用户可以进行灵活的权限控制,想要了解请戳管理用户及权限。  创建数据库。 postgres=#  CREATE DATABASE db_tpcds;       当结果显示为如下信息,则表示创建成功。  CREATE DATABASE       创建完db_tpcds数据库后,就可以按如下方法退出postgres数据库,使用新用户连接到此数据库执行接下来的创建表等操作。当然,也可以选择继续在默认的postgres数据库下做后续的体验。  postgres=#  \q   gsql -d db_tpcds -p 8000 -U joe   Password for user joe:   gsql  compiled at 2020-05-08 02:59:43 commit 2143 last mr 131)   Non-SSL connection (SSL connection is recommended when requiring high-security)   Type "help" for help.       db_tpcds=>  创建表。     创建一个名称为mytable,只有一列的表。字段名为firstcol,字段类型为integer。  db_tpcds=>  CREATE TABLE mytable (firstcol int);        未使用“DISTRIBUTE BY”指定分布列时,系统默认会指定第一列为哈希分布列,且给出提示。系统返回信息以“CREATE TABLE”结束,表示创建表成功。  NOTICE:  The 'DISTRIBUTE BY' clause is not specified. Using 'firstcol' as the distribution column by default.  HINT:  Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column.  CREATE TABLE    向表中插入数据:  db_tpcds=> INSERT INTO mytable values (100);        当结果显示为如下信息,则表示插入数据成功。  INSERT 0 1    查看表中数据:  db_tpcds=> SELECT * from mytable;   firstcol   ----------        100  (1 row)       引申信息:  默认情况下,新的数据库对象是创建在“$user”模式下的,例如刚刚新建的表。关于模式的更多信息请参考创建和管理schema。 关于创建表的更多信息请参见创建和管理表。 除了创建的表以外,数据库还包含很多系统表。这些系统表包含集群安装信息以及GaussDB上运行的各种查询和进程的信息。可以通过查询系统表来收集有关数据库的信息。请参见查看系统表。  二、GaussDB数据库gsql入门 gsql是GaussDB提供在命令行下运行的数据库连接工具,可以通过此工具连接服务器并对其进行操作和维护,除了具备操作数据库的基本功能,gsql还提供了若干高级特性,便于用户使用。  1、基本功能 连接数据库:可以通过gsql远程连接数据库实例。如何使用gsql连接数据库请参考连接实例。 执行SQL语句:支持交互式地键入并执行SQL语句,也可以执行一个文件中指定的SQL语句。 执行元命令:元命令可以帮助管理员查看数据库对象的信息、查询缓存区信息、格式化SQL输出结果,以及连接到新的数据库等。 2、使用指导 步骤 1 使用gsql连接到GaussDB实例。  gsql工具使用-d参数指定目标数据库名、-U参数指定数据库用户名、-h参数指定主机名、-p参数指定端口号信息。  若未指定数据库名称,则使用初始化时默认生成的数据库名称;若未指定数据库用户名,则默认使用当前操作系统用户作为数据库用户名;当某个值没有前面的参数(-d、-U等)时,若连接的命令中没有指定数据库名(-d)则该参数会被解释成数据库名;如果已经指定数据库名(-d)而没有指定数据库用户名(-U)时,该参数则会被解释成数据库用户名。  示例,使用jack用户连接到远程主机postgres数据库的8000端口。  gsql -h 10.180.123.163 -d postgres -U jack -p 8000 详细的gsql参数请参见命令参考。  步骤 2 执行SQL语句。  以创建数据库human_staff为例。  CREATE DATABASE human_staff; CREATE DATABASE 通常,输入的命令行在遇到分号的时候结束。如果输入的命令行没有错误,结果就会输出到屏幕上。  步骤 3 执行gsql元命令。  以列出GaussDB中所有的数据库和描述信息为例。  postgres=#  \l                                 List of databases       Name      |  Owner   | Encoding  | Collate | Ctype |   Access privileges    ----------------+----------+-----------+---------+-------+-----------------------  human_resource | root | SQL_ASCII | C       | C     |   postgres       | root | SQL_ASCII | C       | C     |   template0      | root | SQL_ASCII | C       | C     | =c/root         +                 |          |           |         |       | root=CTc/root  template1      | root | SQL_ASCII | C       | C     | =c/root          +                 |          |           |         |       | root=CTc/root  human_staff    | root | SQL_ASCII | C       | C     |  (5 rows) 更多gsql元命令请参见元命令参考。  3、示例 以把一个查询分成多行输入为例。注意提示符的变化:  postgres=# CREATE TABLE HR.areaS( postgres(# area_ID   NUMBER, postgres(# area_NAME VARCHAR2(25) postgres-# )tablespace EXAMPLE; CREATE TABLE 查看表的定义:  postgres=# \d HR.areaS                Table "hr.areas"   Column   |         Type          | Modifiers  -----------+-----------------------+-----------  area_id   | numeric               | not null  area_name | character varying(25) | 向HR.areaS表插入四行数据:  postgres=# INSERT INTO HR.areaS (area_ID, area_NAME) VALUES (1, 'Europe'); INSERT 0 1 postgres=# INSERT INTO HR.areaS (area_ID, area_NAME) VALUES (2, 'Americas'); INSERT 0 1 postgres=# INSERT INTO HR.areaS (area_ID, area_NAME) VALUES (3, 'Asia'); INSERT 0 1 postgres=# INSERT INTO HR.areaS (area_ID, area_NAME) VALUES (4, 'Middle East and Africa'); INSERT 0 1 切换提示符:  postgres=# \set PROMPT1 '%n@%m %~%R%#' root@[local] postgres=# 查看表:  root@[local] postgres=#SELECT * FROM HR.areaS;  area_id |       area_name         ---------+------------------------        1 | Europe        4 | Middle East and Africa        2 | Americas        3 | Asia (4 rows) 可以用\pset命令以不同的方法显示表:  root@[local] postgres=#\pset border 2 Border style is 2. root@[local] postgres=#SELECT * FROM HR.areaS; +---------+------------------------+ | area_id |       area_name        | +---------+------------------------+ |       1 | Europe                 | |       2 | Americas               | |       3 | Asia                   | |       4 | Middle East and Africa | +---------+------------------------+ (4 rows)   root@[local] postgres=#\pset border 0 Border style is 0. root@[local] postgres=#SELECT * FROM HR.areaS; area_id       area_name         ------- ----------------------       1 Europe       2 Americas       3 Asia       4 Middle East and Africa (4 rows)  使用元命令:  root@[local] postgres=#\a \t \x Output format is unaligned. Showing only tuples. Expanded display is on.   root@[local] postgres=#SELECT * FROM HR.areaS; area_id|2 area_name|Americas   area_id|1 area_name|Europe   area_id|4 area_name|Middle East and Africa   area_id|3 area_name|Asia  三、总结 云数据库 GaussDB各特性版本的功能发布和对应的文档动态,欢迎体验。  GaussDB是华为公司倾力打造的自研企业级分布式关系型数据库,该产品支持优异的分布式事务,同城跨AZ部署,数据0丢失,支持1000+扩展能力,PB级海量存储等企业级数据库特性。拥有云上高可用,高可靠,高安全,弹性伸缩,一键部署,快速备份恢复,监控告警等关键能力,能为企业提供功能全面,稳定可靠,扩展性强,性能优越的企业级数据库服务。  
  • [技术解读] GaussDB关键技术原理:高性能(五)
    GaussDB 关键技术原理:高性能(四)从 USTORE 存储引擎、计划缓存计划技术、数据分区与分区剪枝、列式存储和向量化引擎、SMP 并行执行等五方面对高性能关键技术进行解读,本篇将从 LLVM 动态查询编译执行、SQL-BYPASS 执行优化、线程池化、多核处理器优化、日志无锁刷新与多级流水等方面继续介绍 GaussDB 高性能关键技术,并对高斯数据库性能优化进行总结。3.11 LLVM 动态查询编译执行在传统经典执行器算子中基于遍历树的表达式计算框架,这种框架的好处是清晰明了,但是在性能上却不是最优的,主要有以下几个原因:(1)表达式计算其框架的通用性决定了其执行模式要适配各种不同的操作符和数据类型,因此在运行时要根据其表达式遍历的具体结果来确定其执行的函数和类型,对这些类型的判断要引入非常多的分支判断。(2)表达式计算在整体的执行过程中要进行多次的函数调用,其调用的深度取决于其树的深度,这一部分也有着非常大的开销。这两个核心原因,分支判断和函数调用同样在执行算子中也是影响性能的关键因素,为了提升其执行速度,GaussDB 引入了业界著名的开源编译框架 LLVM(Low Level Virtual Machine)来提速的执行速度,LLVM 是一个通用的编译框架,能够支持不同的计算平台。LLVM 提升整体表达式计算的核心要点如下:(1)GaussDB 内置的 LLVM 编译框架通过为每一个计算单元(表达式或者执行算子里面的热点函数)生成一段独特的执行代码,由于在编译的时候提前知道了表达式涉及的操作和数据类型,为这个表达式生成的执行代码将所有的逻辑内联,完全去除函数调用。GaussDB 内置的 LLVM 编译为这个表达式生成了一段特殊代码。里面已经没有任何其他的函数调用,所有的函数都已经被内联在一起,同时去掉了关于数据类型的分支判断。(2)LLVM 编译框架利用编译技术最大程度的让生成的代码将中间结果的数据存储在 CPU 寄存器里,让数据读取的速度加快。LLVM 通过消除条件逻辑冗余,降低虚函数调用次数,改善数据 locality,可大大降低任务执行代价;LLVM 生成的 machine code 为一次性成本,整个执行过程均可使用,数据量越大,所获取的收益将越大,因此对于一个可以实施 LLVM 动态编译优化的查询,其收益随着数据量的增多会逐步增加,对应的性能提升比例也会越来越大3.12 SQL-BYPASS 执行优化在典型的 OLTP 场景中,简单查询占了很大一部分比例。这类查询本身大多数会走索引、分区剪支、只涉及单表和简单表达式的查询,这类查询的有效数据读取占比在这个查询解析、执行过程中并不大,即便使用计划缓存技术(PBE)把查询解析部分省下来以后,执行器初始化 exec_init_*() 仍然会有比较明显的开销,例如下面火焰图所 profiling 的场景,执行器初始化开销占比超过 40%,并且每个同样的模板查询这部分的操作都是无效的重复开销,有效部分只有 Operator::get_next (),占比只有 15% 左右。因此为了加速这类查询,提出了 SQL-BY-PASS 框架,其核心思想是对执行路径 inline 处理优化,减少不必要的执行器函数迭代的开销,在 parse 层对这类查询做简单的模式判别后,进入到特殊的执行路径里,跳过经典的执行器执行框架,包括算子的初始化与执行、表达式与投影等经典框架,直接重写一套简洁的执行路径,并且直接调用存储接口,这样可以大大加快简单查询的执行速度。以分区表点差举例,通过 SqlByPass 技术将分区表的执行过程进行扁平化 inline 处理,将原来 SQL 执行引擎中很深的调用栈扁平化,性能提升 30%。3.13 线程池化在 OLTP 领域中数据库通常需要处理大量的客户端连接。因此,高并发场景的处理能力是数据库的重要能力之一。对于外部连接最简单的处理模式是 per-thread-per-connection 模式,即来一个用户连接产生一个线程。这个模式好处是架构上处理简单,但是高并发下,由于线程太多,线程切换和数据库轻量级锁区域的冲突过大导致性能急剧下降,使得系统性能(吞吐量)严重下降,无法满足用户性能的 SLA。归纳起来每当面对高并发业务(线程 / CPU 核数比大于 10)场景时,系统通常面临以下几个方面挑战:(1)资源耗尽,由于接入的会话数过多导致消耗过多的内存、连接数资源耗尽产生系统宕机、OOM 等异常,造成系统可用性降低。(2)过度争抢,由于并发数过多而具体 CPU 计算有限,增加了临界区锁、信号量等处理开销,大量资源并未产生客户实际吞吐量。(3)相互影响,如果某一个会话请求占用过多的 CPU、内存资源导致对其他会话资源的挤占,造成单个请求拖垮整个系统的严重问题。因此,对于高并发性能稳定性从本质上分析,数据库系统需要从设计上解耦接入会话数与资源使用量 & 争抢之间的线性耦合关系,同时对极端 “炸弹式” 请求需要有有效的管控措施,将其影响控制在有限的范围内。GaussDB 主要的解决方案过线程资源池化复用的技术来解决该问题。线程池技术的整体设计思想是线程资源池化,并且在不同连接之间复用。系统在启动之后会根据当前核数或者用户配置,启动固定一批数量的工作线程,一个工作线程会服务一到多个连接 session,这样把 session 和 thread 进行了解耦。因为工作线程数是固定的,因此在高并发下不会导致线程的频繁切换,而由数据库层来进行 session 的调度管理。高斯数据库线程池实现主要体现在以下 3 个方面:(1)资源解耦:将接入会话 & 工作线程进行解耦隔离,确保高并发场景下系统资源不会持续增加而是保持稳定。(2)多核优化:在多核场景下考虑到 NUMA 效应,线程池针对工作线程的调度范围根据 NUMA node 进行分配和限制,避免线程的调度跨 numa,降低处理时延提升性能。(3)资源管控:线程池化基础上实现以工作线程为粒度的过载管控,避免单一线程占用过多资源,提升系统可靠性。通过线程池化改进后相比高并发场景下具有明显的性能稳定性,以下是数据库性能稳定性测试,通过标准 OLTP 负载模型(TPCC)的测试结果。并发数MySQL 非线程池GaussDB(线程池)100339,171.29852,701.91200401,879.301,267,780.87400380,815.541,616,192.10600344,775.511,693,294.49800316,093.141,663,179.511600250,559.431,632,902.632400207,585.541,631,816.553200181,735.221,615,253.23总结:在线程池的帮助下数据库系统面对大并发场稳定性、性能两个方面都有明显提升。(1)稳定性:随着并发数增加 MySQL 无线程模式的数据库性能在 CPU 资源满了以后并不会像 GaussDB 这样保持稳定。(2)高性能:数据库线程池化考虑多核 CPU NUMA 亲和以后进一步提升性能,相比 MySQL 有明显优势。3.14 多核处理器优化鲲鹏 ARM 服务器多 CPU-socket 架构下跨 NUMA 内存访问延迟存在严重的不对称,远 / 近端内存访存时延有成倍数差异,同时相比 x86 内存访问时延高 50%、并发控制原语代价高 2-3 倍,在数据库中会以进一步恶化 OLTP 瓶颈,尽管通常在架构下 CPU 物理核心数相比 x86 有了一定提升,但如果不合理设计和实现数据库内核关键数据结构、线程调度模型无法充分利用 ARM 多核的优势,如何优化 NUMA 带来的访问时延问题,如何充分利用众核 CPU 解决并发控制问题成为了鲲鹏上优化数据库 OLTP 负载性能的主要挑战。使用标准事务型负载 TPMC benchmark 测试结果 96 核 x86 135w,128 核 ARM 在 NUMA 优化前只有 110w tpmC 左右。GaussDB Kernel 根据 ARM 处理器的多核 NUMA 架构特点,进行针对性一系列 NUMA 架构相关优化,主要围绕三个方面进行:(1)线程调度访存本地化:减少跨核内存访问的时延问题,让线程调度尽可能在单个 NUMA 节点内,同时针对高频热点数据结构通过适当的冗余保留在本地,减少跨 NUMA 远端内存访问。(2)ARM 多核算力优化:针对鲲鹏 ARM 体系下计算核心多的优势,对数据库查询处理、数据库缓冲区脏页处理、WAL 日志等关键处理流程进行 multi-thread 多级流水线改造,将原有单线程处理流程下发给多个 CPU - 线程进行并行处理提升总体性能。(3)ARM 指令集优化:借助 ARMv8.1 引入的新的原子操作 LSE,将大量的可转换为原子类型操作(plus、minus、CAS)的部分,替换为 ARM 硬件相关原语 LSE 指令集,从而提升多线程间同步性能,例如工作线程 - WAL 写入性能等。3.15 日志无锁刷新与多级流水在写事务型负载中日志落盘位于性能关键路径,为了确保数据可靠性在执行 INSERT、DELETE、UPDATE 等操作均需要记录。经过在多核环境上的性能测试,我们发现日志在 Flush 时存在大量的等待,其本质原因是当前在并发场景下日志落盘环节中很难在 WalInsertLock 数量和锁遍历开销中取得平衡最优解,导致成为瓶颈。上图展示了常见的日志的实现方案,主要可以归纳成 3 个方面:(1)数据库内核线程必须获取日志插入锁 WALInsertLock 才能进入第一个临界区,在临界区中,Backend 线程首先会预留 WAL 的插入位置,然后将生成的 WAL 复制到 WAL Buffer 的对应预留位置中。由于是多个数据库后台线程进行的并发拷贝,每个 Backend 线程拷贝完成的时机并不一致。(2)数据库后台线程需要遍历所有的 WALInsertLock 检查 lsn 是否已经下盘,当 WALInsertLock 的数目越多时,在执行 WAL Flush 之前等待其他 Backend 线程将日志拷贝完成的时间就越长。(3)WALInsertLock 的数目越少时,XLog 插入锁的抢占就越激烈。所以不管 WALInsertLock 的数量如何变化,系统的性能都很难达到最优,这成为了目前日志落盘的瓶颈。GaussDB 针对 WalInsertLock 日志锁进行优化,利用 LSN(Log Sequence Number)及 LRC(LogRecord Count)记录了每个 backend 的拷贝进度,取消 WalInsertLock 机制。在 backend 将日志拷贝至 WalBuffer 时,不用对 WalInsertLock 进行争抢,可直接进行日志拷贝操作。并利用专用的 WalWriter 写日志线程,不需要 backend 线程自身来保证 xLog 的 Flush。通过以上优化,取消 WalInsertLock 争抢及 WalWriter 专用磁盘写入线程,在保持原有 xLog 功能不变的基础上,可进一步提升系统性能。针对 Ustore Inplace update WAL log 写入,Ustore DML operation 并行回放分发进行优化。通过利用 prefix 和 suffix 来减少 update WAL log 的写入。通过把回放线程分多个类型,解决 Ustore DML WAL 大多都是多页面回放问题。同时把 Ustore 的数据页面回放按照 blkno 去分发,更好的提高并行回放的并行程度。Ustore 存储引擎…4 高斯数据库性能优化总结高斯数据库 GaussDB 华为公司过去 10 年打造的一款高性能 OLTP 交易型数据库产品,在迭代演进过程当中吸纳当今主流数据的技术与思路,确保架构和演进层面的领先性,在达到高性能的同时能够保证事务的强一致性,在国内泛金融领域、保险、等主要行业、公司内部 ERP 等有广泛的应用和成功落地实践。首先,高斯数据库从架构层面需要保证处理能力可持续提升、可横向扩展,避免某一单点问题阻碍上限的提升,因此最初架构演进上就做过深入的考虑,因此在相同代码基础上同时具备分布式、集中式两种不同的部署形态,这里集中式部署形态决定了单节点(单分片)的性能上限,而分布式将多个数据分片结合到一起通过横向扩展提升总体上限。因此从产品架构维度上看,高斯数据库的高性能技术点可分成集中式、分布式两个优化维度。(1)集中式性能维度,主要聚焦数据库进程内的算法实现,其目标在于将节点内有限计算资源有效最大化利用。首先,从查询执行算法的宏观维度,优化器通过查询重写、CBO/ABO 代价模型确保查询整体执行步骤最优;其次,执行引擎将执行计划内的每个算子执行效率发挥出来,通过节点内 SMP 对称多线程并行处理技术将多核 CPU 资源加以利用实现处理任务时序在时间维度重叠达到提升,通过算子 Vec 向量化、CodeGen/LLVM 化等技术实现局部编译器执行,确保了 CPU 指令集微观层的优化效果,此外集中式场景还考虑单节点大容量数据场景,执行层面提供了丰富可选数据分区策略(Range、List、Hash、Interval、二级组合分区)能够根据用户业务的定义对数据查询范围进行数量级的裁剪,通过 ustore 存储引擎确保读写混合负载长稳性能以及空间节省,同时为了保证数据的强一致性处理 WAL 日志落盘也进行了异步流水化改造提升单位时间内日志持久化落盘的速率,进而提升读写事务的性能。再次,在性能稳定性层面,同样做了线程池化、内存共享化改造能够确保并发线程在内存、CPU 调度之间得到平衡,能够在极致并发场景下如 5x(相对满负荷负载并发)并发性能不显著下降,十倍甚至百倍并发系统不崩溃,并已在公司 MetaERP 项目中得到过实战检验。(2)分布式性能维度,主要聚焦多数据分片汇聚线性度确保性能可横向扩展,在高斯数据库里实现了 CN 轻量化技术、分布式单分片事务降低 CN 路由和本地事务处理开销能够在 256 大集群内线性度达 0.85 以上,对于分布式事务提供了轻量化全局事务 GTM-lite 技术能够让分布式事务开销进一步降低,在标准 TP 点查负载模型下 32 节点以内线性度达到 0.9 以上。分布式大数据量处理处理场景下,分布式优化器能够基于全据统计信息合理生成分布式查询计划确保在数据搬迁 - 本地计算量两个维度获得最优解,实现跑批处理的高效性,分布式执行框架串联多个分片计算单元在分片间实现并行计算,实现节点内 - 节点间的双重并行叠加最大化分布式系统的资源利用率,在数据分布层面同样提供 HASH、LIST、RANGE 分布策略供客户应用场景进行选择,实现了分布 - 集中式分区两个维度的数据分片能力叠加,极大提升了大数据量场景下的数据剪枝优化能力,并在 CBG、邮储等核心业务系统中得到实战检验其次,为了确保高斯数据库性能易用性,针对历史版本升级、异常场景下的逃生策略同样做了一些列性能辅助特性,例如 SPM 计划管理、SQL-PATCH 能够在版本升级、系统迁移、统计信息突变场景下对已有 optimal 计划起到保护作用,避免计划跳变导致的性能劣化,基于线程调度抗过载逃生能有效控制慢查询等 “性能炸弹” 进行有效隔离,在企业应用的一些边界极端场景确保数据库性能 SLA 达成。回顾过去,GaussDB 在演进迭代过程中积极吸取了时下关系型数据库、分布式数据库的设计与优化方案,在短短的 10 年内走完了 A 国友商 40 年的演进历程,同时并未对分布式 TP/AP 系统的复杂性妥协,在确保单节点性能领先的前提下仍然可通过分布式提升整体的性能上限并具备 0.85 + 不错线性扩展比。放眼未来,随着计算机软硬件、OS / 编译器 / 网络协议等基础软件不断革新,高斯数据库性能优化也扎根到与之相结合的新高度,在近年出现的多核 128/256 多核 CPU,鲲鹏 /x86 体系结构相关背景下基于多核 NUMA 的优化方案也在产品里落地商用,其中鲲鹏 2/4 路 180w/230w tpmC、32 节点 1600w tpmC 的优势更是在友商性能性能比拼测试中获胜,此外还进行编译器相结合的优化,基于毕昇编译器的 PGO、LTO、BOLT、静态编译优化等手段已在局点实战比拼中提升已有上限的 20-30%,进一步巩固领先优势并在可预见的将来落地商用版本。欢迎小伙伴们交流~
  • [技术解读] GaussDB关键技术原理:高性能(四)
    GaussDB关键技术原理:高性能(三)从查询重写RBO、物理优化CBO、分布式优化器、布式执行框架、轻量全局事务管理GTM-lite等五方面对高性能关键技术进行了解读,本篇将从USTORE存储引擎、计划缓存计划技术、数据分区与分区剪枝、列式存储和向量化引擎、SMP并行执行等方面继续介绍GaussDB高性能关键技术。3.6 USTORE存储引擎GaussDB新增的Ustore存储引擎,相比于Append Update(追加更新)行存储引擎,Ustore存储引擎可以提高数据页面内更新的HOT UPDATE的垃圾回收效率,有效减少多次更新元组后存储空间占用的问题。设计原理上Ustore存储引擎采用NUMA-aware的Undo子系统设计,使得Undo子系统可以在多核平台上有效扩展;同时采用多版本索引技术,解决索引清理问题,有效提升了存储空间的回收复用效率。Ustore存储引擎结合Undo空间,可以实现更高效、更全面的闪回查询和回收站机制,能快速回退人为“误操”为GaussDB Kernel提供了更丰富的企业级功能。Ustore基于Undo回滚段技术、页面并行回放技术、多版本索引技术、xLog无锁落盘技术等实现了高可用高可靠的行存储引擎。USTORE存储引擎作为原有ASTORE存储引擎的替代者其核心目标定位于:(1)针对OLTP场景,实现Inplace-update,利用Undo实现新旧版本分离存储;降低类似于AStore存储引擎由于频繁更新或闪回功能开启导致的数据页空间膨胀,以及相应的索引空间膨胀。(2)通过在DML操作过程中执行动态页面清理,去除VACUUM依赖,减少由于异步数据清理产生的大量读写I/O。通过Undo子系统,实现事务级的空间管控,旧版本集中回收。(3)对插入、更新、删除等各种负载的业务,性能和资源使用表现相对平衡。在频繁更新类的业务场景中,更新操作采用原地更新模式,可以获得更高、更平滑的性能表现。适合“短”(事务短)、“频”(更新操作频繁)、“快”(性能要求高)的典型 OLTP类业务场景3.7 计划缓存计划技术数据库接收到SQL语句后通常要经过如下处理:词语法解析->优化重写->生成执行计划-> 执行,从开始解析到计划生成其实是一个比较耗时的过程,一个常用的思想就是将计划缓存下来,当执行到相似的SQL时,从而可以复用计划,跳过SQL语句生成执行计划的整个过程,在一般OLTP业务负载中,由于涉及到的数据量较少,同时借助索引技术能够大大加速数据的访问路径,因此查询的解析、重写、优化阶段占比会比价高,如果能够讲一些模板性质的语句计划缓存起来,每次设置不同的参数那么点查询的处理流程能够大大简化,提升查询时延和并发吞吐量。计划缓存技术:当数据库收到一条 SQL 请求后,首先会通过查询即系模块对 SQL 文本做一次快速参数化处理,参数化处理的作用是把 SQL 文本中的常量参数替换成通配符 ?,例如 SELECT * FROM t1 WHERE c1 = 1 会被替换为 SELECT * FROM t1 WHERE c1 = ?。接着数据库会从计划缓存中查看有没有已经生成好的计划给这条参数化后的 SQL 使用。如果找到了可用的计划,数据库就会直接执行这个计划。如果没有找到可用的计划,数据库会重新为这条 SQL 生成执行计划,并把生成好的计划保存到计划缓存中以备后续的 SQL 使用。通常情况下从计划缓存中直接获取执行计划相比于重新生成执行计划,耗时通常会低至少一个数量级,因此使用计划缓存可以大大降低获取执行计划的时间,从而减少 SQL 的响应时间。上图为对比走计划缓存、不走计划缓存的SQL执行过程,可以看到执行待计划缓存的查询语句可以规避掉大量的处理逻辑,在OLTP并发负载场景下提升效果镜像,首先,事务型负载单条查询执行时间本身就在毫秒级ms,查询解析、RBO/CBO优化等一些列过程也是毫秒级往往会超过查询本身的执行时间,另一方面,查询解析、RBO/CBO本身是消耗CPU计算资源的操作,这对事务型高并发、高吞吐的事务型复杂起来说非常明显的资源占用,如果能将这部分资源剩下、同时将查询解析的时延消减为0对整体性能是非常明显的提升3.8 数据分区与分区剪枝在数据系统中,数据分区是在一个实例内部按照用户指定的策略对数据做进一步的数据切分,将表按照指定规则划分为多个数据互不重叠的部分。从数据分区的角度来看是一种水平分区(horizontal partition)分区策略方式。分区表增强了数据库应用程序的性能、可管理性和可用性,并有助于降低存储大量数据的总体拥有成本。分区允许将表、索引和索引组织的表细分为更小的部分,使这些数据库对象能够在更精细的粒度级别上进行管理和访问。GaussDB Kernel提供了丰富的分区策略和扩展,以满足不同业务场景的需求。由于分区策略的实现完全由数据库内部实现,对用户是完全透明的,因此它几乎可以在实施分区表优化策略以后做平滑迁移,无需潜在耗费人力物力的应用程序更改:(1)改善查询性能,对分区对象的查询可以仅搜索自己关心的分区,提高检索效率(2)增强可用性,如果分区表的某个分区出现故障,表在其他分区的数据仍然可用。(3)方便维护,如果分区表的某个分区出现故障需要修复数据,只修复该分区即可。常见数据库支持的分区表为范围分区表、列表分区表、哈希分区表、间隔分区、组合分区(a.w.k 组合分区)。(1)范围分区(Range Partition):将数据基于范围映射到每一个分区,这个范围是由创建分区表时指定的分区键决定的。这种分区方式是最为常用的。范围分区功能,即根据表的一列或者多列,将要插入表的记录分为若干个范围(这些范围在不同的分区里没有重叠),然后为每个范围创建一个分区,用来存储相应的数据。(2)列表分区(List Partition):将数据基于各个分区内包含的键值映射到每一个分区,分区包含的键值在创建分区时指定。列表分区功能,即根据表的一列,将要插入表的记录中出现的键值分为若干个列表(这些列表在不同的分区里没有重叠),然后为每个列表创建一个分区,用来存储相应的数据。(3)哈希分区(Hash Partition):将数据通过哈希映射到每一个分区,每一个分区中存储了具有相同哈希值的记录。(4)间隔分区(Interval Partition):可以看成是范围分区的一种增强和扩展方式,相比之下间隔分区定义分区时无需为新增的每个分区指定上限和下限值,只需要确定每个分区的长度,实际插入的过程中会自动进行分区的创建和扩展。间隔分区在创建初始时必须至少指定一个范围分区,范围分区键值确定范围分区的高值称为转换点,数据库为值超出该转换点的数据自动创建间隔分区。每个区间分区的下边界是先前范围或区间分区的非包容性上边界。(5)二级分区(Sub Partition,也叫组合分区)是基本数据分区类型的组合,将表通过一种数据分布方法进行分区,然后使用第二种数据分布方式将每个分区进一步细分为子分区。给定分区的所有子分区表示数据的逻辑子集。常见的二级分区组合由Range、List、Hash组成。分区表对查询性能最大的贡献是分区剪枝优化技术,数据库SQL引擎会根据查询条件,只扫描特定的部分分区。分区剪枝是自动触发的,当分区表查询条件符合剪枝场景时,会自动触发分区剪枝。根据剪枝阶段的不同,分区剪枝分为静态剪枝和动态剪枝,静态剪枝在优化器阶段进行,在生成计划之前,数据库已经知道需要访问的分区信息;动态剪枝在执行器阶段进行(执行开始/执行过程中),在生成计划时,数据库并不知道需要访问的分区信息,只是判断“可以进行分区剪枝”,具体的剪枝信息由执行器决定。注意,分区表由于相比普通表多了一层分区选择的处理逻辑,一般而言在数据导入场景下会有一定的性能损耗。3.9 列式存储和向量化引擎传统关系型数据库中对数据模式都是以元组(记录)的形式进行理解和存取,但是在大数量偏分析类的OLAP应用场景中,属于以列方式存储能够获得更高的执行效率,GaussDB Kernel支持行存储和列存储两种存储模型,用户可以根据应用场景,建表的时候选择行存储还是列存储表。一般情况下,如果表的字段比较多(大宽表),查询中涉及到的列不是很多,适合列存储;如果表的字段个数比较少查询大部分字段,那么选择行存储比较好,以下是行存表、列存表在存储模型上的对比。可以看到通常在大宽表、数据量比较大的场景中,查询少数特定的列、行时,行存引擎查询性能比较差。例如单表有200~800个列,经常查询访问的仅其中10个列,在这种情况下,向量化执行技术和列存储引擎可以极大地提升性能,减少存储空间。向量化执行引擎针对数据的列式存储,GaussDB在执行层改进了传统的执行引擎数据流遵循一次一元组的VectorBatch模式,而向量化引擎VectorEngine将这个执行器算子数据传递、计算模型改成VectorBatch模式,这种看似简单的修改却带来非常明显的性能提升。其中的主要提升原因可以应对上面介绍的CPU架构里影响性能的几个关键因素:(1)Batch模式的函数模型在控制流的调动下,每次都需要进行函数调用,调用次数随着数据增长而增长,而一批元组的模式则大大降低了执行节点的函数调用开销,如果我们设定Batch元组数量为1000,函数调用相对于一次一元组能减少三个数量级。(2)VectorBatch模式在内部实现通过数组来表达,数组对于CPU的预取非常友好,能够让数组在后续的数据处理过程中,大概率能够在CACHE中命中。比如对于下面这个简单计算两个整形加法的表达式函数(其代码仅为了展示,不代表真实实现),下面展示了单元组和VectorBatch元组的两种写法。单元组的整形加法int int4addint4(int4 a, int b){return a+b;}VectorBatch模式的整型加法void int4addint4(int4 a[], int b[], int res[]){for(int i = 0; i < N; i++){res[i] = a[i] + b[i];}}(3)VectorBatch模式计算函数内部因为CPU CACHE的局部性原理,数据和指令的cache命中率会非常好,极大提升处理性能,同时也为数据数组化的组织方式为利用SIMD特性带来了非常好的机会,SIMD能够大大提升在元组上的计算性能,还是以刚才上述整形加法的例子,我们可以重写上述的函数如下。可以看到,由于SIMD可以一次处理一批数据,循环的次数衰减,性能能得到进一步提升。void int4addint4SIMD(int4 a[], int b[], int res[]){for(int i = 0; i < N/SIMDLEN; i++){res[i..i+SIMDLEN] = SIMDADD(a[i..i+SIMDLEN], b[i..i+ SIMDLEN];}}在当前GaussDB里向量化引擎和普通行存引擎共存对上上层用户透明,行引擎处理单元TupleSlot与向量化引擎处理单元VectorBatch通过行转列Row2Vec、列转行Vec2Row进行在线转换,因此在复杂查询中涉及到行存、列存表时优化器能够结合代价模型并针对一些典型场景判断使用向量化引擎、行存引擎进行处理将资源利用最大化。3.10 SMP并行执行GaussDB Kernel的SMP并行技术是一种利用计算机多核CPU架构来实现多线程并行计算,以充分利用CPU资源来提高查询性能的技术。在复杂查询场景中,单个查询的执行较长,系统并发度低,通过SMP并行执行技术实现算子级的并行,能够有效减少查询执行时间,提升查询性能及资源利用率。SMP并行技术的整体实现思想是对于能够并行的查询算子,将数据分片,启动若干个工作线程分别计算,最后将结果汇总,返回前端。SMP并行执行增加数据交互算子(Stream),实现多个工作线程之间的数据交互,确保查询的正确性,完成整体的查询。并行技术是提升数据库处理能力的有效手段,关于并行技术GaussDB总体升分成了两个大类:(1)提升单节点ScaleUp:决定整体系统的理论性能上限,充分发挥单节点CPU、内存资源的对业务输出的贡献程度。(2)提升分布式ScaleOut:决定整体系统的实际性能上限,分布式实现的好坏决定了横向的线性扩展比。SMP对称多处理的实现过程:(1)SMP计划生成:一阶段计划生成:在路径生成阶段,加入并行路径,最终根据代价,决定所选择的计划两阶段计划生成:第一步生成原有的串行计划,第二步在将串行计划改造成适应并行的计划。(2)SMP执行过程:为并行执行线程之间进行数据分配、交换和汇总(Scan类:磁盘;stream:网络)。SMP对称多处理自适应选择SMP优化执行对当前执行的资源环境因素相关,因此 不同的硬件环境、不同系统负载的情况下可用的计算资源存在差异,不同时刻特定查询复杂度需要的计算资源也存在不同;自适应SMP目标在于基于当前系统可用资源以及可生成SMP计划的情况,综合判定查询的执行计划。SMP自适应分为两个阶段,第一阶段确定初始dop,第二阶段对基于初始dop生成的计划进行优化。在第一阶段考虑CPU资源、串行还是并发。在第二阶段考虑计划复杂程度。(1)资源情况:CPU core:服务器CPU core 数量 / 服务器部署DN数量;串行/并发:可用CPU core * (1 – CPU usage)。(2)查询复杂度:执行计划被stream算子拆分成多个片段,每个片段由一个线程执行。该计划中,有多少stream可以无阻塞的运行,决定了整个计划的最大并行线程数。采用特征匹配来识别查询复杂度。以上内容从USTORE存储引擎、计划缓存计划技术、数据分区与分区剪枝、列式存储和向量化引擎、SMP并行执行等五方面对高性能关键技术进行了分享,下篇将从LLVM动态查询编译执行、SQL-BYPASS执行优化、线程池化、多核处理器优化、日志无锁刷新与多级流水等方面继续解读GaussDB高性能关键技术,并对高斯数据库性能优化进行总结,敬请期待!
  • [问题求助] 外网访问 Gaussdb HA port 8001端口,放开了安全组限制还是报错
    报错信息:外网访问 Gaussdb8 HA port 8001端口,放开了安全组限制,还是报错,org.postgresql.util.PSQLException: FATAL: no gs_hba.conf entry for replication connection from host "115.204.12.51", user "root", SSL off         at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:525)         at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:146)         at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:206) 疑问:没有找到地方能让我修改 gs_hba.conf 文件放开外网ip访问数据库replication connection限制
  • [技术解读] GaussDB数据库SQL系列-触发器
    一、前言GaussDB是一个高度可靠、可扩展、高性能的数据库管理系统,用于支持企业级应用、数据仓库、数据科学和实时分析等场景。它提供了丰富的功能和工具,以帮助开发和管理员有效地管理数据。在GaussDB中,触发器是一种重要的数据库对象,用于在满足特定条件时自动触发预定义的操作。通过使用触发器,您可以实现数据的实时监控、验证、日志记录和其他自动化任务。本篇文章将介绍GaussDB数据库中触发器的基本概念、创建以及示例,并简要总结触发器的优缺点。二、触发器概念触发器是GaussDB数据库中的一种数据库对象,它是一种自动触发的SQL代码块,用于在满足特定条件时执行预定义的操作。触发器可以用于监控数据库中的数据变化、实施业务规则、日志记录等。与存储过程不同,触发器是自动触发的,无需显式调用。三、GaussDB数据库中的触发器创建一个触发器。 触发器将与指定的表或视图关联,并在特定条件下执行指定的函数。1、语法格式CREATE [ CONSTRAINT ] TRIGGER trigger_name{ BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] } ON table_name[ FROM referenced_table_name ]{ NOT DEFERRABLE | [ DEFERRABLE ] { INITIALLY IMMEDIATE | INITIALLY DEFERRED } }[ FOR [ EACH ] { ROW | STATEMENT } ][ WHEN ( condition ) ]EXECUTE PROCEDURE function_name ( arguments );主要参数说明:CONSTRAINT:可选项,指定此参数将创建约束触发器,即触发器作为约束来使用。除了可以使用SET CONSTRAINTS调整触发器触发的时间之外,这与常规触发器相同。 约束触发器必须是AFTER ROW触发器。trigger_name:触发器名称,该名称不能限定模式,因为触发器自动继承其所在表的模式,且同一个表的触发器不能重名。 对于约束触发器,使用SET CONSTRAINTS修改触发器行为时也使用此名称。命名规范:符合标识符命名规范的字符串,且最大长度不超过63个字符。BEFORE:触发器函数是在触发事件发生前执行。AFTER:触发器函数是在触发事件发生后执行,约束触发器只能指定为AFTER。INSTEAD OF:触发器函数直接替代触发事件。event:启动触发器的事件,取值范围包括:INSERT、UPDATE、DELETE或TRUNCATE,也可以通过OR同时指定多个触发事件。table_name:需要创建触发器的表名称。取值范围:数据库中已经存在的表名称。referenced_table_name:约束引用的另一个表的名称。 只能为约束触发器指定,常见于外键约束。由于当前不支持外键,因此不建议使用。取值范围:数据库中已经存在的表名称。DEFERRABLE | NOT DEFERRABLE:约束触发器的启动时机,仅作用于约束触发器。这两个关键字设置该约束是否可推迟。INITIALLY IMMEDIATE | INITIALLY DEFERRED:如果约束是可推迟的,则这个子句声明检查约束的缺省时间,仅作用于约束触发器。FOR EACH ROW | FOR EACH STATEMENT:触发器的触发频率。FOR EACH ROW是指该触发器是受触发事件影响的每一行触发一次。FOR EACH STATEMENT是指该触发器是每个SQL语句只触发一次。未指定时默认值为FOR EACH STATEMENT。约束触发器只能指定为FOR EACH ROW。condition:决定是否实际执行触发器函数的条件表达式。当指定WHEN时,只有在条件返回true时才会调用该函数。function_name:用户定义的函数,必须声明为不带参数并返回类型为触发器,在触发器触发时执行。arguments:执行触发器时要提供给函数的可选的以逗号分隔的参数列表。参数是文字字符串常量,简单的名称和数字常量也可以写在这里,但它们都将被转换为字符串。 请检查触发器函数的实现语言的描述,以了解如何在函数内访问这些参数。2、创建步骤1)确定触发器的目的和条件:首先,您需要确定触发器的目的和条件。这包括确定您希望在什么情况下触发触发器(例如,在插入、更新或删除数据时)以及触发器的具体条件(例如,仅在特定时间或特定用户执行操作时触发)。2)编写触发器的代码:根据您的需求,编写触发器的SQL代码。这可以包括SELECT、INSERT、UPDATE、DELETE等语句以及逻辑控制语句(例如IF语句)。3)定义触发器的参数:定义触发器的参数,例如要监控的表、触发时机(BEFORE/AFTER)、触发事件(INSERT/UPDATE/DELETE)等。4)创建触发器:使用CREATE TRIGGER语句创建触发器,并指定上述定义好的参数和代码。3、注意事项当前仅支持在普通行存表上创建触发器,不支持在列存表、临时表、unlogged表等类型表上创建触发器。如果为同一事件定义了多个相同类型的触发器,则按触发器的名称字母顺序触发它们。执行触发器语句时是用触发器创建者的身份进行权限判断的。执行创建触发器操作的用户需要拥有指定表的TRIGGER权限或被授予了CREATE ANY TRIGGER权限。触发器常用于多表间数据关联同步场景,对SQL执行性能影响较大,不建议在大数据量同步及对性能要求高的场景中使用。4、附:表和视图上支持的触发器种类触发时机触发事件行级语句级BEFOREINSERT/UPDATE/DELETE表表和视图TRUNCATE不支持表AFTERINSERT/UPDATE/DELETE表表和视图TRUNCATE不支持表INSTEAD OFINSERT/UPDATE/DELETE视图不支持TRUNCATE不支持不支持四、GaussDB数据库中的示例示例一、在GaussDB数据库中创建一个触发器,以便在插入新记录时自动将记录的创建时间设置为当前时间。以下是一个简单的示例,演示了如何在GaussDB数据库中创建一个触发器,以便在插入新记录时自动将记录的创建时间设置为当前时间。--定义一个触发器函数,用于设置创建时间字段的值:CREATE OR REPLACE FUNCTION set_created_at()RETURNS TRIGGERAS $$BEGINNEW.date = NOW();RETURN NEW;END$$LANGUAGE plpgsql;--创建一个INSERT触发器CREATE TRIGGER set_created_at_triggerBEFORE INSERT ON test_1FOR EACH ROWEXECUTE PROCEDURE set_created_at();--执行INSERT触发事件并检查触发结果INSERT INTO test_1 VALUES(6,'');SELECT * FROM test_1;说明:1、其中test_1为测试表,date为测试表的字段名。2、NEW是一个特殊的关键字,代表正在插入的新记录。当一个触发器被触发时,例如在INSERT操作发生时,NEW可以用来引用正在被插入的新记录。这样,你就可以在触发器中使用NEW来引用正在进行操作的数据。3、参数“BEFORE”、“FOR EACH ROW”等可参见上文语法参数说明。示例二、在GaussDB数据库中创建一个触发器,当向测试表test_1中INSERT 数据的时候,同时向测试表test_2中插入相同的数据。以下是在GaussDB数据库中创建一个触发器,当向测试表test_1中INSERT 数据的时候,触发器被触发,并向测试表test_2中插入相同的数据。--创建触发器函数CREATE OR REPLACE FUNCTION tri_insert_func()RETURNS TRIGGERAS $$DECLAREBEGININSERT INTO test_2 VALUES(NEW.id, NEW.date);RETURN NEW;END$$LANGUAGE PLPGSQL;--创建INSERT触发器CREATE TRIGGER insert_triggerBEFORE INSERT ON test_1FOR EACH ROWEXECUTE PROCEDURE tri_insert_func();--执行INSERT触发事件并检查触发结果INSERT INTO test_1(id,date) VALUES(1,current_timestamp);SELECT *, 'test_1' as table_n FROM test_1UNION ALLSELECT *, 'test_2' as table_n FROM test_2;说明:同示例一。更多示例可参见官方文档。五、小结GaussDB数据库中的触发器是一种强大的工具,可用于自动化数据处理、数据验证、日志记录等任务。通过使用触发器,您可以提高数据一致性、减少数据冗余、实施业务规则并增强数据安全性。本文介绍了GaussDB数据库中触发器的基本概念、创建步骤和示例。希望能够帮助您更好地了解和使用GaussDB中的触发器功能。——结束
  • [开发应用] 关于查询DWS 已建表字段信息
    最近在开发工具脚本时,想要获取已建表的字段信息,比如类型,长度问题。现在通过 information_schema.columns 获取字段元数据。发现查询这个系统视图时发现时慢时快,快的时候25秒左右,慢的时候在3-4分钟。后来通过查看产品文档,通过关联几个系统表,整理一份sql,发现字段定义的长度和建表时的ddl存在差异。发现varchar类型的定义长度是atttypmod -4 其他是date ,timestamp,numeric  等类型更是看不懂了。sql:select t1.*from pg_attribute t1inner join pg_class t2on t1.attrelid = t2.oidinner join pg_namespace t3on t2.relnamespace = t3.oidinner join pg_type t4on t1.atttypid=t4.oidwhere t1.attnum>=0 and t2.relname = 'tablename' and t3.nspname='schemaname'order by t1.attnum;有没有熟悉的大神、老师,帮忙解释一下。或者告知其他的方法。
  • [技术干货] 数据库存储管理
    我们以清华大学李国良老师的书《数据库管理系统——从基本原理到系统构建》作为教材,自底而上讲述元组存储、磁盘块、文件存储方式。最后以GaussDB为例,讲述了商用数据库中元组、磁盘块、文件存储方式。讲座面向2024数据库管理系统设计赛的同学。课件和视频链接: https://pan.baidu.com/s/121W3KFQ9apljdA_8AbXeVg?pwd=dr8h 提取码: dr8h
  • [技术干货] 数据库查询执行算法讲解
    我们以清华大学李国良老师的书《数据库管理系统——从基本原理到系统构建》作为教材,讲述 GaussDB 数据库中 SQL 查询执行的算法。包含一元运算符:投影、选择。二元运算符:关系交、并、连接。算法的趟数:一趟算法、两趟算法。以 GaussDB为实践环节,利用 Explain 命令查看执行计划,了解这些算法。链接: https://pan.baidu.com/s/1Ni87TEWX8Hy8Hm6piyGVWw?pwd=s8ez 提取码: s8ez
  • [技术干货] Java连接GaussDB数据库
    以 GaussDB 为实践环境,以社交网络为应用背景,设计了 26 道 SQL 供学生练习。题目分为简单、思考和挑战。同学们尝试利用结对编程解决一些难度较大的 SQL。其次利用 IDEA,开发相应的应用,实现数据库的连接、动态 SQL 的绑定。学生掌握利用Navicat连接数据库的方法,SQL 中大写字母的处理。发现arm 版的驱动支持 MAC M1 芯片。详细内容见链接: https://pan.baidu.com/s/1EHIZDJ7BJcH8hr42lXt7KQ?pwd=tkmp 提取码: tkmp。
  • [技术干货] 关系连接算法以及 SQL 单表查询计划分析
    CMU数据库的第1讲介绍了数据库中的连接算法,本次讲座详细讲述数据库中块连接算法、排序归并连接、Hash连接。以 GaussDB 为实践环节,编写了随机生成字符串、时间戳的函数,向 Wechat 数据库中 Userinfo 表中插入100 条记录,10000 条记录,分析 SQL 语句的查询计划。创建单字段索引,组合索引,分析不同的 SQL 语句的查询计划。同一个 SQL 不同的条件,查询计划也不相同。详细的课件见链接: https://pan.baidu.com/s/1XnBDAyQibIrjppoHo0hLOQ?pwd=va2b 提取码: va2b。
  • [问题求助] 设置字段宽度
    gsql中是否能设置查询表的字段宽度? 类似与Oracle中的 col的方式
  • GaussDB支持自定义聚合函数能在分布式版本运行吗
    GaussDB支持自定义聚合函数能在分布式版本运行吗
  • [技术解读] 【GaussDB技术解读】GaussDB数据库关键技术原理文章集合,宝藏内容值得收藏
    序号标题1GaussDB技术解读——GaussDB架构介绍(一)2GaussDB技术解读——GaussDB架构介绍(二)3GaussDB技术解读——GaussDB架构介绍(三)4GaussDB技术解读——GaussDB架构介绍(四)5GaussDB技术解读——GaussDB架构介绍(五)6GaussDB关键技术原理:高性能(一)7 GaussDB关键技术原理:高性能(二)8GaussDB关键技术原理:高性能(三)9GaussDB关键技术原理:高性能(四)10GaussDB关键技术原理:高性能(五)11GaussDB关键技术原理|高可用:DCF&双集群容灾12GaussDB关键技术原理|高可用:逻辑复制13GaussDB关键技术原理|高可用:两地三中心跨Region容灾14GaussDB关键技术原理:高弹性(一)15GaussDB关键技术原理:高弹性(二)16GaussDB关键技术原理:高弹性(三)17GaussDB关键技术原理:高弹性(四)18GaussDB关键技术原理:高弹性(五)19GaussDB关键技术原理:高弹性(六)20GaussDB高智能--数据库智能化发展史&自治运维技术21GaussDB高智能--自治运维技术(中)
总条数:1672 到第 页
上滑加载中