Greenplum Database 管理员指南 (V6.2.1) - 2

 

  Index      Manuals     Greenplum Database 管理员指南 (V6.2.1)

 

Search            copyright infringement  

 

   

 

   

 

Content      ..      1      2      3      ..

 

 

 

Greenplum Database (V6.2.1) - 2

 

 

Greenplum Database 管理员指南 V6.2.1
性限制这个让编者有点难以接受期待该功能的改进。
基于角色的资源组会从逻辑上根据 CONCURRENCY 属性划分等量的槽位同时会
为这些槽位配额相同百分比的内存资源如果 MEMORY_LIMIT 属性为 0内存资源的
管理方式将与资源队列的方式相同(很多时候这也是资源队列升级到资源组的最平滑
的过渡方式)
基于角色的资源组 CONCURRENCY 属性的缺省值为 20
在资源组中并发事务数量达到并发事务数限制(CONCURRENCY)任何提交的
事务都将排队当正在执行的事务完成之后在有充足内存资源的情况下数据库将开
始执行最早排队的事务。
可以通过设置 GUC 参数 gp_resource_group_bypass TRUE 绕过资源组的
并发事务限制不过通过这种方式提交的事务其资源是受限的而且仍有可能会因
为资源不足而失败。编者认为资源受限并不是什么大事最麻烦的是需要修改 SQL
增加参数的设置才能使用这个特性。
可以设置 gp_resource_group_queuing_timeout 参数来指定事务排队的时
间长度超时之后数据库将 cancel 该事务该参数缺省值为 0意思是排队时间长
度没有限制编者认为这个参数可能一般也不会用到因为编者想不出在生产环境中
什么情况下需要把排队的事务因等待时长的原因而自动 cancel 掉。
CPU 配额
通过 CPU_RATE_LIMIT 来配置资源组可用的 CPU 资源的百分比使用 CPUSET
来配置资源组专用的 CPU Core 的序号二者是不同的 CPU 资源的配额模式。配置资
源组时必须选择其中一种只有需要特殊保护 CPU 资源的极高优先级的资源组需要
考虑 CPUSET 方式的 CPU 资源配额。
GP 允许在不同的资源组中同时使用这两种 CPU 配额模式也可以在使用过程中随
时修改 CPU 的配额模式当发现某类优先级极高的业务 CPU 资源会受到其他资源
组的影响而产生波动时可以尝试将其 CPU 配额模式修改为 CPUSET
参数 gp_resource_group_cpu_limit 用于配置每个主机上最大分配给 GP
Instance CPU 资源的百分比。不管使用哪种 CPU 配额模式该参数都控制着所有
资源组的最大 CPU 使用率。其余的资源需要留给操作系统和数据库的主服务进程使用。
参数 gp_resource_group_cpu_limit 的缺省值为 0.9(90%)
注意如果在 GP 集群的主机上还有其他程序gp_resource_group_cpu_limit
版权所有Esena(陈淼 ) 编写陈淼 - 50 -
Greenplum Database 管理员指南 V6.2.1
的缺省值是没有为其他程序预留 CPU 资源的如果要为其他程序保留 CPU 资源可能
需要调整该参数。
注意应该尽量避免将 gp_resource_group_cpu_limit 设置为大于 0.9这样可
能会导致 GP 工作负载抢占所有的 CPU 资源从而影响数据库的主服务进程获取不到足
够的 CPU 资源。
按照 Core 来配额 CPU
使用 CPUSET 属性来指定哪些 CPU Core 为资源组专用被指定的 Core 必须
是在系统中存在的且不能已经分配给其他资源组虽然 GP 将这些 Core 指定为该资
源组专用但操作系统中的其他非 GP 数据库的进程仍然可以使用这些 CPU Core(
次说明设备专用的重要性)
使用 CPUSET 需要使用单引号引起来一串以逗号分隔的 Core 序号或者序号范
围。例如'1,3-5'
CPU Core 分配给 CPUSET 型的资源组时需要考虑以下因素
使用CPUSET型的资源组时指定的Core是被资源组独占的即便该资源组中没有
正在执行的事务这些CPU Core仍处于空闲状态不会被其他资源组使用所以
应该尽可能的避免设置过多的Core数量避免系统的CPU资源浪费。
不要分配0Core0Core需要保留以备不时之需
缺省资源组admin_groupdefault_group至少需要一个Core当把所有
Core都指定为其他资源组专用时缺省的资源组就只能使用0Core
admin_groupdefault_group将与占用了0Core的资源组共用0
Core
当使用一个新的机器来替换现有集群中的一个机器而新的机器的CPU Core
的数量减少了就没有足够的Core来满足CPUSET的配置数据库将会把0
Core分配给这些资源组以避免启动失败。
CPU Core分配给资源组时应该尽量使用数字小的序号。否则当更换一个CPU
Core的数量变少的机器时或者将数据库备份并恢复到一个CPU Core的数量变
少的集群时资源组的创建可能会失败因为在新的机器上数字大的Core序号可
能不存在。
通过 CPUSET 配置的资源组 CPU 资源的使用上有更高的优先级其最高的 CPU
版权所有Esena(陈淼 ) 编写陈淼 - 51 -
Greenplum Database 管理员指南 V6.2.1
使用率是分配的 Core 数量占节点全部 Core 数量的百分比。
在使用 CPUSET 配置资源组时将不能设置 CPU_RATE_LIMIT 属性会被自动设
置为-1这两个属性不能同时配置只能二选一。
按照百分比来配额 CPU
对于 GP 集群中的每个机器来说CPU 资源是可以按照百分比进行均分的通过
CPU_RATE_LIMIT 属性来配置的资源组系统将会为其配额指定百分比的 CPU 资源。
在设置 CPU_RATE_LIMIT 参数时可设置的最小值是 1最大值是 100同时系统
中所有资源组的 CPU 百分比的总和不能超过 100
通过 CPU_RATE_LIMIT 属性设置的所有资源组的 CPU 资源配额的总和受限于
CPUSET 独占剩余的 CPU Core 的数量 ÷ 机器上 CPU Core 的总数 × 100 ×
gp_resource_group_cpu_limit 参数的值 = CPU_RATE_LIMIT 资源组可利用的
系统 CPU 资源的总百分比。CPUSET 型的资源组CPU 资源百分比也需要从总数中扣
只不过资源的配额采用的是固定 CPU Core 的方式来实现目的是避免与其
他资源组的争抢。
通过 CPU_RATE_LIMIT 配置的资源组其可以使用的 CPU 资源是弹性的不是
固定的数据库可能会将空闲的资源组的 CPU 资源分配给其他繁忙的资源组使用
一旦被划走 CPU 资源的资源组开始有事务执行CPU 资源将会重新分配回去
要注意的是CPUSET 型的资源组即便没有事务在执行 CPU 资源也不会被其他
资源组划走。对于有多个资源组在繁忙的情况他们将按照 CPU_RATE_LIMIT 配置的
按照比例获取空闲资源组的 CPU 资源例如CPU_RATE_LIMIT 设置为 40 的资
源组获得的 CPU 资源将是 CPU_RATE_LIMIT 设置为 20 的资源组的 2 倍。
在使用 CPUSET 配置资源组时将不能设置 CPU_RATE_LIMIT 属性会被自动设
置为-1这两个属性不能同时配置只能二选一。
内存配额
启用资源组之后内存的使用可以在 GP 数据库的 HostInstance 和资源组层
面来管理和控制还可以通过资源组在事务层面来控制。
参数 gp_resource_group_memory_limit 设置了每个 GP Host 主机上可以
版权所有Esena(陈淼 ) 编写陈淼 - 52 -
Greenplum Database 管理员指南 V6.2.1
分配给资源组的系统内存的最大百分比。gp_resource_group_memory_limit
缺省值为 0.7(70%)
GP 数据库在 Host 主机上的可用内存在 Primary 之间平均分配当启用资源组来
管理资源时分配给每个 Instance 的内存是Host 的总可用内存 ×
gp_resource_group_memory_limit ÷ Host 主机上的 Primary 总数可通过
下面的公式计算得出
rg_perseg_mem = ((RAM × (vm.overcommit_ratio ÷ 100) + SWAP) ×
gp_resource_group_memory_limit) ÷ num_of_active_primary
其中[RAM × (vm.overcommit_ratio ÷ 100) + SWAP] Linux 可用内存
的计算方式。
每个资源组都可以配置一定百分比的专享内存在创建资源组时通过
MEMORY_LIMIT 属性来配置MEMORY_LIMIT 属性的最小取值为 0最大取值为 100
当设置 MEMORY_LIMIT 0 GP 将不会为该资源组配置专享内存而是使用全局
共享内存来满足该资源组中的内存需求。可以参见"全局共享内存"章节。
注意GP 数据库中所有资源组的 MEMORY_LIMIT 总和不能超过 100.
基于 ROLE 的内存配额的更多配置
对于基于 ROLE 的内存配额来说为资源组配置的专享内存(MEMORY_LIMIT 不为
0)将会继续分为定额部分和可共享部分。创建资源组时MEMORY_SHARED_QUOTA
性用于指定为资源组配额的专享内存中多少百分比作为可共享内存这部分的可共
享内存该资源组中的并发事务都可以使用并且采用先到先得的原则来分配正在运
行的事务可能完全不用也可能用一些也可能使用到全部。
MEMORY_SHARED_QUOTA 属性的取值范围是 0 100缺省值是 80
正如之前说的CONCURRENCY 属性控制着资源组中最大的并发事务数量如果为
资源组配置了专享内存(MEMORY_LIMIT 不为 0)定额部分的内存将按照最大并发事
务数量来平均分配每个槽位将获得完全相同的份额也就是说即便没有并发事务在
执行这部分定额内存也是保留的。
版权所有Esena(陈淼 ) 编写陈淼 - 53 -
Greenplum Database 管理员指南 V6.2.1
此图展示的是内存配额的情况该图与官方文档中有不同因为 default_group
资源组的 memory_limit 0应该是只能使用全局共享内存的资源。
当一个查询的内存消耗超过了资源组中定额部分的限制将可以从该资源组的可共
享部分获取因此对于一个事务槽位来说可以获得的最大内存使用量是每个槽位
的专享定额部分 + 可共享部分总量。不过当有全局共享内存时资源组的可共享部
分用完之后还可以从全局共享内存获得内存资源。
全局共享内存
为所有资源组(包括缺省的 admin_group default_group)配置的
MEMORY_LIMIT 属性的总和是数据库为这些资源组预留的专享配额。如果总和小于
100剩余部分就会作为全局共享内存来管理。全局共享内存只有使用了 vmtracker
内存管理模式(基于 ROLE 的资源组)的资源组可以使用。
如果可以的话数据库会在为查询分配了资源组的定额部分的内存和可共享部分
(如果有的话)的内存之后为事务分配全局共享内存。这部分内存的分配也是按照先
到先得的原则。
注意数据库会统计(但不主动监测)资源组中事务的内存使用情况如果资源组中的
事务使用内存的情况达到了以下所有条件该事务将会失败
资源组中可共享部分的内存耗尽。
全局共享内存耗尽。
版权所有Esena(陈淼 ) 编写陈淼 - 54 -
Greenplum Database 管理员指南 V6.2.1
事务请求更多的内存。
当预留了一些全局共享内存(例如 10% 20%)数据库通过资源组来管理内存
使用将会更有效。全局共享内存会有助于降低大量内存消耗型查询出现异常的概率。
算子内存配额
大多数的算子(我们将执行计划中的 HashSortJoinAgg 等运算操作统一
称为算子)都不是内存密集型的算子也就是说在执行过程中数据库分配的内存足
够其使用。有些内存密集型的算子例如Join Sort如果内存中放不下大量的
数据数据就需要溢出到磁盘上。
参数 gp_resgroup_memory_policy 用于控制一个查询中所有算子的内存分
配策略对于资源组目前支持 eager_free(缺省值) auto 两种内存策略。当设
置为 auto 策略时数据库的资源组内存管理将会为非内存密集型算子分配固定尺寸
的内存剩余的内存分给内存密集型算子。当设置为 eager_free 策略时内存资源
的分配会更优化数据库会将已经完成的算子释放的内存重新分配给后续的算子。
MEMORY_SPILL_RATIO 属性用于设置在一个事务中分配给该事务的内存的相
对百分比这个比较难描述请参考下面的算式来理解。当达到该限制时该事务将会
产生溢出文件到磁盘上。数据库会根据 MEMORY_SPILL_RATIO 的设置来确定分配给
一个事务的内存尺寸 EXPLAIN ANALYZE 中显示的 Memory used Master
分配的内存值。计算公式为
int(
SYS_MEM
× gp_resource_group_memory_limit
÷ num_of_active_primary
× MEMORY_LIMIT ÷ 100
÷ CONCURRENCY
× MEMORY_SPILL_RATIO ÷ 100
)
注意内存分配的最小单位与SYS_MEM × gp_resource_group_memory_limit ÷
num_of_active_primary的结果是否大于16GB有关如果其大于16GB则会一直
除以2并将最小单位(起始值为1MB)乘以2。比如计算结果得到33GB最小单位为
4MB
实际上是将操作系统可用内存乘以 GP 可用内存百分比乘以资源组的内存配
额比例除以并发事务限制数量除以当前主机上 Primary 的数量得到的是当前事
务所在资源组平均到每个并发事务的内存尺寸MEMORY_SPILL_RATIO 限制的是
这个尺寸的百分比使用量。
版权所有Esena(陈淼 ) 编写陈淼 - 55 -
Greenplum Database 管理员指南 V6.2.1
例如
SYS_MEM = 5537MB
gp_resource_group_memory_limit = 0.7
num_of_active_primary = 3
MEMORY_LIMIT = 10
CONCURRENCY = 10
MEMORY_SPILL_RATIO = 10
带入公式求得初始分配给该事务的内存为 1MB。计算所得的结果甚至可能会出
0MB 的情况如果是 0MB则需要从可共享内存和全局共享内存获得内存未必会
出现溢出文件如果不为 0MB而实际需要的内存大于分配的值则需要溢出文件
所以1MB 可能会产生 workfile 0MB 可能不会产生 workfile
MEMORY_SPILL_RATIO 属性的取值范围是 0 100缺省值是 0。当
MEMORY_SPILL_RATIO 属性的值为 0 数据库将根据 statement_mem 参数的值
来确定初始分配给一个事务的内存尺寸一旦按照 statement_mem 参数的值来确定
内存的初始化分配尺寸超过 statement_mem 参数限制的内存需求将需要溢出到
磁盘。在 MEMORY_SPILL_RATIO 属性不为 0 超过初始分配尺寸的内存需求
要通过产生溢出文件来实现。
注意当设置 MEMORY_LIMIT 属性为 0 MEMORY_SPILL_RATIO 属性也必须设置
0
SESSION 还可以通过设置 memory_spill_ratio 参数的值来设置当前事
务的 MEMORY_SPILL_RATIO 属性。
官方文档上说对于低内存消耗型的查询来说设置如下的参数可以提升查询的性
编者觉得有待验证至少编者认为这种操作可能没有特别显著的性能提升。
=# SET memory_spill_ratio=0;
=# SET statement_mem='10 MB';
使用专享内存还是使用全局共享内存
如果没有为资源组配额专享内存(MEMORY_LIMIT MEMORY_SPILL_RATIO
性被设置为 0)将会产生如下影响
版权所有Esena(陈淼 ) 编写陈淼 - 56 -
Greenplum Database 管理员指南 V6.2.1
全局共享内存的尺寸会增加。
资源组的功能将会与资源队列相似通过statement_mem参数的值来确定初始分
配给一个事务的内存尺寸。
该资源组中的事务将与其他资源组中的事务竞争全局共享内存并且采用先到先得
的原则来分配。
数据库无法保证一定能为该资源组中的事务分配到内存。
当同时有多个事务需要从全局共享内存获取配额时该资源组中的查询出现内存不
足的风险增加。
要降低重要资源组中查询出现内存不足的风险可以考虑为该资源组配置一些专享
内存这样做会降低全局共享内存的尺寸但为了降低该资源组出现内存不足的风险
这是一种权衡的选择。
其他内存事项
基于 ROLE 的资源组会管理所有通过 palloc()函数分配的内存通过 linux
malloc()函数分配的内存将不会被资源组管理。因此为了确保基于 ROLE 的资源组
能够准确的管理内存的使用情况应该避免在自定义函数中使用 malloc()函数来分
配大量内存。
配置与使用资源组
注意RedHat6或者CentOS6中使用资源组是有问题的这是因为早期的cgroup
有缺陷最好将Kernel升级到2.6.32-696或者更高的版本以修复已知的问题从而
可以更好的使用资源组功能。这些问题在Redhat7或者CentOS7中已经修复。
环境要求
版权所有Esena(陈淼 ) 编写陈淼 - 57 -
Greenplum Database 管理员指南 V6.2.1
GP 数据库使用 Linux cgroup 来管理资源组的 CPU 资源同时使用 cgroup
来管理基于外部组件的资源组的内存资源。通过 cgroupGP 数据库将数据库进程的
CPU 资源和外部组件的内存资源与主机上其他进程进行隔离。这就可以将每个资源组
CPU 资源和外部组件的内存资源进行限制。
关于 cgroup 的更多信息可以参考对应 Linux 发行版的 Control Groups 文档。
GP 数据库的每个 Host 主机上完成如下 cgroup 的配置(使用编者的一键部署命
令时除了安装必要的操作系统组件其他配置工作都会自动完成)
1 如果是在 SuSE11+操作系统运行 GP 数据库集群需要将所有 Host 主机启用
swapaccount 内核参数并重启机器之后才能继续进行 cgroup 的配置。
2 使用 ROOT 用户或者通过 sudo 权限创建 GP 数据库的 cgroup 配置文件
$ sudo vi /etc/cgconfig.d/gpdb.conf
3 /etc/cgconfig.d/gpdb.conf 配置文件中加入如下配置信息
group gpdb {
perm {
task {
uid = gpadmin;
gid = gpadmin;
}
admin {
uid = gpadmin;
gid = gpadmin;
}
}
cpu {
}
cpuacct {
}
memory {
}
cpuset {
}
}
这些配置用于设置由 gpadmin 用户管理 CPU CPU Core 以及内存的控制
GP 数据库只针对基于外部组件的资源组会使用 cgroup 来管理内存资源。
4 如果操作系统中没有安装并运行 cgroup 的相关组件需要在 GP 集群的所有 Host
版权所有Esena(陈淼 ) 编写陈淼 - 58 -
Greenplum Database 管理员指南 V6.2.1
主机上进行安装和启用。根据不同的操作系统这些命令会略有不同使用 ROOT
用户或者通过 sudo 权限来执行这些命令
Redhat/CentOS 7.x系统
$ sudo yum install libcgroup-tools
$ sudo cgconfigparser -l /etc/cgconfig.d/gpdb.conf
$ sudo systemctl enable cgconfig.service
Redhat/CentOS 6.x系统
$ sudo yum install libcgroup
$ sudo service cgconfig start
$ sudo chkconfig cgconfig on
SuSE 11+系统
$ sudo zypper install libcgroup-tools
$ sudo cgconfigparser -l /etc/cgconfig.d/gpdb.conf
5 运行以下命令验证是否正确设置了 GP 数据库 cgroup 配置
$ CGROUP_MOUNT_POINT=`df -h|grep cgroup|awk '{print $NF}'`
$ if [ "$CGROUP_MOUNT_POINT" != "" ];then
> ls -l $CGROUP_MOUNT_POINT/{cpu,cpuacct,cpuset,memory}/|grep gpdb
> fi
如果输出 4 owner gpadmin:gpadmin 的目录则表明设置成功了。
启用资源组
在安装 GP 时缺省使用资源队列来管理资源。要使用资源组取代资源队列来管理资
必须修改参数 gp_resource_manager group
1 修改参数 gp_resource_manager 的值为 group
$ gpconfig -s gp_resource_manager
$ gpconfig -c gp_resource_manager -v "group"
2 重启 GP 数据库
版权所有Esena(陈淼 ) 编写陈淼 - 59 -
Greenplum Database 管理员指南 V6.2.1
$ psql postgres -c "CHECKPOINT"
$ gpstop -af
$ gpstart -a
启用资源组之后任何 ROLE 提交的事务都会经过该 ROLE 所属的资源组来执行
并受到该资源组的限制(并发事务数量、CPU 百分比和内存百分比)。类似的外部组
件的 CPU 和内存资源也受到分配到该外部组件的资源组的限制。
GP 数据库缺省创建了两个资源组分别为 admin_group default_group
一旦启用了资源组未明确分配资源组的 ROLE会根据 ROLE 的类型分配一个缺省资
源组SUPERUSER 会被分配 admin_group普通 ROLE 会被分配 default_group
两个缺省资源组的缺省属性如下
属性(限制类型)
admin_group
default_group
CONCURRENCY
10
20
CPU_RATE_LIMIT
10
30
CPUSET
-1
-1
MEMORY_LIMIT
10
0
MEMORY_SHARED_QUOTA
80
80
MEMORY_SPILL_RATIO
0
0
MEMORY_AUDITOR
vmtracker
vmtracker
需要注意的是缺省的两个资源组的 CPU_RATE_LIMIT 属性和 MEMORY_LIMIT
属性也计入 Host 主机的总百分比当创建新的资源组时可能需要调整这两个缺省资
源组的属性配置。
创建资源组
要创建一个资源组需要提供资源组的名称以及 CPU 配额模式还可以配置一些
可选项最大并发事务数量内存配额内存的共享部分占比内存溢出到文件的阈值。
使用 CREATE RESOURCE GROUP 命令来创建一个新的资源组。
创建资源组时必须指定 CPU_RATE_LIMIT 或者 CPUSET 的值这用于限制该资源
组可用的 CPU 的百分比。可以指定 MEMORY_LIMIT 为资源组配置专享内存配额的百分
如果 MEMORY_LIMIT 设置为 0GP 将不会为该资源组配置专享内存而是使用全
局共享内存来满足该资源组中的内存需求。
例如创建一个名称为 rgroup1 的资源组CPU 配额为 20内存配额为 25
版权所有Esena(陈淼 ) 编写陈淼 - 60 -
Greenplum Database 管理员指南 V6.2.1
存溢出到文件的阈值为 20
=# CREATE RESOURCE GROUP rgroup1 WITH
(CPU_RATE_LIMIT=20, MEMORY_LIMIT=25,MEMORY_SPILL_RATIO=20);
分配了 rgroup1 资源组的所有 ROLE 将共享 20% CPU 配额类似的这些 ROLE
也将共享 20%的内存配额。使用缺省的内存管理模式 vmtracker 以及缺省的
CONCURRENCY 20
如果要创建基于外部组件的资源组除了必须指定 CPU_RATE_LIMIT 或者
CPUSET 的值还必须设置 MEMORY_LIMIT 的配额同时还必须设置
MEMORY_AUDITOR cgroup并且明确的设置 CONCURRENCY 0。例如要创建一
个名称为 rgroup_extcomp 的资源组CPU 配额为 1 Core内存配额为 15
=# CREATE RESOURCE GROUP rgroup_extcomp WITH
(MEMORY_AUDITOR=cgroup, CONCURRENCY=0, CPUSET='1', MEMORY_LIMIT=15);
使用 ALTER RESOURCE GROUP 来调整资源组的配额。要修改资源组的配额
要为资源组的属性指定一个新的值。例如
=# ALTER RESOURCE GROUP rg_role_light SET CONCURRENCY 7;
=# ALTER RESOURCE GROUP exec SET MEMORY_SPILL_RATIO 25;
=# ALTER RESOURCE GROUP rgroup1 SET CPUSET '2,4';
注意不能设置 admin_group 资源组的 CONCURRENCY 属性为 0
使用 DROP RESOURCE GROUP 命令来删除资源组要删除一个资源组该资源组
不能被分配给任何 ROLE同时该资源组上不能有任何活动的事务和等待的事务。如
果删除一个基于外部组件的资源组该资源组上正在运行的实例将会被杀死。例如
=# DROP RESOURCE GROUP exec;
配置基于内存限制的查询终止
当有全局共享内存时runaway_detector_activation_percent 参数设置
了全局共享内存的阈值当全局共享内存达到参数指定的利用率时将触发资源组中的
查询被终止这只针对内存管理模式为 vmtracker 的资源组。编者的理解是当阈
值达到时那些继续向全局共享内存申请配额的事务将会被终止其他不需要向全局共
享内存申请配额的事务将不受影响。
版权所有Esena(陈淼 ) 编写陈淼 - 61 -
Greenplum Database 管理员指南 V6.2.1
什么时候会有全局共享内存当系统中所有资源组 MEMORY_LIMIT 属性的值的和
小于 100 时。例如系统中配置了 3 个资源组MEMORY_LIMIT 属性的值分别为 10
2030那么全局共享内存为 100 - (10 + 20 + 30) = 40
分配资源组给 ROLE
在创建了一个 MEMORY_AUDITOR 属性为缺省值 vmtracker 的资源组后该资源
组就可以分配给 ROLE (可以是一个或者多个)。通过 CREATE ROLE ALTER ROLE
命令的 RESOURCE GROUP 子句来分配资源组给 ROLE。如果在 CREATE ROLE 时没有
设置资源组会根据 ROLE 的类型分配一个缺省资源组SUPERUSER 会被分配
admin_group普通 ROLE 会被分配 default_group
使用 ALTER ROLE CREATE ROLE 命令来分配一个资源组给 ROLE。例如
=# ALTER ROLE bill RESOURCE GROUP rg_light;
=# CREATE ROLE mary RESOURCE GROUP exec;
可以将一个资源组分配给一个或者多个 ROLE。如果 ROLE 有层级关系将一个资
源组分配给一个上层的 ROLE这个设置并不会传递到该组的其他 ROLE也就是说
ROLE 的资源组属性不可继承。
注意不能将创建的基于外部组件的资源组分配给一个 ROLE
如果想要将一个资源组从一个 ROLE 移除并按照缺省的规则分配一个缺省资源组
可以修改 ROLE 并分配一个名为 NONE 的资源组。例如
=# ALTER ROLE mary RESOURCE GROUP NONE;
监控资源组状态
本章节介绍查看资源组的状态信息的方法。
版权所有Esena(陈淼 ) 编写陈淼 - 62 -
Greenplum Database 管理员指南 V6.2.1
查看资源组配额
通过 gp_toolkit.gp_resgroup_config 视图可以查看资源组的配额设置。不
编者建议可以重建该视图原有的视图定义实在不够优雅
=# CREATE OR REPLACE VIEW gp_toolkit.gp_resgroup_config AS
SELECT groupid,groupname,
vs[1] AS concurrency,
vs[2] AS cpu_rate_limit,
vs[3] AS memory_limit,
vs[4] AS memory_shared_quota,
vs[5] AS memory_spill_ratio,
DECODE(vs[6],null,'vmtracker','0','vmtracker',
'1','cgroup','unknown') AS memory_auditor,
vs[7] AS cpuset
FROM (
SELECT g.oid AS groupid,
g.rsgname AS groupname,
array_agg(c.value order by reslimittype) vs
FROM pg_resgroup g, pg_resgroupcapability c
WHERE g.oid = c.resgroupid
GROUP BY 1,2
) t;
ALTER TABLE gp_toolkit.gp_resgroup_config OWNER TO gpadmin;
GRANT ALL ON TABLE gp_toolkit.gp_resgroup_config TO gpadmin;
GRANT SELECT ON TABLE gp_toolkit.gp_resgroup_config TO public;
查看资源组的配额设置
=# SELECT * FROM gp_toolkit.gp_resgroup_config;
查看资源组的查询状态和 CPU 内存使用量
通过 gp_toolkit.gp_resgroup_status 视图来查看资源组的事务活跃情况
版权所有Esena(陈淼 ) 编写陈淼 - 63 -
Greenplum Database 管理员指南 V6.2.1
排队情况以及实时的 CPU 和内存的使用量
=# SELECT * FROM gp_toolkit.gp_resgroup_status;
不过编者觉得这个视图没法看CPU 和内存使用量的字段是个很大的 Json
以阅读。像下面这样可能会容易阅读一些
=# SELECT rsgname,groupid,num_running,num_queueing,
num_queued,num_executed,total_queue_duration,
json_each(cpu_usage)::text cpu_usage,
json_each(memory_usage)::text memory_usage
FROM gp_toolkit.gp_resgroup_status
ORDER BY rsgname,cpu_usage;
查看资源组在每个 Host 主机的 CPU 和内存使用量
通过 gp_toolkit.gp_resgroup_status_per_host 视图来查看每个资源组
在每个 Host 主机上的 CPU 和内存的实时使用量
=# SELECT * FROM gp_toolkit.gp_resgroup_status_per_host;
查看资源组在每个 Instance CPU 和内存使用量
通过 gp_toolkit.gp_resgroup_status_per_segment 视图来查看每个资
源组在每个 Instance 上的 CPU 和内存的实时使用量
=# SELECT * FROM gp_toolkit.gp_resgroup_status_per_segment;
查看资源组被分配到 ROLE 的情况
版权所有Esena(陈淼 ) 编写陈淼 - 64 -
Greenplum Database 管理员指南 V6.2.1
通过关联 pg_roles pg_resgroup 两张系统表来查看资源组被分配到 ROLE
的情况
=# SELECT rolname, rsgname FROM pg_roles, pg_resgroup
WHERE pg_roles.rolresgroup=pg_resgroup.oid;
查看资源组中正在执行和排队的查询
通过 pg_stat_activity 系统视图来查看资源组中有哪些查询正在执行或者
正在排队以及排队的时间等
=# SELECT query, waiting, rsgname, rsgqueueduration FROM pg_stat_activity;
pg_stat_activity 视图可以查看执行语句的状态信息这与 PostgreSQL
相似。如果一个查询使用了外部组件( PL/Container)该查询将会有两个部分
一部分是查询本身在 GP 数据库中运行而另一部分 UDF 则在 PL/Container 容器中
运行 GP 数据库中运行的查询本身由 ROLE 的资源组来管理 PL/Container
运行的 UDF PL/Container 的资源组管理后者在 pg_stat_activity 视图中
无法体现数据库无法获取 PL/Container 外部组件中的运行情况。
终止资源组中正在运行或者排队的事务
有时可能需要终止资源组中正在执行的事务或者还在排队的事务。例如想把某个
还在排队的查询移除或者想把某个已经执行很久的事务中断亦或是想把某个占用并
发数槽位的 IDLE 事务清除以让给其他 ROLE 使用。
缺省情况下事务可以无限期的在资源组中排队如果想要为排队设置超时时间
可以设置 gp_resource_group_queuing_timeout 参数该参数指定一个毫秒数
当事务排队时间超过这个设置时将会被数据库中断。
要手动终止一个事务首先要确定该查询相关的进程号(pid)得到了该 pid
通过调用 pg_cancel_backend()函数来终止该查询。
例如通过如下语句查看所有资源组中正在执行和排队的语句如果查询没有结果
说明资源组中没有正在执行的事务或者排队的事务。
版权所有Esena(陈淼 ) 编写陈淼 - 65 -
Greenplum Database 管理员指南 V6.2.1
=# SELECT rolname, g.rsgname, pid, waiting, state, query, datname
FROM pg_roles, gp_toolkit.gp_resgroup_status g, pg_stat_activity
WHERE pg_roles.rolresgroup=g.groupid
AND pg_stat_activity.usename=pg_roles.rolname;
例如要终止 pid 2395 的查询
=# SELECT pg_cancel_backend(2395);
还可以为 pg_cancel_backend()函数提供一个可选的消息参数用于通知该查
询的 ROLE告知为何终止了其执行的事务。例如
=# SELECT pg_cancel_backend(2395,'因系统维护暂停使用');
该事务的 ROLE 会收到如下信息
ERROR: canceling statement due to user request: "因系统维护暂停使用"
注意尽可能避免使用操作系统的KILL命令来杀死GP数据库的任何进程当然有时
如果万不得已在尽量确保安全的情况下也不是绝对不能使用但专业技术支持可能
会不支持这种擅自操作导致的严重后果所以如有必要请联系专业技术支持人员。
转移查询的资源组
数据库的 SUPERUSER 可以执行 gp_toolkit.pg_resgroup_move_query()
函数来将一个正在执行的事务转移到另一个资源组这样在不中断该查询的情况下
可以将其转移到一个资源配额更多的资源组。
注意只能转移一个正在执行的事务不能转移因为并发事务限制或者内存限制导致排
队和等待的事务已经在执行的事务我为什么要转移它编者认为更多的可能是需
要转移一个派对和等待的事务希望这方面可以得到改善。
调用 pg_resgroup_move_query()函数需要提供两个参数PID 和新的资源组
名称。例如
=# SELECT gp_toolkit.pg_resgroup_move_query(2514,'default_group');
在调用 pg_resgroup_move_query()函数时该查询将受到新的资源组的配额
限制
如果目标资源组的最大并发事务数量已经超了该查询会进行排队等待状态。
版权所有Esena(陈淼 ) 编写陈淼 - 66 -
Greenplum Database 管理员指南 V6.2.1
如果目标资源组的内存资源不足调用该函数时会收到如下报错信息
group <group_name> doesn't have enough memory . . .
在这种情况下可以增加目标资源组的内存配额或者等有资源空缺时再转移。
转移查询的资源组之后该查询将与目标资源组中的其他事务竞争资源因此
法保证目标资源组中的事务不受影响目标资源组中的事务可能会受此影响而导致查询
失败保留足够的全局共享内存可能会有效降低这种风险。
pg_resgroup_move_query()函数只是把指定的事务转移到目标资源组中
所在 Session 中之后的事务仍然通过原来的资源组执行。
注意转移查询的资源组这个功能是 6.8 版本才引入的功能。
如果是从 6.8 之前的版本升级而来需要手动创建函数来使用该用能
CREATE FUNCTION gp_toolkit.pg_resgroup_check_move_query(IN session_id
int, IN groupid oid, OUT session_mem int, OUT available_mem int)
RETURNS SETOF record
AS 'gp_resource_group', 'pg_resgroup_check_move_query'
VOLATILE LANGUAGE C;
GRANT EXECUTE ON FUNCTION
gp_toolkit.pg_resgroup_check_move_query(int, oid, OUT int, OUT int)
TO public;
CREATE FUNCTION gp_toolkit.pg_resgroup_move_query(session_id int4,
groupid text)
RETURNS bool
AS 'gp_resource_group', 'pg_resgroup_move_query'
VOLATILE LANGUAGE C;
GRANT EXECUTE ON FUNCTION gp_toolkit.pg_resgroup_move_query(int4,
text) TO public;
如果要将版本降到 6.7 或者更早的 6 版本可以手动删除这些函数
DROP FUNCTION gp_toolkit.pg_resgroup_check_move_query(IN int, IN oid,
OUT int, OUT int);
DROP FUNCTION gp_toolkit.pg_resgroup_move_query(int4, text);
版权所有Esena(陈淼 ) 编写陈淼 - 67 -
Greenplum Database 管理员指南 V6.2.1
使用资源队列
在出现资源组之前GP 一直是使用资源队列来管理资源资源队列最常见的使用
场景就是限制并发查询的数量。资源队列是基于查询语句来做并发控制的而资源组是
基于事务来做并发控制。所以在资源队列中可能会出现多语句的事务之间的死锁现象
一边在等资源队列的锁另一边在等对象的锁这种情况在资源组中不会出现因为资
源组是以事务为单位进行排队的。因此资源队列存在死锁风险虽然概率很低。
资源队列如何工作
在安装GP时缺省使用资源队列来管理资源。所有的ROLE都必须分配到资源队列。
如果管理员创建ROLE时没有指定资源队列ROLE将会被分配到缺省的资源队列
pg_default
建议管理员为不同类型工作负载创建结构性独立的资源队列。例如可以为高级用
户、WEB用户、报表管理等创建不同的资源队列。可以根据相关工作的负载压力设置合
适的资源队列限制。目前资源队列的限制包括
活动语句数量。同时正在执行的最大语句数量。这往往是资源队列的唯一用处。
活动语句内存使用量。所有正在执行的语句使用的总内存不能超过该限制。
活动语句优先级。该值设定了该资源队列相对于其他资源队列在CPU资源使用上的
优先级这里说的优先是相对的。这种优先级几乎是没用的MAXMIN之间可
能也测不出差异无法达到资源组的CPU压制效果如果能达到也就不需要资源
组了。
活动语句的成本限制。该值限制的是由执行计划评估得到的的Cost该值以
涉及的磁盘页(disk page)作为计量单位。
资源队列创建好之后ROLE(User)可以被分配到合适的资源队列。一个资源队列
可以分配多个ROLE但每个ROLE只能被分配到一个资源队列。
资源队列如何工作
在数据库运行时用户提交一个查询该查询会被数据库根据其所在的资源队列的
资源进行评估。如果评估认为该查询不会超过资源限制该查询将被立即执行。如果评
估认为该查询超过了资源限制(例如正在执行的查询语句的数量已经达到了最大活动
语句数的限制)该查询需要等到有足够的资源时才能被执行。查询按照先进先出的方
版权所有Esena(陈淼 ) 编写陈淼 - 68 -
Greenplum Database 管理员指南 V6.2.1
式排队。在查询优先级启用的情况下系统会定期的重新分配计算资源。编者想说
队也是要消耗内存的资源队列的排队相当于是在等待锁而且查询的执行计划已经生
成并开始执行只是未获取必要的锁实际上内存已经分配如果有大量消耗大量内存
的语句在排队可能会出现内存不足的报错。
超级用户是不受资源队列限制的。超级用户的查询语句总是被立即执行不管其所
在的资源队列如何限制。
内存限制如何工作
在资源队列上设置的内存限制使得每个Instance上该资源队列能够使用的内存
总和不能超过设定的最大值。每个查询语句分配的内存大小是资源队列的内存限制除以
最大活动语句数量(建议与活动语句数限制结合使用而不是与cost限制结合使用
果是与cost限制结合使用将按照cost的权重进行分配)。例如资源队列的内存限
制为2000MB活动语句数限制为10那么每条执行语句可以得到200MB的内存。缺省
的内存分配可以针对每条语句通过设置statement_mem参数来覆盖(最大可以达到资
源队列限制的值)。一旦一条语句开始执行其分配的内存一直到执行结束才会释放(
便其实际使用的内存小于分配的内存)
执行优先级如何工作
资源限制是针对活动语句来说的内存和成本的限制属于是否许可类型其决定查
询语句是允许进入查询状态还是保持排队状态。在语句处于活动状态时其需要分享
CPU资源这部分的资源由资源队列的优先级控制。当一个更高优先级的语句进入运行
状态时其要求获得更多的CPU资源相应的需要减少其他运行中语句的CPU资源。
语句的规模和复杂程度不会影响到CPU资源的分配。例如一个简单低cost的查询
与一个庞大复杂的查询同时执行却有着相同的优先级他们在同一时间段内将分配到相
同的CPU资源。当一个新的语句开始执行CPU资源分配的比重需要被重新计算不过
相同优先级的语句之间获得的CPU资源仍然是相同的。
版权所有Esena(陈淼 ) 编写陈淼 - 69 -
Greenplum Database 管理员指南 V6.2.1
例如管理员想要创建3个资源队列adhoc用于做持续查询的业务分析
reporting用于做定期的报表工作executive用于高级用户查询。管理员希望确保
定期报表工作不受到adhoc分析查询不可预测的资源消耗的影响希望高级用户提交的
查询能够获得更多计算资源。因此资源队列优先级可以设置为这样
adhoc -- Low priority
reporting -- High priority
executive -- Maximum priority
运行时CPU资源由正在运行语句的优先级决定如何分配。如果语句1与语句2来自
reporting队列且同时运行他们将获得相同CPU资源。当一个来自adhoc队列语句
开始运行其需要较少的CPU资源。CPU资源的分配将做调整他们之间的比重受他们
的优先级决定
注意该图显示的是粗略的百分比。在CPU的使用上并不总是按照精确的比值来
分配资源因为资源组做不到CPU资源的精细控制。
当一个来自executive的语句开始执行CPU资源将根据他们的优先级重新调整。
该语句相对于adhocreporting来说可能是很简单的但在其执行完之前其仍获
取最大份额的CPU资源。
版权所有Esena(陈淼 ) 编写陈淼 - 70 -
Greenplum Database 管理员指南 V6.2.1
资源队列评估的语句类型
并不是所有的SQL语句都被资源队列评估和限制。缺省状态下只有SELECT
SELECT INTOCREATE TABLE AS SELECTDECLARE CURSOR语句被评估和限
制。若将Server端参数resource_select_only设置为offINSERTUPDATE
DELETE语句也将被评估和限制。
使用资源队列做资源管理的步骤
GP中使用资源队列做资源管理涉及到如下几个任务
1. 创建资源队列并设置合适的限制。
2. User Role指定资源队列。
3. 使用资源队列相关的系统视图监控和管理资源队列。
配置资源队列管理资源
在初始化GP集群时资源管理缺省使用资源队列。缺省的资源队列是pg_default
活动语句数量限制为20成本(Cost)无限制内存(Memory)无限制(Medium)
优先级。建议为不同类型的工作负载创建不同类型的资源队列。
版权所有Esena(陈淼 ) 编写陈淼 - 71 -
Greenplum Database 管理员指南 V6.2.1
配置资源队列
1.
以下为一般的资源队列相关的GUC配置参数
max_resource_queues -- 设置最多可以有多少个资源队列。
max_resource_portals_per_transaction -- 设置每个事务最多可以打
开几个游标(Cursor)。值得注意的是每个游标需要占用资源队列的一个活动查询。
resource_select_only -- 若设置为onSELECTSELECT INTOCREATE
TABLE AS SELECTDECLARE CURSOR语句被评估限制。若设置为offINSERT
UPDATEDELETE语句也将被评估和限制。
resource_cleanup_gangs_on_wait -- 在开始一个新的查询之前先清空所
在资源队列中其他空闲的工作进程。
stats_queue_level -- 打开资源队列使用信息收集这样就可以通过查询系
统视图pg_stat_resqueues查看资源队列的使用情况。
2.
以下参数与内存使用有关
gp_resqueue_memory_policy -- 设置GP内存管理模式。设置为none的情况
下内存管理与4.1版本之前相同。设置为auto的情况下内存受statement_mem
和资源队列内存限制的控制。缺省为eager_free这种模式下内存的管理和分
配会更高效并不是说这种模式下内存就不受statement_mem和资源队列的限制
执行计划会分为很多个算子当设置为eager_free在每个算子执行结束之
会尽快回收那些分配给已经结束的算子的内存并分配给之后的算子。
statement_memmax_statement_mem -- 用于为每个活动语句分配内存
(可以复写资源队列的缺省值)max_statement_memSUPERUSER设置应考
虑避免普通用户的超负荷使用。在任何时候statement_mem都必须小于
max_statement_mem
gp_vmem_protect_limit -- 限制每个Instance上所有语句可以使用的内存
总量的上限值。导致内存使用超过该上限的语句会被取消(Cancel)从而导致得不
到执行。该参数要根据具体硬件情况进行合理的评估OS层面来说物理内存
的容量用完之后根据OS的配置可能会使用SWAP对于普通磁盘来说不到万
不得已强烈建议不要使用SWAP
gp_vmem_idle_resource_timeout
gp_vmem_protect_segworker_cache_limit -- 用于释放Instance上空
DB进程的内存。为了提高并发量管理员可以考虑调整这些配置。一般不需要
修改这些参数。
版权所有Esena(陈淼 ) 编写陈淼 - 72 -
Greenplum Database 管理员指南 V6.2.1
3. 以下参数与查询优先级有关。注意这些参数都是本地化(LOCAL)的参数必须
修改所有Instancepostgresql.conf文件
gp_resqueue_priority -- 查询优先级特性是否启用缺省值为ON如果GUC
参数gp_resource_manager的值为groupgp_resqueue_priority的值
将显示为OFF
gp_resqueue_priority_sweeper_interval -- 设置CPU为所有活动语句
重新计算CPU资源分配的时间间隔。缺省值通常已经可以满足要求。
gp_resqueue_priority_cpucores_per_segment -- 设置每个Instance
使用的CPU core的数量。缺省情况下Instance4Master24。该参数是
LOCAL参数。该参数对于Master也是有影响的需要配置一个较高的值。例如
在一个集群中每个Host主机有8CPU Core并且每个Instance Host4
Instance那可以按照如下配置
Master:
gp_resqueue_priority_cpucores_per_segment = 8
Instance:
gp_resqueue_priority_cpucores_per_segment = 2
提示官方文档中会提到如果每个Instance Host主机上配置的Instance数量低
CPU核数确保将该参数调整到一个合适的值过低的值可能会导致CPU资源利用不
足。编者认为实际上往往可能不需要过于关注这个问题。
4. 要查看和修改这些参数尽可能使用gpconfig命令来统一修改很少有人直接去
postgresql.conf文件不过如果由于参数修改不当导致GP系统无法启动
可能需要手动修改或者进入Master Only模式进行gpconfig配置。
5. 例如要查看一个参数的配置情况
$ gpconfig -s gp_vmem_protect_limit
SQL 中使用 show 命令也可以查看一个参数的值但其不能体现 Master
Instance 之间的差异仅显示 Master 的值。
6. 例如要修改一个参数的值Master的值与Instance不同
$ gpconfig -c gp_resqueue_priority_cpucores_per_segment -v 2 -m 8
7. 重启GP以确保修改的参数生效(本节介绍的参数都需要重启生效)
$ psql -d postgres -c 'CHECKPOINT'
$ gpstop -af
版权所有Esena(陈淼 ) 编写陈淼 - 73 -
Greenplum Database 管理员指南 V6.2.1
$ gpstart -a
创建资源队列
创建资源队列涉及到Namecost、最大活动语句数量、执行优先级等。通过CREATE
RESOURCE QUEUE命令来创建新的资源队列。
创建含活动语句数量限制的资源队列
资源队列通过设置ACTIVE_STATEMENTS控制最大活动语句数量。例如创建一
个名称为adhoc最大活动语句数量为3的资源队列
=# CREATE RESOURCE QUEUE adhoc WITH (ACTIVE_STATEMENTS=3);
这意味着分配到adhoc资源队列的所有ROLE在同一时刻最多只能有3个语句处
于执行状态。如果该队列当前已经有3个语句正在执行在该队列的ROLE提交第4个语
句时其将处于等待状态直到前面3个语句有一个执行完成。
创建含内存限制的资源队列
资源队列通过设置MEMORY_LIMIT控制该队列所有语句可以使用的内存总量。每
个主机上所有Primary可以获得的物理内存总和不得超过该主机的物理内存总量。建
议将MEMORY_LIMIT控制在该Primary可以获得的物理内存总数的90%以下。例如
一个Host主机有512GB的物理内存配置有6Primary那么每个Primary可以获
得的物理内存为85GB。这样就可以简单的得到MEMORY_LIMIT=0.9*85GB=76GB。如
果存在多个资源队列他们的MEMORY_LIMIT的总和应被控制在不超过76GB
当与ACTIVE_STATEMENTS结合使用时缺省每个语句获得的内存为
MEMORY_LIMIT / ACTIVE_STATEMENTS。当与MAX_COST结合使用时缺省的内存
分配为MEMORY_LIMIT * (query_cost / MAX_COST)。推荐与
ACTIVE_STATEMENTS结合使用而不是与MAX_COST结合使用因为cost的评估很多
时候会严重失准这样将会严重影响内存分配的合理性。
版权所有Esena(陈淼 ) 编写陈淼 - 74 -
Greenplum Database 管理员指南 V6.2.1
例如创建一个活动语句数量为10内存限制为2000MB的资源队列(每个语句在
执行时在每个Primary上将获得200MB的内存)
=# CREATE RESOURCE QUEUE myqueue WITH (ACTIVE_STATEMENTS=10,
MEMORY_LIMIT='2000MB');
缺省的内存分配可以在每个语句通过设置statement_mem参数覆盖但不可超过
MEMORY_LIMITmax_statement_mem设定的值。例如分配更多的内存
=> SET statement_mem='2GB';
=> SELECT * FROM my_big_table WHERE column='value' ORDER BY id;
=> RESET statement_mem;
通常来说对于MEMORY_LIMIT的设置建议所有的资源队列的总和不要超过
Primary可以获得的物理内存总量但这个建议未必真的完全合理。如果不同类型语
句之间交错执行可能真实的使用量会远小于资源队列限制的总量所以并不能简单
的说MEMORY_LIMIT的总和绝对不能超过Primary可以获得的物理内存总量这取
决于如何安排和优化并行作业编者提醒如果某个Primary超出了内存限制超
关语句会被取消而导致失败所以如何更合理的配置内存参数以真实生产环境的多
日统计结果为依据来进行调整最为稳妥。
创建包含成本限制的资源队列
资源队列通过设置MAX_COST限制被执行的语句可消耗的最大成本(Cost)Cost
以一个浮点数(100.0或使用科学计数法如1e+2)来指定。
Cost是查询优化器(如使用EXPLAIN查看)评估出来的总预估成本。因此管理员在
设置时需要对该系统执行的查询很熟悉才可以得到一个恰当的Cost阈值。Cost意味着
对磁盘的操作数量。1.0等于获取一个磁盘页(disk page)
例如创建一个Cost阈值为100000.0 (1e+5)名称为webuser的资源队列
=# CREATE RESOURCE QUEUE webuser WITH (MAX_COST=100000.0);
或者
=# CREATE RESOURCE QUEUE webuser WITH (MAX_COST=1e+5);
这意味着分配到webuser资源队列的所有ROLE执行的全部语句Cost总和不能超
版权所有Esena(陈淼 ) 编写陈淼 - 75 -
Greenplum Database 管理员指南 V6.2.1
100000.0的限制。例如20Cost5000.0的语句正在执行21Cost
1000.0的语句提交后只能等到空闲的Cost足够时才能得到执行。
允许在系统空闲时执行语句
若一个资源队列配置了Cost阈值管理员可以设置允许COST_OVERCOMMIT(缺省
设置是FALSE经过编者实际测试与官方文档说的TRUE恰好相反)。在系统没有其他
语句执行时超过资源队列Cost阈值的语句可以被执行。而当有其他语句在执行时
Cost阈值仍被强制评估和限制。如果COST_OVERCOMMIT被设置为FALSE超过Cost
阈值的语句将永远被拒绝。这个特性听起来很不错可是仔细想一想没有其他语句在
执行的时间肯定是极少的。
允许小查询绕过队列限制
可能存在一些工作负载很小的查询管理员希望其不占用资源队列的活动语句数量
而直接被允许执行。例如一些检索系统表的语句不涉及大的资源消耗甚至不需要与
Instance进行交互。管理员可以设置MIN_COST指明低于指定的开销被认为是小查询。
那些低于MIN_COST的语句将立即被执行。MIN_COST不仅可以同MAX_COST一起使用
还可以和活动语句数量一起使用。例如
=# CREATE RESOURCE QUEUE adhoc WITH (ACTIVE_STATEMENTS=10, MIN_COST=100.0);
设置优先级级别
为了控制CPU资源的使用管理员可以设置合适的优先级。在并发争抢CPU资源时
高优先级资源队列中的语句将可以获得比低优先级资源队列中的语句更多的CPU资源。
优先级可以在CREATE RESOURCE QUEUEALTER RESOURCE QUEUE的时候通
WITH子句来设置和修改。例如adhocreporting队列指定优先级管理员可
以使用下面的命令
=# ALTER RESOURCE QUEUE adhoc WITH (PRIORITY=LOW);
=# ALTER RESOURCE QUEUE reporting WITH (PRIORITY=HIGH);
创建最高优先级的资源队列executive管理员可以使用下面的命令
=# CREATE RESOURCE QUEUE executive WITH (ACTIVE_STATEMENTS=3, PRIORITY=MAX);
在查询优先级特性开启时资源队列的优先级缺省为MEDIUM。如果关闭(GUC参数
版权所有Esena(陈淼 ) 编写陈淼 - 76 -
Greenplum Database 管理员指南 V6.2.1
gp_resqueue_priority的值为OFF或者FALSE)则不会对优先级的设置进行评估
也就是说无论什么优先级大家没有高低之分一起公平的争抢CPU资源。
重要提示要使得资源队列的优先级设置在执行语句中强制生效必须确保优先级特性
的相关参数已经设置好。
分配 ROLE(User)到资源队列
一旦资源队列被创建好了就需要把ROLE(User)分配到合适的资源队列。如果
ROLE没有被明确的分配到一个资源队列其将被分配到缺省的资源队列pg_default
缺省的资源队列有20个活动语句数量限制和MEDIUM的优先级。
使用ALTER ROLE或者CREATE ROLE命令来分配ROLE到资源队列。例如
=# ALTER ROLE name RESOURCE QUEUE queue_name;
=# CREATE ROLE name WITH LOGIN RESOURCE QUEUE queue_name;
每个ROLE同一时间只能被分配到一个资源队列可以使用ALTER ROLE命令修改
ROLE的资源队列。
资源队列的分配必须通过逐个User的方式进行。如果有一个层级较高的ROLE(
GROUP ROLE)将该ROLE分配到一个资源队列并不会将其包含的User分配到该资
源队列也就是说ROLE的资源队列属性不具有可继承的性质。
SUPERUSER总是不受资源队列的限制。SUPERUSER的查询总是可以立即得到执行
而不管资源队列的限制如何设置。
从资源队列中移除 ROLE
所有ROLE都需要分配到资源队列。如果没有被明确分配到指定的资源队列
ROLE将会进入缺省资源队列pg_default。如果想将ROLE从现有资源队列中移除并放
到缺省队列中可将其资源队列分配到none。例如
=# ALTER ROLE role_name RESOURCE QUEUE none;
版权所有Esena(陈淼 ) 编写陈淼 - 77 -
Greenplum Database 管理员指南 V6.2.1
修改资源队列
在创建资源队列后可以使用ALTER RESOURCE QUEUE命令来改变或者重置队列
的限制。还可以使用DROP RESOURCE QUEUE命令删除资源队列。
变更资源队列
使用ALTER RESOURCE QUEUE命令来改变资源队列的限制。一个资源队列必须包
ACTIVE_STATEMENTS或者MAX_COST(或者都包含)。变更资源队列设置新的参
数值。例如
=# ALTER RESOURCE QUEUE adhoc WITH (ACTIVE_STATEMENTS=5);
=# ALTER RESOURCE QUEUE exec WITH (MAX_COST=100000.0);
要将活动语句数量或者内存限制重置为无限制可以使用-1值。要重置Cost阈值
为无限制可以设置为-1值。例如
=# ALTER RESOURCE QUEUE adhoc WITH (MAX_COST=-1.0, MEMORY_LIMIT='2GB');
可以使用ALTER RESOURCE QUEUE命令改变查询优先级。例如设置一个资源队
列的优先级为最低级别
=# ALTER RESOURCE QUEUE webuser WITH (PRIORITY=MIN);
删除资源队列
使用DROP RESOURCE QUEUE命令删除资源队列。要删除一个资源队列该资源
队列不能与任何ROLE相关联或者队列中有语句正等待执行。删除一个资源队列
=# DROP RESOURCE QUEUE name;
版权所有Esena(陈淼 ) 编写陈淼 - 78 -
Greenplum Database 管理员指南 V6.2.1
检查资源队列状态
检查资源队列状态涉及以下内容
查看排队语句和资源队列状态
查看资源队列统计信息
查看分配到资源队列的ROLE
查看资源队列中等待的语句
清除资源队列中等待的语句
查看活动语句的优先级
重置活动语句的优先级
查看排队语句和资源队列状态
管理员可以通过查看视图gp_toolkit.gp_resqueue_status来查看资源队列
的状态。该视图展示系统中每个资源队列有多少个语句在等待执行多少语句正在执行。
查看资源队列在系统中当前的状态
=# SELECT * FROM gp_toolkit.gp_resqueue_status;
查看资源队列统计信息
如果要追踪资源队列的统计信息和性能需要为资源队列开启统计信息收集的配置。
这可以通过配置Masterpostgresql.conf文件的这个参数来实现(修改参数请使
gpconfig命令)
stats_queue_level = on
版权所有Esena(陈淼 ) 编写陈淼 - 79 -
Greenplum Database 管理员指南 V6.2.1
一旦该配置开启就可以使用系统视图pg_stat_resqueues来查看资源队列使
用的统计信息。注意开启该配置会带来轻微的资源开销每个通过资源队列被执行的
语句都会被追踪。开启统计信息收集对于初期的资源队列诊断是有帮助的而后期的运
行应该关闭该参数。
查看分配到资源队列的 ROLE
要查看ROLE与资源队列之间的关联关系可以使用系统视图pg_roles
gp_toolkit.gp_resqueue_status来获得
=# SELECT rolname, rsqname FROM pg_roles, gp_toolkit.gp_resqueue_status
WHERE pg_roles.rolresqueue=gp_toolkit.gp_resqueue_status.queueid;
或者可以创建一个视图来简化以后的视图。例如
=# CREATE VIEW role2queue AS
SELECT rolname, rsqname FROM pg_roles, pg_resqueue
WHERE pg_roles.rolresqueue=gp_toolkit.gp_resqueue_status.queueid;
这样就可以直接查询视图了
=# SELECT * FROM role2queue;
查看资源队列中等待的语句
当语句通过资源队列执行时其会被记录在pg_locks系统表中。这里可以查看到
所有的活动语句和等待语句。要检查处于等待状态的语句可以使用
gp_toolkit.gp_locks_on_resqueue视图。例如
=# SELECT * FROM gp_toolkit.gp_locks_on_resqueue WHERE lorwaiting = TRUE;
若该查询没有结果返回意味着此时没有语句在资源队列中等待执行。
版权所有Esena(陈淼 ) 编写陈淼 - 80 -
Greenplum Database 管理员指南 V6.2.1
清除资源队列中等待的语句
有时候可能需要清除资源队列中处于等待状态的语句。例如想要清除在资源队列
中处于等待状态还没有得到执行的语句也有可能想要终止一个已经开始而需要很长时
间才能完成的语句或者该语句处于空闲的事务状态而希望把其占用的资源让给其他需
要的ROLE。要达到这些目的首先需要知道哪些语句需要被清除确定该进程的PID
然后使用pg_cancel_backend函数来终止该进程。
例如查看当前处于活动状态或者等待状态的语句
=# SET from_collapse_limit TO 1;
SELECT rolname, rsqname, a.pid, granted, a.query, datname
FROM pg_roles r, gp_toolkit.gp_resqueue_status s, pg_locks l,
pg_stat_activity a
WHERE r.rolresqueue = l.objid AND r.rolname = a.usename
AND l.objid=s.queueid AND a.pid=l.pid;
若没有结果返回意味着当前没有语句处于资源队列中。例如有两个语句在资源队
列中可能是这种样子的
根据输出结果确定需要清除语句的进程PID(pid)。通过下面的方式清除语句
=# SELECT pg_cancel_backend(1855);
注意尽量不要使用OSKILL命令。当然也不是完全不可以用除非有把握确保不会
导致数据库损坏。
查看活动语句的优先级
gp_toolkit模式中有个视图gp_resq_priority_statement其包含了所
有正在执行的语句的优先级会话ID等信息。该视图只能通过gp_toolkit模式访问。
版权所有Esena(陈淼 ) 编写陈淼 - 81 -
Greenplum Database 管理员指南 V6.2.1
重置活动语句的优先级
SUPERUSER可以在语句运行期间通过内置函数
gp_adjust_priority(session_id, statement_count, priority)调整优
先级。通过该函数SUPERUSER可以提升或者降低任何语句的优先级。例如
=# SELECT gp_adjust_priority(752, 24905, 'HIGH');
该函数需要获取语句的SESSION IDStatement Count两个参数SUPERUSER
可以通过gp_toolkit.gp_resq_priority_statement视图获得session_id
statement_count两个参数分别对应rqpsessionrqpcommand。该函数只对指
定的语句有效同一个资源队列随后的语句仍然使用其预先设定的优先级。
版权所有Esena(陈淼 ) 编写陈淼 - 82 -
Greenplum Database 管理员指南 V6.2.1
第七章定义数据库对象
本章介绍GP的数据定义语言(DDL)以及如何创建和管理数据库对象。
创建与管理数据库
创建与管理表空间
创建与管理模式
创建与管理表
分区大表
创建与使用序列
GP中使用索引
创建与管理视图
创建与管理物化视图
创建与管理数据库
一个GP系统可以有多个数据库(Database)。这与一些DBMS不同(例如Oracle)
它们的Instance就是Database。在GP系统中虽然可以创建多个DB但是客户端程
序一次只能连接一个DB而且不可以跨越DB执行查询语句。
关于数据库模版
每个新的数据库都是基于一个模版数据库创建的这种创建可以理解为模板数据库
的复制如果基于一个非空的模版数据库来创建那么该模板数据库中的所有对象和数
据都会一模一样的复制到新创建的数据库中。缺省的数据库模版为template1在初
始化GP系统初期可以连接到该库在没有明确指定模版的情况下创建新的数据库将缺
省使用该DB作为模版除非你希望之后创建的DB包含你所创建的对象不然的话
要在该DB中创建任何对象。
除了template1之外每个新建的GP系统还包含另外两个模版template0
postgres这两个DB是系统内部使用的最好不要删除或者修改。template0模版
版权所有Esena(陈淼 ) 编写陈淼 - 83 -
Greenplum Database 管理员指南 V6.2.1
可以用来创建仅包含标准对象的完全干净的数据库。如果想避免从template1中拷贝
任何的对象可以考虑使用该模。
注意在创建新的数据库时模板数据库上必须没有任何连接否则创建数据库的操作
将会报错失败。
创建数据库
通过CREATE DATABASE命令来创建一个新的数据库。例如
=# CREATE DATABASE new_dbname;
要创建一个数据库必须具备创建数据库的权限或者是SUPERUSER身份。若没有
正确的权限是无法创建数据库的需要联系GP管理员授予必要的权限或者帮助创建一
个数据库。
还有一个客户端程序createdb可以用来创建数据库。例如通过命令行终端执行
下面的命令将会在指定的HostMasterGP集群上创建名为mydatabase的数据库
$ createdb -h masterhost -p 5432 mydatabase
克隆一个数据库
缺省情况下创建数据库是通过克隆数据库模版template1的方式完成的。然而
任何的DB都可以作为模版来创建一个新的数据库因此可以通过指定DB的方式克隆或
者拷贝出一个新的数据库新的DB包含模版库中的所有对象和数据。例如
=# CREATE DATABASE new_dbname TEMPLATE old_dbname;
查看数据库列表
psql客户端程序中直接使用\l指令查看GP中包含模版书籍库在内的所有
Database的列表。使用其他客户端程序时可以通过查询pg_database系统表来得
到。例如
=# SELECT datname from pg_database;
版权所有Esena(陈淼 ) 编写陈淼 - 84 -
Greenplum Database 管理员指南 V6.2.1
修改数据库
使用ALTER DATABASE命令来修改Database的属性例如OwnerName以及缺
省配置等。必须是该DatabaseOwner或者SUPERUSER才可以执行这样的操作。下
面的例子演示修改缺省的搜索路径
=# ALTER DATABASE mydatabase SET search_path TO myschema, public, pg_catalog;
删除数据库
使用DROP DATABASE命令来删除Database。该操作将从系统表中删除该
Database的信息记录并删除该Database包含的全部磁盘数据。必须是该Database
Owner或者SUPERUSER才可以执行删除Database操作其他用户无法删除该
Database在删除Database不能有任何用户连接到该Database包括当前的
操作用户因此可以先连接到template1(或者其他Database)然后再删除需要
删除的Database。例如
=# \c template1
=# DROP DATABASE mydatabase;
这里同样有一个客户端程序叫做dropdb用以删除Database。例如通过命令行
终端执行下面的命令将会在指定的HostMasterGP集群上删除名为mydatabase
的数据库
$ dropdb -h masterhost -p 5432 mydatabase
警告删除数据库操作是无法回退的。慎用该操作
创建与管理表空间
表空间(tablespace)允许Database管理员使用多个文件系统来存储数据库对
从而可以决定如何更好的利用他们的物理储存设备。表空间的存在有具体的意义
例如在访问频度不同的数据库对象上使用不同性能的磁盘例如将经常使用的表放在
高性能磁盘的文件系统上(例如SSD固态盘)而将其他表放在普通硬盘的文件系统上。
一个表空间GP集群中对应的是一组分布式的操作系统目录在每个Instance
上都有一个目录这些目录的集合组成了一个表空间表空间创建成功之后用户在
使用这些表空间时不需要再关心这些目录的具体位置只需要在建表时指定表空间名
版权所有Esena(陈淼 ) 编写陈淼 - 85 -
Greenplum Database 管理员指南 V6.2.1
或者设置缺省的表空间即可缺省表空间通过参数default_tablespace来设置。
6版本之前表空间还不是一个完全独立的概念其需要依赖文件空间对象
6版本之前的文件空间实际上也是一组分布式的操作系统目录在每个Instance
都有一个目录这些目录的集合组成了一个文件空间。这一段看起来和刚刚介绍表空
间的几乎一样是的没错6版本之前虽然说表空间是依赖文件空间的但是
如果这样来描述表空间也是正确的为什么一般不这样描述呢因为文件空间已经把
这个定义做好了表空间的目录就是这些文件空间的那些目录的子目录表空间在文件
空间的目录下建立以<tablespace_id>/<database_id>组成的子目录不同的数
据库中的对象用到对应的表空间时数据文件则存储到对应的子目录。
6版本中表空间的概念在单个Instance上来看几乎与PostgreSQL完全
一致当创建一个表空间时需要为该表空间指定一系列的路径而这些路径将会通过
软连接的方式关联到Instance工作目录的pg_tblspc目录下<tablespace_id>
为名称其中的目录结构为GPDB_大版本号_系统表版本号/<database_id>
这里还将继续介绍文件空间的内容实际上如果使用6之前的版本很多时候
我们的客户并不需要为创建文件空间头疼编者在为各位客户安装初始化GP集群时会
自动创建一个名为gpfs的文件空间当需要使用表空间时只需要使用这个文件空间
来创建表空间即可。
创建文件空间
注意6版本开始已经不再有文件空间的概念此处所说的是6版本之前的概念。
要创建文件空间首先需要在所有相关的GP Host主机上准备好需要的目录。文
件系统位置对于Master和所有的PrimaryMirror来说都是必须的。在准备好了文
件目录之后使用gpfilespace命令来创建文件空间。只有SUPERUSER才能进行该操
一般由gpadmin用户来完成。
注意GP并不直接知晓文件系统的界限只是把文件存向指定的目录位置。因此
一个逻辑磁盘上定义多个文件空间是没有必要的因为基于文件空间创建的表空间就是
多个子目录在一个逻辑磁盘上定义多个文件空间只会增加维护的难度。如果有多个逻
辑磁盘则需要创建创建多个文件空间虽然一般不会这样规划磁盘
使用gpfilespace创建文件空间
1. 使用gpadmin用户登录到GP系统的Master主机。
$ su - gpadmin
2. 创建一个文件空间的配置文件
版权所有Esena(陈淼 ) 编写陈淼 - 86 -
Greenplum Database 管理员指南 V6.2.1
$ gpfilespace -o gpfilespace_config
3. 将会提示输入一个文件空间的名称Primary Instance的文件系统位置
Mirror Instance的文件系统位置Master的文件系统位置。例如若每个
Instance Host配置了2Primary2Mirror将会提示输入5个文件系统
位置(包括Master)。就像这样
Enter a name for this filespace> fastdisk
primary location 1> /gpfs1/seg1
primary location 2> /gpfs1/seg2
mirror location 1> /gpfs2/mir1
mirror location 2> /gpfs2/mir2
master location> /gpfs1/master
4. 该命令将会输出一个配置文件。请再次检查该文件确保其按照期望的那样反映出了
想要使用的文件系统位置。
5. 再次执行该命令基于之前生成的配置文件创建文件空间
$ gpfilespace -c gpfilespace_config
转移临时文件或事务文件的位置
注意此处所说的是6版本之前的概念。
可以选择将临时文件或事务文件转移到一个特殊的文件空间从而改善 DB 的查询性
能、备份性能、数据读写的性能。
临时文件和事务文件缺省都是存储在每个 Instance(包括 MasterStandby
Primary Mirror)目录下。只有 SUPERUSER 可以移动该位置。只有 gpfilespace
命令可以修改临时文件和事务文件的位置。
关于临时文件和事务文件
除非另有指明临时文件和事务文件和用户数据放在一起。缺省的临时文件位置为
<filespace_directory>/<tablespace_oid>/<database_oid>/pgsql_tmp
使用gpfilespace --movetempfiles命令来修改临时文件的位置。
版权所有Esena(陈淼 ) 编写陈淼 - 87 -
Greenplum Database 管理员指南 V6.2.1
关于临时文件和事务文件需要注意以下几点
虽然可以使用同一个文件空间存储不同类型文件但只能为临时文件或者事务文件
指定一个文件空间。
如果文件空间被临时文件使用该文件空间将不能被删除。
文件空间必须提前被创建好才能使用。
使用 gpfilespace 移动临时文件
1 确保文件空间存在且与存储其他用户数据的文件空间不同。
2 GP 系统停掉保持停机状态。
注意任何活动的连接都会导致 gpfilespace --movetempfiles 操作的失败。
3 GP 启动为限制模式确保其他用户无法连接执行下面的命令
$ gpfilespace --movetempfilespace filespace_name
注意临时文件位置在 Instance 中配合共享内存使用在创建、打开、删除临时文
件时用到。如果查询用到了临时文件表明当前的可用内存已经无法满足该查询对内存
的需求。很多时候我们宁愿使用临时文件也不选择使用 SWAP 作为内存扩展方案。除非
SWAP 的性能比临时文件目录所在文件系统的性能还要高。
使用 gpfilespace 移动事务文件
1. 确保文件空间存在且与存储其他用户数据的文件空间不同。
2. GP 系统停掉保持停机状态。
注意任何活动的连接都会导致 gpfilespace --movetransfiles 操作的失败。
3. GP 启动为限制模式确保其他用户无法连接执行下面的命令
$ gpfilespace --movetransfilespace filespace_name
注意事务文件位置在 Instance 中配合共享内存使用在创建、打开、删除事务文
件时用到。
如果要移动临时文件或事务文件的目录到缺省路径使用如下命令
$ gpfilespace --movetempfilespace default
版权所有Esena(陈淼 ) 编写陈淼 - 88 -
Greenplum Database 管理员指南 V6.2.1
$ gpfilespace --movetransfilespace default
在编者看来这一块的功能几乎不会有人用到一般来说Instance 的工作目
录所在的磁盘就是整个主机上性能最好的磁盘了。
注意处所说的是 6 版本的概念。
可以选择将临时文件或事务文件转移到一个特殊的表空间从而改善 DB 的查询性能、
备份性能、数据读写的性能。GP 数据库通过 temp_tablespaces 参数来控制用于
Hash AggHash Join排序操作等临时溢出文件的存储位置。这个目录缺省为
<data_dir>/base/pgsql_tmp这与 6 之前的版本不同6 之前的版本这个目录
缺省为<data_dir>/base/<database_id>/pgsql_tmp
当使用 CREATE 命令创建临时表和临时表上的索引时如果没有明确的指定表空
temp_tablespaces 所指向的表空间将存储这些对象的数据文件。
使用 temp_tablespaces 时需要注意
1. 只能为临时文件或事务文件指定一个临时表空间该表空间还可以用于存储其他数
据对象的表空间。
2. 如果表空间被用作临时表空间该表空间将不能被删除。
创建表空间
注意此处所说的是6版本之前的概念。
一旦文件空间创建好了就可以使用该文件空间定义表空间了。要定义一个表空间
使用CREATE TABLESPACE命令例如
=# CREATE TABLESPACE fastspace FILESPACE gpfs;
表空间必须由SUPERUSER才可以创建不过在创建好之后可以允许普通的DB
User来使用该表空间。可以将CREATE权限授予相应的用户。例如
=# GRANT CREATE ON TABLESPACE fastspace TO admin;
注意此处所说的是6版本的概念
通过CREATE TABLESPACE来创建表空间。例如
=# CREATE TABLESPACE fastspace LOCATION '/data/gpfs';
版权所有Esena(陈淼 ) 编写陈淼 - 89 -
Greenplum Database 管理员指南 V6.2.1
表空间必须由SUPERUSER才可以创建不过在创建好之后可以允许普通的DB
User来使用该表空间。可以将CREATE权限授予相应的用户。例如
=# GRANT CREATE ON TABLESPACE fastspace TO admin;
正如看到的这样6版本中的表空间的概念发生了很大的变化不再需要依赖文
件空间的概念而是直接在表空间的定义中指定路径的信息这既带来了便捷也带来
了困扰以往PrimaryMirror的文件空间的路径可能是不同的而在6版本中
PrimaryMirror的路径必须相同因为没有地方可以指定相同Content值的
PrimaryMirror拥有不同的路径信息。当集群中不同的Content之间的路径也不相
同时(实际上只要一台机器多于一个数据目录肯定就会有不同)则需要使用这样的
语法来完成表空间的定义
=# CREATE TABLESPACE gpts LOCATION '/data/master_ts'
WITH(content0='/data1/gpts', content1='/data2/gpts');
不管是LOCATION还是WITH中的路径都必须指定绝对路径而且长度不能超过100
个字符否则会有问题如果没有指定WITH则所有ContentInstance都需要有
LOCATION指定的路径gpadmin用户拥有该路径的权限该目录必须为空目录
LOCATION指定Master的目录其他的Content目录全部在WITH中列出。不要试图
通过修改pg_tblspc目录下软连接的指向去设置PrimaryMirror指向不同的目录
因为这样会有一个很大的问题当出现PrimaryMirror的故障切换时在做
gprecoverseg全量恢复时GP数据库并不清楚软连接的目标是不同的这个软连接
的信息是不会存储在系统表中的做全量恢复时只是按照对应Content活着的
Instance的信息去重建。
使用表空间存储 DB 对象
表、索引、甚至整个DB都可以存储在特定的表空间。需要拥有对应的表空间的
CREATE权限的ROLE才可以在该表空间上创建对象。例如space1表空间上创建一
张名为foo的表
=# CREATE TABLE foo(i int) TABLESPACE space1;
或者使用缺省表空间参数default_tablespace来设定
=# SET default_tablespace = space1;
=# CREATE TABLE foo(i int);
在将default_tablespace设置为一个非空字符串后其相当于给CREATE
TABLECREATE INDEX等命令添加一个TABLESPACE的子句但却不必明确写出。
版权所有Esena(陈淼 ) 编写陈淼 - 90 -
Greenplum Database 管理员指南 V6.2.1
如果一个表空间与DB关联那么其将存储所有该DB的系统表、临时文件等。此外
其也是在该DB上创建表、索引等缺省的表空间(除非通过TABLESPACE或者
default_tablespace参数重新指定)。如果DB在创建的时候没有与特定的表空间相
关联那么该DB与其使用的模版DB使用相同的表空间。
一旦表空间被创建了将可以被任何有访问权限的用户在任意的DB中使用。
查看现有的表空间和文件空间
每个GP系统都有两个缺省的表空间pg_global(用以存储全局系统表的数据
系统保留不可使用)pg_default(缺省表空间存储template1template0
模版数据库和postgres数据库也是其他数据库的缺省表空间)
注意此处所说的是6版本之前的概念。
6之前的版本中这些缺省的表空间使用的是缺省的文件空间pg_system(这是
GP集群在初始化的时候建立的使用的是Instance的工作目录)
要获取文件空间的信息可以通过系统表pg_filespace
pg_filespace_entry进行关联查询。例如
=# SELECT fsname AS filespace, fsedbid AS dbid,fselocation AS datadir
FROM pg_filespace f, pg_filespace_entry e
WHERE e.fsefsoid = f.oid ORDER BY filespace,dbid;
可通过上述两个系统表与pg_tablespace关联查看表空间的完整定义。例如
=# SELECT spcname AS tablespace, fsname AS filespace, fsedbid AS dbid,
fselocation ||
decode(spcname,'pg_default','/base','pg_global','/global','/'||t.oid) AS
datadir
FROM pg_tablespace t, pg_filespace f, pg_filespace_entry e
版权所有Esena(陈淼 ) 编写陈淼 - 91 -
Greenplum Database 管理员指南 V6.2.1
WHERE t.spcfsoid = e.fsefsoid AND e.fsefsoid = f.oid
ORDER BY tablespace, dbid;
注意此处所说的是6版本的概念。
6版本中这些缺省的表空间使用的是系统初始化时指定的Master
Instance的工作目录。
要获取表空间的信息可以查询pg_tablespace系统表。例如
=# SELECT oid,* FROM pg_tablespace;
然后使用gp_tablespace_location()函数来查看具体某个表空间的目录信息。
例如
=# SELECT * FROM gp_tablespace_location(86891) ORDER BY gp_segment_id;
通过该函数无法查询到缺省表空间pg_globalpg_default的目录信息不过
这些信息可以通过查询gp_segment_configuration系统表的datadir字段来获
取。
版权所有Esena(陈淼 ) 编写陈淼 - 92 -
Greenplum Database 管理员指南 V6.2.1
删除表空间和文件空间
在表空间相关的所有对象被删除之前该表空间是不能被删除的。同样的对于6
之前的版本来说在相关的表空间被删除之前文件空间也是不能被删除的。
要删除表空间可通过DROP TABLESPACE命令完成。表空间只能被其Owner
SUPERUSER删除。
6版本之前要删除文件空间可通过DROP FILESPACE命令完成。只有
SUPERUSER可以删除文件空间。
注意6版本之前如果文件空间被临时文件或者事务文件使用该文件空间将不能
被删除。在6版本开始如果表空间被临时文件或者事务文件使用该表空间将不能被
删除。
创建与管理模式
模式(Schema)是在DB内组织对象的一种逻辑结构。模式可以允许用户在一个DB
内不同的模式之间使用相同Name的对象(例如Table)
缺省"Public"模式
每个新创建的DB都有一个缺省的模式public。如果没有创建其他的模式在创建
DB对象时将缺省使用public模式。缺省情况下所有的ROLE(User)都有public模式
下的CREATEUSAGE权限。而在创建其他模式时需要将该模式授权给相关的
ROLE(User)
创建模式
使用CREATE SCHEMA命令来创建一个新的模式。例如
=# CREATE SCHEMA myschema;
要访问某个模式中的对象可以通过模式名加小数点加对象名来指明对象所属的模
式。例如
schema.table
版权所有Esena(陈淼 ) 编写陈淼 - 93 -
Greenplum Database 管理员指南 V6.2.1
还可以在创建模式的时候将Owner设置为其他ROLE(User)。语法如下
=# CREATE SCHEMA schemaname AUTHORIZATION username;
模式搜索路径
当需要查询特定模式下的对象时可以通过明确指定模式名的方式来实现。例如
=# SELECT * FROM myschema.mytable;
若不想通过指定模式名称的方式来实现可以通过设置search_path参数来完成。
该参数告诉DB在哪些可用的模式中搜索对象。在不指明模式名称的情况下搜索路径
(search_path)列表中的第一个模式将成为缺省模式例如创建对象等操作时对象
将会自动创建到search_path的第一个模式中。
设置模式搜索路径
search_path用于设置模式的搜索顺序。该参数可以通过ALTER DATABASE命令
修改DB的模式搜索路径。例如
=# ALTER DATABASE mydatabase SET search_path TO myschema, public, pg_catalog;
还可以通过ALTER ROLE命令修改特定ROLE(User)的模式搜索路径。例如
=# ALTER ROLE sally SET search_path TO myschema, public, pg_catalog;
设置了模式搜索路径之后在未明确指明模式名称的情况下访问DB对象将会按
search_path列表的顺序依次在相应的Schema中查找对应的Object直到找到为
若在不同的Schema中存在相同NameObjectDB优先匹配search_path中靠
前的Schema下的Object
查看当前的模式
有时不确定当前所在的模式或者搜索路径。要查看这些信息可以通过使用
current_schema()函数或者SHOW命令来查看。例如
=# SELECT current_schema();
=# SHOW search_path;
版权所有Esena(陈淼 ) 编写陈淼 - 94 -
Greenplum Database 管理员指南 V6.2.1
删除模式
使用DROP SCHEMA命令来删除模式。例如
=# DROP SCHEMA myschema;
缺省状态下只有空的模式才可以被删除。若想要直接删除模式及相关的所有
Object(TableIndexFunction)。使用如下命令
=# DROP SCHEMA myschema CASCADE;
系统模式
下面的这些系统模式在所有的DB中都存在
pg_catalog模式存储着系统表(System Catalog Table)、内置类型(Type)
函数(Function)和运算符(Operator)。该模式无论是否在search_path中指
都存在search_path因为没有这个模式的话SQL将无法执行数据库
将无法使用。
information_schema模式由一组标准化视图构成这些视图用于以标准化的方
法从系统表中查看对象信息不过该模式中的很多视图定义复杂且臃肿当库中
对象较多时这些视图的性能可能会很差有时候只需要查询必要的信息时可以
考虑写SQL重新实现。
pg_toast模式是一个储存大对象的地方(那些超过页面尺寸(page size)的记
)。该模式仅供GP系统内部使用通常不建议管理员或者任何用户访问。
pg_bitmapindex视图是一个储存Bitmap Index对象的地方。该模式仅供GP
系统内部使用通常不建议管理员或者任何用户访问。
pg_aoseg视图是一个储存append-optimized表辅助信息的地方。该模式仅供
GP系统内部使用通常不建议管理员或者任何用户访问。
gp_toolkit是一个管理用的模式可以查看和检索系统日志文件和其他的系统
信息。gp_toolkit视图包含一些外部表、视图、函数可以通过SQL的方式访问
它们。gp_toolkit视图对于所有DB User都是可以访问的。
版权所有Esena(陈淼 ) 编写陈淼 - 95 -
Greenplum Database 管理员指南 V6.2.1
创建与管理表
GP中的Table除了数据是分布在不同Instance这点外和其他关系型数据库的
Table是很类似的。在创建Table需要一个额外的SQL语法来指明Table的分布策
略。
创建表
CREATE TABLE命令用于创建一张新的Table和定义其结构。在创建Table
通常需要定义如下几个方面的信息
都有哪些字段(Column)以及对应的数据类型。
Table或者Column的约束(Constraint)其限定了Table或者Column可以储
存什么样的数据。
Table的分布策略其决定了TableData如何被分割存储在GP的各个
Instance上。
TableDisk上的存储方式。例如压缩、按列存储等选项。
大表的分区策略(Partition Table)
选择 Column 的数据类型
ColumnData Type决定了其可以储存什么类型的数据值。通常应该考虑使用最
小的空间储存数据不是为了节省空间重要的是要考虑Data Type对数据范围的
约束。例如使用Character类型储存字符串Date或者Timestamp储存日期
Numeric储存数字等如果用TEXT来存储VARCHAR(32)将会允许任意数据范围
这样会导致很多异常数据不容易被发现。
对于Character类型来说CHARVARCHARTEXT之间不存在性能差异当然
是在不考虑填补空白导致的储存尺寸增加的情况下。然而在其他的DB系统中可能
CHAR会表现出最好的性能但在GP中是不存在这种性能差异的。在多数情况下应该
选择使用TEXT或者VARCHAR而不是CHAR
对于Numeric类型来说应该尽量选择更小的数据类型来存储数据。例如选择
版权所有Esena(陈淼 ) 编写陈淼 - 96 -
Greenplum Database 管理员指南 V6.2.1
BIGINT类型来存储SMALLINT类型范围内的数值会造成空间的大量浪费。另外
于宽泛的类型定义会容许异常的数值造成隐藏的问题且不容易被发现应该选择合
适的类型当有异常数据尝试插入表中时会因为类型不匹配而报错。
对于打算用来做Table JoinColumn来说应该考虑选择相同的数据类型。如
果做JoinColumn具有相同的数据类型(例如主键Primary Key与外键Foreign
Key)其工作效率会更高。如果两者的数据类型不同DB还需要将其中一个类型做转
换才可以做关联比较这种开销是不必要的浪费。
设置 Table Column 的约束
数据类型用来限制在Table中可以存储的数据的性质。但对于很多应用来说数据
类型提供的限制粒度太大。SQL标准允许在TableColumn上定义约束。约束将允许
Table的数据上使用更多的限制。如果User试图在Table上储存违反约束的数据将
会报错。在GP中使用约束是有一些限制的最为显著的是外键(Foreign Key)、主键
(Primary Key)和唯一约束(Unique Constraint)。对其它类型约束的支持与
PostgreSQL相同。
检查约束
检查约束是最常见的约束类型。其通过指定数据必须满足一个布尔表达式来约束。
例如要求产品的价格必须为正数可以这样
=# CREATE TABLE products (
product_no integer,
name text,
price numeric CHECK (price > 0)
);
非空约束
非空约束简单的理解就是不可以存在空(NULL)值。非空约束是一种Column类型
版权所有Esena(陈淼 ) 编写陈淼 - 97 -
Greenplum Database 管理员指南 V6.2.1
的约束。例如
=# CREATE TABLE products (
product_no integer NOT NULL,
name text NOT NULL,
price numeric
);
唯一约束
唯一约束可以确保包含某些Column的数据在整个Table中是唯一的。在GP中使用
唯一约束存在强制限制条件Table必须是HASH分布的或者复制分布的(而不是
DISTRIBUTED RANDOMLY)如果是HASH分布的唯一约束的Column集合必须完整
包含所有的DK Column也就是说分布键字段的集合必须是唯一约束的字段集合的
子集。例如
=# CREATE TABLE products (
product_no integer UNIQUE,
name text,
price numeric
) DISTRIBUTED BY (product_no);
复制分布的表对唯一约束没有限制条件因为每个Instance都包含了完整的数
无论如何都不会发生跨Instance检查唯一性的情况。如同之前介绍GP的分布式概
念中提到的GPShare-Nothing结构的每个Instance只负责自己的数据和计算
对于唯一约束也一样假如唯一约束的字段不能包含全部的分布键字段就可能需要跨
Instance检查数据的唯一性这是无法做到的也违反Share-Nothing的设计初衷。
主键约束
主键约束就是唯一约束与非空约束的结合体。在GP中使用主键约束存在强制条件
Table必须是HASH分布的或者复制分布的(而不是DISTRIBUTED RANDOMLY)并且
主键约束的Column集合必须完整包含所有的DK Column。如果一个Table包含主键
且在建表时没有指定分布键那么主键将被用作分布键也就是说会把主键包含的所
有字段用作分布键。例如
版权所有Esena(陈淼 ) 编写陈淼 - 98 -
Greenplum Database 管理员指南 V6.2.1
=# CREATE TABLE products (
product_no integer PRIMARY KEY,
name text,
price numeric
) DISTRIBUTED BY (product_no);
创建主键和创建唯一约束+非空约束的效果是完全等价的。
外键约束
在目前版本的GP中外键约束是没有被支持的。可以定义外键约束但参照完整性
是无效的就是说DB不会理会定义参照完整性限制。
外键约束要求一个Table中某些Column的值必须在另外一个Table中出现。这样
可以保持两个相关表之间的数据参照完整性。在当前版本的GP在分布式的Table
之间的数据参照完整性检查是无效的如同唯一约束中所述要支持该功能将无法避
免的需要跨Instance检查数据性能会失控。
选择表的分布策略
GP的所有Table都是分布式存储的。在CREATE TABLEALTER TABLE的时候有
DISTRIBUTED BY(HASH分布)DISTRIBUTED RANDOMLY(随机分布)
DISTRIBUTED REPLICATED(复制分布)子句用以决定TableRow数据如何分布。
在选择表的分布策略时需要重点考虑以下几点(依次更重要)
平坦的数据分布 -- 为了尽可能达到最好的性能所有的 Instance 应该尽量储
存等量的数据。若数据的分布不平衡或倾斜那些储存了较多数据的 Instance
在处理自己那部分数据时将需要耗费更多的时间。为了达到数据的平坦分布可以
考虑选择唯一性较高的 DK。虽然主键往往是唯一性最好的字段但是不建议
为了选择一个分布键而去增加一个主键这是一种逻辑颠倒的做法通常应该选
择一个常用于大表之间关联的某个唯一性较高的字段作为分布键一般这个字段可
能在其他某个表中具有主键特征例如客户 ID例如会员卡号例如手机号码
例如身份证号码等等在选择分布键时仅需要考虑大表与大表之间的关联
何涉及到小表关联的场景均不应作为选择分布键的考虑因素。
版权所有Esena(陈淼 ) 编写陈淼 - 99 -

 

 

 

 

 

 

 

Content      ..      1      2      3      ..