|
| 1 | +## 如何搭建阿里云RDS PostgreSQL数据库的物理备库 |
| 2 | + |
| 3 | +### 作者 |
| 4 | +digoal |
| 5 | + |
| 6 | +### 日期 |
| 7 | +2016-03-01 |
| 8 | + |
| 9 | +### 标签 |
| 10 | +PostgreSQL , 阿里云 , RDS , 物理备库 |
| 11 | + |
| 12 | +---- |
| 13 | + |
| 14 | +## 背景 |
| 15 | +如何搭建阿里云RDS PostgreSQL数据库的物理备库 |
| 16 | + |
| 17 | +用户在阿里云购买了RDS PostgreSQL,如何在自己的机房或者ECS上建立备库? |
| 18 | + |
| 19 | +关于如何构建逻辑备库,在我以前的文章有详细的讲解,所谓逻辑备库,是可以跨版本,甚至仅仅同步一部分相同步的表的备库。 |
| 20 | + |
| 21 | +https://yq.aliyun.com/articles/7240 |
| 22 | + |
| 23 | +如果用户需要构建一个和RDS PostgreSQL一模一样的备库,则可以通过流复制或者归档来完成。 |
| 24 | + |
| 25 | +步骤如下 |
| 26 | + |
| 27 | +1\. 准备备库环境 |
| 28 | + |
| 29 | +安装64位Linux |
| 30 | + |
| 31 | +安装与RDS PostgreSQL大版本一致的PostgreSQL软件 |
| 32 | + |
| 33 | +空间规划 |
| 34 | + |
| 35 | +2\. 申请一个replication角色的用户(目前RDS 的根用户已自带replication权限,可忽略此步骤) |
| 36 | + |
| 37 | +3\. 配置外网地址(可选) |
| 38 | + |
| 39 | +4\. 配置白名单,测试连通性正常 |
| 40 | + |
| 41 | +5\. 下载全量备份集,测试归档的下载接口是否正常 |
| 42 | + |
| 43 | +6\. 配置postgresql.conf, recovery.conf |
| 44 | + |
| 45 | +7\. 启动备库,检查是否同步 |
| 46 | + |
| 47 | +详细步骤 |
| 48 | + |
| 49 | +1\. 准备备库环境 |
| 50 | + |
| 51 | +安装CentOS 6.x x64,步骤略。 |
| 52 | + |
| 53 | +线上RDS PostgreSQL版本为9.4.x,所以备库环境也需要安装9.4的大版本,我们可以安装9.4.6,关注一下release notes,确保兼容性。 |
| 54 | + |
| 55 | +PS,目前阿里RDS PostgreSQL软件还没有下载或开源,如果将来开放下载或开源的话,建议安装阿里云提供的PostgreSQL版本,可以保证兼容性,以及出问题可以找到阿里云的PostgreSQL内核团队修复。 |
| 56 | + |
| 57 | +确保与线上版本编译参数一致,包括插件版本。 |
| 58 | + |
| 59 | +只需要关注如下 |
| 60 | + |
| 61 | +``` |
| 62 | +select name,setting from pg_settings; |
| 63 | + block_size | 8192 |
| 64 | + wal_block_size | 8192 |
| 65 | + rds_available_extensions | plpgsql,pg_stat_statements,btree_gin,btree_gist,chkpass,citext,cube,dblink,dict_int,earthdistance,hstore,intagg,intarray,isn,ltree,pgcrypto,pgrowlocks,pg_prewarm,pg_trgm,postgres_fdw,sslinfo,tablefu |
| 66 | +nc,tsearch2,unaccent,postgis,postgis_topology,fuzzystrmatch,postgis_tiger_geocoder,plperl,pltcl,plv8,plls,plcoffee,"uuid-ossp",zhparser,pgrouting,rdkit,pg_hint_plan,pgstattuple |
| 67 | +``` |
| 68 | + |
| 69 | +安装软件 |
| 70 | + |
| 71 | +``` |
| 72 | +wget https://ftp.postgresql.org/pub/source/v9.4.6/postgresql-9.4.6.tar.bz2 |
| 73 | +tar -jxvf postgresql-9.4.6.tar.bz2 |
| 74 | +cd postgresql-9.4.6 |
| 75 | +./configure --prefix=/home/postgres/pgsql9.4.6 --with-blocksize=8 --with-wal-blocksize=8 |
| 76 | +gmake -j 32 world |
| 77 | +gmake install-world |
| 78 | +``` |
| 79 | + |
| 80 | +配置环境变量 |
| 81 | + |
| 82 | +``` |
| 83 | +vi ~/env_pg.sh |
| 84 | +# add by digoal |
| 85 | +export PS1="$USER@`/bin/hostname -s`-> " |
| 86 | +export PGPORT=1921 |
| 87 | +export PGDATA=/data01/pgdata |
| 88 | +export LANG=en_US.utf8 |
| 89 | +export PGHOME=/home/postgres/pgsql9.4.6 |
| 90 | +export LD_LIBRARY_PATH=$PGHOME/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib:/usr/lib:/usr/local/lib:$LD_LIBRARY_PATH |
| 91 | +export DATE=`date +"%Y%m%d%H%M"` |
| 92 | +export PATH=$PGHOME/bin:$PATH:. |
| 93 | +export MANPATH=$PGHOME/share/man:$MANPATH |
| 94 | +export PGHOST=$PGDATA |
| 95 | +export PGDATABASE=postgres |
| 96 | +export PGUSER=postgres |
| 97 | +alias rm='rm -i' |
| 98 | +alias ll='ls -lh' |
| 99 | +unalias vi |
| 100 | + |
| 101 | +postgres@digoal-> . ./env_pg.sh |
| 102 | +-bash: unalias: vi: not found |
| 103 | +postgres@digoal-> psql -V |
| 104 | +psql (PostgreSQL) 9.4.6 |
| 105 | +``` |
| 106 | + |
| 107 | +以下插件如果没有用到可以不安装,否则需要手动安装,安装方法见相应的插件官网或者搜索我的blog: |
| 108 | + |
| 109 | +``` |
| 110 | +postgis, plv8, plls, plcoffee, zhparser, pgrouting, rdkit, pg_hint_plan |
| 111 | +``` |
| 112 | + |
| 113 | +规划空间 |
| 114 | + |
| 115 | +目录空间至少要大于你所购买的RDS的容量规格,例如我买的是5G的实例,那么我本地的单个目录的空间要大于5GB。 |
| 116 | + |
| 117 | +PS,目前RDS PostgreSQL不支持自定义表空间,所以所有的数据都是放在默认表空间的,也即是需要单个目录的空间大于购买规格的空间的原因。将来如果RDS开放了创建表空间的权限,可以重新规划本地的目录。 |
| 118 | + |
| 119 | +``` |
| 120 | +[root@digoal ~]# df -h |
| 121 | +Filesystem Size Used Avail Use% Mounted on |
| 122 | +/dev/sda2 39G 22G 15G 61% / |
| 123 | +tmpfs 3.9G 0 3.9G 0% /dev/shm |
| 124 | +/dev/sdb 20G 44M 19G 1% /data01 |
| 125 | +``` |
| 126 | + |
| 127 | +2\. 申请一个replication角色的用户(目前RDS 的根用户已自带replication权限,可忽略此步骤) |
| 128 | + |
| 129 | +在阿里云管理控制台的右上方点击 工单服务 -> 提交工单 -> 关系型数据库RDS -> 直接提交工单,让客服创建一个有replication角色的用户。 |
| 130 | + |
| 131 | +PS,将来如果开放创建replication角色的API,就不需要提工单来申请账号了。 |
| 132 | + |
| 133 | +3\. 如果你需要将RDS复制到阿里云以外的主机,或者RDS和ECS在不同的可用区,则需要通过公网来连接。 |
| 134 | + |
| 135 | +那么需要用户配置RDS的公网地址,同样在阿里云管理控制台的RDS实例管理中可以申请公网地址。 |
| 136 | + |
| 137 | +4\. 在阿里云管理控制台的RDS 实例管理 -> 数据安全 配置白名单,测试连通性正常 |
| 138 | + |
| 139 | +例如备库的出口IP是固定的,则将这个IP添加到白名单,如果不是固定的IP,则需要添加0.0.0.0。 |
| 140 | + |
| 141 | +5\. 下载全量备份集 |
| 142 | + |
| 143 | +在控制台下载最近的一次全量备份集。 |
| 144 | + |
| 145 | +6\. 测试归档的下载接口是否正常 |
| 146 | + |
| 147 | +归档文件的下载需要通过调用API完成。 |
| 148 | + |
| 149 | +https://help.aliyun.com/document_detail/rds/OpenAPI-manual/RDS-OpenAPI-LogManagement/DescribeBinlogFiles.html?spm=5176.docrds/OpenAPI-manual/RDS-OpenAPI-BackupRecovery/DescribeBackups.6.217.tqV3VW |
| 150 | + |
| 151 | +什么情况下需要用到API呢?当备库需要的XLOG文件已经被主库删除时。这种情况通常发生在自建的备库和主库网络异常,或者自建的备库由于某些原因停库后,长时间没有接收来自RDS PostgreSQL的XLOG,这些XLOG在RDS归档后就会从线上数据库的WAL日志中清除。 |
| 152 | + |
| 153 | +如果发现自建的备库报需要获取的XLOG不存在的错误,这个时候就需要从OSS下载归档了。 |
| 154 | + |
| 155 | +如果连OSS中都无法找到需要的归档,说明归档也清除了,那么就需要重建备库,回到第五步骤。 |
| 156 | + |
| 157 | + |
| 158 | +7\. 测试数据库的流复制连通性 |
| 159 | + |
| 160 | +请替换成您自己的RDS实例连接信息进行测试 |
| 161 | + |
| 162 | +``` |
| 163 | +postgres@digoal-> psql "replication=true" -h xxxx.pg.rds.aliyuncs.com -p 3433 -U digoal |
| 164 | +Password for user digoal: |
| 165 | +psql (9.4.6, server 9.4.1) |
| 166 | +Type "help" for help. |
| 167 | +postgres=> IDENTIFY_SYSTEM; |
| 168 | + systemid | timeline | xlogpos | dbname |
| 169 | +---------------------+----------+------------+-------- |
| 170 | + 6165616856935119759 | 3 | 0/6B3A0180 | |
| 171 | +(1 row) |
| 172 | +``` |
| 173 | + |
| 174 | +8\. 配置postgresql.conf, recovery.conf |
| 175 | + |
| 176 | +解压全量备份集到规划好的目录。 |
| 177 | + |
| 178 | +/data01/pgdata |
| 179 | + |
| 180 | +配置 postgresql.conf |
| 181 | + |
| 182 | +在文件末尾追加如下: |
| 183 | + |
| 184 | +``` |
| 185 | +# add by digoal |
| 186 | +port=1921 |
| 187 | +unix_socket_directories='.' |
| 188 | +tcp_keepalives_idle = 70 |
| 189 | +tcp_keepalives_interval = 10 |
| 190 | +tcp_keepalives_count = 10 |
| 191 | +log_destination='csvlog' |
| 192 | +logging_collector=on |
| 193 | +log_truncate_on_rotation=on |
| 194 | +log_line_prefix = '' |
| 195 | +log_checkpoints = on |
| 196 | +log_connections = on |
| 197 | +log_disconnections = on |
| 198 | +log_error_verbosity = verbose |
| 199 | +hot_standby = on |
| 200 | +max_standby_archive_delay = 300s |
| 201 | +max_standby_streaming_delay = 300s |
| 202 | +wal_receiver_status_interval = 1s |
| 203 | +hot_standby_feedback = on |
| 204 | +log_statement='none' |
| 205 | +archive_mode=on |
| 206 | +archive_command = '/bin/date' |
| 207 | +track_io_timing=off |
| 208 | +listen_addresses='0.0.0.0' |
| 209 | +``` |
| 210 | + |
| 211 | +配置 recovery.conf |
| 212 | + |
| 213 | +请替换成您自己的RDS实例连接信息 |
| 214 | + |
| 215 | +``` |
| 216 | +standby_mode = 'on' |
| 217 | +primary_conninfo = 'host=xxxxxx.pg.rds.aliyuncs.com user=digoal password=xxxx port=3433' |
| 218 | +recovery_target_timeline = 'latest' |
| 219 | +``` |
| 220 | + |
| 221 | +9\. 启动备库,检查是否同步 |
| 222 | + |
| 223 | +``` |
| 224 | +pg_ctl start |
| 225 | + |
| 226 | +RDS |
| 227 | +postgres@digoal-> psql -h xxxx.pg.rds.aliyuncs.com -p 3433 -U digoal postgres |
| 228 | +Type "help" for help. |
| 229 | +postgres=> create table test(id timestamp); |
| 230 | +postgres=> insert into test values (now()); |
| 231 | +postgres=> update test set id=now() returning *; |
| 232 | +postgres=> \watch 1 |
| 233 | + |
| 234 | +备库 |
| 235 | +postgres@digoal-> psql -h 127.0.0.1 -p 1921 -U digoal postgres |
| 236 | +Type "help" for help. |
| 237 | +postgres=> select * from test; |
| 238 | +postgres=> \watch 1 |
| 239 | + |
| 240 | +查看是否能同步 |
| 241 | +``` |
| 242 | + |
| 243 | +风险点评估 |
| 244 | + |
| 245 | +1\. 建议不要使用replication slot, 因为slot会导致主节点不删除XLOG, 从而可能因为网络堵塞,备库异常等无法实时接收XLOG的情况下导致主节点因为保留pg_xlog而把空间用满。 |
| 246 | + |
| 247 | +用户可以通过这种方法搭建自己的备库,在RDS没有提供异地容灾服务前,进行异地容灾。 |
| 248 | + |
0 commit comments