GreenPlum实践 ==============================================
目录:
一、安装环境准备
二、GP数据库安装
三、集群添加standby节点
四、master和standby相互切换
五、新增segment节点
六、非Mirror模式为Segment节点增加Mirror
七、Segment节点故障转移到Mirror并恢复segment
八、迁移(替换)segment节点
九、移除segment节点
十、常用SQL和数据导入导出
十一、GP集群中表的数据分布机制以及同步机制
============================================== 一、安装环境准备
机器IP 角色
192.168.156.144 master
192.168.156.145 segment1
192.168.156.146 segment2
192.168.156.200 standby Greenplum 需要在GP 数据库系统的所有主机(masters 和 segments) 上配置推荐的OS参数,以root用户登录,修改所有主机的OS参数
(1)、关闭防火墙(三台主机)(学习时可以直接关闭,正式环境是通过开放端口)
#service iptables stop 停止防火墙服务,重启电脑后仍然会开启
#chkconfig iptables off 关闭防火墙服务开机启动,重启后生效
(2)、修改/etc/hosts文件(三台主机)
在hosts文件中添加或修改一下内容:
192.168.156.144 master
192.168.156.145 segment1
192.168.156.146 segment2
添加之后,可以通过ping命令测试是否正确,如:ping master测试是否能访问master节点
(3)、修改或添加/etc/sysctl.conf(三台主机)
kernel.shmmax = 500000000
kernel.shmmni = 4096
kernel.shmall = 4000000000
kernel.sem = 250 512000 100 2048
kernel.sysrq = 1
kernel.core_uses_pid = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.msgmni = 2048
net.ipv4.tcp_syncookies = 1
net.ipv4.ip_forward = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.conf.all.arp_filter = 1
net.ipv4.ip_local_port_range = 1025 65535
net.core.netdev_max_backlog = 10000
vm.overcommit_memory = 2
(4)、配置/etc/security/limits.conf文件,添加以下内容(三台主机)
* soft nofile 65536
* hard nofile 65536
* soft nproc 131072
* hard nproc 131072
(5)、设置预读块的值为16384(三台主机)
# blockdev --getra /dev/sda 查看预读块,默认大小为8196
# blockdev --setra 16384 /dev/sda 设置预读块
(6)、设置磁盘访问I/O调度策略(三台主机)
# echo deadline > /sys/block/sda/queue/scheduler
(7)、上传并解压数据库安装文件(master节点)
# unzip gpmaster.zip
之后的目录文件如下:
greenplum_path.sh - Greenplum 数据库环境变量配置文件
GPDB-LICENSE.txt- Greenplum license 文件
LICENSE.thirdparty- 第三方 license 文件
bin- 目录下包括Greenplum 数据库管理程序,也包括PostgreSQL 客户端和服务程序
demo - 目录下包括Greenplum 演示程序
docs - Greenplum 数据库帮助文档(PDF 格式)
etc - OpenSSL 配置文件
ext - Greenplum 数据库程序用的附加程序( 如 Python)
include - Greenplum 数据库C header files
lib - Greenplum 数据库和 PostgreSQL 库文件
sbin - Supporting/Internal 脚本和程序
share - Greenplum 数据库共享文件 二、GP数据库安装
1、安装软件(master节点)
在/etc/profile中增加:# source /usr/local/gpmaster/greenplum_path.sh,然后在三台主机执行命令:source /usr/local/gpmaster/greenplum_path.sh
2.创建用户和节点文件
# useradd gpadmin -m
# passwd gpadmin
在gpadmin账户下创建all_hosts,文件内容:(三台主机)
master
segment1
segment2
3.运行gpseginstall工具(master节点 /home/gpadmin)在所有节点上安装GP软件,完成后提示成功.
# chgrp -R gpadmin /usr/local
# chmod -R 0775 /usr/local
# su - gpadmin
# gpseginstall -f all_hosts -u gpadmin -p gpadmin
4.切换到gpadmin用户验证无密码登录(三台主机)
(1)切换用户
# su - gpadmin
(2)使用gpssh工具来测试无密码登录所有主机,结果如下图:
# gpssh-exkeys -f all_hosts
# gpssh -f all_hosts -e ls -l $GPHOME
5.配置环境变量(master节点)
在/home/gpadmin路径下,以root用户添加下述信息到.bashrc和.bash_profile文件最后
# source /usr/local/gpmaster/greenplum_path.sh
然后将.bashrc文件发送到segment1和segment2,命令如下:
# scp .bashrc segment1:~
# scp .bashrc segment2:~
6.创建存储区域(master节点)
(1)创建Master数据存储区域
# gpssh -h master -e 'mkdir -p /data/master'
(2)改变目录的所有权
# gpssh -h master -e 'chown gpadmin:gpadmin /data/master'
(3)创建一个包含所有segment主机名的文件/home/gpadmin/seg_hosts,内容如下:
segment1
segment2
(4)使用gpssh工具在所有segment主机上创建主数据和镜像数据目录,如果没有设置镜像可以不创建mirror目录(切换gpadmin用户)
# gpssh -f seg_hosts -e 'mkdir -p /data/primary'
# gpssh -f seg_hosts -e 'mkdir -p /data/mirror'
# gpssh -f seg_hosts -e 'chown gpadmin /data/primary'
# gpssh -f seg_hosts -e 'chown gpadmin /data/mirror'
7.同步系统时间,需要安装ntpd。# yum install ntp -y
(1) 在Master主机上编辑/etc/ntp.conf来设置如下内容:
server 127.127.1.0
(2) 在Segment主机上编辑/etc/ntp.conf
server master
(3) 在Master主机上,通过NTP守护进程同步系统时钟(切换gpadmin用户)
# gpssh -f all_hosts -v -e 'ntpd'
8.验证操作系统设置(切换gpadmin用户)
# gpcheck -f all_hosts -m master
检查运行结果是否有error信息,如果有处理掉错误信息后重新执行上面的命令检查,直至没有error信息。目前知道的xfs相关的报错不影响安装。
9.创建Greenplum数据库配置文件
(1) 以gpadmin用户登录
# su - gpadmin
(2) 从模板中拷贝一份gpinitsystem_config文件
# cp $GPHOME/docs/cli_help/gpconfigs/gpinitsystem_config /home/gpadmin/gpinitsystem_config
# chmod 775 gpinitsystem_config
(3) 设置所有必须的参数
ARRAY_NAME="EMC Greenplum DW"
SEG_PREFIX=gpseg
PORT_BASE=40000
declare -a DATA_DIRECTORY=(/data/primary)
MASTER_HOSTNAME=master
MASTER_DIRECTORY=/data/master
MASTER_PORT=5432
TRUSTED SHELL=ssh
CHECK_POINT_SEGMENT=8
ENCODING=UNICODE
(4) 设置可选参数
MIRROR_PORT_BASE=50000
REPLICATION_PORT_BASE=41000
MIRROR_REPLICATION_PORT_BASE=51000
declare -a MIRROR_DATA_DIRECTORY=(/data/mirror)
10.运行初始化工具初始化数据库
# gpinitsystem -c gpinitsystem_config -h seg_hosts
成功之后,数据库便启动了,出现Continue with Greenplum creation Yy/Nn>,输入 y,然后等待完成即可。初始化过程中遇到的报错如下:
错误1:
gpadmin-[FATAL][1]:-Failed Update port number to 40000
解决:安装ed-1.1-3.3.el6.x86_64.rpm
错误2:
psql: FATAL: DTM initialization: failure during startup recovery, retry failed, check segment status (cdbtm.c:1603)
20180513:23:05:43:gpinitsystem:master:gpadmin-[FATAL]:-Failed to retrieve rolname. Script Exiting!
解决:关闭防火墙。
11.设置环境变量:
添加"export MASTER_DATA_DIRECTORY=/data/master/gpseg-1"到~/.bashrc文件尾,并同步到segment1和segment2节点。
# scp .bashrc root@segment1:~
# scp .bashrc root@segment2:~
12.启动和停止数据库测试是否能正常启动和关闭,命令如下:
# gpstart -a
# gpstop -a
13.访问数据库:
# psql -d postgres
postgres=# select datname,datdba,encoding,datacl from pg_database;
14.调整数据库参数,必须重新启动数据库:
调整方法:执行命令 gpconfig -c 参数名 -v 参数值 -m Master节点值
检查方法:重启数据库后,执行命令 gpconfig -s 参数名
(1)调整
#gpconfig -c shared_buffers -v 128MB -m 128MB
#gpconfig -c gp_vmem_protect_limit -v 15360 -m 15360
#gpconfig -c max_connections -v 1000 -m 200
#gpconfig --skipvalidation -c wal_send_client_timeout -v 60s -m 60s
(2)查看:
#gpconfig -s shared_buffers
#gpconfig -s gp_vmem_protect_limit
#gpconfig -s max_connections
#gpconfig -s wal_send_client_timeout
或者
# psql -d postgres
postgres=# show shared_buffers;
postgres=# show gp_vmem_protect_limit;
postgres=# show max_connections;
postgres=# show wal_send_client_timeout;
15.查看数据库状态:
# gpstate 三、集群添加standby节点
1.在standby节点的/etc/profile添加:# source /usr/local/gpmaster/greenplum_path.sh
2.所有节点的/etc/hosts中添加:# 192.168.156.200 standby的配置
3.按照安装前准备配置standby主机,然后在master节点的all_hosts文件中添加standby,重新建立ssh互信(root和gpadmin两个用户都要),并复制必要的文件和环境变量。(在master上操作)
# gpssh-exkeys -f all_hosts
# gpssh -h standby -e 'mkdir -p /data/master'
# gpssh -h standby -e 'chown gpadmin:gpadmin /data/master'
# scp /usr/local/gpmaster standby:/usr/local/gpmaster
# scp .bashrc standby:~
# scp .bash_profile standby:~
4.在master上执行以下命令初始化standby节点即可:
# gpinitstandby -s standby
# 如果是重新配置需要先删除原来的standby信息,然后在执行初始化:
# gpinitstandby -r
# rm -rf /data/master/*
# gpinitstandby -s standby 四、master和standby相互切换
1.在master上执行以下命令模拟宕机
# gpstop -m
2.在standby上执行以下命令切换为master身份顶替原来的master
# gpactivatestandby -d $MASTER_DATA_DIRECTORY
# 执行之前需要在gpadmin用户下的.bashrc文件下添加一下两个环境变量,否则会报错。
# export MASTER_DATA_DIRECTORY=/data/master/gpseg-1
# export PGPORT=5432
3.切换完成之后在原来的master上删除/data/master/gpseg-1目录,然后在standby(现在的master)上初始化master,把原来的master变成standby角色。
# gpinitstandby -s master
4.然后可以重复上述操作把master恢复成master角色。 五、新增segment节点
注:新增segment节点有两种情况:第一种是在集群中的原有机器中添加segment;第二种是新增主机,添加segment。Master节点存在Standby,
GreenPlum认为Master有Standby,那么Segment就应该有Mirror,认为数据库开启了Mirror模式,如果实际segment没有mirror则查不到相关的资料,
加入新节点会报错,以下操作在master执行了# gpinitstandby -r去掉集群的standby。
1.按照安装流程把standby节点准备好,新加节点需要在master上的.bashrc文件指定#export PGDATABASE=dbtest环境变量,初始化时候需要把信息写到这个数据库。
(本例是第二种把standby当成新节点加入,如果是第一种把newseg文件内容改为集群中现有的节点主机名即可,操作是一样的。)
2.在master上新建newseg文件,内容为:standby,新加节点的主机名。
3.执行安装前检查,如果有报错先进行处理。
# gpcheck -f newseg
4.检查ssh互信和时间
# gpssh -f newseg -e date
5.执行命令生成加入配置文件
# gpexpand -f newseg
# 输入y
# 输入0或1 ,0表示只在新节点上初始化segment实例,1表示在所有segment节点初始化一个再加一个segment,新的节点是2个segment。这里输入0.
# 生成gpexpand_inputfile_20180529_164324文件和gpexpand_inputfile_20180529_164324.fs文件(若还没有文件空间则没有.fs文件)
# standby:standby:40000:/data/primary/gpseg2:4:2:p --根据两个文件中的内容在各自的节点上创建好对应的目录并授权
6.执行以下命令正式加入节点
# gpexpand -i gpexpand_inputfile_20180529_164324 -S -V -v -n 1 -B 1 -t /tmp --参数-S是表示用spread方式,不加是默认的group模式
# 由于standby节点没有新建/data/primary目录导致报错执行# gpexpand -r -D dbdream回滚掉之前的操作,在回滚时也报错,发现数据库已经关闭,
需要通过# gpstart -R将数据库启动到utility模式,然后回滚掉之前的添加Segment操作:gpexpand -r -D dbdream,回滚后再启动数据库# gpstart -a重新执行加入命令加入成功。
7.segment添加成功之后如果需要将数据重分布则执行以下命令:
# gpexpand -a -d 1:00:00 -D dbtest -S -t /tmp -v -n 1
# 等待重分布完成
# select * from gpexpand.expansion_progress; --查看重分布进度
8.清除gpextend产生的schema gpexpand
# gpexpand -c -D dbtest
# 输入两次y 六、非Mirror模式为Segment节点增加Mirror
1.在所有segment节点上创建mirror的数据存放文件和文件空间所需的目录(如果有文件空间)
# mkdir /data/mirror
# chown -R gpadmin.gpadmin mirror
2.在master节点上使用以下参数生成添加Mirror的参数文件
# gpaddmirrors -o add_mirror
# 输入mirror的数据目录:/data/mirror
#生成文件内容如下,可以看到segment1对应的mirror0放到了segment2节点上,以此类推:
# cat add_mirror
filespaceOrder=
mirror0=0:segment2:41000:42000:43000:/data/mirror/gpseg0
mirror1=1:standby:41000:42000:43000:/data/mirror/gpseg1
mirror2=2:segment1:41000:42000:43000:/data/mirror/gpseg2
3.执行以下命令正式添加mirror
# gpaddmirrors -i add_mirror
# 添加完成会提示通过gpstate –s命令来查看Mirror的状态,Use gpstate -s to check the resynchronization progress。
4.查看mirror信息
# gpstate -m
5.数据库查看mirror的信息
# select * from gp_segment_configuration order by dbid;
6.把初始化standby接入集群。
# gpinitstandby -s standby
7.此时GP集群正常,拥有master,standby实例,3个segment实例和3个mirror实例。 七、Segment节点故障转移到Mirror并恢复segment
1.重启segment2节点主机,模拟segment2节点宕机。此时集群读写正常,但是standby节点的mirror切换为primary了,standby有两个primary,数据分布不均衡了。
使用以下sql可以查看到各个节点之间的状态变化。(注意segment2重启后关闭iptables,否则执行# gprecoverseg 会很久并卡住)
# dbtest=# select * from gp_segment_configuration order by 1;
dbid | content | role | preferred_role | mode | status | port | hostname | address | replication_port | san_mounts
------+---------+------+----------------+------+--------+-------+----------+----------+------------------+------------
1 | -1 | p | p | s | u | 5432 | master | master | |
2 | 0 | p | p | c | u | 40000 | segment1 | segment1 | 43000 |
3 | 1 | m | p | s | d | 40000 | segment2 | segment2 | 43000 |
4 | 2 | p | p | s | u | 40000 | standby | standby | 43000 |
5 | 0 | m | m | s | d | 41000 | segment2 | segment2 | 42000 |
6 | 1 | p | m | c | u | 41000 | standby | standby | 42000 |
7 | 2 | m | m | s | u | 41000 | segment1 | segment1 | 42000 |
8 | -1 | m | m | s | u | 5432 | standby | standby | | 2.恢复到原来的架构,有两种可能情况,第一种情况,当故障主机启动后,这台主机上的节点会自动启动,当然现在已经都是Mirror节点了,角色是不会切换的,
而且数据是不一致状态。这种情况只需要使用gprecoverseg命令同步一下数据后,就可以切换到原来的架构了。第二种情况,当故障主机segment2启动后,
这台主机上的节点并没有启动,而且在重启数据库时,这台主机上的节点也没有启动。以下操作针对第二种情况,需要使用gprecoverseg命令同步故障机节点的数据,
如果数据量很大,同步要很长时间。
# gprecoverseg
# 会列出需要同步的节点,输入y
# 数据同步完成,查看mirror节点的信息,mirror状态正常,但是当前角色还没有切换回来。# gpstate -m
3.进行primary和mirror角色切换
# gprecoverseg -r
# 会列出需要切换的节点,输入y
# 切换完成,使用gpstate –m查看mirror信息。
# 使用# gpstate -e 命令有可能会看到主/备数据正在同步,这是正常的,过段时间同步好了再查看就正常了。
# 还可以使用以下sql来查看数据库的切换信息,还有扩充segment和加mirror的信息
# select * from gp_configuration_history; 八、迁移(替换)segment节点
# 这里迁移standby主机上的primary和mirror到master主机,如果是新机器则按照“新增一个segment节点”步骤执行到第四步初始化好机器,无需执行gpextend,
迁移过程中gp集群会自动将其加入。(迁移segment节点还可以手动停掉segment实例:# pg_ctl stop -D /data/primry/gpseg1,然后停集群,拷贝segment数据目录到目的迁移主机上,只修改status为d的记录主机为目的迁移的主机名重启做恢复和角色切换即可。)
1)在master主机上创建对应的目录
# mkdir {primary,fspc_primary,mirror,fspc_mirror}
# chown -R gpadmin.gpadmin primary fspc_primary mirror fspc_mirror
2)查看集群的节点信息并备份:
# pg_dump -t gp_segment_configuration -c -f ~/gp_segment_configuration.dat
dbtest=# select * from gp_segment_configuration;
dbid | content | role | preferred_role | mode | status | port | hostname | address | replication_port | san_mounts
------+---------+------+----------------+------+--------+-------+----------+----------+------------------+------------
1 | -1 | p | p | s | u | 5432 | master | master | |
4 | 2 | p | p | s | u | 40000 | standby | standby | 43000 |
7 | 2 | m | m | s | u | 41000 | segment1 | segment1 | 42000 |
8 | -1 | m | m | s | u | 5432 | standby | standby | |
2 | 0 | p | p | s | u | 40000 | segment1 | segment1 | 43000 |
5 | 0 | m | m | s | u | 41000 | segment2 | segment2 | 42000 |
3 | 1 | p | p | s | u | 40000 | segment2 | segment2 | 43000 |
6 | 1 | m | m | s | u | 41000 | standby | standby | 42000 |
dbtest=# select * from pg_filespace_entry; --查看文件空间
fsefsoid | fsedbid | fselocation
----------+---------+---------------------------
3052 | 2 | /data/primary/gpseg0
3052 | 3 | /data/primary/gpseg1
3052 | 1 | /data/master/gpseg-1
3052 | 4 | /data/primary/gpseg2
3052 | 5 | /data/mirror/gpseg0
3052 | 6 | /data/mirror/gpseg1
3052 | 7 | /data/mirror/gpseg2
3052 | 8 | /data/master/gpseg-1
16471 | 1 | /data/fspc_master/gpseg-1
16471 | 2 | /data/fspc_primary/gpseg0
16471 | 3 | /data/fspc_primary/gpseg1
16471 | 4 | /data/fspc_primary/gpseg2
16471 | 5 | /data/fspc_mirror/gpseg0
16471 | 6 | /data/fspc_mirror/gpseg1
16471 | 7 | /data/fspc_mirror/gpseg2
16471 | 8 | /data/fspc_master/gpseg-1
3)停掉集群
# gpstop -a
4)master方式启动集群
# gpstart -m
5)修改集群的节点信息
# PGOPTIONS="-c gp_session_role=utility" psql -d postgres
# set allow_system_table_mods='dml'; --获取修改系统表的权限
# update gp_segment_configuration set hostname='master',address='master',status='d' where (content=1 and role='m');
# update gp_segment_configuration set mode='c' where (content=1 and role ='p');
# update gp_segment_configuration set hostname='master',address='master',status='d' where (content=2 and role='p');
# update gp_segment_configuration set role = CASE WHEN preferred_role='p' then 'm' ELSE 'p' END where content=2;
# update gp_segment_configuration set mode='c' where (content=2 and role ='p');
dbtest=# select * from gp_segment_configuration; --查看修改后的配置
dbid | content | role | preferred_role | mode | status | port | hostname | address | replication_port | san_mounts
------+---------+------+----------------+------+--------+-------+----------+----------+------------------+------------
1 | -1 | p | p | s | u | 5432 | master | master | |
8 | -1 | m | m | s | u | 5432 | standby | standby | |
2 | 0 | p | p | s | u | 40000 | segment1 | segment1 | 43000 |
5 | 0 | m | m | s | u | 41000 | segment2 | segment2 | 42000 |
6 | 1 | m | m | s | d | 41000 | master | master | 42000 |
3 | 1 | p | p | c | u | 40000 | segment2 | segment2 | 43000 |
4 | 2 | m | p | s | d | 40000 | master | master | 43000 |
7 | 2 | p | m | c | u | 41000 | segment1 | segment1 | 42000 |
6)重启集群
# gpstop -m
# gpstart -a
# 集群可以启动成功,但是会提示有2个segment需要恢复,此时standby节点上的segment不会启动了,相当于自动移除了。
7)恢复master上的segment
# gprecoverseg -F --执行完全恢复
# 输入y
# 集群会自动在master上启动segment的进程并同步数据,但是此时master上的两个segment都是mirror,角色没有切换,需要手工切换,但是需要在数据同步完成之后执行。
注意:恢复过程,数据越大,时间越长,需要注意使用# gpstate -m检查时,如果出现Resynchronizing字样,一定不能执行下一步操作,需要等状态变为Synchronized之后,
才能继续下一步操作。
8)数据同步完成后进行角色切换
# gpstate -m --查看数据是否同步完成
# gprecoverseg -r
# 输入y
# gpstate -e --切换后查看同步状态
# 等待一段时间再次查看所有segment同步数据完成,状态正常。
9)查看此时的节点信息和文件空间目录
dbtest=# select * from gp_segment_configuration; --节点的信息更新了
dbid | content | role | preferred_role | mode | status | port | hostname | address | replication_port | san_mounts
------+---------+------+----------------+------+--------+-------+----------+----------+------------------+------------
1 | -1 | p | p | s | u | 5432 | master | master | |
8 | -1 | m | m | s | u | 5432 | standby | standby | |
2 | 0 | p | p | s | u | 40000 | segment1 | segment1 | 43000 |
5 | 0 | m | m | s | u | 41000 | segment2 | segment2 | 42000 |
3 | 1 | p | p | s | u | 40000 | segment2 | segment2 | 43000 |
6 | 1 | m | m | s | u | 41000 | master | master | 42000 |
4 | 2 | p | p | s | u | 40000 | master | master | 43000 |
7 | 2 | m | m | s | u | 41000 | segment1 | segment1 | 42000 |
dbtest=# select * from pg_filespace_entry; --可以看到最后四行被更新了
fsefsoid | fsedbid | fselocation
----------+---------+---------------------------
3052 | 2 | /data/primary/gpseg0
3052 | 3 | /data/primary/gpseg1
3052 | 1 | /data/master/gpseg-1
3052 | 5 | /data/mirror/gpseg0
3052 | 7 | /data/mirror/gpseg2
3052 | 8 | /data/master/gpseg-1
16471 | 1 | /data/fspc_master/gpseg-1
16471 | 2 | /data/fspc_primary/gpseg0
16471 | 3 | /data/fspc_primary/gpseg1
16471 | 5 | /data/fspc_mirror/gpseg0
16471 | 7 | /data/fspc_mirror/gpseg2
16471 | 8 | /data/fspc_master/gpseg-1
3052 | 4 | /data/primary/gpseg2
16471 | 4 | /data/fspc_primary/gpseg2
3052 | 6 | /data/mirror/gpseg1
16471 | 6 | /data/fspc_mirror/gpseg1 九、移除segment节点
# 移除segment节点有两种方式,第一种是采用替换segment的步骤将要移除的segment的实例迁移到其他segment节点;第二种是全备数据库,删除节点后重新恢复数据,
大数据量场景下耗时长。以下操作是第二种,将master上的segment节点移除掉(这里的移除的segment是包含了primary和mirror的,
若只有primary则第四步中不需要执行update操作,第五步不用# gprecoverseg恢复操作)。
1)备份数据库
# gp_dump --gp-d=/home/gpadmin/backup dbtest --该命令会备份每个segment的自己那部分数据在各自节点的指定目录下
2)关闭数据库
# gpstop -a
3)master模式启动数据库
# gpstart -m
4)登录数据库
# PGOPTIONS="-c gp_session_role=utility" psql -d dbtest
# set allow_system_table_mods='dml'; --获取修改系统表的权限
# delete from gp_segment_configuration where dbid in (4,6);
# update gp_segment_configuration set content = 1 where dbid = 7;
# delete from pg_filespace_entry where fsedbid in (4,6);
# update pg_filespace_entry set fselocation='/data/mirror/gpseg1' where fsefsoid=3052 and fsedbid=7;
# update pg_filespace_entry set fselocation='/data/fspc_mirror/gpseg1' where fsefsoid=16471 and fsedbid=7;
# gpstop -m
5)启动数据库并查看节点是否删除,并且执行同步操作恢复mirror
# gpstart -a
# gpstate -s
# gprecoverseg
# gpstate -e
# gpstate -m
6)恢复数据,只需要将移除节点上backup目录下的数据重分布到集群即可。
# psql dbtest -f /home/gpadmin/backup/gp_dump_0_* 十、常用SQL和数据导入导出
1.远程登录
# create role usertest password 'test123' createdb login; //创建用户并授予登录和创建数据库的权限
# alter role gpadmin with password ‘gpadmin’;
# select rolname,oid from pg_roles; //查看用户信息
# vi pg_hba.conf //添加以下内容
host all gpadmin 192.168.156.145/32 md5
# gpstop -u //重新加载后才能使之生效,不需要重启数据库
# psql -d dbtest -U gpadmin -h master -p 5432
2.查看数据库集群的数据分布情况
# select gp_segment_id,count(*) from tt group by 1 order by 1;
gp_segment_id | count
---------------+-------
0 | 4
1 | 5
2 | 3
3.查看表空间和文件空间对应关系,默认只有pg_segment一个文件空间,上面有pg_default和pg_global两个表空间
# select a.spcname,b.fsname from pg_tablespace a,pg_filespace b where spcfsoid=b.oid;
4.新建表空间
1)先创建文件空间,master节点和所有segment节点
# mkdir /data/fspc_master && chown -R gpadmin.gpadmin /data/fspc_master (master和standby节点都要创建)
# gpssh -f seg_hosts -e 'mkdir /data/fspc_primary'
# gpssh -f seg_hosts -e 'mkdir /data/fspc_mirror'
# gpssh -f seg_hosts -e 'chown -R gpadmin.gpadmin /data/fspc_primary'
# gpssh -f seg_hosts -e 'chown -R gpadmin.gpadmin /data/fspc_mirror'
2)创建文件空间
# gpfilespace
# 输入表空间的名字,名字随便起,但是不能使用gp_开头,输入:tablespace1
# 输入Segment节点的文件空间目录:/data/fspc_primary
# 输入Mirror节点的文件空间目录:/data/fspc_mirror
# 输入Master节点的文件空间目录:/data/fspc_master
# 生成一个类似gpfilespace_config_20180529_195239的配置文件,这个文件可以自己创建和修改
3)正式创建文件空间
# gpfilespace --config gpfilespace_config_20180529_195239
4)创建完文件空间,即可在文件空间上创建表空间,创建表空间必须使用support权限用户
# create tablespace tbs1 filespace tablespace1;
5)设置用户默认就使用新建的表空间
# alter role gpadmin set default_tablespace='tbs1';
# grant all on tablespace tbs1 to gpadmin;
6)在创建数据库时,指定数据库使用的默认表空间
# create database tt tablespace tbs1;
5.修改表字段和CTAS(create table as select)的方式创表
# alter table tt alter column tt type bigint;
# create table t_ctas as select * from tt;
6.加载和卸载数据(必须要超级用户)
# copy命令导入导出都要经过master,效率低下,适合数据量小的场景。数据量大,需要并发导入导出使用外部表gpfdist工具,
直接从segment节点导入导出。数据加载还可以使用gpload工具,需要使用yaml语言编写gpload工具的控制文件。
1)copy命令数据加载
# copy tt from '/home/gpadmin/tt.txt' with delimiter ',' null '' LOG ERRORS INTO TT_ERRS SEGMENT REJECT LIMIT 100;
# 指定null参数时,包含空值的数据可以成功加载,但是可能会遇到字段类型不匹配的情况,也就是错误数据,解决这个问题可以修改数据文件中错误的数据,
还可以通过指定记录并跳过错误数据,将正确的数据加载到数据库,这是常用的方法,毕竟大多数情况都不知道数据文件中存在多少错误的数据,也可以修改数据文件中空数据为\N。
2)copy命令数据卸载
# copy tt to '/home/gpadmin/tt_output.txt' WITH DELIMITER AS ',';
# 使用copy命令卸载数据时,空数据以\N的方式卸载,\N是null的转义
7.查看表文件大小:
# select pg_size_pretty(calc_partition_table('public','tt'));
# select pg_size_pretty(pg_relation_size('tt'));
# select pg_size_pretty(pg_database_size('dbtest'));
8.查看活动会话:
# select * from pg_stat_activity;
# select pg_cancel_backend(procpid); --杀死某次查询
# select pg_cancel_backend(85475);
# ps -ef | grep -i postgres | grep -i con
9.表分析:
# Vacuum analyze tt;
# select * from pg_stat_user_tables where relname = 'tt';
10.查看磁盘、数据库空间
# SELECT * FROM gp_toolkit.gp_disk_free ORDER BY dfsegment;
# SELECT * FROM gp_toolkit.gp_size_of_database ORDER BY sodddatname;
11.查看日志
# SELECT * FROM gp_toolkit.__gp_log_master_ext;
# SELECT * FROM gp_toolkit.__gp_log_segment_ext;
12.查看表占用空间
# SELECT relname as name, sotdsize/1024/1024 as size_MB, sotdtoastsize as toast, sotdadditionalsize as other
FROM gp_toolkit.gp_size_of_table_disk as sotd, pg_class WHERE sotd.sotdoid = pg_class.oid ORDER BY relname;
13.查看索引占用空间
# SELECT soisize/1024/1024 as size_MB, relname as indexname FROM pg_class, gp_toolkit.gp_size_of_index
WHERE pg_class.oid = gp_size_of_index.soioid AND pg_class.relkind='i';
14.查看锁
# SELECT locktype, database, c.relname, l.relation, l.transactionid, l.transaction, l.pid, l.mode, l.granted, a.current_query
FROM pg_locks l, pg_class c, pg_stat_activity a WHERE l.relation=c.oid AND l.pid=a.procpid ORDER BY c.relname;
15.查看队列
# SELECT * FROM pg_resqueue_status;
16.OBJECT的操作统计
#SELECT schemaname as schema, objname as table, usename as role, actionname as action, subtype as type, statime as time FROM pg_stat_operations
WHERE objname = '<name>'; 十一、GP集群中表的数据分布机制以及同步机制
1)GreenPlum数据库支持hash分布(DISTRIBUTED BY)和随机分布(DISTRIBUTED RANDOMLY)两种分布策略,hash分布会计算分布键的hash值,
相似的hash值的数据会放到同一个Segment节点上,和hash分区算法有些类似,这样,同样的分布键的数据肯定会分布到同一个Segment节点,
这样在多表关联的时候,如果关联字段都是分布键,就可以在每个Segment节点关联后,Segment节点把结果发送到Master节点,再由Master节点汇总,
将最终的结果返还客户端。而随机分布则不能保证同样分布键的数据分布在同一个Segment节点上,这样在表关联的时候,就需要将数据发送到所有Segment节点去做运算,
这样网络传输和大量数据运算都需要较长的时间,性能非常低下,GreenPlum数据库不建议需要多表关联的表使用随机分布,也不推荐使用随机分布。
还有一点,因为每个Segment节点都是独立的PostgreSql数据库,只能保证在单个Segment几点的数据唯一性,而随机分布不能保证整体数据的唯一性,
而hash分布,相同分布键的数据会分配到同一个Segment节点,这样在单个Segment节点保证数据唯一性,也就保证了整体数据的唯一性。hash分布也是GreenPlum数据库的默认分布方式。
2)建表时如果不指定分布键和分布策略,如果表中包含主键,默认会选择主键为分布键,如果表上有唯一约束但没有主键,那么默认选择唯一字段作为分布键,
否则默认使用第一个字段作为分布键,并且使用hash分布策略。GreenPlum数据库不支持同时存在两个唯一的字段(复合主键除外)。如果建表时指定的分布键不是主键,
那么GreenPlum会把表的分布键改为主键字段,而不是指定的字段,但是SQL语句中指定的分布键必须包含主键字段,而且主键字段必须在SQL指定的分布键的第一列出现才可以,
否则会导致SQL无法成功运行。另外,随机分布不支持主键和唯一键,因为随机分布保证不了整体数据的唯一性。
3)master和standby之间是使用流复制机制同步数据的,同步的是元数据,所以一般情况下同步很快完成。segment的primary和mirror之间是采用文件同步的方式。
4)greenplum的两种节点分布模式:grouped和spread。grouped模式,默认的节点分布方式,主机的mirror节点全部放在下一个主机上,在segment主机数非常多的情况下,
至少允许两台主机挂掉;spread模式,主机的第一个mirror在下个主机,第二个mirror在次下个主机,第三mirror在次次下个主机,在segment主机数非常多的情况下,
只可以挂掉一台主机。执行初始化命令:gpinitsystem加上-S,节点分布方式为spread,如:# gpinitsystem -c gpinitsystem_config -h seg_hosts -S
或者是:# gpexpand -f new_seg -S。