Load-Balanced MySQL Cluster
สืบเนื่องมาจากการทำ MySQL Cluster เสร็จแล้ว เราลองมาต่อยอดด้วยการทำ Load-Balance สำหรับ MySQL Cluster กันดู
ลักษณะการทำงานของ Load Balance
คือ การจัดกลุ่มของคอมพิวเตอร์หลายๆตัวเพื่อแบ่งงานกัน หรือกระจาย load การใช้งานของ user ไปยังคอมพิวเตอร์ภายในกลุ่ม เพื่อให้สามารถรับจำนวน user ที่เข้ามาใช้งานได้มากขึ้น หรือสามารถรับงานที่เข้ามาได้มากขึ้น นอกจากนั้นยังมีคุณสมบัติของ Fail Over คือหากมีคอมพิวเตอร์ภายในกลุ่มไม่สามารถทำงานได้ เช่น Down อยู่ หรือไม่สามารถรับงานหรือ user เพิ่มได้เนื่องจาก resource ที่ใช้ทำงานไม่พอ ตัว Load Balancer ที่เป็นตัวแจก load ให้คอมพิวเตอร์ภายในกลุ่มก็จะส่ง load ไปยังคอมพิวเตอร์เครื่องอื่นๆแทน จนกว่าคอมพิวเตอร์เครื่องนั้นจะกลับมาใช้งานได้ใหม่
ตัว load balancer อาจเกิดปัญหา bottleneck แล้วจะเกิดอะไรขึ้นถ้า load balancer fail ขึ้นมา ดังนั้นในที่นี้เราจะให้มี load balancer 2 ตัว โดย load balancer ทั้ง 2 ตัวจะมีตัวใดตัวหนึ่งมีสถานะเป็น active และตัวที่เหลือจะมีสถานะเป็น passive ซึ่งหมายความว่าจะมีหนึ่ง active load balancer และอีกตัวหนึ่งเป็น hot-standby load balancer โดยจะกลายเป็น active เมื่อตัวที่เป็น active fail
หมายเหตุ ขอปรับเปลี่ยน API node ให้เป็น Load Balancer ตัวที่2 แทน เนื่องจากในการทำ load balance ไม่จำเป็นที่จะต้องใช้ API node ซึ่งขั้นตอนการปรับเปลี่ยน API node เพื่อเตรียมเป็น Load Balancer 2 มีดังนี้
ขั้นตอนที่ 1 ทำการตรวจสอบสถานะของ cluster บน MySQL cluster management server / Load Balancer1 (sqlmang:192.168.0.4) ดังนี้
sqlmang:192.168.0.4 ndb_mgmndb_mgm> show; Cluster Configuration ——————— [ndbd(NDB)] 2 node(s) id=2 @192.168.0.1 (Version: 5.0.38, Nodegroup: 0) id=3 @192.168.0.2 (Version: 5.0.38, Nodegroup: 0, Master) [ndb_mgmd(MGM)] 1 node(s) id=1 @192.168.0.4 (Version: 5.0.38) [mysqld(API)] 3 node(s) id=4 @192.168.0.2 (Version: 5.0.38) id=5 @192.168.0.1 (Version: 5.0.38) id=6 @192.168.0.3 (Version: 5.0.38)
ขั้นตอนที่ 2 ลบ [MYSQLD] ออกจาก file /var/lib/mysql-cluster/config.ini บน MySQL cluster management server / Load Balancer1 (sqlmang:192.168.0.4) ดังนี้
sqlmang:192.168.0.4 cd /var/lib/mysql-cluster pico config.ini
ขั้นตอนที่ 3 แก้ไข file /etc/mysql/my.cnf บน sqlload:192.168.0.3 ดังนี้
sqlload:192.168.0.3 cd /etc/mysql pico my.cnf
#ใส่เครื่องหมาย # หน้าบรรทัด ndbcluster และ ndb-connectstring=192.168.0.4
#ndbcluster #ndb-connectstring=192.168.0.4 [MYSQL_CLUSTER] #ndb-connectstring=192.168.0.4
ขั้นตอนที่ 4 restart service MySQL บน sqlload:192.168.0.3 ดังนี้
sqlload:192.168.0.3 /etc/init.d/mysql restart
ขั้นตอนที่ 5 restart cluster บน MySQL cluster management server / Load Balancer1
(sqlmang:192.168.0.4) ดังนี้
sqlmang:192.168.0.4 ndb_mgm ndb_mgm> shutdown; Node 2: Cluster shutdown initiated Node 3: Cluster shutdown initiated Node 2: Node shutdown completed. 2 NDB Cluster node(s) have shutdown. Disconnecting to allow management server to shutdown. ndb_mgm> quit; ndb_mgmd -f /var/lib/mysql-cluster/config.ini sqlnode1:192.168.0.1/sqlnode2:192.168.0.2 ndbd – initial
ขั้นตอนที่ 6 ตรวจสอบสถานะของ cluster บน MySQL cluster management server / Load Balancer1(sqlmang:192.168.0.4) อีกครั้ง ดังนี้
sqlmang:192.168.0.4 ndb_mgmndb_mgm> show; Cluster Configuration ——————— [ndbd(NDB)] 2 node(s) id=2 @192.168.0.1 (Version: 5.0.38, Nodegroup: 0, Master) id=3 @192.168.0.2 (Version: 5.0.38, Nodegroup: 0)[ndb_mgmd(MGM)] 1 node(s) id=1 @192.168.0.4 (Version: 5.0.38) [mysqld(API)] 2 node(s) id=4 @192.168.0.2 (Version: 5.0.38) id=5 @192.168.0.1 (Version: 5.0.38) ndb_mgm> quit;
นอก จากนี้ Load balancer ทั้ง 2 จะใช้ heartbeat ในการตรวจสอบว่า load balancer อีกตัวยังทำงานได้ตามปกติหรือไม่ และ load balancer ทั้งคู่จะใช้ ldirectord เพื่อเป็นตัวแบ่งการทำงานออกไปยัง cluster node
เมื่อเรา install Ultra Monkey package ก็จะมีการ install ทั้ง heartbeat และ ldirectord ให้โดยอัตโนมัติ
สรุป การทำระบบ Load-Balanced MySQL Cluster ครั้งนี้จะใช้เครื่องทั้งหมด จำนวน 4 เครื่องดังนี้
เครื่องที่1 : เป็น storage node หรือ cluster node (sqlnode1:192.168.0.1)
เครื่องที่2 : เป็น storage node หรือ cluster node (sqlnode2:192.168.0.2)
เครื่องที่3 : เป็น Load Balancer 2 (sqlload:192.168.0.3)
เครื่องที่4 : เป็น MySQL cluster management server / Load Balancer1 (sqlmang:192.168.0.4)
และใช้ virtual IP address เป็น 192.168.0.5
Install Ultra Monkey
เริ่ม ต้นเราต้อง enable IPVS (IP Virtual Server) บน Load Balancer1(sqlmang:192.168.0.4) และ Load Balancer2(sqlload:192.168.0.3) ดังนี้
sqlmang:192.168.0.4/ sqlload:192.168.0.3 modprobe ip_vs_dh modprobe ip_vs_ftp modprobe ip_vs modprobe ip_vs_lblc modprobe ip_vs_lblcr modprobe ip_vs_lc modprobe ip_vs_nq modprobe ip_vs_rr modprobe ip_vs_sed modprobe ip_vs_sh modprobe ip_vs_wlc modprobe ip_vs_wrr
ในกรณีที่ต้องการให้มีการ load IPVS kernel modules ขณะที่มีการ boot เครื่อง ทำได้ดังนี้
pico /etc/modules
จากนั้นให้เพิ่ม Ultra Monkey respository ต่อท้ายของเดิมที่มีอยู่ ที่ /etc/apt/sources.list แล้ว install Ultra Monkey
sqlmang:192.168.0.4/ sqlload:192.168.0.3 pico /etc/apt/sources.list
apt-get update apt-get install ultramonkey libdbi-perl libdbd-mysql-perl libalps-heap1-dev dev
เรา ต้อง install MySQL เพื่อให้สามารถใช้งาน DBD::mysql Perl ได้ (ถ้าเครื่องไหนได้ install mysql-server แล้ว ไม่ต้องทำขั้นตอนนี้ใหม่)
sqlmang:192.168.0.4/ sqlload:192.168.0.3 cd /tmp sudo apt-get install mysql-server
จากนั้นเปิดให้มีการใช้งาน packet forwarding
sqlmang:192.168.0.4/ sqlload:192.168.0.3 pico /etc/sysctl.conf
sysctl - p
จะแสดงผล
kernel.printk = 4 4 1 7
net.ipv4.conf.default.forwarding = 1
Configure heartbeat
ใน การ configure heartbeat เราจะต้องสร้าง file ขึ้นมา 3 file บน Load Balancer1(sqlmang:192.168.0.4) และ Load Balancer2 (sqlload:192.168.0.3) ซึ่งได้แก่ file ha.cf file haresources และfile authkeys ดังนี้
sqlmang:192.168.0.4/ sqlload:192.168.0.3
pico /etc/ha.d/ha.cf
คำสั่งสำหรับแสดงรายชื่อ node คือ uname –n
pico /etc/ha.d/haresources
ใน file นี้เราต้องใส่ชื่อ node ของ Load Balance1 และใส่ virtual IP address ซึ่งในที่นี้ใช้ 192.168.0.5 พร้อมทั้ง netmask (27) และ broadcast address (192.168.0.31)
pico /etc/ha.d/authkeys
ซึ่ง somerandomstring คือ password ที่จะใช้เชื่อมต่อระหว่าง heartbeat บน LoadBalance1(sqlmang:192.168.0.4) และ Load Balance2 (sqlload:192.168.0.3)
จากนั้นกำหนดสิทธิ์ให้ root เท่านั้นที่สามารถอ่าน file authkeys ได้
chmod 600 /etc/ha.d/authkeys
Configure ldirectord
เริ่ม ต้นสร้าง configuration file ldirectord.cf สำหรับ ldirectord บน Load Balancer1(sqlmang:192.168.0.4) และ Load Balancer2(sqlload:192.168.0.3)
sqlmang:192.168.0.4/ sqlload:192.168.0.3
pico /etc/ha.d/ldirectord.cf
ซึ่ง ค่า login ค่า passwd ค่า database และค่า resquest ที่เรากำหนดใน file ldirectord.cf นี้ ขึ้นอยู่กับที่เราสร้างใน MySQL ซึ่งจะกล่าวถึงในหัวข้อ Create A Database Called ldirector
จาก นั้น create system startup link สำหรับ heartbeat และ remove system startup link ของ ldirectord ที่มีอยู่ออก(เพราะว่า ldirectord จะถูก start ด้วย heartbeat) ดังนี้
update-rc.d -f heartbeat remove
จะปรากฎข้อความ
Removing any system startup links for /etc/init.d/heartbeat …
/etc/rc0.d/K05heartbeat
/etc/rc1.d/K05heartbeat
/etc/rc2.d/S75heartbeat
/etc/rc3.d/S75heartbeat
/etc/rc4.d/S75heartbeat
/etc/rc5.d/S75heartbeat
/etc/rc6.d/K05heartbeat
update-rc.d heartbeat start 75 2 3 4 5 . stop 05 0 1 6 .
จะปรากฎข้อความ
Adding system startup for /etc/init.d/heartbeat …
/etc/rc0.d/K05heartbeat -> ../init.d/heartbeat
/etc/rc1.d/K05heartbeat -> ../init.d/heartbeat
/etc/rc6.d/K05heartbeat -> ../init.d/heartbeat
/etc/rc2.d/S75heartbeat -> ../init.d/heartbeat
/etc/rc3.d/S75heartbeat -> ../init.d/heartbeat
/etc/rc4.d/S75heartbeat -> ../init.d/heartbeat
/etc/rc5.d/S75heartbeat -> ../init.d/heartbeat
update-rc.d -f ldirectord remove
จะปรากฎข้อความ
Removing any system startup links for /etc/init.d/ldirectord …
Create A Database Called ldirector
เรา จะสร้าง database ชื่อ “ldirectordb” บน MySQL Cluster node ทั้งสอง (sqlnode1:192.168.0.1 และ sqlnode2:192.168.0.2) ซึ่งเป็น database ที่ load balancer ใช้ตรวจสอบว่า MySQL cluster node ยังทำงานอยู่หรือไม่
sqlnode1:192.168.0.1 mysql -u root –p GRANT ALL ON ldirectordb.* TO ‘ldirector’@’%’ IDENTIFIED BY ‘ldirectorpassword’; FLUSH PRIVILEGES; CREATE DATABASE ldirectordb; USE ldirectordb; CREATE TABLE connectioncheck (i INT) ENGINE=NDBCLUSTER; INSERT INTO connectioncheck () VALUES (1); quit;
sqlnode2:192.168.0.2 mysql -u root –p GRANT ALL ON ldirectordb.* TO ‘ldirector’@’%’ IDENTIFIED BY ‘ldirectorpassword’; FLUSH PRIVILEGES; CREATE DATABASE ldirectordb; quit;
Prepare The MySQL Cluster Nodes For Load Balancing
เรา ต้อง configure ให้ MySQL cluster node ทั้งสอง (sqlnode1:192.168.0.1 และ sqlnode2:192.168.0.2) รับการร้องขอ (request) จาก virtual IP address (192.168.0.5)
sqlnode1:192.168.0.1/ sqlnode2:192.168.0.2
apt-get install iproute
จากนั้นแก้ไข file sysctl.conf ที่ /etc/sysctl.conf (เพิ่มข้อความด้านล่างนี้ต่อท้ายของเดิม)
pico /etc/sysctl.conf
sysctl -p
จากนั้นแก้ไข interfaces สำหรับรองรับ virtual IP address (192.168.0.5)
pico /etc/network/interfaces
ifup lo:0
Start The Load Balancer
เริ่มต้น start heartbeat บน Load Balancer ทั้งสอง (sqlmang:192.168.0.4 และ sqlload:192.168.0.3) ดังนี้sqlmang:192.168.0.4/sqlload:192.168.0.3
/etc/init.d/heartbeat start
ถ้าไม่มี error เกิดขึ้น ให้ reboot load balancer ทั้งสองตัว โดยใช้คำสั่ง
shutdown – r now
ภายหลังจากที่ reboot load balancer ทั้งสองตัวเสร็จ ให้ตรวจสอบการทำงานของ load balancer โดยsqlmang:192.168.0.4/sqlload:192.168.0.3
ip addr sh eth0
จะปรากฎข้อความในกรณีที่เป็น active Load Balancer
2: eth0: mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:01:29:4b:54:0b brd ff:ff:ff:ff:ff:ff
inet 192.168.0.4/27 brd 192.168.0.31 scope global eth0
inet 192.168.0.5/27 brd 192.168.0.31 scope global secondary eth0
และจะปรากฎข้อความในกรณีที่เป็น hot-standby Load Balancer
2: eth0: mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:0b:cd:94:cf:06 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.3/27 brd 192.168.0.31 scope global eth0
sqlmang:192.168.0.4/sqlload:192.168.0.3
ldirectord ldirectord.cf status
จะปรากฎข้อความในกรณีที่เป็น active Load Balancer
ldirectord for /etc/ha.d/ldirectord.cf is running with pid: 5801
และจะปรากฎข้อความในกรณีที่เป็น hot-standby Load Balancer
ldirectord is stopped for /etc/ha.d/ldirectord.cf
sqlmang:192.168.0.4/sqlload:192.168.0.3
ipvsadm -L –n
จะปรากฎข้อความในกรณีที่เป็น active Load Balancer
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.100.22:3306 wrr
-> 192.168.100.20:3306 Route 1 0 0
-> 192.168.100.19:3306 Route 1 0 0
และจะปรากฎข้อความในกรณีที่เป็น hot-standby Load Balancer
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
sqlmang:192.168.0.4/sqlload:192.168.0.3
etc/ha.d/resource.d/LVSSyncDaemonSwap master status
จะปรากฎข้อความในกรณีที่เป็น active Load Balancer
master running
(ipvs_syncmaster pid: 5951)
และจะปรากฎข้อความในกรณีที่เป็น hot-standby Load Balancer
master stopped
(ipvs_syncbackup pid: 6072)
Testing (การทดสอบ)
สำหรับ การทดสอบ เราจะให้มีการเรียก connect database จากเครื่องอื่นที่อยู่ภายในวง network เดียวกัน ผ่านทาง virtual IP address (192.168.0.5) ที่เรากำหนดไว้ ดังนี้
C:\Documents and Settings\Administrator>mysql -h 192.168.100.22 -u ldirector –p
Enter password: *****************
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 917500 to server version: 5.0.38-Ubuntu_0ubuntu1-log
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the buffer.
mysql>
หมายเหตุ
1. เมื่อมีการ run คำสั่ง ip addr sh eth0 แล้วปรากฎ inet6 fe80:20b:cdff:fe94:of06 /64 scope link(ให้แก้ไขที่ Load Balance ทั้ง 2 ตัว)
- pico /etc/modprobe.d/aliases
- ให้หาบรรทัด alias net-pf-10 ipv6 แล้วแก้ไขเป็น alias net-pf-10 off
- ให้ save file และทำการ reboot โดยใช้คำสั่ง “ifdown -a” และตามด้วย “ifup -a”
2. ในกรณีใช้คำสั่ง ipvsadm –L –n แล้วตรง ส่วน Route ไม่แสดงเลข 1 แนะนำให้ไปตรวจสอบ bindaddress และ usr % (สำหรับ Load Balancer)
Reference :
[1] www.narisa.com/forums/index.php?showtopic=6466
[2] http://www.howtoforge.com/loadbalanced_mysql_cluster_debian
apt-get install mysql-server mysql-client build-essential
Make sure that mysql will be started by heartbeat, not at boot-time on either server.
update-rc.d -f mysql remove
Verify the partitions we are using are exactly the same on both servers. We will be using sda6
(256MB) and sda7(94GB): Actual partitions should be something like this:
fdisk -l
Device Boot Start End Blocks Id System
/dev/sda1 * 1 24 192748+ 83 Linux
/dev/sda2 25 1969 15623212+ 82 Linux swap / Solaris
/dev/sda3 1970 19320 139371907+ 5 Extended
/dev/sda5 1970 6954 40041981 83 Linux
/dev/sda6 6955 6984 240943+ 83 Linux
/dev/sda7 6985 19320 99088888+ 83 Linux
sda6 will be our meta-disk sda7 will be our distributed replication block device Verify that sda6
and sda7 are not mounted:
mount -l
/dev/sda5 on / type ext3 (rw,errors=remount-ro)
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
procbususb on /proc/bus/usb type usbfs (rw)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
/dev/sda1 on /boot type ext3 (rw)
Determine the kernel in use to install headers:
uname -r
apt-get install linux-headers-<<what was returned above>>
ETH0 will be the public interface on 10.10.10.XXX, while ETH1 will be on 192.168.1.xxx, a separate
network or crossover cable connected between the two machines. DRBD will run using eth1 of both
machines. On both servers, perform the following:
apt-get install drbd0.7-module-source drbd0.7-utils ipvsadm heartbeat
cd /usr/src/
tar xvfz drbd0.7.tar.gz
cd modules/drbd/drbd
make
make install
mv /etc/drbd.conf /etc/drbd.conf.sample
Edit /etc/drbd.conf and create the following contents:
resource r0 {
protocol C;
incon-degr-cmd “halt -f”;
startup {
degr-wfc-timeout 120; # 2 minutes.
}
disk {
on-io-error detach;
}
net {
}
syncer {
rate 10M;
group 1;
al-extents 257;
}
on mysqldb01 { # the hostname of server 1 (uname -n)
device /dev/drbd0; #
disk /dev/sda7; # data partition on server 1
address 192.168.1.10:7788; # ETH1 IP Address
meta-disk /dev/sda6[0]; # 256MB partition for DRBD on server 1
}
on mysqldb02 { # ** EDIT ** the hostname of server 2 (uname -n)
device /dev/drbd0; #
disk /dev/sda7; # ** EDIT ** data partition on server 2
address 192.168.1.11:7788; # ETH1 IP Address
meta-disk /dev/sda6[0]; # 256MB partition for DRBD on server 2
}
}
Start drbd on both servers
/etc/init.d/drbd start
Verify they are running. Both should be in a secondary state.
cat /proc/drbd
version: 0.7.24 (api:79/proto:74)
SVN Revision: 2875 build by root@mysqldb01, 2007-12-14 02:55:51
0: cs:Connected st:Secondary/Secondary ld:Inconsistent
ns:0 nr:0 dw:0 dr:0 al:0 bm:12096 lo:0 pe:0 ua:0 ap:0
1: cs:Unconfigured
Make server1 the primary and format the the device. You want to format the drbd device, not the sda
device. The server you are formatting must be the primary. You cannot format the drbd device if it
is in secondary mode. There is no need to perform the format operation on the secondary as it will
be sync’d as well.
drbdsetup /dev/drbd0 primary –do-what-I-say
mkfs.ext3 /dev/drbd0
drbdadm connect all
Verify that they are now sync’ing
watch cat /proc/drbd
version: 0.7.24 (api:79/proto:74)
SVN Revision: 2875 build by root@mysqldb01, 2007-12-14 02:55:51
0: cs:SyncTarget st:Secondary/Primary ld:Inconsistent
ns:0 nr:9660908 dw:9660908 dr:0 al:0 bm:12685 lo:0 pe:0 ua:0 ap:0
[=>..................] sync’ed: 9.5% (87332/96415)M
finish: 1:54:03 speed: 12,968 (10,140) K/sec
1: cs:Unconfigured
Next, setup the mysql datafiles on the drbd device. Stop mysql on both servers
/etc/init.d/mysql stop
Move the mysql data files and test mounting on mysqldb01
mkdir /mnt/move
mount -t ext3 /dev/drbd0 /mnt/move
mv /var/lib/mysql/* /mnt/move/.
umount /mnt/move
mount -t ext3 /dev/drbd0 /var/lib/mysql
chown -R mysql:mysql /var/lib/mysql
Clear databases from mysqldb02 so we can be sure we’re starting from the proper set.
rm -R /var/lib/myssql/*
Start Mysql on mysqldb01 and verify that you can connect
/etc/init.d/mysql start
mysql -u root -p
Test drive MySQL on mysqldb01 a little bit, create a new database and a table in the database. The
following is the basic process to manually switch from the primary server to the secondary. We will
use it to verify everything is working as expected before proceeding to the heartbeat. Stop MySQL on
mysqldb01 and unmount drbd0
/etc/init.d/mysql stop
umount /var/lib/mysql
drbdadm secondary r0
On mysqldb02, make it the primary, mount the drbd and then start mysql
drbdadm primary r0
mount -t ext3 /dev/drbd0 /var/lib/mysql
ls /var/lib/mysql
/etc/init.d/mysql start
On mysqldb02, login to mysql and verify that the database and table we created exists. Create some
new records in our test table.
mysql -u root -p
If everything is working as planned, stop mysql on mysqldb02, unmount the drbd and switch the
services back to mysqldb01 to verify that works. On mysqldb02:
/etc/init.d/mysql stop
umound /var/lib/mysql
drbdadm secondary r0
On mysqldb01
drbdadm primary r0
mount -t ext3 /dev/drbd0 /var/lib/mysql
/etc/init.d/mysql start
Test connecting to Mysql as we did before. Verify any changes you made on mysqldb02 exist on
mysqldb01. This will be a good time to set a root password since the server won’t be listening on
localhost any longer:
GRANT ALL PRIVILEGES ON *.* TO ‘root’@'%’ IDENTIFIED BY ’some_pass’ WITH GRANT
OPTION;
FLUSH PRIVILEGES;
Edit the /etc/mysql/my.cnf file and change the IP address of the “bind-address”
setting to be that which we will use for the heartbeat. Now, since the heartbeat will control both
drbd and MySQL, stop MySQL and unmount the drbd
/etc/init.d/mysql stop
umount /var/lib/mysql
Create entries in /etc/hosts for the two servers which will be in the cluster. Use the ip address
which is bound to the public interface (eth0) which the heartbeat will use.
Create the /etc/ha.d/ha.cf file on both servers as follows:
debugfile /var/log/ha-debug
logfile /var/log/ha-log
logfacility local0
keepalive 2
deadtime 30
warntime 10
initdead 120
udpport 694
bcast eth0
auto_failback on
node mysqldb01 ## make sure both names are accessible - check /etc/hosts
node mysqldb02
ping 10.10.10.1 ## ETH0, public network
apiauth ipfail gid=haclient uid=hacluster
Create the /etc/ha.d/haresources. This file is the same on both servers. It lists the primary
servername, tells it to use LVS, sets the IP address of the heartbeat, the drbddisk name from
/etc/drbd.conf, the drbd device name and mount point and finally the server to start.
mysqldb01 LVSSyncDaemonSwap::master IPaddr::10.10.10.12/24/eth0 drbddisk::r0
Filesystem::/dev/drbd0::/var/lib/mysql::ext3 mysql
Create authkeys on both servers in /etc/ha.d/authkeys. Heartbeat will complain if you don’t
secure the file.
auth 3
3 md5 plaintextpassword
chmod 600 /etc/ha.d/authkeys
Start heartbeat on both servers, starting with mysqldb01:
/etc/init.d/heartbeat start
Errors will be in /var/log/ha-debug and /var/log/ha-log if you have problems. You should now be able
to connect to mysql on the heartbeat’s ip address. Shutdown heartbeat on mysqldb01, and you
should notice that /var/lib/mysql is now mounted on mysqldb02 and you can still connect to the
database.
Upgrading Mysql with DRBD and Heartbeat
After recently running into the dilemma of how to upgrade something that doesn’t like you to shut
it down, I’ve resolved it thus: First, upgrade the secondary database server. The MySQL upgrade
will actually fail since Debian cannot start and stop a database that isn’t running and whose
file storage isn’t mounted. After the secondary is mounted, commence to upgrading the primary.
The data files will now be upgraded, and the database shouldn’t be down long enough to create a
fail over on the heartbeat while the containers are upgraded.
เอาวิธีแรก ที่ใช้กันง่ายๆก่อนนะ
/usr/sbin/mysqld --skip-grant-tables --user=root &mysql -u root -pUPDATE user SET password=password('secret') WHERE user='root';ส่วนวิธีที่สองไปอ่านเจอที่อื่น
# mkdir temp
# for i in *jpg; do convert $i -interlace line temp/$i ; done# convert -adjoin `ls *.tif` newfile.pdf$ convert x1.tif x2.tif x3.tif -adjoin newfile.tif$ convert x.tif x%d.tifหมายเหตุ
ต้องลงแพกเกจ imagemagick ก่อน
# aptitude install imagemagick
ยังหาโปรแกรมที่ใช้แก้ไขภาพ tif แบบหลายหน้า แบบ Imaging for Windows บนลินุกซ์ไม่ได้
ก็คงต้องใช้แบบบรรทัดคำสั่งไปพลาง ๆ ก่อน
ขั้นตอนคือ
ต้องลง ImageMagick ก่อน
$ sudo aptitude install imagemagick
แตกไฟล์ tif แบบหลายหน้าออกมาเป็น แบบหน้าเดียวหลายไฟล์
$ convert image.tif x%d.tif
แก้ไขหน้าที่ต้องการจากไฟล์ที่แตกออกมาแล้ว ด้วย gimp สมมุติว่าเป็นหน้า 2
$ gimp x2.tif
เมื่อบันทึกเรียบร้อยแล้ว ก็รวมกลับเป็นไฟล์เดียวตามเดิม สมมุติว่ามีทั้งหมด 3 ไฟล์
$ convert x1.tif x2.tif x3.tif -adjoin newimage.tif
ถ้าจะให้บีบอัดด้วย
$ convert newimage.tif -compress lzw newimage.tif$ convert newimage.tif -compress fax newimage.tifสำหรับการบีบอัดมีพารามิเตอร์คือ None BZip Fax Group4 JPEG JPEG2000 Lossless LZW RLE และ Zip
ต้องทดลองเลือกใช้ดูให้เหมาะกับประเภทของภาพ
ลยไฟล์ย่อยทิ้ง
$ rm x?.tif
ดูผลได้ด้วย evince
$ evince newimage.tif
อ้างอิง : debian: บันทึก imagemagick - convert
*** โปรดระวัง - ไม่สามารถใช้กับไฟล์ tif ที่มีข้อมูล annotation ได้ ***
update
จากขั้นตอนข้างบน สามารถนำมาเขียนสคริปต์ทำให้ใช้คำสั่งเดียวได้ ดังนี้
สมมุติว่าจะต้องการแก้ไข image.tif ในหน้า 0 และหน้า 1 สั่งจากสคริปต์ว่า
$ d.edittif image.tif 0 1
gimp จะเปิดไฟล์ออกมา 2 ไฟล์ คือหน้าแรก และหน้าที่สอง
หลังจากบันทึกและปิด gimp แล้ว จะได้ไฟล์ image-new.tif ออกมาเป็นภาพที่แก้ไขแล้วพร้อมบีบอัดเรียบร้อย
เนื้อไฟล์ d.edittif มีดังนี้
$ sudo touch /usr/local/bin/d.edittif
$ sudo chmod 755 /usr/local/bin/d.edittif
$ sudo vi /usr/local/bin/d.edittif
#!/bin/bash
# EDIT MULTIPLE PAGES TIF FILE
# PREREQUIST: gimp imagemagick evince
#NAME=${0##*/}
NAME=`basename $0`
USAGE=" Usage: $NAME FILE PAGE0 PAGE1 ...
ex1: $NAME image.tif 0 1 = Edit file image.tif on PAGE0 and PAGE1"
phelp()
{
echo "$NAME: edit multiple pages tif.
$USAGE"
}
while getopts "h" opt; do
case "$opt" in
h) phelp; exit 0;;
*) echo "$Usage" 1>&2; exit 2;;
esac
done
shift $((OPTIND - 1))
if [ ! $2 ]; then
phelp
exit 1;
fi
TIF=$1
shift
FILE=${TIF%.*} #STRIP FILENAME
EDITFILE=”"
while [ $1 ]; do
EDITFILE=”$EDITFILE ~${FILE}$1.tif”
shift
done
ALLFILE=`ls ~${FILE}*.tif`
if [ -f $TIF ]; then
echo “Process $TIF”
/usr/bin/convert $TIF “~$FILE%d.tif”
if [ -f "~${FILE}0.tif" ]; then
#EDIT WITH gimp
echo “Edit $EDITFILE”
/usr/bin/gimp $EDITFILE
#COMPRESS EACH TIF
for i in $ALLFILE; do
echo -n “IDENTIFY $i ”
if /usr/bin/identify -verbose $i | grep “Gray: 1-bits”; then
/usr/bin/convert $i -compress fax $i
else
/usr/bin/convert $i -compress lzw $i
fi
done
/usr/bin/convert $ALLFILE -adjoin -compress lzw “$FILE-new.tif” #COMPRESS & JOIN
/usr/bin/evince “$FILE-new.tif” #VIEW NEW FILE
rm $ALLFILE #DELETE ALL SPLIT FILE
fi
fi
ลองบนเดเบียน sid ครับ
ความจำเป็นบีบบังคับให้ต้องรีบหาโปรแกรมที่สามารถทำ Annotation ไฟล์ tif ให้ได้
จริง ๆ ก็มีโปรแกรมชื่อ Xournal ที่สามารถทำ annotate บน pdf ได้
ซึ่งเราอาจแปลง tif ไปเป็น pdf ก่อน แล้วจึงค่อยลงมือแก้ไข
แต่พบว่าในรุ่นปัจจุบันบน sid คือ 0.3.3 ยังทำ Text annotation ไม่ได้
และรุ่นล่าสุด 0.4 ความสามารถและการใช้งานยังค่อนข้างด้อยกว่าที่ Kodakimg ทำได้อยู่โข
แต่จากครั้งก่อนที่ทำ การแก้ไข multiple pages tif
คราวนี้เลยได้ความคิดว่าถ้าลองเปลี่ยนจาก Gimp มาเป็น Inkscape เราก็จะได้ความสามารถในการทำ annotation จาก inkscape ในแบบที่ก้าวหน้าสุด ๆ
มีปัญหาที่ต้องแก้คือ inkscape ไม่สามารถแก้ไขไฟล์แบบหลายหน้าได้ (แต่ในอนาคตคงมาแน่ ๆ เห็นอยู่ใน wishlist ลำดับต้น ๆ )
ทางแก้แบบชั่วคราวคือ กระจายไฟล์ลงในไดเรคทอรี่ชั่วคราวที่สร้างไว้ แล้วแก้ไขตามไฟล์ที่เราระบุ
อีกปัญหาคือเวลาแปลงกลับจาก svg มาเป็น tif แบบหลายหน้าแล้ว ข้อมูล annotation ที่เราทำไว้ จะถูกแปลงเป็นข้อมูล bitmap ฝังรวมกับไฟล์ tif ไปหมด
ทางแก้ชั่วคราวอีกเหมือนกันคือ ให้คงไดเรกทอรี่ชั่วคราวนี้ไว้ โดยไม่ลบไฟล์ทิ้งเลย เมื่อเวลาเราใช้คำสั่ง annotate ครั้งใหม่ เขาก็จะมาแก้ไขต่อจากที่เราเคยแก้เอาไว้ โดยต้องยอมรกรุงรังบ้าง
เนื้อแบตช์ไฟล์มีดังนี้
$ sudo vi /usr/local/bin/d.tifannotate
#!/bin/bash
# ANNOTATE MULTIPLE PAGES TIF FILE
# PREREQUIST: inkscape imagemagick evince
#NAME=${0##*/}
NAME=`basename $0`
USAGE=" Usage: $NAME FILE PAGE0 PAGE1 ...
ex1: $NAME image.tif 0 1 = Edit file image.tif on PAGE0 and PAGE1"
phelp()
{
echo "$NAME: annotate multiple pages tif.
$USAGE"
}
while getopts "h" opt; do
case "$opt" in
h) phelp; exit 0;;
*) echo "$Usage" 1>&2; exit 2;;
esac
done
shift $((OPTIND - 1))
if [ ! $2 ]; then
phelp
exit 1;
fi
TIF=$1
shift
FILE=${TIF%.*} #STRIP FILENAME
TEMPDIR=”${FILE}~”
EDITFILES=”"
while [ $1 ]; do
EDITFILES=”$EDITFILES ${FILE}$1.svg”
shift
done
INKSCAPE=`which inkscape`
IDENTIFY=`which identify`
CONVERT=`which convert`
VIEW=`which evince`
if [ -f $TIF ]; then
echo “Process $TIF”
#TEST TEMP DIR EXIST
if ! [ -d $TEMPDIR ]; then
#CREATE TEMP DIR AND SPLIT tif INTO
mkdir $TEMPDIR
$CONVERT $TIF “${TEMPDIR}/$FILE%d.tif”
#ENTER WORKING TEMP DIR
pushd $TEMPDIR
ALLFILE=`ls ${FILE}*.tif`
#CONVERT TO svg
for i in $ALLFILE; do
$INKSCAPE -l “${i%.*}.svg” $i
done
else
#ELSE; EDIT OLD svg
pushd $TEMPDIR
fi
#ANNOTATE
if [ -f "${FILE}0.svg" ]; then
#ANNOTATE WITH inkscape
echo “Edit $EDITFILES”
$INKSCAPE $EDITFILES
ALLSVG=`ls ${FILE}*.svg`
#CONVERT ADJOIN
$CONVERT $ALLSVG -adjoin -compress lzw “$FILE-new.tif” #COMPRESS & JOIN
$VIEW “$FILE-new.tif” #VIEW NEW FILE
mv “$FILE-new.tif” ..
fi
#EXIT WORK DIR
popd
#REMOVE DIR
#rm -rf $TEMPDIR
fi
$ sudo chmod 755 /usr/local/bin/d.tifannotate
เรียกใช้งานด้วยคำสั่ง… โปรแกรม ไฟล์tif หน้าที่ต้องการแก้ไข
$ d.tifannotate FILE.tif 0 1 ...
จะได้ไฟล์ที่ทำ annotate แล้วชื่อ FILE-new.tif และไดเรกทอรี่ชั่วคราวชื่อ FILE~ เหลืออยู่ เพื่อใช้ในการแก้ไขครั้งต่อไป (แต่ถ้าไม่ได้ใช้แน่ ๆ ก็อาจเติมคำสั่งลบต่อท้ายแบตช์ไฟล์ หรือลบด้วยมือเอาทีหลังก็ได้ครับ)
กระท่อนกระแท่นหน่อย เพราะเป็นการทำเพื่อรอโปรแกรมลินุกซ์แนวนี้ในอนาคตตัวจริง ก็พอใช้งานได้ไปพลาง ๆ ก่อนครับ
อย่าลืม เปลี่ยนขนาดกระดาษไน inkscape ด้วย
แต่ติดใจการใช้งาน annotation บน inkscape จริง ๆ แฮะ
For those of you that may not know what unixodbc does, “ODBC is an open specification for providing application developers with a predictable API with which to access Data Sources. Data Sources include SQL Servers and any Data Source with an ODBC Driver.” They include a text file driver as an example of a non-SQL source. Two examples are Asterisk and OpenOffice.org.
Unixodbc allows cross-platform use of databases with many bridges available in many popular programming languages.
Installing and configuring isn’t necessarily as simple as “apt-get install unixodbc“. This HOWTO was written on Etch and may vary if you are using a different version.
Step 1: Download Packages
Running:
apt-get install unixodbc libmyodbc odbc-postgresql \ odbcinst1debian1
will get you the ODBC binaries, database drivers for MySQL and PostgreSQL and a Debian helper application for ODBC respectively.
Step 2: Add odbcinst.ini Records
As the root user, check for two empty text files /etc/odbc.ini and /etc/odbcinst.ini. If they aren’t there, then create them. (eg. “touch /etc/odbcinst.ini“)
Create a directory for the odbcinst.ini scripts:
username@host:~$ mkdir /home/username/odbc
Step 3: Adding ODBC Instances
In order to minimize entry-error, I use text files to load ODBC instances. Odbcinst’s error messages are a bit cryptic so I control errors using a separate file for each database type.
As root create a file name pgsql and paste the following into it.
[PostgreSQL] Description = PostgreSQL driver for Linux & Win32 Driver = /usr/lib/odbc/psqlodbca.so Setup = /usr/lib/odbc/libodbcpsqlS.so FileUsage = 1
If you are on another version double-check your library names.
Name the file pgsql so the following command should work.
odbcinst -i -d -f /home/username/odbc/pgsql
You can create another file for MySQL with the following contents:
[MySQL] Description = MySQL driver for Linux & Win32 Driver = /usr/lib/odbc/libmyodbc3_r-3.51.11.so Setup = /usr/lib/odbc/libodbcmyS.so FileUsage = 1
To use it run, as root: “odbcinst -i -d -f /home/username/odbc/mysql“.
With PostgreSQL and MySQL done, lets create a sample ODBC connection!
Step 4: Create ODBC Connection
Create another text file and copy the text below into it. I called it asterisk. Copy the contents of this file into odbc.ini. (Note, in theory “odbcinst -i -s -f /path/to/file” writes the contents of the named file into /etc/odbc.ini. I could not get it to do so and there were no error messages) So, copy and paste the following into odbc.ini too
[asterisk] Description = MySQL Asterisk Driver = MySQL SERVER = localhost USER = username PASSWORD = password PORT = 3306 DATABASE = asterisk Option = 3
Make sure your database permissions are configured to allow the login/connection before testing.
Step 5 Test Connection:
As the root enter run:
isql asterisk
This should put you into the asterisk database!
apt-get update apt-get install pgsql
Example plpgsql
su postgres createlang plpgsql template1 exit
We need to edit file pg_hba.conf to change authentification method for accessing PostgreSQL database.
cp /etc/postgresql/pg_hba.conf /etc/postgresql/pg_hba.confbak vi /etc/postgresql/pg_hba.conf
Find this section
# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD # Database administrative login by UNIX sockets local all postgres ident sameuser # # All other connections by UNIX sockets local all all ident sameuser # # All IPv4 connections from localhost host all all 127.0.0.1 255.255.255.255 ident sameuser # # All IPv6 localhost connections host all all ::1 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff ident sameuser host all all ::ffff:127.0.0.1/128 ident sameuser # # reject all other connection attempts host all all 0.0.0.0 0.0.0.0 reject
Edit that section to
# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD # Database administrative login by UNIX sockets local all postgres ident sameuser # # All other connections by UNIX sockets local all all password # # All IPv4 connections from localhost host all all 127.0.0.1 255.255.255.255 password # # All IPv6 localhost connections host all all ::1 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff password host all all ::ffff:127.0.0.1/128 password # # reject all other connection attempts host all all 0.0.0.0 0.0.0.0 reject
/etc/init.d/postgresql restart
Example wordpress
su postgres createdb -T template1 wordpress exit
Example: User supriyadisw with password cak3p
su postgres createuser supriyadisw -P Enter password for new user: cak3p [enter] Enter it again: cak3p [enter] Shall the new user be allowed to create databases? (y/n) y [enter] Shall the new user be allowed to create more new users? (y/n) n [enter] CREATE USER exit
pgsql -U supriyadisw wordpress [enter] Password: cak3p [enter]
Good Luck ![]()
Statistics