前言:Postgresql是最接近Oracle的免费替代品,用Postgresql+Slony搭建数据库集群是非常理想的选择。本人用这两个组合搭建了 Live database ->Backup datase,Live database ->Report database两路的在线复制,并实现了无人值守(崩溃自动恢复功能,详见另一自动维护文章)。
环境:
OS: RHEL 4.7
进入 /usr/local/src,分别下载bison-2.4.1,flex-2.5.4a-1-src并安装,再安装slony1-2.0.3-rc :进入 slony1-2.0.3-rc目录,然后
./configure
gmake all
gmake install
此时,用pgadmin打开postgresql服务器,你会发现每个数据库多了一个Slony复制的分支。
我用Slony工具为公司几台服务器上的live database作了在线同步,效果理想。
我们先定义环境变量初始化的replinit.sh,master_db/master_ip为live database的定义,slave_db/slave_ip为 备份database的定义:
#!/bin/sh PGsqlPATH=/usr/local/pgsql/bin SLONIK=/usr/local/pgsql/bin/slonik SLON=/usr/local/pgsql/bin/slon LOGPATH=/live/bin/replbms/log LOG_TIME=`/bin/date +"%Y%m%d"` LOG_MASTER="$LOGPATH/slon_m.out.$LOG_TIME" LOG_SLAVE="$LOGPATH/slon_s.out.$LOG_TIME" MASTER_DB=bmsdb MASTER_IP=128.30.14.220 SLAVE_DB=bmsdb SLAVE_IP=128.30.14.221 REPLUSER=repl REPLPWD=password CLUSTER=dgbmssp_bmsdb CLUSTERID=10 MASTERNODE=10 SLAVENODE=22 SETID=10
再定义复制节点,slave_1.sh:
#!/bin/sh source ./replinit.sh $SLONIK << _END_ cluster name = $CLUSTER; # 定义复制节点 node $MASTERNODE admin conninfo = 'dbname=$MASTER_DB host=$MASTER_IP port=5432 user=$REPLUSER password=$REPLPWD'; node $SLAVENODE admin conninfo = 'dbname=$SLAVE_DB host=$SLAVE_IP port=5432 user=$REPLUSER password=$REPLPWD'; try { echo 'Cluster defined,nodes identified'; # 初始化集群,id从1开始 init cluster (id=$CLUSTERID,comment='Master Node'); # 设置参与同步的数据表 #先创建一个复制集,id也是从1开始 #向自己的复制集种添加表,每个需要复制的表一条set命令 #id从1开始,逐次递加,步进为1; #fully qualified name是表的全称:模式名.表名 #这里的复制集id需要和前面创建的复制集id一致 #假如某个表没有主键,但是有唯一键字,那么可以用key关键字 #指定其为复制键字,如下面的key参数 #set add table ( set id = 1,origin = 1,id = 4,fully qualified name = 'public.history',key = "column",comment = 'Table history' ); #对于没有唯一列的表,需要这样处理,这一句放在 create set 的前面 #table add key (node id = 1,fully qualified name = 'public.history'); # 这样设置结果集 #set add table (set id=1,origin=1,id=4,#comment='history table',key = serial); create set (id=$SETID,origin=$MASTERNODE,comment='$DBNAME tables'); #set add table ( set id=$SETID,id=1,fully qualified name='public.vn_op',comment='Table vn_op' ); set add table ( set id=$SETID,id=2,fully qualified name='public.t22_daily_mh',comment='Table t22_daily_mh' ); set add table ( set id=$SETID,id=3,fully qualified name='public.t31_daily_prod',comment='Table t31_daily_prod' ); set add table ( set id=$SETID,fully qualified name='public.tq_dailyjob',comment='Table tq_dailyjob' ); set add table ( set id=$SETID,id=5,fully qualified name='public.t10_opgl_hist',comment='Table t10_opgl_hist' ); set add table ( set id=$SETID,id=6,fully qualified name='public.r_721',comment='Table r_721' ); #set add table ( set id=$SETID,id=7,fully qualified name='public.rep_log',comment='Table rep_log' ); set add table ( set id=$SETID,id=8,fully qualified name='public.r_ngqty_diff',comment='Table r_ngqty_diff' ); set add table ( set id=$SETID,id=9,fully qualified name='public.r_721_det',comment='Table r_721_det' ); #set add table ( set id=$SETID,id=10,comment='Table r_721' ); set add table ( set id=$SETID,id=11,fully qualified name='public.t59_Feeder_type',comment='Table t59_Feeder_type' ); set add table ( set id=$SETID,id=12,fully qualified name='public.t58_position',comment='Table t58_position' ); set add table ( set id=$SETID,id=13,fully qualified name='public.t57_Feeder_trx',comment='Table t57_Feeder_trx' ); set add table ( set id=$SETID,id=14,fully qualified name='public.t56_Feeder',comment='Table t56_Feeder' ); set add table ( set id=$SETID,id=15,fully qualified name='public.r_729',comment='Table r_729' ); set add table ( set id=$SETID,id=16,fully qualified name='public.r_514',comment='Table r_514' ); set add table ( set id=$SETID,id=17,fully qualified name='public.r_361_opseq',comment='Table r_361_opseq' ); set add table ( set id=$SETID,id=18,fully qualified name='public.r_361_det',comment='Table r_361_det' ); set add table ( set id=$SETID,id=19,fully qualified name='public.r_361',comment='Table r_361' ); set add table ( set id=$SETID,id=20,fully qualified name='public.t55_qa_chk_hist',comment='Table t55_qa_chk_hist' ); set add table ( set id=$SETID,id=21,fully qualified name='public.t54_room',comment='Table t54_room' ); set add table ( set id=$SETID,id=22,fully qualified name='public.t53_qa_chk',comment='Table t53_qa_chk' ); set add table ( set id=$SETID,id=23,fully qualified name='public.t52_prb_reply',comment='Table t52_prb_reply' ); set add table ( set id=$SETID,id=24,fully qualified name='public.t51_line_machine',comment='Table t51_line_machine' ); set add table ( set id=$SETID,id=25,fully qualified name='public.v2_op_cnt',comment='Table v2_op_cnt' ); set add table ( set id=$SETID,id=26,fully qualified name='public.te_dept',comment='Table te_dept' ); set add table ( set id=$SETID,id=27,fully qualified name='public.v2_prod_cnt',comment='Table v2_prod_cnt' ); set add table ( set id=$SETID,id=28,fully qualified name='public.tz_damage_hist',comment='Table tz_damage_hist' ); set add table ( set id=$SETID,id=29,fully qualified name='public.ty_damage_part',comment='Table ty_damage_part' ); set add table ( set id=$SETID,id=30,fully qualified name='public.tx_matrep',comment='Table tx_matrep' ); set add table ( set id=$SETID,id=31,fully qualified name='public.tw_opgrp',comment='Table tw_opgrp' ); set add table ( set id=$SETID,id=32,fully qualified name='public.tv_outgoing_mail',comment='Table tv_outgoing_mail' ); set add table ( set id=$SETID,id=33,fully qualified name='public.tu_prodrptrx',comment='Table tu_prodrptrx' ); set add table ( set id=$SETID,id=34,fully qualified name='public.tt_ucc4',comment='Table tt_ucc4' ); set add table ( set id=$SETID,id=35,fully qualified name='public.ts_prodpdtrx',comment='Table ts_prodpdtrx' ); set add table ( set id=$SETID,id=36,fully qualified name='public.tr_prodmstr',comment='Table tr_prodmstr' ); set add table ( set id=$SETID,id=37,fully qualified name='public.to_rpop',comment='Table to_rpop' ); set add table ( set id=$SETID,id=38,fully qualified name='public.tn_op',comment='Table tn_op' ); set add table ( set id=$SETID,id=39,fully qualified name='public.tm_drawloc',comment='Table tm_drawloc' ); set add table ( set id=$SETID,id=40,fully qualified name='public.tl_ucc3',comment='Table tl_ucc3' ); set add table ( set id=$SETID,id=41,fully qualified name='public.tk_ucc2',comment='Table tk_ucc2' ); set add table ( set id=$SETID,id=42,fully qualified name='public.tj_ucc1',comment='Table tj_ucc1' ); set add table ( set id=$SETID,id=43,fully qualified name='public.ti_udc',comment='Table ti_udc' ); set add table ( set id=$SETID,id=44,fully qualified name='public.tc_user_access',comment='Table tc_user_access' ); set add table ( set id=$SETID,id=45,fully qualified name='public.tb_menu_item',comment='Table tb_menu_item' ); set add table ( set id=$SETID,id=46,fully qualified name='public.ta_user',comment='Table ta_user' ); set add table ( set id=$SETID,id=47,fully qualified name='public.t9_cmi',comment='Table t9_cmi' ); set add table ( set id=$SETID,id=48,fully qualified name='public.t8_dailywarn_log',comment='Table t8_dailywarn_log' ); set add table ( set id=$SETID,id=49,fully qualified name='public.t7_dailywarn',comment='Table t7_dailywarn' ); set add table ( set id=$SETID,id=50,fully qualified name='public.t6_opgl',comment='Table t6_opgl' ); set add table ( set id=$SETID,id=51,fully qualified name='public.t5_prb_reply',comment='Table t5_prb_reply' ); set add table ( set id=$SETID,id=52,fully qualified name='public.t50_cause_cnt_det',comment='Table t50_cause_cnt_det' ); set add table ( set id=$SETID,id=53,fully qualified name='public.t4_cause_cnt',comment='Table t4_cause_cnt' ); set add table ( set id=$SETID,id=54,fully qualified name='public.t49_job_parm',comment='Table t49_job_parm' ); set add table ( set id=$SETID,id=55,fully qualified name='public.t47_daily_rp',comment='Table t47_daily_rp' ); set add table ( set id=$SETID,id=56,fully qualified name='public.t45_defect',comment='Table t45_defect' ); set add table ( set id=$SETID,id=57,fully qualified name='public.t44_daily_qc',comment='Table t44_daily_qc' ); set add table ( set id=$SETID,id=58,fully qualified name='public.t43_prod_ai_std',comment='Table t43_prod_ai_std' ); set add table ( set id=$SETID,id=59,fully qualified name='public.t41_spec_std',comment='Table t41_spec_std' ); set add table ( set id=$SETID,id=60,fully qualified name='public.t40_ppc_jobproc',comment='Table t40_ppc_jobproc' ); set add table ( set id=$SETID,id=61,fully qualified name='public.t3_defect_cnt',comment='Table t3_defect_cnt' ); set add table ( set id=$SETID,id=62,fully qualified name='public.t39_aid_setup',comment='Table t39_aid_setup' ); set add table ( set id=$SETID,id=63,fully qualified name='public.t36_daily_seat',comment='Table t36_daily_seat' ); set add table ( set id=$SETID,id=64,fully qualified name='public.t35_series_mh_period',comment='Table t35_series_mh_period' ); set add table ( set id=$SETID,id=65,fully qualified name='public.t34_sysvalues',comment='Table t34_sysvalues' ); set add table ( set id=$SETID,id=66,fully qualified name='public.t33_model_cat_mstr',comment='Table t33_model_cat_mstr' ); set add table ( set id=$SETID,id=67,fully qualified name='public.t32_holiday',comment='Table t32_holiday' ); set add table ( set id=$SETID,id=68,fully qualified name='public.t30_comp_qty',comment='Table t30_comp_qty' ); set add table ( set id=$SETID,id=69,fully qualified name='public.t2_op_cnt',comment='Table t2_op_cnt' ); set add table ( set id=$SETID,id=70,fully qualified name='public.t1_matrep_log',comment='Table t1_matrep_log' ); set add table ( set id=$SETID,id=71,fully qualified name='public.t19_dfpcb_cnt',comment='Table t19_dfpcb_cnt' ); set add table ( set id=$SETID,id=72,fully qualified name='public.t18_dfcmp_cnt',comment='Table t18_dfcmp_cnt' ); set add table ( set id=$SETID,id=73,fully qualified name='public.t16_pcb_split',comment='Table t16_pcb_split' ); set add table ( set id=$SETID,id=74,fully qualified name='public.t15_qcrpdet',comment='Table t15_qcrpdet' ); set add table ( set id=$SETID,id=75,fully qualified name='public.t14_matrep_hist',comment='Table t14_matrep_hist' ); set add table ( set id=$SETID,id=76,fully qualified name='public.t12_tmslot_def',comment='Table t12_tmslot_def' ); set add table ( set id=$SETID,id=77,fully qualified name='public.t11_op_swp_hist',comment='Table t11_op_swp_hist' ); set add table ( set id=$SETID,id=78,fully qualified name='public.t29_aidmh',comment='Table t29_aidmh' ); set add table ( set id=$SETID,id=79,fully qualified name='public.t28_aiddaily',comment='Table t28_aiddaily' ); set add table ( set id=$SETID,id=80,fully qualified name='public.t48_repair',comment='Table t48_repair' ); set add table ( set id=$SETID,id=81,fully qualified name='public.t13_fv_hist',comment='Table t13_fv_hist' ); set add table ( set id=$SETID,id=82,fully qualified name='public.tp_jobmstr',comment='Table tp_jobmstr' ); set add table ( set id=$SETID,id=83,fully qualified name='public.t27_prod_lab_det',comment='Table t27_prod_lab_det' ); set add table ( set id=$SETID,id=84,fully qualified name='public.t26_prod_labour',comment='Table t26_prod_labour' ); set add table ( set id=$SETID,id=85,fully qualified name='public.t25_jobproc_det',comment='Table t25_jobproc_det' ); set add table ( set id=$SETID,id=86,fully qualified name='public.th_model',comment='Table th_model' ); set add table ( set id=$SETID,id=87,fully qualified name='public.tg_series',comment='Table tg_series' ); set add table ( set id=$SETID,id=88,fully qualified name='public.t24_job_ship',comment='Table t24_job_ship' ); set add table ( set id=$SETID,id=89,fully qualified name='public.t23_job_proc',comment='Table t23_job_proc' ); set add table ( set id=$SETID,id=90,fully qualified name='public.t21_mh_type',comment='Table t21_mh_type' ); set add table ( set id=$SETID,id=91,fully qualified name='public.t20_firm_ver',comment='Table t20_firm_ver' ); set add table ( set id=$SETID,id=92,fully qualified name='public.tf_line',comment='Table tf_line' ); set add table ( set id=$SETID,id=93,fully qualified name='public.t60_smt_daily_ext',comment='Table t60_smt_daily_ext' ); set add table ( set id=$SETID,id=94,fully qualified name='public.t61_daily_sn',comment='Table t61_daily_sn' ); set add table ( set id=$SETID,id=95,fully qualified name='public.t62_smt_daily_trans',comment='Table t62_smt_daily_trans' ); set add table ( set id=$SETID,id=96,fully qualified name='public.t63_smt_prod_job',comment='Table t63_smt_prod_job' ); set add table ( set id=$SETID,id=97,fully qualified name='public.r_721_jf',comment='Table r_721_jf' ); set add table ( set id=$SETID,id=98,fully qualified name='public.r_721_det_jf',comment='Table r_721_det_jf' ); set add table ( set id=$SETID,id=99,fully qualified name='public.t64_series_mh_period_photo',comment='Table t64_series_mh_period_photo' ); set add table ( set id=$SETID,id=100,fully qualified name='public.t66_sch_mstr',comment='Table t66_sch_mstr' ); set add table ( set id=$SETID,id=101,fully qualified name='public.t68_urg_part',comment='Table t68_urg_part' ); set add table ( set id=$SETID,id=102,fully qualified name='public.t69_iqc_imp_log',comment='Table t69_iqc_imp_log' ); set add table ( set id=$SETID,id=103,fully qualified name='public.t70_urg_det',comment='Table t70_urg_det' ); set add table ( set id=$SETID,id=104,fully qualified name='public.t71_pt_mstr',comment='Table t71_pt_mstr' ); set add table ( set id=$SETID,id=105,fully qualified name='public.t72_iqc_imp_det',comment='Table t72_iqc_imp_det' ); echo 'set 1 of $MASTER_DB tables created'; # 设置存储节点 store node (id=$SLAVENODE,comment='Slave Node',event node=$MASTERNODE); #定义从库节点 echo 'Nodes defined'; # 设置存储路径 store path (server=$MASTERNODE,client=$SLAVENODE,conninfo='dbname=$MASTER_DB host=$MASTER_IP port=5432 user=repl'); store path (server=$SLAVENODE,client=$MASTERNODE,conninfo='dbname=$SLAVE_DB host=$SLAVE_IP port=5432 user=repl'); #设置侦听事件和订阅方向,复制中角色,主节点是原始提供者,从节点是接受者 store listen (origin=$MASTERNODE,provider = $MASTERNODE,receiver =$SLAVENODE); store listen (origin=$SLAVENODE,provider = $SLAVENODE,receiver =$MASTERNODE); subscribe set (id=$SETID,provider=$MASTERNODE,receiver=$SLAVENODE,forward=no); echo 'set 1 of $MASTER_DB tables subscribed by node 2'; } on success { echo 'Setup OK.' ; } on error{ echo 'Setup error.' ; } _END_
再定义一个删除复制节点的slave_0.sh:
#!/bin/sh source ./replinit.sh $SLONIK << _END_ # # Define cluster namespace and node connection information #a #集群名称 cluster name = $CLUSTER; # 定义复制节点 node $MASTERNODE admin conninfo = 'dbname=$MASTER_DB host=$MASTER_IP port=5432 user=$REPLUSER password=$REPLPWD'; node $SLAVENODE admin conninfo = 'dbname=$SLAVE_DB host=$SLAVE_IP port=5432 user=$REPLUSER password=$REPLPWD'; DROP SET (id=$SETID,origin=$MASTERNODE); uninstall node (id=$MASTERNODE); uninstall node (id=$SLAVENODE); echo 'Drop $CLUSTER set'; _END_ echo "drop SCHEMA _$CLUSTER CASCADE ;" |$PGsqlPATH/psql -h $SLAVE_IP $SLAVE_DB echo "drop SCHEMA _$CLUSTER CASCADE ;" |$PGsqlPATH/psql -h $MASTER_IP $MASTER_DB #echo "VACUUM ANALYZE;" |$PGsqlPATH/psql $DBNAME
好了,现在要定义主 shellscript,把它们集合起来调用, smain.sh:
#!/bin/sh BINPATH=/live/bin/replbms case $1 in start) cd $BINPATH /bin/sh slave_3.sh ;; stop) killall -KILL slon ;; rebuild) cd $BINPATH killall -KILL slon # sh slave_0.sh >> /dev/null 2>&1 /bin/sh slave_0.sh /bin/sh slave_1.sh #sh slave_2.sh /bin/sh slave_3.sh ;; *) echo "Please input start or stop or rebuild!!" ;; esac