Sunday, November 17, 2019

PostgreSQL Multiple Instances : ตอนที่ 1 การติดตั้ง PostgreSQL ให้มีหลายๆ instance ทำงานพร้อมกัน

ปกติแล้วในเครื่อง  PostgreSQL Server หนึ่งเครื่องเราจะติดตั้ง  Postgres Cluster หรือ Data Directory ที่ไว้เก็บข้อมูลของ Postgres (ผมขอเรียกย่อๆ ว่า PGDATA) หนึ่งชุด

แต่ในบางสถานะการณ์ เครื่อง server เรามีทรัพยากรเหลือ เราอยากจะมี PGDATA และมี PostgreSQL อยู่หลายๆ ชุด บนเครื่อง server เครื่องเดียวกัน ทำงานพร้อมๆกัน แทนที่จะต้องหา Linux Server เครื่องใหม่ และติดตั้ง  Postgres บน Linux Server อีกเครื่อง

คำถามที่มีคนถามผมบ่อยๆ คือ ทำได้หรือไม่

คำตอบก็คือ ทำได้ครับ โดยใน server หนึ่งเครื่อง เราจะทำการสร้าง PGDATA ได้หลายชุด โดย PGDATA แต่ละชุด จะมีชุดของ PostgreSQL Process ถูก start ขึ้นมาทำงานแยกกัน เราเรียก PostgreSQL Process แต่ละชุดนี้ว่าเป็น PostgreSQL instance ครับ ซึ่งในกรณีนี้ข้อมูลต่างๆ ของ Postgres แต่ละ instance นี้จะอยู่แยกกันต่างหาก เหมือนอยู่คนละเครื่องกันเลยครับ


Diagram โครงสร้างการทำงานในกรณีที่มี Postgres 2 instance ทำงานอยู่บนเครื่องเดียวกัน


ขั้นตอนการ setup

สมมติว่า เรามี  PostgreSQL ทำงานอยู่บนเครื่องแล้ว เราอยากจะสร้าง PostgreSQL อีกหนึ่ง instance ขึ้นมาทำงาน ซึ่งเราสามารถทำได้ครับ ตราบเท่าที่ทรัพยากรของระบบเพียงพอ โดยขั้นตอนก็คลายๆ กับการสร้าง PostgreSQL Cluster Directory ขึ้นมาใหม่ โดยมีขั้นตอนเพิ่มเติมอีกนิดหน่อยดังนี้ครับ

หมายเหตุ เนื่องจากส่วนใหญ่ เราใช้ PostgreSQL บน Linux Server ในบทความนี้ จะขอพูดถึงขั้นตอนการติดตั้งบน Linux Server เป็นหลักนะครับ

1) สร้าง Directory ที่เก็บข้อมูลของ PostgreSQL ขึ้นมาใหม่แยกออกจากของเดิมโดยใช้คำสั่ง mkdir ตัวอย่างเช่น ผมต้องการสร้าง directory ชื่อ /pgdata2


2) กำหนด  permission ของ directory ที่ถูกสร้างในข้อ 1) ให้เป็น 700 (rwx------) และกำหนด owner ซึ่งปกติ เราะจะกำหนดให้ เจ้าของ directory นี้เป็นของ user ที่ชื่อ postgres


3) ทำการ initial database โดยใช้คำสั่ง initdb โดยรูปแบบของคำสั่งคือ 
initdb -D pgdata_path 

โดยแทนที่ pgdata_path ด้วยชื่อ cluster directory

และนอกจากนี้ การเรียกใช้คำสั่งนี้ ต้องเรียกใช้ในขณะที่เป็น user ชื่อ postgres ดังนั้นในตัวอย่างข้างล่างนี้ จากที่ login เป็น root อยู่ ผมเลยต้องทำการ switch user เป็น postgres โดยใช้คำสั่ง

su - postgres

ตัวอย่างเช่น


 ซึ่งในบางเครื่อง การเรียกใช้คำสั่งนี้อาจจะต้องระบุเป็น full path name คือเรียกชื่อโดยระบุ directory แบบเต็มตั้งแต่ / (เช่น /usr/local/pgsql/bin/initdb) ซึ่ง full path name ของคำสั่ง initdb ในแต่ละเครื่องจะไม่เหมือนกัน ขึ้นอยู่กับว่าคำสั่ง initdb ถูกติดตั้งอยู่ที่ directory ไหน

 ในบางกรณี เราต้องการย้าย PGDATA directory ที่เคยใช้งานแล้วจากเครื่องอื่น หรือจาก media ที่ถูก backup ไว้ ก็ไม่จำเป็นต้องทำการ initdb ใหม่ แต่ต้องให้แน่ใจครับ หลังจากที่ restore มาแล้ว file และ directory ใน cluster directory  ตัว user postgres  บน Linux มีสิทธ์เขียนอ่านทุกไฟล์

4) แก้ไขไฟล์ postgresql.conf ใน Cluster Directory (จากตัวอย่างในข้อ 3 ไฟล์นี้คือ /pgdata2/postgresql.conf) โดยแก้ให้ Port ที่เปิดหรือ ip address ไม่ซ้ำกับ postgres instance อื่นๆที่อยู่ในเครื่องเดียวกัน ซึ่งโดยปกติ เราจะแก้ไข parameter ที่ชื่อ port ยกตัวอย่างเช่น เราแก้ไข ค่า port ให้เป็น 5433 แทนที่ค่า default ที่เป้น 5432 ตามรูป


ซึ่งถ้าเราไม่แก้ให้ไม่ซ้ำกับ instance อื่น จะ start postgres ไม่ขึ้นนะครับ ที่จริงเรา port เดียวกัน แต่แก้ ip address ที่ postgres เปิด port รอรับ connection จาก client ไม่ให้ซ้ำกัน ก็ได้ แต่ยากไป และผลลัพท์อาจจะทำให้ เราะ connect postgres ผิดตัว(ผิด instance ) ก็ได้ครับ เลยไม่ขอกล่าวถึง

