可能出于某种目的,需要把一个PG数据库整个的复制到另一个数据库。
实现方法非常多,如:(第一个和第三个都需要注意reference关系)
1.使用DB_LINK打通两个数据库,这个的话也是比较通用的,缺点是要编译一下源码并安装DB_LINK套件。
2.使用pg_dump管道连接两个数据库直接导入到附属库
3.使用SHELL脚本实现
今天的话主要介绍一下使用SHELL脚本来实现附属库的数据传入
主库A放在上海IDC,使用postgresql8.3
附属库B放在香港IDC,使用的是POSTGRESQL8.4,假设已经有了与A库相同的DDL在某SCHEMA下面
步骤:
1.首先是在A库上建立一个只读用户,赋予需要被复制的表,数据库,SCHEMA只读权限。配置PG_HBA开放这个只读用户的访问权限
2.在B库服务器上配置一个.pgpass文件,放上连接A库的只读用户密码,这样的话在B库连接A库就不需要输密码了
3.在B库上编写2个SHELL脚本,就开搞了
第一个脚本是执行实体(关键字需要用引号)
#!/bin/bash
. /home/postgres/.bash_profile
if [ $# -ne 2 ]; then
echo -e “parameter error”
exit 1
fi
TABLE_NAME=$1
address_tbl_COL=”\”type\”, xxx, xxx”
message_tbl_COL=”id, xxx, xxx, xxx, \”type\”"
rp_newaccess_20100301_COL=”xxx, xxx, xxx, xxx”
tbl_action_log_COL=”id, xxx, xxx, xxx, xxx, xxx,objid”
eval TABLE_COL=”$”${TABLE_NAME}_COL
if [ $2 == "TRUNCATE" ]; then
psql -h /tmp -p 1921 -U user -d dbname -c “truncate table ${TABLE_NAME} CASCADE”
exit
fi
if [ $2 == "INSERT" ]; then
psql -h ***.***.***.*** -p 1921 -U user -d dbname -c “copy schema.${TABLE_NAME} (${TABLE_COL}) to stdout”|psql -h /tmp -p 1921 -U user -d dbname -c “copy ${TABLE_NAME} (${TABLE_COL}) from stdin”
exit
fi
exit
第二个脚本是执行外壳
#!/bin/bash
. /home/postgres/.bash_profile
# 判断是否已经在运行
test -f /home/postgres/script/run/db_xxx_sync_entry.run
if [ $? -eq 0 ]; then
exit 3
fi
# 生产在运行标记
touch /home/postgres/script/run/db_xxx_sync_entry.run
/home/postgres/script/db_xxx_sync.sh address_tbl TRUNCATE
/home/postgres/script/db_xxx_sync.sh message_tbl TRUNCATE
/home/postgres/script/db_xxx_sync.sh rp_newaccess_20100301 TRUNCATE
/home/postgres/script/db_xxx_sync.sh tbl_action_log TRUNCATE
/home/postgres/script/db_xxx_sync.sh address_tbl INSERT
/home/postgres/script/db_xxx_sync.sh message_tbl INSERT
/home/postgres/script/db_xxx_sync.sh rp_newaccess_20100301 INSERT
/home/postgres/script/db_xxx_sync.sh tbl_action_log INSERT
vacuumdb -ze -d dbname
# 删除运行标记
sleep 10
rm -f /home/postgres/script/run/db_xxx_sync_entry.run
4.创建相关目录,把脚本放进去就OK了
su – postgres
mkdir -p ~/script/run
剩下的事情就是,直接调用外壳就OK了,数据会自动添加进来。下次要添加表或者是更新了字段的话修改一下第一个脚本就可以了。
如果数据量比较大的情况下,可以在SHELL里面加上一些异常处理,邮件通知等等,随时掌握复制进度和健康状况。