debian: ติดตั้ง slony1 บน etch และ lenny เบื้องต้น
ติดตั้ง slony1 บน etch และ lenny เบื้องต้น
slony เป็นแพ็กเกจส่วนขยายของ PostgreSQL ที่ใช้ทำหน้าที่สำเนาฐานข้อมูลปัจจุบันขณะ แบบใช้ตัวแม่และตัวลูก (master to multiple slaves replication system)
เหมาะสำหรับงานที่ต้องกระจายการทำงาน คืออ่านจากตัวลูกหลายตัว เขียนที่ตัวแม่ตัวเดียว
หรืองานที่ต้องการสำรองข้อมูลแบบปัจจุบันขณะ
ข้อจำกัดของ slony คือ รุ่นของโปรแกรมในการรัน ต้องเป็นรุ่นเดียวกันทั้งตัวแม่และตัวลูก ดังนั้นจึงไม่สามารถใช้แพกเกจของเดเบียนเองได้ เราจึงต้องมาคอมไพล์เอง เพราะเราติดตั้งบนเครื่องที่ต่างรุ่นกัน
และเนื่องจากหาเอกสารที่สมบูรณ์ยาก ในข้อเขียนนี้จึงเป็นเพียงแค่การเริ่มต้นให้ slony ทำงานได้เท่านั้น ยังต้องการปรับตั้งอีกมากที่จะทำให้สามารถใช้งานได้จริง
ข้อควรรู้
- slony ทำงานแบบ 1 ตัวแม่ หลายตัวลูก เราสามารถอ่านได้ทั้งจากตัวแม่และตัวลูก แต่จะเขียนได้ที่ตัวแม่อย่างเดียว (แต่เขาบอกว่าสามารถทำให้ตัวลูกแทนตัวแม่ได้ด้วย ในกรณีที่ตัวแม่ขัดข้อง และสามารถกลับสู่สภาพเดิมได้ ถ้าตัวแม่กลับขึ้นมาอีกครั้ง แต่ต้องศึกษาเพิ่ม, ถ้ามีเครื่อง 3 เครื่องขึ้นไป มีคนทำให้เป็นตัวแม่ตัวลูกแบบวนรอบได้ ทำให้ได้ระบบที่เหมือนมีตัวแม่ได้หลายตัว แต่เปลืองพลังการทำงาน)
- โปรแกรมที่ใช้ตั้งค่าเริ่มต้นระบบ ชื่อ slonik ใช้รันที่ตัวแม่อย่างเดียว และโปรแกรมที่ทำงานสำเนาเป็นเบื้องหลังชื่อ slon ตัองสั่งรันทั้งตัวแม่และตัวลูก
- cluster คือการตั้งชื่อกลุ่มคอมพิวเตอร์ที่เกี่ยวข้องในงานสำเนา 1 งาน ซึ่งจะประกอบด้วย node คือคอมพิวเตอร์และฐานข้อมูลแต่ละชุด และ node จะประกอบด้วย table คือตารางที่เราต้องการคัดลอก ทั้งหมดนี้เราจะต้องนำไปเขียนเป็นข้อกำหนดให้โปรแกรม slonik ทำงาน
- slony ใช้หลักการทำงาน โดยสร้าง trigger ที่ฐานข้อมูลที่เราจะสำเนา โดยทำในระดับตาราง และมีข้อแม้ว่า ตารางที่ต้องการสำเนา ต้องมี Primary Key ด้วย แต่ถ้าหากไม่มี Primary Key เราตัองแจ้งไว้ในส่วนตั้งข้อกำหนด แล้ว slony ก็จะสร้าง Primary Key ขึ้นมาในตารางของเรา
ดังนั้นฐานข้อมูลเราจะถูกปรับเปลี่ยนโดย slony ใน 2 จุด คือ 1. เพิ่ม trigger ในแต่ละตารางที่ต้องการสำเนา และ 2. สร้าง Primary Key ในตารางที่ยังไม่มี
รายละเอียดในการทดสอบ คือ
- ติดตั้งบน etch ใช้เป็นตัวแม่ และบน lenny ใช้เป็นตัวลูก
- ใช้กับ PostgreSQL รุ่น 8.3 และ slony รุ่น slony-1 1.2.15
- ตัวอย่างที่ใช้ ปรับปรุงจากตัวอย่างในไฟล์ซอร์สของ slony (ไฟล์ชื่อ
SAMPLE
)
เริ่มงาน
1 ติดตั้งแพกเกจ และคอมไพล์
- ทำเฉพาะที่ตัวแม่ etch
- จะปรับรุ่น postgresql ให้เป็น 8.3 เพราะมันเร็วกว่า 8.1 เยอะ จึงต้องใช้บริการของ Debian Backports
ขั้นตอนคือ แก้ /etc/apt/sources.list เพิ่ม backports# vi /etc/apt/sources.list
... deb http://www.backports.org/debian etch-backports main contrib non-free ...
- ทำทั้งตัวแม่และตัวลูก
- ขั้นตอนคือสั่งอัปเดต ติดตั้งแพกเกจ ดาวน์โหลด slony และคอมไพล์
# 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 ตอนเริ่มระบบ
- ทำที่ตัวแม่
- จะทำงานด้วยผู้ใช้ชื่อ postgres โดยใช้วิธีสร้างสคริปต์ เพื่อให้สะดวกในการปรับแต่ง
3.1 เตรียมการสร้างไดเรกทอรี่# 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 แล้ว
- ทำที่ตัวลูก
- จะทำงานด้วยผู้ใช้ชื่อ postgres เหมือนกัน
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)
- ทำที่ตัวแม่อย่างเดียว
- สร้างสคริปต์สำหรับ subscribe ตั้งชื่อว่า slony-subscribe.sh
$ 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 ให้สะดวกมากขึ้น
เอามาจาก
- Printer-friendly version
- Log in or register to post comments
- 3509 reads
Recent comments