[原创]Greenplum数据库集群实践

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。

  

转载于:https://www.cnblogs.com/wsjhk/p/9116975.html

你可能感兴趣的:(数据库,运维,shell)