5) ทดลอง start postgres instance นี้โดยใช้คำสั่ง มีรูปแบบดังนี้

 pg_ctl -D pgdata_path

โดยแทนที่ pgdata_path ด้วยชื่อ cluster directory ที่เราสร้างขึ้นในข้อ 3)

และในขั้นตอนนี้ถ้าเราต้องเรียกใช้คำสั่ง ขณะที่เป็น user postgres นะครับ ( ถ้าเรา login เป็น root อยู่ เราต้อง switch user เป็น postgres ก่อน ) ตัวอย่างเช่น

 su – postgres
/usr/local/pgsql/bin/pg_ctl -D /pgdata2

6) ถ้าต้องการ ให้ instance ที่ติดตั้งใหม่นี้ ถูกเรียกขึ้นมาใช้งานโดยอัตโนมัติ (auto start) เมื่อมีการเปิดหรือ reboot เครื่อง ต้องสร้าง startup file สำหรับ instance นี้นะครับ เพื่อความสะดวก เราจะใช้วิธีเอา startup file ของเดิมมาแก้ ที่นี้ก็ขึ้นอยู่ว่า ระบบของคุณใช้ startup ไฟล์แบบไหน ซึ่งผมขอพูดถึงในบทความตอนต่อไปก็แล้วกันนะครับ

Tuesday, October 22, 2019

เทคนิคการใช้งาน wildcard ในคำสั่ง psql

คนที่ใช้งาน PostgreSQL ส่วนใหญ่ จะรู้จักกับ คำสั่ง psql อยู่แล้ว คำสั่งนี้เป็น PostgreSQL Client  ทีมีมากับชุดคำสั่งต่างๆ ของ PostgreSQL  ทำให้เราสามารถเข้าไปจัดการ PostgreSQL database ของเรา โดยใช้  คำสั่งนี้ ที่ Linux command line ได้

วันนี้ผมมีเทคนิคการใช้งาน wildcard กับคำสั่งใน psql มาฝากครับ

Wildcard  คืออะไร 
สำหรับคนที่คุ้นเคยกับคำสั่ง command line  ของ Linux  หรือ Unix ก็จะรู้จักหรือเคยใช้ wildcard เป็นอย่างดี เช่น การเรียกใช้คำสั่ง
ls -l  *abc* 
 จะเป็นการเรียกดูไฟล์ที่มีคำว่า abc อยู่ในชื่อไฟล์ ทำนองนี้ หรือ
ls -l  postgresql?1[0-9]*
จะเป็นการเรียกดูชื่อไฟล์ ที่ขึ้นต้นด้วย postgresql ตามด้วยตัวอักขระอะไรก็ได้ 1 ตัว (?) และตามด้วยตัวเลข 0-9 อีกหนึ่งตัว

Wildcard กับคำสั่ง psql 

เราลองมาดูตัวอย่างคำสั่ง ใน psql ที่เรียกใช้ wildcard  ได้กันนะครับ ตัวอย่างแรกคือคำสั่ง \l  ซึ่งปกติถ้าไม่ระบุ parameter  อะไร จะเป็นการ list ดูชื่อ database ทั้งหมด ที่มีอยู่ในระบบ ออกมา



แต่ถ้าเราเรียกใช้คำสั่ง โดยระบุชื่อ  database  จะเป็นการ list ดู เฉพาะ database ที่เราระบุชื่อ



แต่เราก็สามารถเรียกใช้ตัวอักษร * ซึ่งเป้นตัวอักษรพิเศษตัวหนึ่ง ซึ่งใช้แทน ชุดตัวอักษรใดๆ ตั้งแต่ 0 ตัวเป็นต้นไป ได้ ตัวอย่างเช่น



จากตัวอย่างนี้ เป็นการเรียกใช้คำสั่ง \l template*  ผลลัพท์ที่ได้เป้นการเรียกดู database ที่มีชื่อขึ้นต้นด้วยคำว่า template  และตามด้วยตัวอักขระอะไรก็ได้ ตั้งแต่ 0 ตัวขึ้นไปครับ เราจะได้ database สองตัวคือ  template0 และ template1 

ลองดูอีกตัวอย่าง เช่น list ดู database ซึ่งในชื่อ มีตัวอักษร underscore (_)  อยู่ 


จากตัวอย่างนี้ เราจะเห็น database ชื่อ test_pentaho อยู่

ที่จริงการใช้ wildcard  นี้สามารถใช้กับคำสั่งอื่นๆ ใน psql ได้นะครับ คำสั่งที่ผมใช้บ่อยๆ อีกคำสั่งหนึ่งคือ \dt  ซึ่งปกติ เป็นการ list รายชื่อ table ที่มีอยู่ใน database ที่เรา connect อยุ่ออกมา 

จากตัวอย่าง ผมใช้คำสั่ง psql connect ไปที่ database ชื่อ test_pentaho แล้วลองใช้คำสั่ง \dt  ทำการ list table  ที่มีอยู่ใน database นี้ จะเห็นมีสอง table  


ลองใช้ \dt *1  เพื่อ list ชื่อ table ที่ลงท้ายด้วย 1



ลองใช้  \dt *[0-9] เป็นการ list ชื่อ table ที่ลงท้ายด้วยตัวเลข  0-9











ที่จริงเทคนิคนี้ สามารถใช้กับคำสั่งอื่นๆ ของ psql ได้อีกนะครับ ลองไปใช้กันดูนะครับ

ศิวัฒน์ ศิวะบวร