Greenplum Database (V6.2.1) - 6

 

  Index      Manuals     Greenplum Database (V6.2.1)

 

Search            copyright infringement  

 

   

 

   

 

Content      ..     4      5      6      7     ..

 

 

 

Greenplum Database (V6.2.1) - 6

 

 

Greenplum Database 管理员指南 V6.2.1
错误记录处理
可读外部表通常用于将数据导入数据库内的常规数据表中。通过CREATE TABLE
AS SELECT或者INSERT INTO . . . SELECT语句来实现数据的导入。缺省情况下
如果数据中包含了错误的记录格式整个命令将会失败不会有数据被导入目标表中。
SEGMENT REJECT LIMIT子句允许将可读外部表中格式错误的记录进行隔离
正确的记录可以正常的导入目标表中。通过该子句可以设置错误记录隔离的阈值允许
按照百分比(PERCENT)或者记录数(ROWS)来限制当格式错误的记录数量超过设置的
阈值整个导入操作仍然会失败这个阈值的设定可用于控制数据质量确保在有大量
数据异常时可以失败报错。这个阈值是针对每个Primary进行统计的并不是全局
统计。
当格式错误的记录数量没有达到设置的阈值对外部表的查询整体是成功的
误的记录会被隔离还可以选择是直接丢弃这些错误的记录或者记录到日志信息中
(通过在SEGMENT REJECT LIMIT子句前加上LOG ERRORS子句实现)以便进一步的
处理(比如找到错误的原因可以有助于改善数据质量)
当指定了SEGMENT REJECT LIMIT子句GP读取可读外部表时就开启了单行
错误隔离模式对于多字段、少字段、字段数据类型不匹配、编码错误等都可以进行
隔离但不会对约束冲突进行隔离数据违反目标表的约束仍会导致数据导入的失败。
不过这种情况在导入时可以进行必要的过滤处理。例如
=# INSERT INTO table_with_pkeys
SELECT DISTINCT * FROM external_table;
定义一个错误记录隔离的外部表
用一个简单的例子来说明
=# CREATE EXTERNAL WEB TABLE test_ext (a int, b int, c int)
EXECUTE E'for i in {1..9};do echo "$i|$((i+100))|$((i+200))a";done
版权所有Esena(陈淼 ) 编写陈淼 - 250 -
Greenplum Database 管理员指南 V6.2.1
echo "1|3|5"' ON ALL
FORMAT 'text' (delimiter E'\x7c')
LOG ERRORS SEGMENT REJECT LIMIT 10 ROWS;
SELECT * FROM test_ext;
NOTICE: found 18 data formatting errors (18 or more input rows), rejected
related input data
a | b | c
---+---+---
1 | 3 | 5
1 | 3 | 5
(2 rows)
该例中SEGMENT REJECT LIMIT子句前使用了LOG ERRORS子句错误记录将
会被记录到GP数据库的统一的错误记录日志中如果没有LOG ERRORS子句错误记
录将会被直接丢弃。
使用GP自带的函数gp_read_error_log('external_table')可以查看出错
记录的日志。从5版本开始GP的可读外部表不再使用ERROR表来记录错误记录
是使用统一的错误记录日志来记录通过gp_read_error_log函数来查询错误记录
日志通过gp_truncate_error_log函数来清除指定的错误记录日志。原因是
前的ERROR表无法保证事务的原子性在多个外部表并发使用一张ERROR表时会报错。
将这个例子稍微改一下用百分比来定义阈值
=# CREATE EXTERNAL WEB TABLE test_ext (a int, b int, c int)
EXECUTE E'for i in {1..9};do echo "$i|$((i+100))|$((i+200))a";done
echo "1|3|5"' ON ALL
FORMAT 'text' (delimiter E'\x7c')
LOG ERRORS SEGMENT REJECT LIMIT 10 PERCENT;
SELECT * FROM test_ext;
NOTICE: found 18 data formatting errors (18 or more input rows), rejected
related input data
a | b | c
---+---+---
1 | 3 | 5
1 | 3 | 5
(2 rows)
定义的百分比阈值是10%正确的记录是2错误的记录是18但是查询依
然成功了。这里需要解释一下gp_reject_percent_threshold这个参数该参数
定义了一个阈值(记为N缺省值为300)在使用百分比设置时对于每个Primary
N条记录不统计失败的百分比这是一个无奈的方法因为如果不设置这样的
阈值当第一条记录就是错误数据(或者前几条记录的错误记录数较多)就直接到
达了100%无论后续的数据质量如何都会整体失败。
版权所有Esena(陈淼 ) 编写陈淼 - 251 -
Greenplum Database 管理员指南 V6.2.1
还有一个参数gp_initial_bad_row_limit该参数的缺省值为1000当开始
的数据全部为错误记录且达到了该参数设定的值整个导入操作就失败了如果有一
条正确的记录整体操作不受该参数影响。
对于外部表这两个参数都是对单个Primary作用的因为Primary之间都是独
立工作的无法在处理的过程中互相串通这种统计数据。如果能在处理完最后一条记录
时统计一下整体的成功率是不是就不需要这两个参数了编者觉得设计有待改善。
查看错误记录日志
错误记录日志的格式为
字段
类型
描述
cmdtime
timestamptz
查询外部表的 SQL 命令执行的时间。
relname
text
外部表的名称或者 COPY 命令的目标表名称。
filename
text
错误记录所在的文件名称(可能是 URI 或者 URL)
linenum
int
错误记录所在的文件中的行号。
bytenum
int
gpfdist 是按照 block 来分拆文件的无法记录行号
以记录出错位置的字节数。
errmsg
text
错误记录的错误信息。
rawdata
text
错误记录的文本数据。
rawbytes
bytea
比如编码错误等无法记录错误记录的文本将记录错误记
录的八进制编码。
gpfdist 服务
在使用CREATE EXTERNAL TABLE命令创建外部表时使用了gpfdist协议
以用gpfdist服务来提供数据。当使用gpfdist服务配合gpfdist协议的外部表时
GP集群的Primary可以并行的读写外部数据。
本节主要包括以下内容
关于gpfdist和外部表。
关于gpfdist的规划和性能。
控制Primary访问gpfdist的并发。
安装gpfdist
版权所有Esena(陈淼 ) 编写陈淼 - 252 -
Greenplum Database 管理员指南 V6.2.1
启停gpfdist
gpfdist的故障排查。
关于 gpfdist 和外部表
gpfdist服务的命令GP数据库集群的每台主机上自带安装了
$GPHOME/bin目录下sourceGPpath文件之后就可以直接使用该命令了。当
启动gpfdist服务时需要指定服务监听的端口和工作目录(该目录内的数据都可以被
访问)。例如下面的命令是启动一个gpfdist服务端口为8080目录为/并将服
务提交后台运行
$ nohup gpfdist -p 8080 -d /../ &
此处说明一下gpfdist不允许直接在/目录上启动服务因此可以通过/../
方式间接的从/上启动服务。
CREATE EXTERNAL TABLE命令的LOCATION子句将外部表指向一个或者多个
gpfdist服务如果是可读外部表gpfdist服务将根据外部表的URI路径在其工
作的相对路径下找到对应的文件读取这些文件并分拆为一个一个的block分发给
GP数据库的Primary(根据Primary的请求情况)Primary收到数据包之后按照外
表定义的ROW类型进行处理格式化为表的tuple然后根据具体执行语句的情况决定
在哪里进一步处理这些tuple(实际上这一步已经不属于外部表的职责格式化为
tuple之后的操作都是因为实际任务的需要优化器为执行计划增加的处理操作)
如要将数据INSERT到一张常规的数据表中Primary将会根据目标表的分布键来决定
将数据重新发送到哪个Primary。如果是可写外部表Primary将会把表的tuple
式化为文本然后打包发送给gpfdist服务gpfdist再将这些数据包写到一个或多个
文件中当写到多个文件时(LOCATION中会有多个URI选项)根据可写外部表指定的
分布键来决定发送给哪个gpfdist服务。
关于 gpfdist 的规划和性能
可以在不同的机器上运行多个gpfdist服务也可以在一台机器上运行多个
gpfdist服务。从而可以充分利用文件服务器的IO性能和网络带宽以配合GP外部表
高速的并行数据加载性能获得更高的数据导入和导出的性能。
版权所有Esena(陈淼 ) 编写陈淼 - 253 -
Greenplum Database 管理员指南 V6.2.1
gpfdist服务允许一个外部表同时使用一台gpfdist文件服务器的多个网络
端口以提升数据访问的性能。这是因为gpfdist不通过网络地址来区分是否为
对同一个资源的请求。而是通过X-GP-XIDX-GP-CIDX-GP-SNHeader信息来
区分的。如下图所示一个gpfdist服务GP外部表经由多个网络端口来访问。
具体到URI来说不同的URI通过不同的主机名指向相同的gpfdist服务的相
同目录和文件实际上获取的是一份文件利用了多个网络带宽只有这种情况才是
对同一份文件利用了多个网络带宽如果gpfdist服务、文件路径或文件名称有任何
的不同都不是同一份资源在使用这一特性时需要注意避免重复加载数据。
可以将数据文件均匀的分散到多个gpfdist服务同时为外部表提供数据可以
提升外部数据源的供数性能。比如将数据均分到两台文件服务器上每台文件服务器
上启动一个gpfdist服务。例如
版权所有Esena(陈淼 ) 编写陈淼 - 254 -
Greenplum Database 管理员指南 V6.2.1
对于性能很高的文件服务器来说在多个端口(PORT)上启动gpfdist服务很有必
毕竟一个gpfdist服务使用的CPU资源有限当需要处理压缩、多并发等场景时
使用多个gpfdist服务可以提升高性能文件服务器的资源利用。
编者认为分隔符对数据导出到gpfdist的性能几乎不会有任何影响实际上
对可写外部表性能影响最大的是Primary每次向gpfdist服务发送的数据包的尺寸
4.3.7版本之前Primary发送的数据包的缺省尺寸是32K由于是HTTP协议的数
据传输大量数据导出时更多的时间浪费在反复的HTTP连接建立和断开将这个尺
寸提升到比如16MB导出的性能得到极大提升可以瞬间占满gpfdist服务所在文件
服务器的所有网络端口这个尺寸由writable_external_table_bufsize参数设
目前的版本该参数的缺省值为64KB还是太小了建议直接设置到16MB
控制 Primary 访问 gpfdist 的并发
通过gp_external_max_segs参数来控制同时访问一个gpfdist服务的
Primary的数量这样可以减轻gpfdist所在服务器的网络压力该参数的缺省值是
64对于绝大部分的情况不需增加这个参数反而对于一些gpfdist所在服务器的
网络环境较差的情况需要适当的减小这个参数当然对于网络环境好的情况增加
这个参数是可以提升外部表导入的性能的。不过这个参数仅对gpfdist外部表有效
其他协议不受此影响。
版权所有Esena(陈淼 ) 编写陈淼 - 255 -
Greenplum Database 管理员指南 V6.2.1
安装 gpfdist
可以在所有安装了GP服务端软件的机器上运行gpfdist服务也可以在需要运行
gpfdist服务的机器上复制一份GP服务端软件的安装目录。或者安装loaders客户端。
启停 gpfdist
可以在当前目录启动gpfdist服务如果不使用-d参数指定工作目录缺省的工
作目录是当前执行命令的目录。如果不使用-p参数指定监听的端口缺省的监听端
口为8080。例如下面的命令是启动一个gpfdist服务端口为8080目录为/
将服务提交后台运行
$ nohup gpfdist -p 8080 -d /../ &
可以通过-l参数来指定gpfdist服务的日志输出如果不需要gpfdist的输出
可以这样启动gpfdist服务
$ nohup gpfdist -p 8080 -d /../ >/dev/null 2>&1 &
$ nohup gpfdist -p 8081 -d /../ >/dev/null 2>&1 &
正如上面的例子可以在相同的目录上启动多个gpfdist服务只要监听端口不
同即可。这样就可以为不同的外部表配置不同的gpfdist服务更充分的利用CPU资源。
要停止后台运行的gpfdist服务可以先找到gpfdist服务的进程ID
$ ps ax|grep gpfdist
使用kill命令杀掉gpfdist的进程。例如(加入2345gpfdist的进程ID)
$ kill 2345
gpfdist 的故障排查
Primary在外部表被访问时才会真正的访问LOCATION中的资源指向在定义外部
版权所有Esena(陈淼 ) 编写陈淼 - 256 -
Greenplum Database 管理员指南 V6.2.1
表时并不会检查资源是否存在或者是否可以访问。如果查询外部表时有访问方面的报
错信息首先要确保gpfdist已经正确的启动然后确定所有Primary所在的机器可
以正常的访问gpfdist服务。可以通过下面的步骤来测试gpfdist服务的可访问性
1 首先确定gpfdist已经启动
$ ps ax|grep gpfdist
根据输出信息确定gpfdist的进程ID(pid)比如pid5134
2 如果已经启动确认服务的监听端口和工作目录(上一步输出中已经显示的信息
可以不用确认)
$ netstat -nltp|grep gpfdist
$ lsof -p 5134|grep cwd
根据输出信息确定gpfdist服务的监听端口和工作目录。
3 确定工作目录下有一个小尺寸文件用于测试可访问性比如有个file0文件
听的端口为8080。先在gpfdist服务器本地执行如下测试命令
$ wget --delete-after --header 'X-GP-PROTO:0' http://localhost:8080/file0
如果可以成功获取测试数据文件再从GP集群的所有主机测试该命令确保所有
主机都可以成功获取测试数据文件。这一步需要修改URL的主机名信息为真实的主机名
或者IP地址。
使用外部表导入数据
使用外部表导入数据到GP数据库中涉及以下几方面的前期准备工作
1 启动gpfdist服务或者配置PXF服务。
2 确定数据文件所在的目录位置。
3 根据文件的数据格式创建外部表。
在这些工作准备就绪之后就可以直接通过外部表来查询外部数据了。剩下的事情
就像使用常规的数据表一样来进行数据导入操作。例如使用INSERT INTO命令实现
从外部表ext_expenses导入类型为'travel'的数据到expenses_travel数据表
版权所有Esena(陈淼 ) 编写陈淼 - 257 -
Greenplum Database 管理员指南 V6.2.1
=# INSERT INTO expenses_travel
SELECT * from ext_expenses where category='travel';
正如该例中所示在查询外部表时可以像使用常规的数据表那样使用各种过滤条件。
再例如新建一张表并将外部表的数据全部导入
=# CREATE TABLE expenses AS SELECT * from ext_expenses;
使用外部表导出数据
可写外部表用于将库内的数据导出。可以是文件可以是命名管道可以是其他
的应用程序(比如WEB服务)GP MapReduce已经毫无意义了不提也罢。不过
果对性能和稳定性有很高的要求导出到命令管道可能会是一项极其复杂的工作
为命名管道的状态无法精确的控制和获取这就导致在编程时需要设计很多的迂回措
施来解决这些问题最典型的场景就是以前的gptransfer命令目前该命令已经废除
不过该命令从一开始出现就注定是失败的可以欣赏一下这段代码注释
# Make sure all named pipes get an EOF on them or empty tables
# will hang.
# TODO: currently no way to ensure gpfdist on the write side has
#
written all data available to the pipe. Closing the pipe
#
while data is remaining causes and EPIPE on the writable
#
gpfdist side. Need a better way to coordinate this.
time.sleep(self._wait_time)
gptransferPython代码中充斥着各种sleep操作因为无法精确控制命
名管道的状态导致的结果是一个表中哪怕只有几条记录也需要花费至少十多秒来
完成数据的传输。在不追求极致性能的场景很多时候命名管道是非常不错的方案
这样就可以与其他程序进行无缝对接实现不落地的数据导入和导出。
使用 gpfdist 协议外部表导出数据
使用gpfdist协议的可写外部表导出数据时数据库的Primary将打包好的文本
数据发送给gpfdist服务gpfdist服务将数据写入目标文件中。必须所有Primary
都可以访问gpfdist服务数据是在Primarygpfdist服务之间直接传输的不经
Master(断开Mastergpfdist之间的网络并不影响gpfdist外部表的使用)
版权所有Esena(陈淼 ) 编写陈淼 - 258 -
Greenplum Database 管理员指南 V6.2.1
要将导出的数据分拆到多个文件中需要指定多个URI属性每个URI指定一个文
并结合可写外部表的DISTRIBUTED子句来决定数据的分布情况。URI中也可以使
用通配符但是不得匹配多个文件所以虽然可以用实际无意义。URI的数量也
不能超过Primary的数量。关于DISTRIBUTED子句缺省使用的是随机分布的策略
这也是建议的最佳选项如果一定要选择HASH分布的策略建议选择需要导出数据的
表的分布键作为可写外部表的分布键如果这样做了再次使用这些文件导入同构的
GP集群时也需要每个文件都列出来否则会影响导入的性能因为通配符匹配的文
件是一个一个读取的这样会大致实际匹配的Primary是一个一个匹配的。例如
=# CREATE WRITABLE EXTERNAL TABLE test_ext
(a integer, b integer, c integer)
LOCATION (
'gpfdist://mdw:8080/tmp/file1.gz',
'gpfdist://mdw:8080/tmp/file2.gz'
)
FORMAT 'text' (delimiter '|');
=# INSERT INTO test_ext SELECT i+10,i+20,i+30
FROM generate_series(1,10) i;
使用基于命令的 WEB 型外部表导出数据
定义基于命令的WEB型外部表将数据发送至脚本或命令。当向基于命令的可写
WEB型外部表INSERT数据时数据将会以输入流的形式发送给这些脚本或命令。这些
脚本或命令将由GP集群内的所有Primary通过gpadmin用户来执行这与基于命令的
可读WEB型外部表不同基于命令的可读WEB型外部表可以指定执行脚本或命令的
Primary范围或HOST范围基于命令的WEB型可写外部表不行哪怕Primary上没
有数据脚本或命令也会被调用因为每个Primary都有自己需要处理的任务自己
的数据不能由其他Primary来处理。外部表中的脚本或命令是由数据库执行的所以
并不会source gpadmin用户的登录文件(.bashrc.profile)在执行命令时
可以手动source这些环境文件也可以使用预先定义好的GP环境变量。例如
=# CREATE WRITABLE EXTERNAL WEB TABLE test_ext
(a integer, b integer, c integer)
EXECUTE 'more > /tmp/test_ext.out'
FORMAT 'TEXT'
DISTRIBUTED RANDOMLY;
=# INSERT INTO test_ext SELECT i+10,i+20,i+30
FROM generate_series(1,10) i;
版权所有Esena(陈淼 ) 编写陈淼 - 259 -
Greenplum Database 管理员指南 V6.2.1
关于可用的GP环境变量可参考"基于命令的WEB型外部表"章节的介绍。
使用 COPY 命令导入导出
COPYPostgreSQL的命令非常有用可以实现非并行的数据导入与导出。通
COPY命令可以实现把数据从文件导入常规的数据库表中或者将表中的数据或一
个查询的结果导出到文件中不仅是文件还可以是标准输入输出。COPY是很多工具
的功能基础比如备份恢复集群之间的数据同步基本上都是在COPY的功能基础
上构建的。虽然COPY命令本身是串行的(后来因为gpcopygpbackup的需要引入
ON SEGMENT子句从命令的层面实现了并行不过这种并行是针对所有Primary
实例的操作的都是Primary实例的本地文件与一般意义上的COPY不同)但如果
并行调用那就是并行了以前的备份恢复都是通过并行调用COPY命令来实现并行的。
COPY命令每次执行不论是导入还是导出都只能指定一个文件不可以使用通
配符匹配多个文件 -- 不认通配符。
还需要注意6版本的语法差异6版本中可以把格式选项放在WITH()6版本
之前是不能这么写的不过6版本仍然可以省略WITH关键字格式选项也可以按照之
前版本的格式连着写。
COPY 导入
使用COPY FROM命令可以将数据从文件或者标准输入追加到目标表中。COPY不是
并行的是串行的每条数据都需要经过Master串行的处理和分发因此COPY应该
只用于数据量不大的导入导出的场景。
COPY的文件必须在Master的主服务进程可以访问的位置。文件路径必须是
Master工作目录的相对路径或者绝对路径。
COPY数据到STDOUT或从STDIN COPY数据数据时实际上是GPMaster和客
户端之间的数据复制。这样就实现了远程流数据的复制比如要从一个集群复制少量数
据到另一个集群可以采用如下的命令
$ psql -h src -d srcdb -c 'COPY test TO STDOUT'|psql -h des -d desdb -c 'COPY
test FROM STDIN'
版权所有Esena(陈淼 ) 编写陈淼 - 260 -
Greenplum Database 管理员指南 V6.2.1
COPY 导入文件
使用COPY导入文件实际上是数据库的postgres主服务进程在服务器上打开了
指定的文件并完成数据的导入。所以数据库的运行用户必须拥有该文件的读取权限
文件路径必须是Master工作目录的相对路径或者绝对路径。例如
=# COPY test FROM '/tmp/file0' DELIMITER '|';
COPY STDIN 导入
为了避免需要先将文件复制到Master主机上使用COPY FROM STDIN命令通过
标准输入将数据输送到Master服务。如果COPY FROM STDIN命令运行时还没有已
经就绪的标准输入(比如COPY命令是在其他命令的标准输出之后的匿名管道接着执
)COPY FROM STDIN命令执行开始将会开始接受每行一条记录的数据输入
直到接收到反斜杠和一个小数点(\.)结束。例如
=# copy test from stdin;
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself, or an EOF signal.
>> 1
2
3
>> \.
COPY 1
以前的gpcrondump类的备份命令备份出来的数据就是这种格式的文件数据
SQL混合在一起直接当做SQL文件执行即可。
\COPY 导入数据
\COPY是一个和COPY完全不同的命令\COPY的工作原理和COPY FROM STDIN
一致的数据通过psql客户端发送到服务器。因此\COPY命令操作的是psql客户端
所在机器的本地文件运行psql命令的OS用户必须拥有这些文件的访问权限。\COPY
可以理解为对COPY FROM STDIN的包装也是为了避免将数据文件复制到Master
机上。例如
版权所有Esena(陈淼 ) 编写陈淼 - 261 -
Greenplum Database 管理员指南 V6.2.1
=# \COPY test FROM '/tmp/file0' DELIMITER '|';
可以在任意可以使用psql命令访问GP数据库的机器上运行\COPY命令可以是任
意有文件访问权限的OS用户甚至是root
COPY 数据格式
COPY FROM允许使用FORMAT子句来指定输入的数据格式可选的选项是TEXT
CSVBINARY(5版本和6版本支持该选项4版本不支持)。例如
=# COPY test FROM '/tmp/file0' WITH(FORMAT CSV);
缺省情况下CSV格式的字段分隔符为逗号(,0x2C)TEXT格式的字段分隔符为
水平制表符(0x09)可以使用DELIMITER来指定不同的字段分隔符。例如
=# COPY test FROM '/tmp/file0' WITH(FORMAT CSV, DELIMITER '|');
缺省情况下文件的编码使用的是客户端的编码可以通过ENCODING来指定文件
的编码。例如
=# COPY test FROM '/tmp/file0' WITH(DELIMITER '|', ENCODING 'latin1');
COPY 的错误记录隔离
缺省请款下如果导入的数据包含错误的记录在第一条错误记录发生时整个操
作就会失败退出且不会有任何数据被导入。如果使用了错误记录隔离模式数据库会
跳过包含错误的记录并将正确的数据记录导入目标表中。错误记录隔离仅对格式错
误的数据有效违反约束(比如NOT NULLCHECK和唯一性约束等)的数据仍会导致整
个导入失败不会有任何数据被导入。
在使用COPY导入数据时使用SEGMENT REJECT LIMIT子句对错误记录进行隔
离。通过该子句可以设置错误记录隔离的阈值允许按照百分比(PERCENT)或者记录
(ROWS)来限制当格式错误的记录数量超过设置的阈值整个导入操作仍然会失败
这个阈值的设定可用于控制数据质量确保在有大量数据异常时可以失败报错。这个阈
值是针全局统计的(编者实测是全局的不是每个Primary统计自己的因为COPY
版权所有Esena(陈淼 ) 编写陈淼 - 262 -
Greenplum Database 管理员指南 V6.2.1
的数据处理是在Master上完成的Primary根本不会收到错误的数据)跟外部表不
而且如果设置为ROWS的限制最小值是2否则会报错。
另外当使用PERCENT来控制错误记录的阈值时和可读外部表一样还通过
gp_reject_percent_threshold参数(缺省值为300)来控制最开始不统计失败百
分比的记录数还有一个参数gp_initial_bad_row_limit该参数的缺省值为
1000当开始的数据全部为错误记录且达到了该参数设定的值整个导入操作就失
败了。这两个参数都是全局统计的。
和可读外部表一样通过在SEGMENT REJECT LIMIT子句前加上LOG ERRORS
子句实现对错误记录的记录如果没有指定LOG ERRORS子句错误记录将直接被丢弃。
例如
=# COPY test FROM '/tmp/file0' LOG ERRORS SEGMENT REJECT LIMIT 10;
=# SELECT * FROM gp_read_error_log('test');
=# SELECT gp_truncate_error_log('test');
跟可读外部表类似使用gp_read_error_log()函数来查看隔离的错误记录
使用gp_truncate_error_log()函数来清除隔离的错误记录。不同的是可读外部
表使用外部表的名称作为函数的参数COPY命令隔离的错误记录使用目标表的名称
作为函数的参数。
COPY 导出
使用COPY TO命令将一张表或者一个查询语句导出到一个文件或者标准
输出。COPY TO的数据也全部需要通过Master处理。例如
=# COPY (SELECT * FROM test WHERE a < 100) TO '/tmp/file100';
在导出数据是同样可以使用\COPY命令其工作原理与使用COPY导入是一样的。例如
=# \COPY (SELECT * FROM test WHERE a < 100) TO '/tmp/file100';
与数据导入相关的优化
关于数据加载的性能优化和数据加载后的查询性能可以参考如下因素
版权所有Esena(陈淼 ) 编写陈淼 - 263 -
Greenplum Database 管理员指南 V6.2.1
在加载数据之前先删除目标表上的索引。
在已经有数据的表上创建索引的性能可能比带索引增量导入数据的性能要高很
因为带索引导入是每条数据的导入都需要更新索引信息。可以临时增加
maintenance_work_mem参数的值来提升CREATE INDEX命令的的性能。重
建索引应该在没有用户会用到该索引时进行。
当需要在一张新表上创建索引时应该在最后一步来创建索引在导入所有的数据
之后再创建必要的索引。
导入数据后应该考虑在目标表上是否应该执行ANALYZE操作收集统计信息。当
表中有大比例的数据发生变化时应该考虑执行ANALYZE操作以更新统计信息
保持统计信息反映了最新的数据情况有助于优化器生成正确的执行计划。当然
如果不收集统计信息也能生成最优的执行计划可以不收集。
在加载失败之后应该考虑是否需要执行VACUUM操作。如果目标表不是空表
载失败之后垃圾记录和有用的记录混在一起需要考虑在合适的时间执行
VACUUM操作来回收垃圾空间。如果目标表每次加载都是空表可以通过TRUNCATE
来清空目标表。更多关于VACUUM的信息可以参见"回收空间"章节。
版权所有Esena(陈淼 ) 编写陈淼 - 264 -
Greenplum Database 管理员指南 V6.2.1
第十二章安装部署与初始化
GP是一个纯软件的MPP解决方案可以运行在多种环境比如物理机、虚拟机、
公有云、私有云、一体机等等。甚至一个1 Core 1GB的虚拟机中都可以安装运行
执行正常的数据计算和分析。但是任何的性能都是由硬件保证的所以要获得一个
计算能力超强的GP集群一套计算能力超强的硬件是最基础的条件没有无源之水。
本章节会从硬件开始介绍包括硬件的配置指标预期的性能指标硬件的搭配
平衡以及整体的物理架构甚至如何规划机房的摆放等。然后是如何安装操作系统
如何配置操作系统参数如何安装GP数据库软件如何初始化一套符合各种安全和指
标要求的GP数据库集群。
对于安装好操作系统配置好网络之后的操作本章节主要是为了解说相关的知识
编者不再使用这种纯手工的方法因为效率太低编者有一个自动化脚本来完成这些重
复且容易出错的工作目前仅在编者为客户提供实施时使用暂不公开传播。
硬件选型
GP是一个分布式数据库软件整体数据库的性能依赖于硬件的性能和各种硬件资
源的均衡。如果过度强调某一方面硬件资源会造成资源的不均衡也是对资源的浪费
同时也是投资的浪费。对于OLAP应用来说最大的瓶颈是磁盘性能(而不是磁盘容量)
因此所有其他资源都应该围绕磁盘性能来均衡配置。这些资源包括CPU主频与Core
数量、内存容量、网络带宽、Raid性能等但基本宗旨是IO资源必须绝对富余CPU
资源永远是被充分利用的资源内存和网络带宽也必须有富余。
CPU 主频与 Core 数量
CPU主频理论上来说肯定是越高越好目前GP还不支持并行度的概念随着PG
版本的进一步合并未来可能会支持所以就目前来说一个SQL语句的执行性能
取决于单个Core的计算能力和有多少个Primary参与计算通常对于一个Primary
来说在执行一个任务时只能利用一个CPU Core的计算能力。不过主频这个事情
基本上没有太多的选择服务器级别的CPU相同Core数量的情况下追求很高的主
频需要很高的成本性价比很低。
目前主流的两路X86服务器CPU一般都配置64 Core甚至更高的Core数量。
主频基本上没有什么选择的空间所以要提升集群的整体计算能力Core的数量是
版权所有Esena(陈淼 ) 编写陈淼 - 265 -
Greenplum Database 管理员指南 V6.2.1
个非常重要的因素。如果有可能配置96 Core甚至128 Core以上的CPU将会带来
更好的计算能力。本章介绍的硬件搭配是均衡的搭配磁盘的性能是有充分保障的
所以很多时候CPU是最先到达瓶颈的资源因此如有可能尽可能的增加CPU Core
的数量越多越好。
内存容量
目前的主流配置单机内存至少256GB很多已经到512GB甚至更高因为这些
年来数据量在不断增长超大规模数据的关联分析需求上升。GP的很多算子比如
HashAGGSort都属于内存密集型算子可能需要消耗大量的内存。
配置了很多的内存不等于说所有时间段活跃内存的比例都能达到很高活跃
内存的消耗量与计算的数据量计算的类型并发数都有关系。只能说内存多
GP在处理内存需求量很大的场景时会更高效但不能保证活跃内存的使用率就一定能
很高。因此如果极少有内存密集型计算可以适当的降低内存的配置。不过编者建
议一个Primary的最低内存配置不要低于30GB
内存多是一种能力的体现在真正的生产运行之前无法评估真实的活跃内存使
用率。也无法根据一个生产系统的情况来评估另一个生产系统的规划当前的情况也不
代表未来的情况。总体来说内存富余是好事情只是用不完而已。在GP集群中
IO资源是最珍贵的资源如果内存不够用就要从内存溢出到磁盘文件把压力转移
到磁盘上这种情况是不应该出现的。
内联网络
内联网络的带宽是极其重要的。GPMPP架构目的是为了解决IO问题MPP
架构下IO问题解决了但带来了一个新的问题数据的移动这是无法避免的。但
好在现在的网络能力已经足够强万兆网卡和万兆交换机已经不再昂贵。使用24块全
机械盘的主流配置IO已经可以达到3GB左右的连续读写能力。虽然数据移动不是总会
发生但如果发生带宽尤其重要否则数据移动操作就会卡在网络层。
一定要选择万兆网络作为内联网络要坚决杜绝用千兆网络作为内联网络的想法。
另外为了实现网络的高可用最少使用两个万兆网口。如果可以选择要采用mode4
bond而不是mode1从安全性角度来说mode4mode1是完全一样的都有多
个通道只要不是全部通道故障不影响连通性而从带宽角度考虑正常情况下
mode4的带宽更高mode1的带宽就相当于故障了的mode4当然如果循规蹈矩
就要用mode1这是自由但是理论和事实就是如此。
版权所有Esena(陈淼 ) 编写陈淼 - 266 -
Greenplum Database 管理员指南 V6.2.1
一定要确保网络的健康长期大量的错包丢包必定会导致非常严重的后果影响
集群的稳定性甚至是性能。
对于超大规模的集群应该考虑为Master服务器配置更多的网口做链路聚合
为随着Master管理的机器增多Master本身的网络压力会跟着上升100台以上的集
可以考虑增加Master的网络带宽为4个万兆口做mode4的链路聚合。
Raid 卡性能
这个是常常不被引起重视的问题如果使用的是机械磁盘Raid卡非常重要Raid
卡是缓解磁盘压力的关键Raid卡的最大作用是将不连续的IO操作缓存并合并为连
续的IO操作。
使用Raid卡的最关键原因是普通的机械盘的随机读写能力很差一个10K/Min
转速的机械盘连续的磁盘读写性能不会超过200MB/S大多数情况下就100MB/S
随机读写的性能就更差了一般IOPS能力都到不了200这还是磁盘厂商给的指标
实际测试可能更低。
对于OLAP型的应用主要是大尺寸的连续读写如果Raid卡有Cache功能不管
是读还是写都可以经过Raid卡的Cache进行IO合并充分发挥机械盘的连续读写性
能。
一般要求24块盘机械盘起码要配置2GB以上Cache的双通道Raid否则Raid
卡的性能可能会成为充分发挥磁盘性能的障碍。根据经验24块机械盘一般采用12
块一组的Raid 5方案条带一般选择256KB的尺寸。
磁盘配置
GP主要是为了解决IO瓶颈而设计的所以磁盘性能尤其重要。对OLAP型的应用
目前主流的配置方案是计算节点主机配置24块机械盘Master节点主机一般配置
812块机械硬盘。如果选择SSD或者NVMe可以根据容量和性能来评估磁盘数量。
不能只是单纯的追求容量要综合考虑性能指标单块磁盘的容量越大故障恢复
的时间就越久。一般来说如果选择机械盘目前主流的选择是单盘不超过1.8TB
版权所有Esena(陈淼 ) 编写陈淼 - 267 -
Greenplum Database 管理员指南 V6.2.1
容量评估
在规划GP集群时评估可用容量至关重要这决定了需要部署什么样规模的集群。
对于使用Raid 5的磁盘需要扣除一块磁盘的容量如果有Hotspare磁盘该盘容
量也不属于可用容量对于Raid 10的磁盘需要扣除50%的磁盘容量。比如有24
磁盘做成2Raid 5的盘阵在没有Hotspare的情况下实际可用容量是22块磁
盘提供的如果有2Hotspare实际可用容量是20块磁盘提供的。由于进制换
算折损操作系统中实际显示的磁盘可用容量大约是标称容量的90%。所以
对于Raid 5来说
有效磁盘数量 = 磁盘总数 - Raid数量 - Hotspare磁盘数量
对于Raid 10来说
有效磁盘数量 = (磁盘总数 - Hotspare磁盘数量) / 2
操作系统中看到的存储裸容量为
裸容量 = 单盘容量 * 有效磁盘数量 * 90%(进制换算率)
由于磁盘不能使用100%的可用空间GP建议为了性能保障磁盘使用量不能超
70%所以数据库可用的磁盘空间为
可用磁盘空间 = 裸容量 * 70%
GP还建议为每个Primary预留25%的可用空间用作查询的工作空间这可能会涉
临时表溢出文件等为了简化计算可以简单的将数据库可用空间按照裸容量的
60%来计算(这里考虑了Mirror的因素为了便于计算的粗略评估)
数据库可用空间 = 裸容量 * 60%
如果集群启用了MirrorMirror占用的空间与Primary相同所以可存储的
数据容量还要之前所有计算的基础上再折损50%
可存储数据容量 = 裸容量 * 60% * (Mirror ? 50% : 100%)
举个例子来说241.2TB的磁盘做成两组Raid 5没有HotspareMirror
的情况下单机可存储的数据容量为
单机可存储数据容量 = 1.2TB * (24 - 2 - 0) * 90% * 60% * 50% ≈ 7TB
注意这里得到的[单机可存储数据容量]没有考虑库内数据压缩问题当按照入库
版权所有Esena(陈淼 ) 编写陈淼 - 268 -
Greenplum Database 管理员指南 V6.2.1
前的未压缩平面文件尺寸进行评估时一般可以考虑1:3的压缩比。
机房规划
机房规划会涉及网络和供电等问题同时还应该考虑高可用的影响。例如下图
是一个典型的机房摆放参考图。
建议将MasterStandby分别放置在不同的机柜将计算节点主机分组放到不同
的机柜因为这些机器可以形成机柜之间的备份关系。如果有条件可以将有镜像关系
的机柜分开供电可以确保单个机柜出现断电的情况下GP数据库可以继续提供服务
这回涉及到镜像策略问题可以参考"Instance镜像"章节的介绍。
安装操作系统
建议按照推荐的模式安装操作系统避免在之后安装部署GP集群时带来不必要的
麻烦。GPSWAP和数据盘的划分都有一定的讲究但这些不是硬性规范只是建议遵
也可以咨询专业服务人员的意见。
版权所有Esena(陈淼 ) 编写陈淼 - 269 -
Greenplum Database 管理员指南 V6.2.1
开启超线程
根据实测经验开启超线程计算能力有几乎翻倍的提升所以一定要开启超线
否则是对CPU资源的极大浪费。
Raid 划分最佳实践
机械盘建议做Raid 5一方面可以提高安全级别另一方面可以缓解倾斜的
影响如果不在乎成本Raid 10也是可以的。对于机械盘的Raid 5一般采取如下
方式配置
StripSize -- Master建议32K ~ 128K准确的选择可以根据测试情况来确
定。如果无法确定可以选择128K。计算节点建议256K这是经验值具体设
备的最优值可以根据测试来确定。
WritePolicy -- 根据最佳实践的经验需要选择[Always Write Back]
者称为[Force Write Back]
ReadPolicy -- 根据最佳实践的经验需要选择[Read Ahead]
Raid Cache比例 -- 根据最佳实践的经验不建议调整因为调整了反而综合
性能往往会下降。
Drive Cache -- 根据最佳实践的经验需要选择[Disable]
IO Policy -- 根据最佳实践的经验需要选择[Direct]
系统盘 -- 操作系统建议安装在单独的两块盘的Raid1上。
Hotspare -- 如果需要建议做Global Hotspare。如果更换磁盘的流程不
是很长比如一两天就能更换故障磁盘建议可以不配置HotspareHotspare
不是一定会带来好处因为出现故障切换时Raid的性能会有很大下降且这个
过程是自动的无法根据业务情况灵活安排而更换磁盘是可以灵活安排的。
Master类主机的Raid划分参考示例
磁盘
Raid 类型
磁盘数量
设备号
可用容量
挂载点
用途
2048MB
/boot
Raid 1
2
/dev/sda
操作系统
剩余尺寸
/
版权所有Esena(陈淼 ) 编写陈淼 - 270 -
Greenplum Database 管理员指南 V6.2.1
/dev/sdb
内存尺寸
swap
SWAP
Raid 5
X+1+1
/dev/sdc
剩余尺寸
/data
GP 数据盘
计算节点类主机的Raid划分参考示例
磁盘
Raid 类型
磁盘数量
设备号
可用容量
挂载点
用途
2048MB
/boot
Raid 1
2
/dev/sda
操作系统
剩余尺寸
/
/dev/sdb
内存尺寸/2
swap
SWAP
Y+1+1
/dev/sdc
剩余尺寸
/data1
GP 数据盘
Raid 5
/dev/sdd
内存尺寸/2
swap
SWAP
Y+1+1
/dev/sde
剩余尺寸
/data2
GP 数据盘
生产环境一般都需要有个Mirror的保护一旦出现故障切换Mirror被激活的
主机将会消耗更多的内存资源因此SWAP是对故障切换的一种保护。
在配置GP数据库时在健康状态下不应该使用SWAP如果镜像模式是一一镜像
一台主机的镜像全部在另外一台主机SWAP尺寸应该与物理内存相同如果一台
主机的镜像均分在另外的N台主机一般可以设置SWAP尺寸为物理内存的1/N
由于SWAP的性能会极大影响计算效率Greenplum要求将SWAP设置在性能最好
的磁盘上2块盘组成的Raid1用作OS安装其性能与数据数据盘的Raid 5相比差很
因此不可以将SWAP设置在OS磁盘上。
对于SSD或者NVMe的磁盘来说以上关于性能的问题需要重新衡量比如SWAP
在哪里比如是否要做Raid一般来说在不考虑Raid 5安全要求的情况下建议不
Raid 5因为Raid 5的校验计算对于Raid卡的计算能力来说会约束磁盘的性能
发挥。如果条件允许可能SSD或者NVMe会是更好的选择这也是磁盘技术的未来趋
势。机械盘在长期高压力下故障率会高很多SSD技术则会稳定很多。
GP 安装条件
本节主要按照6版本的情况来介绍不过除了GP软件包的安装方式有变化外
他内容基本上没有太大差异。
支持的操作系统
6版本的GP Server支持RHEL6.x_x86_64RHEL7.x_x86_64
版权所有Esena(陈淼 ) 编写陈淼 - 271 -
Greenplum Database 管理员指南 V6.2.1
CentOS6.x_x86_64CentOS7.x_x86_64Ubuntu18.04LTS
5版本的GP Server支持RHEL6.x_x86_64RHEL7.x_x86_64
CentOS6.x_x86_64CentOS7.x_x86_64SuSE12SP2SuSE12SP3SuSE11SP4
注意RedHat6CentOS6中使用资源组是有问题的这是因为早期的cgroup有缺
最好将Kernel升级到2.6.32-696或者更高的版本以修复已知问题从而可以更
好的使用资源组功能。这些问题在Redhat7CentOS7中已经修复。
注意Redhat7CentOS77.3之前的版本因为有Kernel BUG会导致GP运行
大负载任务时出现进程被hang所以建议使用7.3及之后版本7.3及之后的版本解
决了这个问题。
软件依赖
在使用rpm安装6版本GP下列的软件包是自动检查依赖关系的
apr,apr-util,bash,bzip2,curl,krb5,libcurl,libevent,libxml2,
libyaml,zlib,openldap,openssh,openssl,openssl-libs,perl,
readline,rsync,R,sed,tar,zip
这个清单是根据最新的官方文档罗列的具体的情况以实际安装时的报错提示信息
为准。5版本和4版本也都有不完全相同的依赖包而且安装的模式也各不相同。最好
GP数据库的操作系统配置yum在部署GP集群时缺少的rpm包可以随时补上
不建议通过yum命令来安装GPyum难以修改安装目录直接使用rpm命令安装即
可以方便的修改安装目录(通过--prefix参数指定)
硬件与网络最低要求
下面列出生产环境中Linux系统中GP数据库服务器的最低配置要求。GP数据库
中所有计算节点的服务器应该具有相同的硬件配置和软件环境。建议由GP工程师检查
GP的运行环境确保其适合GP数据库的生产运行。
最低 CPU 配置
x86_64 兼容的 CPU
最低内存配置
官方文档说每台机器 16GB编者建议每个 Primary 30GB
GP 软件安装 2GB 空间
磁盘空间要求
GP 的数据盘需要保持使用量不超过 70%
版权所有Esena(陈淼 ) 编写陈淼 - 272 -
Greenplum Database 管理员指南 V6.2.1
必须是万兆以太网建议多个网口做 bond
网络要求
如果坚持使用千以太兆网后果请自负
文件系统要求
GP数据库运行要求使用XFS文件系统原厂未明确支持其他文件系统。所以GP
数据库的数据目录应该使用XFS文件系统。
对于网络文件系统或者共享存储也必须挂载为本地XFS文件系统。非本地磁盘的
文件系统虽然支持但不推荐对于GP来说都是本地目录不会区分对待不同的
存储。网络文件系统或者共享存储虽然可以运行但性能和可靠性无法保证。
安装 RHEL 的介绍
根据实践总结建议按照如下方式安装RHEL7操作系统这也是目前的主流选择
选项
要求
操作系统版本
rhel-server-7.4-x86_64
挂载点
设备名
文件系统格式
尺寸
/boot
/sda1
XFS
2048MB
目录及尺寸要求
/
/sda2
XFS
剩余全部
SWAP
/sdb
SWAP
内存尺寸/2
SWAP
/sdd
SWAP
内存尺寸/2
语言选择
English(United States)
时区选择
Asia/Shanghai
软件选择
File and Print Server
附加组件选择
Development Tools
初始 root 密码
123456
如果在安装操作系统时图形化引导界面中无法配置超过128GBSWAP可以先
不配置留在操作系统装好之后再做配置。
GP数据库使用的数据盘不需要在安装操作系统时配置(上述表格中未列出数据
)可以在装好操作系统之后在准备安装部署GP数据库时再统一按照GP数据库的文
件系统挂载要求进行配置。
版权所有Esena(陈淼 ) 编写陈淼 - 273 -
Greenplum Database 管理员指南 V6.2.1
最好为GP数据库的操作系统配置yum在部署GP集群时可能会有少量的软件
包需要安装对于未按照建议安装的操作系统可能会有大量的软件包需要安装。
修改操作系统配置
在正式开始安装和部署及初始化GP数据库集群之前要先对操作系统进行配置修
以满足GP的运行需要否则直接安装多机集群时会有各种失败报错。
需要注意的是GP数据库的运行是依靠主机名来区分不同主机的主机名
(hostname)在整个集群中必须是唯一的。
禁用 SELinux 和防火墙
root身份登录或者获得root权限比如sudo权限执行如下命令禁用SELinux
RHEL6
# sed s/^SELINUX=.*$/SELINUX=disabled/ -i /etc/selinux/config
# setenforce 0
# service iptables stop
# chkconfig iptables off
RHEL7
# sed s/^SELINUX=.*$/SELINUX=disabled/ -i /etc/selinux/config
# setenforce 0
# systemctl stop firewalld.service
# systemctl disable firewalld.service
如果安装SuSE支持的版本SuSE上的操作为
# yast runlevel delete service=boot.apparmor runlevels=B
# yast runlevel delete service=SuSEfirewall2_init runlevels=B
# yast runlevel delete service=SuSEfirewall2_setup runlevels=B
版权所有Esena(陈淼 ) 编写陈淼 - 274 -
Greenplum Database 管理员指南 V6.2.1
修改 hostname
根据不同操作系统的配置方式修改相应的配置文件确保主机名被永久修改。可
能会涉及如下几个文件
/etc/sysconfig/network
/etc/hostname
/etc/HOSTNAME
修改 hosts 文件
修改/etc/hosts文件确保GP集群用到的所有主机名都进行了正确的配置确保
所有GP数据库集群会使用到的网络接口都配置了正确的名称。将修改好的文件覆盖到
GP集群中的所有主机上。
修改 sysctl.conf 文件
GP 集群中所有主机的/etc/sysctl.conf 文件修改为如下内容
kernel.shmmax = 5000000000000
kernel.shmmni = 32768
kernel.shmall = 40000000000
kernel.sem = 1000 32768000 1000 32768
kernel.sysrq = 1
kernel.core_uses_pid = 1
kernel.msgmnb = 1048576
kernel.msgmax = 1048576
kernel.msgmni = 32768
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.tcp_max_syn_backlog = 32768
net.ipv4.tcp_syn_retries = 3
版权所有Esena(陈淼 ) 编写陈淼 - 275 -
Greenplum Database 管理员指南 V6.2.1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.conf.all.arp_filter = 1
net.ipv4.ip_local_port_range = 1025 65535
net.ipv4.ip_local_reserved_ports =
5432,40000-40127,41000-41127,50000-50127,51000-51127
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.core.netdev_max_backlog = 80000
net.core.rmem_default = 2097152
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
vm.overcommit_memory = 2
vm.overcommit_ratio = 95
vm.swappiness = 0
vm.zone_reclaim_mode = 0
vm.dirty_expire_centisecs = 200
vm.dirty_writeback_centisecs = 100
vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 5
vm.dirty_bytes = 0
vm.dirty_ratio = 10
这里就不对每一项做解释了这个配置是编者一直使用的版本有兴趣可以对其中
的配置项深入研究一下也欢迎反馈给编者。有些配置设置的比推荐值大了很多主要
目的是为了使用多种硬件配置环境比如共享内存等实际上真实的内存使用量
据库本身仍会有限制参数。
修改 limits 文件
GP 集群中所有主机的/etc/security/limits.conf 文件进行如下修改
# sed -e s/^ulimit/#ulimit/ -i /etc/profile
# sed -e /^[^#]/d -e /^[[:space:]]*$/d -i /etc/security/limits.conf
# echo '' >> /etc/security/limits.conf
# echo '* soft nofile 1048576' >> /etc/security/limits.conf
# echo '* hard nofile 1048576' >> /etc/security/limits.conf
# echo '* soft nproc
1048576' >> /etc/security/limits.conf
# echo '* hard nproc
1048576' >> /etc/security/limits.conf
# nprocname="/etc/security/limits.d/90-nproc.conf"
# if [ -f "/etc/security/limits.d/20-nproc.conf" ];then
版权所有Esena(陈淼 ) 编写陈淼 - 276 -
Greenplum Database 管理员指南 V6.2.1
#
nprocname="/etc/security/limits.d/20-nproc.conf"
# fi
# if [ -f $nprocname ];then
#
sed -e /^[^#]/d -e /^[[:space:]]*$/d -i $nprocname
#
echo '' >> $nprocname
#
echo '*
soft nproc
1048576' >> $nprocname
#
echo 'root soft nproc
1048576' >> $nprocname
# fi
确认 XFS 挂载参数
RHELCentOSXFS挂载参数为
rw,nodev,noatime,nobarrier,inode64
Ubuntu不支持nobarrier参数因此XFS挂载参数为
rw,nodev,noatime,inode64
比如在/etc/fstab文件中的挂载配置为
/dev/sdc /data xfs nodev,noatime,nobarrier,inode64 0 0
确认 IO 参数和 Huge Page 设置
执行如下命令来修改IO参数和Huge Page设置
# localfile="/etc/rc.d/rc.local"
# if [ -f "/etc/init.d/boot.local" ];then
#
localfile="/etc/init.d/boot.local"
# fi
# chmod +x $localfile
# sed -e "/^####GP_BEGIN/,/^####GP_END/d" -i $localfile
# cat <<'END_OF_CMD'
>> $localfile
> ####GP_BEGIN'
版权所有Esena(陈淼 ) 编写陈淼 - 277 -
Greenplum Database 管理员指南 V6.2.1
> for i in /dev/sd*;do blockdev --setra 16384
$i;done
> for i in /sys/block/sd*/queue/scheduler;do echo deadline > $i;done
> echo never > /sys/kernel/mm/transparent_hugepage/enabled
> ####GP_END
> END_OF_CMD
# sed -n "/^####GP_BEGIN/,/^####GP_END/p" $localfile|bash
确认 ssh 设置
由于GP的集群操作是使用ssh来实现的在实例多的集群中可能会同时向一个机
器发起多个ssh访问缺省的ssh设置可能会遭遇如下报错
ssh_exchange_identification: Connection closed by remote host
执行如下命令来修改sshMaxStartups参数
# sed s/.*MaxStartups.*/'MaxStartups 400:30:500'/ -i /etc/ssh/sshd_config
根据不同的系统使用不同的命令来生效修改
# ##RHEL7
# systemctl reload sshd.service
# ##RHEL6
# service sshd reload
# ##SuSE
# service ssh reload
时钟同步
请根据具体的操作系统配置时钟同步。GP数据库要求所有机器的时间要保持同步。
版权所有Esena(陈淼 ) 编写陈淼 - 278 -
Greenplum Database 管理员指南 V6.2.1
创建 GP 数据库的管理员用户
一般根据惯例GP数据库的管理员用户使用gpadmin(例如uid300)这个名
例如
创建gpadmin用户组
# groupadd -r -g 300 gpadmin
创建gpadmin用户
# useradd -r -m -g gpadmin -u 300 gpadmin
gpadmin用户设置密码
# echo gpadmin | passwd gpadmin --stdin
安装 GP 软件
获取安装包根据安装包的类型选择合适的安装方式。比如在6版本只有rpm
包可选建议使用rpm命令来安装5版本和4版本zip包的情况下可以通过解
压后使用bash命令执行bin文件安装开源版本则需要通过源码编译来安装。例如
$ sudo rpm -ivh greenplum-db-<version>-<platform>.rpm
$ sudo chown -R gpadmin:gpadmin /usr/local/greenplum*
建立 ssh 互信
GP要求所有主机之间gpadmin用户可以免密ssh访问6版本之前通过命令
gpssh-exkeys可以自动完成所有步骤6版本该命令有了变化必须先确保
Master和其他主机之间已经建立了互信关系才能完成全局互信。例如
$ ssh-copy-id -i ~/.ssh/id_rsa.pub gpadmin@sdw01
在完成Master和其他主机的互信之后可以使用gpssh-exkeys命令建立全局互信
版权所有Esena(陈淼 ) 编写陈淼 - 279 -
Greenplum Database 管理员指南 V6.2.1
$ gpssh-exkeys -f hostfile_exkeys
其中hostfile_exkeys文件中包含GP集群中所有会被GP数据库使用到的主机名
和子网端口名称。例如
mdw
mdw-1
mdw-2
smdw
smdw-1
smdw-2
sdw1
sdw1-1
sdw1-2
sdw2
sdw2-1
sdw2-2
注意主机名不能有下划线下划线属于非法字符在有些系统中可能会带来麻烦。
安装确认
在所有主机上安装完GP数据库软件之后有必要检查一下所有主机上都已经正确
的安装。可以通过如下步骤来验证。
1 使用gpadmin用户登录Master服务器
# su - gpadmin
2 使用gpssh工具批量检查所有主机上的安装目录
# gpssh -f hostfile_exkeys -e 'ls -l /usr/local/greenplum-db/bin/gpstart'
如果安装成功了该命令将会自动登录所有主机并列出gpstart命令的文件。
版权所有Esena(陈淼 ) 编写陈淼 - 280 -
Greenplum Database 管理员指南 V6.2.1
GP 软件目录结构
greenplum_path.sh -- GP数据库运行需要的环境变量文件。
bin -- GP数据库的管理命令所在的目录。
docs/cli_help -- GP数据库命令的帮助信息。
docs/cli_help/gpconfigs -- gpinitsystem命令的示例文件目录。
ext -- GP数据库命令所需的一些依赖软件比如Python
include -- GP数据库的一些C语言头文件。
lib -- GP数据库以及PostgreSQL的库文件。
sbin -- 内部脚本和命令。
share -- GP数据库的共享文件。
创建数据库工作目录
GP的所有PostgreSQL实例工作在独立的监听端口同时需要工作在独立的文
件系统目录所以需要在每台主机上为PrimaryMirror创建工作目录。
创建 Master 工作目录
通常MasterStandby的工作目录与计算节点不同一般来说Master的工
作目录会有一层目录叫做master以明确的界定这是Master的工作目录在以后的
日常维护工作中可以更直观和快速的找到Master的工作目录。
Master不存储用户数据只存储系统表信息和一些全局信息不过这不等于
Master的磁盘指标就不重要。一般来说Master目录的容量不需要像计算节点那
么大但最好还是要有一定的保障比如1TB的尺寸还是有必要的因为会有日志等信
息的累积。另外Master磁盘的性能也不能太差毕竟系统表的性能影响也不能忽略。
如果条件允许可以考虑为Master目录配置NVMe保证系统表的性能。
版权所有Esena(陈淼 ) 编写陈淼 - 281 -
Greenplum Database 管理员指南 V6.2.1
例如同时在Master(mdw001)Standby(mdw002)两台主机的/data目录下
创建一个子目录master并将owner改为gpadmin
# ./usr/local/greenplum-db/greenplum_path.sh
# gpssh -h mdw001 -h mdw002 -e 'mkdir -p /data/master/default'
# gpssh -h mdw001 -h mdw002 -e 'chown gpadmin. /data/master'
# gpssh -h mdw001 -h mdw002 -e 'chown gpadmin. /data/master/default'
创建 Instance 的工作目录
6版本之前tablespace不是一个独立的概念其必须基于filespace来创建
filespace在创建时允许为PrimaryMirror创建不同的路径所以按照惯
为了区分PrimaryMirror初始化路径也使用primarymirror子目录来做
区分这也是很容易实现的。
然而6版本中filespace的概念没有了取而代之的是CREATE
TABLESPACE时直接指定统一的路径或者为每个content值的Instance指定一个路
但不能为PrimaryMirror指定不同的路径。虽然在初始化安装时仍然可以
按照惯例为PrimaryMirror设置不同的路径但是如果再创建tablespace
者将会遵从不同的路径规则可能会带来不必要的困扰因此编者建议不再遵从这个
惯例6版本中PrimaryMirror完全可以使用相同的目录路径(接下来的示例为
了便于理解有些示例可能仍会使用不同的目录路径但这只是为了示例)。例如
sdw001 ~ sdw004/data1/data2目录下创建初始化缺省的工作路径
# ./usr/local/greenplum-db/greenplum_path.sh
# gpssh -hsdw{001..004} -e 'mkdir -p /data{1,2}/{default,gpfs}'
# gpssh -hsdw{001..004} -e 'chown gpadmin. /data{1,2}/{default,gpfs}'
对于5版本和4版本可以按照惯例来创建Instance的工作目录
# ./usr/local/greenplum-db/greenplum_path.sh
# gpssh -hsdw{001..004} -e 'mkdir -p
/data{1,2}/{primary,mirror}/{default,gpfs}'
# gpssh -hsdw{001..004} -e 'chown gpadmin. /data{1,2}/{primary,mirror}'
# gpssh -hsdw{001..004} -e 'chown gpadmin.
/data{1,2}/{primary,mirror}/{default,gpfs}'
版权所有Esena(陈淼 ) 编写陈淼 - 282 -
Greenplum Database 管理员指南 V6.2.1
系统性能检查
在真正使用GP数据库集群用于生产应用之前应该使用GP提供的性能测试命令
gpcheckperf对集群中所有主机的硬件性能进行评估检查确保性能符合预期。
检查网络性能
通过gpcheckperf命令的-r n-r N-r M参数来测试网络性能结果以MB
为单位来显示。-r n是进行串行一对一测试-r N是进行并行一对一测试-r M
进行全矩阵交叉测试。
从指定的参与测试的网络端口列表按照顺序进行配对比如-r n按照顺序
第一个向第二个发包发包完成后第二个向第一个发包然后第三个和第四个配对
顺序相互发包然后依次测试剩下的网络端口直到所有的网络端口测试完。如果是
-r N匹配的顺序与-r n一致不同的是所有的分组测试同时开始相互发包。对于
-r n-r N的情况如果是奇数个网络端口最后一个会和第一个再组成一组对于
-r N的测试可能会影响最终的显示结果。-r M则是每个网络端口都向其他网络端口
发包形成全矩阵式交叉测试。
-r n-r N能够体现网卡之间的独立性能-r M则更能体现实际生产使用时
的网络负载能力是真实的工作模式。
如果一台机器上有多个网卡会有不同的子网端口(也可以称为hostname)在测
试时应该避免同一台机器的不同子网端口之间配对测试因为这种情况体现的是主机
内的本地网络速度性能很高对测试结果会是很大的混淆如果网络有跨交换机的情
为了测试交换机之间的性能应该避免同一交换机内的配对可以使用-r N模式
配置不同交换机的网络端口进行配对测试。
例如下面是4个计算节点的子网端口情况
主机名
一号子网端口
二号子网端口
sdw001
sdw001-1
sdw001-2
sdw002
sdw002-1
sdw002-2
sdw003
sdw003-1
sdw003-2
sdw004
sdw004-1
sdw004-2
可以根据子网端口创建两个主机名文件。例如
hostfile_gpchecknet_ic1
hostfile_gpchecknet_ic1
版权所有Esena(陈淼 ) 编写陈淼 - 283 -
Greenplum Database 管理员指南 V6.2.1
sdw001-1
sdw001-2
sdw002-1
sdw002-2
sdw003-1
sdw003-2
sdw004-1
sdw004-2
例如根据创建的主机名文件分别进行并行配对测试
# ./usr/local/greenplum-db/greenplum_path.sh
# gpcheckperf -f hostfile_gpchecknet_ic1 -r N -d /tmp
# gpcheckperf -f hostfile_gpchecknet_ic2 -r N -d /tmp
缺省情况下数据包发送时间为15可以通过--duration参数来自定义发送
的时间长度单位可以是秒(s)、分钟(m)、小时(h)或天(d)。一般来说对于-r n
-r N没有必要修改时间长度-r M测试几分钟就差不多了。
检查磁盘性能
通过gpcheckperf命令的-r d参数对磁盘性能做测试结果以MB为单位来显示。。
磁盘性能测试实际上是使用Linuxdd命令在指定的目录中进行连续的大文件读写
测试。
进行磁盘性能测试之前要确定需要测试的目录需要测试的主机名称列表比如
hostfile_gpcheckperf文件中包含了需要进行磁盘性能测试的节点的主机名
sdw001
sdw002
sdw003
sdw004
例如要对hostfile_gpcheckperf文件中列出的主机进行测试测试的目录为
/data1/data2
$ gpcheckperf -f hostfile_gpcheckperf -r d -d /data1 -d /data2 -D
缺省情况下按照当前运行命令主机的物理内存的2倍进行磁盘性能测试命令会
根据指定的目录的数量进行均匀分割尺寸如果磁盘性能很高可能会出现dd命令的
CPU资源100%的情况这种情况下可以通过指定更多的子目录分拆更多的dd命令
来进行测试切记不要指定完全相同的-d参数这样会导致测试结果严重失真。有时
候会有用户选择使用fio命令来测试磁盘性能fio是直接对磁盘设备进行操作的
经过文件系统所以会对文件系统产生破坏如果确实需要使用fio来测试需要确
版权所有Esena(陈淼 ) 编写陈淼 - 284 -
Greenplum Database 管理员指南 V6.2.1
保设备没有被文件系统使用或者可以接受损坏的后果。另外fio的测试结果并不能
真实反映文件系统的性能gpcheckperf的测试结果不具有直接的可比性。
注意对于磁盘性能完全未知的情况下为了避免直接运行大尺寸的性能测试耗时太久
可以先进行小尺寸的磁盘性能测试确保磁盘性能不是太差之后在增加测试尺寸
终使用缺省尺寸进行测试。如有必要还是应该指定尺寸比如Master主机的内存尺
寸与计算节点主机不一致或者gpcheckperf计算尺寸出错等。通过-S参数来执行测
试尺寸详情可以参考gpcheckperf命令的help信息。
初始化 GP 数据库集群
在前面的准备工作全部做完之后就可以开始初始化GP集群了。接下来将逐步介
绍初始化一个GP集群的常规方法定制化方案不会过多提及。实际上编者对这一章
的内容不太感兴趣因为编者早就不这样安装部署和初始化GP数据库集群了因为这
样太费劲了完全就是体力活完全可以自动完成所以编者一直致力于优化一个更
好的自动化脚本来完成本章的工作。但对于学习来说这部分内容还是很有价值的
为这非常有助于了解如何一步一步初始化一个GP集群熟悉GP集群的架构关系对日
常的开发使用和运维都会有很大的帮助。
创建初始化网络端口文件
gpinitsystem命令可以通过一个网络端口清单文件来指定在哪些主机上初始
GP集群该文件指定的是计算节点不包含MasterStandby主机。初始化命令根
gpinitsystem_config配置文件中指定的目录个数来决定在一个计算节点的主机
上初始化多少个Instance。当一个主机上有多个子网端口时多个Instance将会均
分到所有的子网端口上。文件的格式为每个网络端口一行。
比如主机名如下所示
sdw001
sdw002
sdw003
sdw004
子网端口可以采用-1-2这种加后缀的方式来命名。要在GP集群中使用这些子网
端口需要在初始化网络端口文件中使用这些子网端口(可以不使用主机名
gpinitsystem会自动获取主机名来分析各个子网端口属于哪个主机)初始化时
Instance将会分散到不同的子网端口上。例如网络端口文件
版权所有Esena(陈淼 ) 编写陈淼 - 285 -
Greenplum Database 管理员指南 V6.2.1
hostfile_gpinitsystem中包含如下信息
sdw001-1
sdw001-2
sdw002-1
sdw002-2
sdw003-1
sdw003-2
sdw004-1
sdw004-2
注意不管是主机名还是子网端口都必须已经在所有主机的/etc/hosts文件中配置
否则gpinitsystem命令会报错说主机名无法识别通过DNS配置也是可以的。
创建初始化配置文件
初始化配置文件决定了gpinitsystem创建一个什么样的集群。数据库软件安
装好之后在安装目录下已经有一个初始化配置文件模板
$GPHOME/docs/cli_help/gpconfigs/gpinitsystem_config
可以通过拷贝模板的方式来创建初始化配置文件。例如
$ cat $GPHOME/docs/cli_help/gpconfigs/gpinitsystem_config >
~/gpinitsystem_config
根据环境的情况修改刚刚复制的文件。一个GP系统必须要有一个Master也必
须要有Primary如果有Mirror一般至少需要两个计算节点主机。
通过DATA_DIRECTORY参数来指定一个主机上配置多少个Primary。当一个主机
上有多个子网端口时多个Instance将会均分到所有的子网端口上。PORT_BASE
定了端口的开始值这些端口最好设置在/etc/sysctl.conf文件中
net.ipv4.ip_local_reserved_ports参数的范围内这样的话这些端口就不
会被作为动态端口分配给客户端程序。
ARRAY_NAME="Greenplum Data Platform"
SEG_PREFIX=gpseg
PORT_BASE=40000
declare -a DATA_DIRECTORY=(/data1/primary /data1/primary /data1/primary /
data2/primary /data2/primary /data2/primary)
版权所有Esena(陈淼 ) 编写陈淼 - 286 -
Greenplum Database 管理员指南 V6.2.1
MASTER_HOSTNAME=mdw001
MASTER_DIRECTORY=/data/master
MASTER_PORT=5432
TRUSTED_SHELL=ssh
CHECK_POINT_SEGMENTS=8
ENCODING=UNICODE
SEG_PREFIX指的是DATA_DIRECTORY声明的目录下创建的子目录的前缀
后缀是InstanceContent(参考gp_segment_configuration系统表的
content字段)值。PORT_BASE指的是在一个主机上Primary的监听端口从多少
开始连续分配比如上述的例子中该参数的值为40000DATA_DIRECTORY参数
指定了6个目录就会在一台主机上初始化6Primary6Primary的监听端口
就依次为40000 ~ 40005DATA_DIRECTORY实际上是一个数组指定了将在每个
主机的哪些目录下初始化Primary上述的例子中指定了6个目录初始化命令将会
在这6个目录下初始化6Primary这里的目录是可以重复的因为真正的工作目
录是这些目录下再创建的子目录SEG_PREFIX参数指定了子目录的前缀
content值决定了子目录的后缀。MASTER_HOSTNAME参数指定了Master所在的主机
的主机名初始化命令会将该主机作为MasterMASTER_DIRECTORY指定了Master
的工作目录不过Master的实际工作目录也是要创建一个子目录规则与Primary
相同content值为-1所以常见的名称为gpseg-1MASTER_PORT指定了Master
的监听端口这是整个GP集群的访问入口端口客户端程序通过该端口来访问数据库
集群。TRUSTED_SHELL指的是使用什么命令来执行远程命令之前准备的互信在这里
就开始用上了。CHECK_POINT_SEGMENTS指定了WAL检查点最多可以等待的WAL文件
个数如无必要建议不修改增加该参数的值checkpoint的频繁度会降低但崩
溃后恢复的时间就会延长数据库初始化之后仍然可以通过checkpoint_segments
参数来修改这一配置。ENCODING参数指定了服务端的编码集建议不要修改对于中
文环境没有更好的选择与编码集相关的还有--locale--lc-collate
--lc-ctype参数这几个是gpinitsystem的命令行参数具体可以参考
PostgreSQL文档值得注意的是6版本之前CREATE DATABASE命令没有
LC_COLLATE选项缺省的排序行为遵循UTF8编码集这会导致ascii字符串的排
序不是按照ascii编码进行排序的很多时候不符合预期可以通过--lc-collate
参数在初始化时指定排序特征。在6版本中要创建一个LC_COLLATE属性与模板库不
同的Database是有限制的模板库只能是template0否则会报错失败。
如果在初始化时选择配置Mirror还需要配置Mirror相关的参数通过
MIRROR_PORT_BASE参数指定Mirror端口的开始值该参数的特点与PORT_BASE
全相同。例如
#REPLICATION_PORT_BASE=41000
#MIRROR_REPLICATION_PORT_BASE=51000
MIRROR_PORT_BASE=50000
declare -a MIRROR_DATA_DIRECTORY=(/data1/mirror /data1/mirror /data1/
mirror /data2/mirror /data2/mirror /data2/mirror)
版权所有Esena(陈淼 ) 编写陈淼 - 287 -
Greenplum Database 管理员指南 V6.2.1
注释掉的两行6以前的版本需要用到的端口REPLICATION_PORT_BASE
Primary的复制端口MIRROR_REPLICATION_PORT_BASEMirror的复制端口
6版本已经不再需要这两个参数6版本不再使用filerep进行PrimaryMirror
间的同步复制而是使用WAL复制。
MIRROR_PORT_BASE的特点可以参考前面讲到的PORT_BASE参数的解释
MIRROR_DATA_DIRECTORY指定的是Mirror的工作目录信息特点参考前面讲到的
DATA_DIRECTORY参数。
关于Primary的工作目录和Mirror工作目录是否要相同参见"创建Instance
的工作目录"章节。
执行初始化操作
通过gpinitsystem命令根据配置文件中设置的情况初始化一个新的GP数据
库集群。该操作需要使用gpadmin用户来进行。例如
$ ./usr/local/greenplum-db/greenplum_path.sh
$ gpinitsystem -c gpinitsystem_config -h hostfile_gpinitsystem
如果要在初始化的时候设置Standby可以通过-s参数指定Standby的主机名来
实现例如
$ gpinitsystem -c gpinitsystem_config -h hostfile_gpinitsystem -s mdw002
如果在初始化时选择了设置Mirror可以通过--mirror-mode参数来指定
Mirror的策略自带的Mirror策略有两种groupspread缺省为group。根据
主机名的排序所有的主机组成一个环在环上的每个主机Primary对应的Mirror
会分布在后续的主机上。group的意思是一个主机上所有Primary对应的Mirror
在环中的下一个主机上。spread的意思是一个主机上所有Primary对应的Mirror
一个一个分散到后面的多个主机上当前主机上有多少个PrimaryMirror就分散到
多少个后续主机上。因此group镜像策略要求最少要有两台计算节点主机spread
镜像策略要求最少的计算节点主机的数量要大于一台主机上Primary的数量。
如果要定制镜像策略可以在gpinitsystem时不配置Mirror在初始化成功之
通过gpaddmirrors命令来创建Mirror通过对Mirror配置文件进行定制化编
辑的方式实现任意的Mirror策略。编者的自动化命令实现了更复杂和优化的镜像策略
可以参考"Instance镜像"章节。
在执行gpinitsystem命令过程中命令会自动检查所有主机的环境初始化参
数文件确定可以继续初始化后会提示确认是否继续根据提示输入需要的信息后继
版权所有Esena(陈淼 ) 编写陈淼 - 288 -
Greenplum Database 管理员指南 V6.2.1
续初始化安装操作。例如
Continue with Greenplum creation? Yy/Nn
gpinitsystem命令在确认输入[Yy]会继续进行并行的集群初始化操作
初始化成功之后GP数据库集群就处于已启动状态并会输出如下消息
Greenplum Database instance successfully created
初始化异常排查
在初始化过程中如果某个Instance创建或启动失败都会导致初始化报错失败
初始化操作的日志信息会存储在gpadmin用户的gpAdminLogs目录下日志文件以命令
的名称和日期命名。例如
gpinitsystem_20200705.log
通常在初始化日志中会有相关的失败原因比如操作系统参数没有正确的修改导
致内存分配不足或者SELinux未禁用或者防火墙未关闭等SELinux和防火墙的
问题可能会表现为无法访问远程主机或数据库Instance。对于实例启动失败的情况
还可以查看具体Instance的日志日志中会详细显示为什么实例启动失败。应该根据
日志信息解决相关的问题之后再重新初始化集群。
回退脚本
gpinitsystem命令失败时会给出一个回退脚本位于gpadmin用户的
gpAdminLogs目录下。格式为
~/gpAdminLogs/backout_gpinitsystem_<user>_<timestamp>
通过运行该回退脚本将会清除由gpinitsystem命令产生的目录文件和日志等信
关闭残余的postgres数据库进程清理完成后解决了失败的原因就可以重新尝试
初始化GP集群了。例如
$ sh backout_gpinitsystem_gpadmin_20200705_141658
版权所有Esena(陈淼 ) 编写陈淼 - 289 -
Greenplum Database 管理员指南 V6.2.1
gpadmin 用户配置环境变量
为了使得gpadmin用户每次登陆操作系统之后能够直接对数据库进行操作
要为gpadmin用户配置好必要的环境变量。通常修改.bashrc配置文件比如使用vi
命令修改。例如
$ vi ~/.bashrc
加入如下环境变量设置信息
####GP_BEGIN
if [ -e /usr/local/greenplum-db ];then
. /usr/local/greenplum-db/greenplum_path.sh
fi
export MASTER_DATA_DIRECTORY=/data/default/gpseg-1
export PGPORT=5432
export LD_PRELOAD=/lib64/libz.so.1 ps
####GP_END
如果有必要还可以指定缺省的登录用户和登录的数据库名称甚至指定登录密码。
例如
export PGUSER=gpadmin
export PGDATABASE=postgres
export PGPASSWORD=gparray
版权所有Esena(陈淼 ) 编写陈淼 - 290 -
Greenplum Database 管理员指南 V6.2.1
第十三章启动与停止 GP 数据库
在使用GP数据库时常规的启动和停止数据库都是一个分布式操作。所有主机上
MasterStandbyPrimaryMirror共同组成了一个分布式系统的整体
现为一个统一的数据库系统所以启动是所有实例都启动停止是所有实例都停
止。
既然是分布式系统启动过程自然也就不同于一般的数据库系统。细心的用户可能
已经发现整个启动过程大致可以分为5个阶段
1. 启动MasterMaster Only的模式启动其效果与gpstart -m一致。
2. 获取集群的配置信息。
3. 关闭Master其效果与gpstop -m一致。
4. 启动所有的PrimaryMirror
5. 正常启动Master
这里需要解释一下为什么会分为这么多阶段因为这是一个分布式系统整个系
统的信息是存储在数据库中的我们在安装配置GP集群的时候会涉及到Master的主
机名、目录和端口Standby的主机名、目录和端口所有Primary以及Mirror的主
机名、目录和端口这些信息统一保存在gp_segment_configuration系统表中。
当然这些信息不可能保存在Master的某个配置文件中(虽然表中存储数据的也是文
)因为那样太容易被篡改了。
因此启动命令需要根据MASTER_DATA_DIRECTORY环境变量或者-d参数来确定
Master的工作目录读取postgresql.conf配置文件获取port参数启动Master
实例。gp_segment_configuration系统表其实是Master Only的系统表Master
启动之后启动命令就可以通过Utility模式获取整个集群的配置信息然后关闭
Master(因为此时的Master的模式不能提供正常的连接和访问)然后根据获取的集
群配置信息来启动PrimaryMirror一定要先启动PrimaryMirror因为
有数据是完整的数据库才能提供正常的服务PrimaryMirror能否正常启动
接决定了集群启动的成败如果有成对的PrimaryMirror启动失败将会报出如下
错误且数据库启动整体失败
Do not have enough valid segments to start the array.
这种情况一般称为double faultdouble down或者双宕。解决这种问题
并没有什么简单的方法找到最后一个没有在gp_segment_configuration系统表
中被标记为down的启动失败的Instance根据报错日志解决相关的问题之后再尝
版权所有Esena(陈淼 ) 编写陈淼 - 291 -
Greenplum Database 管理员指南 V6.2.1
试重新启动集群。这种情况不是gprecoverseg命令能处理的因为数据库已经不可
用了所有依赖数据库可正常工作的命令都已经不能正常工作gprecoverseg是根
据健康的PrimaryMirror来恢复与其对应的MirrorPrimary所以该命令无法
处理双宕故障。
通过位于安装路径的bin目录下的gpstartgpstop命令来启动和停止GP数据
库集群这两个命令和PostgreSQLpg_ctl命令的功能类似区别是gpstart
gpstop提供了集群操作对于单实例的操作实际上仍然可以通过pg_ctl来完成
编者提醒pg_ctl命令应该仅在必要时刻使用。
注意尽量不要使用OSkill命令来终止Postgres进程而是要使用
pg_cancel_backend函数或者pg_terminate_backend函数来完成。当然也不是
完全不可以用除非有把握确保不会导致数据库损坏。通过kill -9或者kill -11
可能会导致数据库崩溃且无法记录异常日志以至于无法进行RCA(root cause
analysis)。另外kill -9或者kill -11即便没有导致数据库宕机也会导致所
有连接中断这个副作用是必然会发生的。
启动 GP 数据库
Master使用gpstart命令来启动一个已经存在的GP集群。GP数据库在初
始化成功时已经处于启动状态不需要执行gpstart命令对已经启动的集群执行
gpstart命令会收到如下报错
Master instance process running
对于初始化成功之后的GP集群已经处于停止状态的情况下通过gpstart命令
来启动集群gpstart命令会完成整个集群的启动PrimaryMirror的启动是并行
的。gpstart命令应该在Master主机上gpadmin用户来执行
$ gpstart
gpstart命令常见的参数有
1.
-a不提示确认如果没有指定该参数将会有确认继续的提示信息
Continue with Greenplum instance startup Yy|Nn (default=N):
2.
-m启动的只是Master实例在运维的时候会经常用到。不过对于Primary
实例来说也可以使用gpstart -m的方式来单独启动比如在处理故障时可以
通过这种方式来测试某个Primary是否可以正常启动虽然启动时会收到如下错
但这并不影响成功启动。
版权所有Esena(陈淼 ) 编写陈淼 - 292 -
Greenplum Database 管理员指南 V6.2.1
4版本和5版本的错误信息为
gpstart failed. (Reason='Database does not contain gp_fault_strategy entry')
exiting...
6版本的错误信息为
FATAL - no master dbs defined!
gpstart failed. (Reason='Error: GpArray() - no master dbs defined')
exiting...
3.
-R限制模式启动数据库在运维的时候会经常用到。限制模式仅允许
SUPERUSER连接数据库在进行系统表VACUUM FULL操作时限制模式将可以确
VACUUM FULL不受其他用户访问的影响尽量命令执行的时间。
4.
-B同时启动的实例数量缺省值为64最大值为128一般不需要修改此参数。
5.
-y启动集群时忽略Standby。在Standby存在故障影响集群的正常启动时
可以通过该参数来跳过Standby的启动和检查该参数只是跳过Standby而不
会删除Standby在特定的故障处理场景会很有帮助。
停止 GP 数据库
要停止一个GP数据库系统使用gpstop命令来完成只要Master是活着的
gpstop会尝试停止集群中的所有实例包括StandbyPrimaryMirror哪怕这
些实例已经停止。缺省情况下gpstop命令会一直等到所有连接都断开才停止数据库。
gpstop命令常见的参数有
1.
-a不提示确认如果没有指定该参数将会有确认继续的提示信息
Continue with Greenplum instance shutdown Yy|Nn (default=N):
2.
-m只关闭Master实例在运维的时候会经常用到。与gpstart命令不同的是
不能使用gpstop命令来单独停止PrimaryMirror实例应该使用pg_ctl
stop的方式来停止。例如
$ pg_ctl stop -D /data/primary/default/gpseg0
3.
-B同时停止的实例数量缺省值为64最大值为128一般不需要修改此参数。
4.
-u在不停止数据库的情况下使得pg_hba.conf配置文件的修改生效使得
版权所有Esena(陈淼 ) 编写陈淼 - 293 -
Greenplum Database 管理员指南 V6.2.1
postgresql.conf配置文件中的运行时参数生效。类似于PostgreSQL
pg_ctl reload命令不同的是gpstop -u是并行的所有实例都会生效参
数的修改。需要注意的是对于postgresql.conf配置文件中的参数那些启动
参数不会立即生效必须等到数据库重启时才能生效。
5.
-M停止数据库的模式可选值有smartfastimmediate实际上-M smart
-M fast-M immediate分别对应了三种缩写-s-f-i虽然help中没
有说明但是命令是这样工作的详情可以参考gpstopPython源码。缺省情
况下smart模式gpstop命令会一直等到所有连接都断开才停止数据库
般无法满足这个条件。最常使用的是fast模式该模式会中断并回滚正在执行的
事务。immediate模式一般不建议使用该模式有时可能会导致严重的数据损坏
需要手动恢复数据库。
6.
--host停止指定主机名上的所有实例。该参数主要用于将指定主机名的机器剥
离集群。
7.
-r停止数据库并重新启动。该方式在重新启动数据库时不会在命令行输出日志
信息所以一般不建议这样操作建议停止数据库之后通过执行gpstart命令
来启动数据库。
8.
-y停止集群时忽略Standby。该参数目前已知用处不多。
访问 Master Only 模式的 Master
通过gpstart -m启动的是Master Only模式该模式下启动的只有Master
实例不会启动任何PrimaryMirror也不会启动Standby。通常是为了进行特定
的维护操作。
注意Master Only模式应该由专业服务人员进行操作。在该模式下专业服务人员
将可以只对Master实例进行访问以便进行Catalog的修改等操作。修改Catalog
的操作属于高风险操作建议不要擅自尝试否则后果自负。
使用gpstart-m参数来启动Master Only模式
$ gpstart -m
使用Utility模式连接Master实例。例如
$ PGOPTIONS='-c gp_session_role=utility' psql postgres
在完成维护操作之后应该停止Master Only模式的Master实例。然后再正常启
GP数据库集群。例如
版权所有Esena(陈淼 ) 编写陈淼 - 294 -
Greenplum Database 管理员指南 V6.2.1
$ gpstop -m
注意Master Only模式修改Catalog可能会导致集群状态不一致甚至导致数据库
无法正常启动这个操作应该由专业服务人员进行操作。通常Master Only模式修改
Catalog会导致MasterStandby的不一致可能需要重建Standby所以正常
启动数据库之后需要注意Standby的启动信息以及同步状态。
中断客户端进程
GP数据库会为每个客户端连接启动一个后台进程计算实例上也会有相应的后台
进程。SUPERUSER可以取消查询或者中断客户端连接的后台进程。
通过pg_cancel_backend()函数来取消正在执行或者排队的SQL通过
pg_terminate_backend()函数来中断客户端连接。
pg_cancel_backend()函数有两种参数模式(不过并不是所有版本都提供msg
参数选项4版本没有msg参数该参数从5版本开始提供)
pg_cancel_backend(pid int4)
pg_cancel_backend(pid int4, msg text)
pg_terminate_backend()函数也有两种参数模式(不过并不是所有版本都提供
msg参数选项4版本没有msg参数该参数从5版本开始提供)
pg_terminate_backend(pid int4)
pg_terminate_backend(pid int4, msg text)
pg_cancel_backend()函数是取消正在执行或者排队的SQL但不会中断客
户端的连接客户端在SQL被取消之后仍然可以继续执行其他SQL
pg_terminate_backend()函数是中断客户端连接客户端将无法继续使用被中断
的连接要想继续访问数据库必须重连建立数据库连接。
如果提供了msg参数数据库在取消SQL或者中断客户端连接时会将该信息发送
给客户端。消息的长度限制是128个字节超出的部分会被截断如果有中文被截断导
致半个中文客户端将会收不到msg信息而是收到如下的报错信息
ERROR: Message skipped due to incorrect encoding.
如果pg_cancel_backend()函数和pg_terminate_backend()函数执行成
版权所有Esena(陈淼 ) 编写陈淼 - 295 -
Greenplum Database 管理员指南 V6.2.1
功了将会返回true否则会返回false不过返回true不等于说SQL就立即被取
消了或者说连接就立即被中断了有时对于一些复杂事务可能需要执行多次才能
达到取消和中断的目的。对于一些使用了外部资源的查询来说还可能出现无法取消和
中断的情况此时可能需要找到使用外部资源的子进程先杀死这些子进程。
要取消查询或中断连接要先找到后台的进程号。可通过pg_stat_activity
统视图来查询该视图在6版本有了较大的变化6版本中进程号的字段为pid
6版本之前进程号的字段为procpid。例如查看所有正在执行和排队的SQL的信息
=# SELECT usename, pid, waiting, state, query, datname FROM pg_stat_activity;
查询输出的示例
可以根据查询的输出来确定需要取消或中断的后台进程号。比如要中断查出来的
空闲连接并通知客户端"中断空闲连接"可以这样执行中断函数
=# SELECT pg_terminate_backend(1542,'中断空闲连接');
FATAL: terminating connection due to administrator command: "中断空闲连接"
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
版权所有Esena(陈淼 ) 编写陈淼 - 296 -
Greenplum Database 管理员指南 V6.2.1
第十四章开启高可用
GP数据库可以配置高可用以使得GP数据库集群更可靠的运行。如果不能接受数
据丢失GP数据库要求MasterPrimary实例都必须开启高可用配置。也就是说
可用配置不仅仅是系统可靠性的保证也是数据安全的保证GP支持为Master配置
StandbyPrimary配置Mirror以确保GP数据库中的每个角色都有两份(互为备
)。关于MasterPrimary的镜像的更多介绍可以参考"冗余与故障切换"章节。
GP 数据库高可用概述
要获得一个高可用的GP数据库集群涉及多方面的因素除了GP数据库本身提供
软件层面的冗余设置外磁盘Raid网络冗余双集群等也是重要的手段。同
还需要配合日常监控和维护及时发现故障并解决才能确保GP数据库集群长期
稳定运行。
硬件设备总是无法绝对避免出故障尤其是一些比较低端或者价格低廉的X86设备
根据编者的经验来看购买配置良好架构成熟配件稳定的X86设备GP数据库集
群运行稳定的坚实基础。任何设备都有发生故障的可能所以GP数据库建议所有组
件都做冗余配置。对于有些用户来说冗余的成本已经超过了故障恢复时间的容忍程度
也可以考虑其他的数据安全方案比如备份恢复但是如果数据只有一份一旦出现
重大故障官方技术支持也不能保证一定可以恢复数据当然对于一些极端故障
便有镜像也存在无法恢复的可能性但是这种概率要低很多。
在使用GP数据库时可以从以下几个方面考虑高可用的保护
硬件层面的Raid保护
数据块的checksum校验
计算实例的Mirror镜像
Master的镜像
双集群灾备
逻辑备份与恢复
硬件层面的Raid保护
GP的最佳实践通常建议在生产环境配置Raid保护比如Raid 5可以将单盘失
版权所有Esena(陈淼 ) 编写陈淼 - 297 -
Greenplum Database 管理员指南 V6.2.1
败的故障隔离在GP数据库之外而完全不会影响到数据库的运行状态。有很多生产环
境有这方面的安全要求而且可能是硬性要求这样可以为数据库提供多一层的保障
如果条件允许GP建议这样做因为这样可以将故障隔离在硬件层面。
不过对于是否应该做Raid以及应该选择什么级别的RaidGP数据库软件本身
并没有限制毕竟用户的硬件环境也是各不相同的。不过从性能角度来说校验计算
越复杂Raid卡的性能要求也就越高正如"Raid卡性能"章节中提到的配置24
块机械盘的主机Raid卡需要很高的配置否则磁盘的性能将得不到充分的发挥
那是极大的浪费(如果可以接受这样的性能折损也是可行的)。对Raid卡的要求是以
性能为导向的比如使用NVMe单盘的连续读写性能可以轻松超过1GB/S甚至有些
可以到3GB/S左右此时如果有多块NVMe目前的常规Raid卡性能可能都无法满足多
块高性能NVMe磁盘的Raid 5策略不仅如此目前还很少有Raid卡能直接支持NVMe
协议如果用SATA口转接NVMe磁盘的话还不如直接少花点钱用SATA口的SSD。如果
不那么在乎磁盘失效带来的影响通过PCIE接口直连NVMe也许更能发挥磁盘的性能优
势。另外Raid 5在出现单盘故障时的性能损失也是一个需要考虑的因素虽然这种
故障的概率一般很低。
关于性能是一个复杂的系统性问题之前的章节已经解释过GP诞生的最初目
是要解决共享存储的IO瓶颈按照目前主流的X86配置OLAP场景的IO问题其实
已经解决2410K转速的SAS机械盘配合主流的Raid划分为2Raid 5
续读写能力已经可以达到3GB/S甚至更高再配合库内压缩这样的IO吞吐能力80
CoreCPU配置也能常常跑满CPU资源所以仅从IO性能的角度来说OLAP场景
2410K转速的SAS机械盘已经完全能够胜任。如果要考虑OLTP场景的IOPS能力和磁
盘的可靠性和稳定性编者相信在未来SSD一定是更好的选择。
数据块的checksum校验
GP数据库在从磁盘读取数据到内存时会检查数据文件是否已经发生损坏(前提时
写入数据是计算了校验值并和Header一同写入磁盘)。这种损坏可能是机械盘出现
坏道Raid卡的程序有BUG等。不少个人计算机用户也曾遭遇过长期存储的文件
突然有一天发现打开报错了。GP会为每个数据块存储一个checksum在读取数据
会校验数据块与checksum的值是否吻合一旦发现不吻合则相应的查询会报错
失败。
GP数据库内部的常规数据表大体上可以分为两种类型heap(或者叫堆表)
AO(或者叫追加优化表)。在4.3版本之前AO表实际上是Append-Only的缩写
思是这种表是只能追加记录的不能修改记录虽然从4.3版本开始AO表的真实含义
已经是Append-Optimized但为了保持语法的一致AppendOnly这个关键字一直
延续和保留着这并不影响对AO表数据的修改操作。在GP数据库内这两种表都使用
checksum来进行数据块的校验。AO表从诞生时就自带checksum支持而且缺省是
打开的heap表的checksum是从5版本才开始支持。
4版本时heap表没有checksum检查5版本heap表有了checksum检查。
然而无论是heap表还是AOMirror在收到同步的page缺省不会做checksum
版权所有Esena(陈淼 ) 编写陈淼 - 298 -
Greenplum Database 管理员指南 V6.2.1
检查这将无法从根本上避免page损毁被同步到Mirror的情况发生。而6版本完全放
弃了filerep的机制使用了WAL同步策略这将从根本上避免了损毁page被同步到
Mirror的情况发生。
GP数据库对数据的修改操作是在内存中完成的之后数据会被刷入磁盘在将
数据刷入磁盘时数据库会自动计算checksum的值并与数据一同保存到page
checksum的值将会作为pageheader被一同存储到磁盘上。当从磁盘读取page
会根据checksum的值进行校验如果校验不通过数据库会报错并导致事务失败。
所以checksum是一个非常重要的保护可以防止未被系统检测到的磁盘文件损
坏影响数据库的正常运行因为并不是所有的异常都能够被磁盘管理系统或者操作系统
检测到。尤其是机械盘这种机械原理的硬件设备异常是时有发生的所以厂商都会
设置一个经验性的阈值只有异常比例超过预设的阈值时才被认为设备有故障而在此
之前可能已经有很多的异常发生且已经影响到操作系统和数据库的正常运行。
目前的5版本和6版本在使用gpinitsystem初始化数据库集群时都是缺省打
开了heap表的checksum检查虽然可以关闭但这显然是不推荐的选择可以通过
gpinitsystem的初始化配置文件中设置参数HEAP_CHECKSUMoff来关闭
heap表的checksum检查。实际上对应的是initdb命令的--data-checksums参数
需要注意的是这是初始化参数在集群被初始化之后无法修改此参数因为这与数
据文件的结构相关如果要修改此参数只有重新初始化集群所以保持缺省打开是
最好的选择。虽然不能修改但仍可以通过gpconfig命令和show来查看该只读参数
的值。例如
$ gpconfig -s data_checksums
或者
=# show data_checksums;
在执行gpstart命令来启动GP集群时gpstart也会检查Master以及所有
Instanceheapchecksum设置是否一致。如果该参数的设置存在不一致启动会
报错退出。虽然可以通过--skip-heap-checksum-validation参数来忽略启动时
heapchecksum参数的一致性检查但是除非确有必要否则不要使用。
在确实需要忽略checksum检查以便恢复数据时可以修改postgresql.conf
文件中的ignore_checksum_failure参数为on这样数据库在发现checksum
验异常时只是输出警告信息而不会中断事务并继续将磁盘上的数据读取到内存中。
之后如果损毁的数据被再次修改修改后的数据会被刷入磁盘并且一定会被扩散到
Mirror(虽然在6版本是基于WAL同步但由于更新的是错误的数据WAL同步的也是
错误的更新结果)这可能会导致更严重的数据损坏或者数据丢失所以仅应该在进
行数据的灾难性恢复时考虑开启该参数。
对于AO可以针对每个表甚至每个叶子分区来设置是否打开checksum校验
版权所有Esena(陈淼 ) 编写陈淼 - 299 -

 

 

 

 

 

 

 

Content      ..     4      5      6      7     ..