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 = ''; 十一、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。