ติดตั้ง slony1 บน etch และ lenny เบื้องต้น
slony เป็นแพ็กเกจส่วนขยายของ PostgreSQL ที่ใช้ทำหน้าที่สำเนาฐานข้อมูลปัจจุบันขณะ แบบใช้ตัวแม่และตัวลูก (master to multiple slaves replication system)
เหมาะสำหรับงานที่ต้องกระจายการทำงาน คืออ่านจากตัวลูกหลายตัว เขียนที่ตัวแม่ตัวเดียว
หรืองานที่ต้องการสำรองข้อมูลแบบปัจจุบันขณะ
ข้อจำกัดของ slony คือ รุ่นของโปรแกรมในการรัน ต้องเป็นรุ่นเดียวกันทั้งตัวแม่และตัวลูก ดังนั้นจึงไม่สามารถใช้แพกเกจของเดเบียนเองได้ เราจึงต้องมาคอมไพล์เอง เพราะเราติดตั้งบนเครื่องที่ต่างรุ่นกัน
และเนื่องจากหาเอกสารที่สมบูรณ์ยาก ในข้อเขียนนี้จึงเป็นเพียงแค่การเริ่มต้นให้ slony ทำงานได้เท่านั้น ยังต้องการปรับตั้งอีกมากที่จะทำให้สามารถใช้งานได้จริง
ข้อควรรู้
รายละเอียดในการทดสอบ คือ
SAMPLE
)เริ่มงาน
1 ติดตั้งแพกเกจ และคอมไพล์
# vi /etc/apt/sources.list
... deb http://www.backports.org/debian etch-backports main contrib non-free ...
# aptitude update # aptitude install postgresql-8.3 postgresql-8.3-slony1 postgresql-contrib-8.3 postgresql-server-dev-8.3 build-essential byacc flex # cd # mkdir slony # cd slony # wget http://slony.info/downloads/1.2/source/slony1-1.2.15.tar.bz2 # tar xfj slony1-1.2.15.tar.bz2 # cd slony1-1.2.15 # ./configure --prefix=/usr/local/slony1-1.2.9 # make # make install # (uninstall with make uninstall)
2. ปรับแต่ง postgresql
# vi /etc/postgresql/8.3/main/postgresql.conf
... listen_addresses = '*' ...
ปรับตั้งผู้ใช้ (แต่งกันเองนะครับ อันนี้เป็นเพียงตัวอย่าง)
# vi /etc/postgresql/8.3/main/pg_hba.conf
... # "local" is for Unix domain socket connections only local all all md5 # IPv4 local connections: host all all 127.0.0.1/32 md5 host all all 192.168.0.0/16 md5 # IPv6 local connections: host all all ::1/128 md5 ...
เริ่มการทำงานใหม่
# /etc/init.d/postgresql-8.3 restart
3. ปรับตั้ง slony ตอนเริ่มระบบ
# su postgres $ cd $ mkdir slony-script $ cd slony-script
หมายเหตุ หากต้องการเปลี่ยนผู้ใช้เป็นคนอื่น ควรสร้างไฟล์รหัสผ่านของ postgres ไว้ในไดเรกทอรี่บ้านของตัวเอง ทั้งนี้เพื่อไม่ให้โปแกรมขึ้นมาถามรหัสผ่านตอนรัน ไฟล์รหัสผ่านนี้ ต้องมีชื่อว่า ~/.pgpass
มีรูปแบบเป็น HOSTNAME:PORT:DATABASE:USERNAME:PASSWORD
และต้องมีข้ออนุญาตเป็น 600
เท่านั้น
3.2 โปรแกรมเก็บตัวแปร ใช้เพื่อกันข้อผิดพลาด จึงทำแยกไว้ เพื่อให้โปรแกรมอื่นมาเรียกใช้ ตั้งชื่อว่า variable.sh ข้อกำหนดเบื้องต้นต่าง ๆ สามารถอ่านจากตัวแปรในโค๊ดได้เลย
$ vi variable.sh
#!/bin/bash #*** WARNING *** # All dabase name DBNAME1 and DBNAME2 will be deleted and replaced by this script. *** CLUSTER=test_cluster #CLUSTER NAME DBNAME1=test #DB OF MASTER DBNAME2=test #SLAVE DB HOST1=master.example.com #MASTER MACHINE NAME HOST2=slave.example.com #SLAVE MACHINE NAME SLONY_USER=postgres #SUPERUSER NORMAL_USER=user1 #NORMAL USER
$ chmod 700 variable.sh
ข้อควรระวัง ห้ามตั้งชื่อเครื่องเป็น localhost เพราะข้อมูลต้องถูกส่งผ่านไปมาระหว่างเครื่องแม่กับเครื่องลูก จะเกิดความสับสนได้ ต้องใช้ชื่อจริงของเครื่อง
3.3 โปรแกรมเตรียมฐานข้อมูล และคัดลอกโครงสร้างไปยังเครื่องลูก ตั้งชื่อว่า slony-prepare.sh
โปรแกรมนี้ดัดแปลงตามใจชอบ สำคัญอยู่แค่ บรรทัดเอาตัวแปรจาก variable.sh กับ 2 บรรทัดสุดท้าย
$ vi slony-prepare.sh
#!/bin/bash . ./variable.sh #*** WARNING *** # All dabase name DBNAME1 and DBNAME2 will be deleted and replaced by this script. *** echo "$HOST1 task" #create db to replicate at master dropdb -U $SLONY_USER -h $HOST1 $DBNAME1 createdb -U $SLONY_USER -O $NORMAL_USER -h $HOST1 $DBNAME1 createlang -U $SLONY_USER -h $HOST1 plpgsql $DBNAME1 psql -U $SLONY_USER $DBNAME1 <<EOF CREATE TABLE accounts ( aid SERIAL, name VARCHAR(50), address VARCHAR(255) ); INSERT INTO accounts (name, address) VALUES ('account1','address1'); CREATE TABLE branches ( bid SERIAL, name VARCHAR(50), address VARCHAR(255) ); INSERT INTO branches (name, address) VALUES ('branch1','address2'); CREATE TABLE tellers ( tid SERIAL, name VARCHAR(50), address VARCHAR(255) ); INSERT INTO tellers (name, address) VALUES ('tellers1','address3'); CREATE TABLE history ( session VARCHAR(50), detail VARCHAR(255) ); INSERT INTO history (session, detail) VALUES ('xxxx','detail1'); EOF #... echo "$HOST2 task" #drop old db at slave dropdb -U $SLONY_USER -h $HOST2 $DBNAME2 #create db at slave createdb -U $SLONY_USER -O $NORMAL_USER -h $HOST2 $DBNAME2 #copy structure from master to slave pg_dump -s -U $SLONY_USER -h $HOST1 $DBNAME1 | psql -U $SLONY_USER -h $HOST2 $DBNAME2
$ chmod 700 slony-prepare.sh $ ./slony-prepare.sh
3.4 โปรแกรมสร้างเซ็ตให้ slony บรรจุข้อกำหนดของคลัสเตอร์ โหนด และตารางที่จะทำการคัดลอก
ตั้งชื่อว่า slony-setup.sh
$ vi slony-setup.sh
#!/bin/bash . ./variable.sh slonik <<_EOF_ # ---- # This defines which namespace the replication system uses # ---- cluster name = $CLUSTER; # ---- # Admin conninfo's are used by the slonik program to connect # to the node databases. So these are the PQconnectdb arguments # that connect from the administrators workstation (where # slonik is executed). # ---- node 1 admin conninfo = 'dbname=$DBNAME1 host=$HOST1 user=$SLONY_USER'; node 2 admin conninfo = 'dbname=$DBNAME2 host=$HOST2 user=$SLONY_USER'; # ---- # Initialize the first node. The id must be 1. # This creates the schema "_test1" containing all replication # system specific database objects. # ---- init cluster ( id = 1, comment = 'Node 1' ); # ---- # The pgbench table history does not have a primary key or # any other unique constraint that could be used to identify # a row. The following command adds a bigint column named # "_Slony-I_test1_rowID" to the table. It will have a default # value of nextval('"_test1".sl_rowid_seq'), be unique and not # null. All existing rows will be initialized with a number. # ---- table add key ( node id = 1, fully qualified name = 'public.history' ); # ---- # The Slony replication system organizes tables in sets. The # smallest unit another node can subscribe is a set. Usually the # tables contained in one set would be all tables that have # relationships to each other. The following commands create # one set containing all 4 pgbench tables. The "master" or origin # of the set is node 1. # ---- create set ( id = 1, origin = 1, comment = 'All pgbench tables' ); set add table ( set id = 1, origin = 1, id = 1, fully qualified name = 'public.accounts', comment = 'Table accounts' ); set add table ( set id = 1, origin = 1, id = 2, fully qualified name = 'public.branches', comment = 'Table branches' ); set add table ( set id = 1, origin = 1, id = 3, fully qualified name = 'public.tellers', comment = 'Table tellers' ); set add table ( set id = 1, origin = 1, id = 4, fully qualified name = 'public.history', key = serial, comment = 'Table history' ); # ---- # Create the second node, tell the two nodes how to connect to # each other and that they should listen for events on each # other. Note that these conninfo arguments are used by the # slon daemon on node 1 to connect to the database of node 2 # and vice versa. So if the replication system is supposed to # use a separate backbone network between the database servers, # this is the place to tell it. # ---- store node ( id = 2, comment = 'Node 2' ); store path ( server = 1, client = 2, conninfo = 'dbname=$DBNAME1 host=$HOST1 user=$SLONY_USER'); store path ( server = 2, client = 1, conninfo = 'dbname=$DBNAME2 host=$HOST2 user=$SLONY_USER'); store listen ( origin = 1, provider = 1, receiver = 2 ); store listen ( origin = 2, provider = 2, receiver = 1 ); _EOF_
$ chmod 700 slony-setup.sh $ ./slony-setup.sh
หมายเหตุ บันทึกกันลืม ใน slony1 รุ่น 2.X ขึ้นไป ไม่ต้องใช้คำสั่ง table add key
สำหรับตารางที่ไม่มี Primary Key แล้ว
3.5 เตรียมการสร้างไดเรกทอรี่
# su postgres $ cd $ mkdir slony-script $ cd slony-script
3.6 โปรแกรมเก็บตัวแปร (กันข้อผิดพลาด)
$ vi variable.sh
#!/bin/bash #*** WARNING *** # All dabase name DBNAME1 and DBNAME2 will be deleted and replaced by this script. *** CLUSTER=test_cluster #CLUSTER NAME DBNAME1=test #DB OF MASTER DBNAME2=test #SLAVE DB HOST1=master.example.com #MASTER MACHINE NAME HOST2=slave.example.com #SLAVE MACHINE NAME SLONY_USER=postgres #SUPERUSER NORMAL_USER=user1 #NORMAL USER
$ chmod 700 variable.sh
4. สั่งเตรียมคัดลอก
$ . ./variable.sh $ slon $CLUSTER "dbname=$DBNAME1 user=$SLONY_USER"
จะมีข้อความรายงานออกมามากมายเป็นปกติ
$ . ./variable.sh $ slon $CLUSTER "dbname=$DBNAME2 user=$SLONY_USER"
ถึงตอนนี้ ฐานข้อมูลของทั้งสองโหนด พร้อมที่คัดลอกไปสู่กันแล้ว แต่ยังไม่มีการคัดลอกจริง ๆ เราต้องสั่ง subscribe เซ็ตที่เราสร้างขึ้นในหัวข้อ 3 ในหัวข้อถัดไป
5. สั่งให้ทำการคัดลอกตามเซ็ตที่กำหนด (subscribe)
$ vi slony-subscribe.sh
#!/bin/bash . ./variable.sh slonik <<_EOF_ # ---- # This defines which namespace the replication system uses # ---- cluster name = $CLUSTER; # ---- # Admin conninfo's are used by the slonik program to connect # to the node databases. So these are the PQconnectdb arguments # that connect from the administrators workstation (where # slonik is executed). # ---- node 1 admin conninfo = 'dbname=$DBNAME1 host=$HOST1 user=$SLONY_USER'; node 2 admin conninfo = 'dbname=$DBNAME2 host=$HOST2 user=$SLONY_USER'; # ---- # Node 2 subscribes set 1 # ---- subscribe set ( id = 1, provider = 1, receiver = 2, forward = no); _EOF_
$ chmod 700 slony-subscribe.sh $ ./slony-subscribe.sh
ถึงตอนนี้ slony จะทำการคัดลอกฐานข้อมูล ใช้เวลาแป๊ปเดียวก็เสร็จ เพราะข้อมูลเรามีนิดเดียว (แหล่งที่มาบอกว่า ฐานข้อมูลขนาด 30G ใช้เวลา 4 ชั่วโมง)
จบแล้วครับ
การศึกษาต่อไปคือ ให้ทดลองติดตั้งแพกเกจ slony1-bin และ slony1-doc ของเดเบียน และศึกษาการทำงานของสคริปต์ในแพกเกจนั้น ในการทำให้โปรแกรมทำงานเป็นเบื้องหลัง และสั่ง subscribe หรือ unsubscribe ให้สะดวกมากขึ้น
เอามาจาก