(Update20200327)Replication database postgres แบบ master to master ด้วย rubyrep บน centos 7
ที่มา: http://www.rubyrep.org/installation.html
เข้าไปอ่านได้ หากมีข้อสงสัยเพิ่มเติม
ในส่วนของการติดตั้ง postgres จะไม่ได้อธิบาย อาจจะต้องหาอ่านเอง หรือที่นี้ http://kmzohan.com/2019/03/04/%e0%b8%95%e0%b8%b4%e0%b8%94%e0%b8%95%e0%b8%b1%e0%b9%89%e0%b8%87-postgres-%e0%b8%9a%e0%b8%99-centos/
เริ่มแรกให้ติดตั้ง ruby ก่อน (เราทำงานติดตัั้ง ruby ที่ server เดียว ที่ server นั้นจะเช็ค ทั้ง 2 server เอง)
yum install ruby
yum install ruby-devel
จากนั้น ตรวจสอบ เวอร์ชั่น ruby -v (หากเป็น centos 7 น่าจะเป็น 2.0)
จากนั้น ติดตั้งตัว เสริมของ ruby
อันแรกจะเป็นตัวเชื่อม postgres (คาดว่าน่าจะมีมากับตอน yum ruby แล้ว แต่ เพื่อให้แน่ใจ)
gem install pg
แต่หากเป็น Centos 8 จะ error จึงควร ลงเป็น
yum install rubygem-pg
จากนั้นเป็น rubyrep
gem install rubyrep
หากต้อากรเช็คว่า gem ครบไหม ด้วยคำสั่ง
gem list
จากนัั้น โหลด rubyrep ได้ที่ https://github.com/rubyrep/rubyrep
และ โหลด JRuby ได้ที่ https://www.jruby.org/download
และ Java ต้องเป็น 1.8 ตรวจสอบด้วยคำสั่ง java -version
*** จากปัญหาที่เจอ เรื่อง version ของ ruby จะมีประเด็นมาก เนื่องจาก centos 7 ไม่ update ruby version
โดยพบว่า JRuby ต้องการ ruby version 2.3หรือ 2.5 แต่ ruby บน centos 7 คือ 2.0
ดังนั้นผมมีJRuby ที่ใช้กับ ruby 2.0 ได้อยู่ >> jruby โหลดได้***
นำไปวางที่ๆต้องการ โดยผมไปวางที่ /root/rubyrep-master
จากนั้นสร้างไฟล์ testrubyrep.conf ดังนี้
RR::Initializer::run do |config|
config.left = {
:adapter => ‘postgresql’, # or ‘mysql’
:database => ‘db_rep’,
:username => ‘postgres’,
:password => ‘123456’,
:host => ‘192.168.1.46’
}
config.right = {
:adapter => ‘postgresql’,
:database => ‘db_rep’,
:username => ‘postgres’,
:password => ‘123456’,
:host => ‘192.168.1.42’
}
config.include_tables /./
end
############
หากเป็น postgres10 จะเจอปัญหา
Exception caught: ActiveRecord::JDBCError: org.postgresql.util.PSQLException: ERROR: column “increment_by” does not exist
Position: 20: select last_value, increment_by from “account_account_id_seq”
สรุปคือ auto id ที่ชื่อ account_account_id_seq ไม่พบ ฟิว increment_by ใน postgres 10 ดังนั้นต้องแก้ที่ไฟล์
/home/rubyrep-master/lib/rubyrep/replication_extenders/postgresql_replication.rb
หรือที่คุณวางไฟล์นั้นๆไว้ โดยให้แก้จาก
row = select_one(“select last_value, increment_by from \”#{sequence_name}\””)
เป็น
row = select_one(“select last_value, increment_by from pg_sequences where sequencename=’#{sequence_name}'”)
โดยจะมีอยู่ 2 ที่ อาจจะหาจาก increment_by
###################
ลอง scan
/root/rubyrep-master/rubyrep scan -c /root/rubyrep-master/testrubyrep.conf
จากนั้นใช้คำสั่ง กับโฟเดอร์ที่มาวาง
/root/rubyrep-master/rubyrep replicate -c /root/rubyrep-master/testrubyrep.conf
จากนั้นทดสอบดูครับ ส่วนตัว table ต้อง มี primary key ทุกอัน
หากเอาไปทำ .sh ไฟล์ ต้อง vi สร้างไหม่ เจอว่า copy มา vi แล้ว หาไฟล์ไม่เจอ เนื่องจากมีตัวอักษรพิเศษเข้ามาปน
แนะนำให้นำไปทำเป็น service ไฟล์ โดยเอา commend rubyrep ไป ใส่ใน .sh หรือไม่ใส่ก็ได้ แล้วแต่สะดวก
เพื่อให้ไม่ต้อง runผ่านหน้า commend และ จะสามารถตั้งเป็น start up ได้อยู่ เวลาเครื่อง down หรือ restart
commend rubyrep จะกลับมา start เอง วิธีทำ service บน centos
วิธีสร้าง service และ startup บน centos7 (ตัวอย่าง python3.6)
ปัญหาที่พบ และ วิธีแก้
-หากเครื่อง ที่ไม่ได้ลง rubyrep down จะเจอว่า data จะไม่กลับมา Replication สามารถแก้ปัญหาได้ 2 ทาง
1.หากเครื่อง ที่ down กลับมา ให้ไป run commend rubyrep หรือไป start service rubyrep ใหม่หากทำเป็น service ไว้
2.สั่งงานจากเครื่องที่ไม่มี service restart rubyrep วิธีนี้ เครืองที่มี commend rubyrep ต้องทำ rubyrep เป็น service ไว้แล้ว
โดยเราจะใช้ commend sshpass ช่วย โดยวิธีทำ sshpass จะช่วยให้เราไปสั่ง restart service rubyrep ของอีกเครื่องที่เราทำไว้ได้โดยไม่ติด password
จากนั้นให้ทำ sshpass เป็น service ไว้ หาก เครื่องที่ไม่มี service rubyrep down เวลา up กลับมา มันจะไปสั่งให้ เครื่อง service rubyrep Replication ใหม่
-หากพบว่า ทำ Replication ไปแล้วหลุดจ่ากัน และฐานข้อมูล ทั้ง2 ฝั่งมีจำนวนมาก ที่ไม่ได้ sync กับ (ระดับ แสน row) จะพบปัญหาว่า Replication ใหม่ไปสักพักก็จะหลุด
ต้องทำการลบ table ของ rubyrep ก่อน ชื่อ ขึ้นต้นด้วย rr_* ต่างๆ ทั้ง 2 เครื่อง จากนั้นค่อยทำการ Replication
-หาก network ระหว่าง 2 server ขาด จริงๆแล้ว สามารถแก้ปัญหาโดย ใช้โปรแกรมอืน (Bucardo ยังไม่ได้ทดสอบ) หรือ proxy ของ rubyrep (ยังไม่ได้ทดสอบ)
แต่เนื่องจาก หลายงานที่ ใช้ rubyrep run production ไปแล้วและมีข้อมูลจำนวนมาก จึงกลัวว่า หากเลือก 2 ทางนี้จะมีปัญหาอืนๆตามมาภายหลังเพราะยังไม่ได้ทดสอบ
ดังนั้นผมเลยเลือกใช้ ทำ tabel gen และ check เอา โดยหลักการเอาหลักการของ Replication มาช่วย ซึ่งผมจะสร้าง table ใหม่ขึ้น ทั้ง 2 database โดย table นี้จะรับค่า gen รหัส จากdatabase เครื่องแรก
ดังนั้นหากdatabase เครื่องสอง Replication อยู่ ก็จะได้ค่าเดียวกัน นี้คือ GEN โดยจะนำไปตั้งเป็น crontab ให้ทำงานทุกๆ 0,10,20,30,40,50 นาที
ต่อมาเราจะทำการ check ทั้ง 2 table โดย check ว่า รหัส ที่ gen ของทั้ง 2 server นั้น ตรงกันหรือไม่ หากไม่ตรงจะทำการ Replication ใหม่ โดย check จะนำไปตั้งเป็น crontab ให้ทำงานทุกๆ 5,15,25,35,45,55 นาที