DumpDB

จาก OpenTLE Wiki

ข้ามไปที่: ป้ายบอกทาง, ค้นหา

เอามาจากระทู้คุณ จักรนันท์ มาแถลงแล้วครับ http://www.opentle.org/th/node/4697 แปะไว้ก่อนกันลืม ไว้ทดสอบแน่ๆ แล้วจะมาเขียนให้ดีครับ

เมื่อถามมาแล้วก็จะเล่าให้อ่านนะครับ ทั้งหมดที่จะเล่าต่อไปนี้ ต้องทำบน Console ภายใต้ root นะครับ การ เข้าใช้ Console ตลอดจนการ Login เป็น root และพื้นฐานอื่นๆ ผมจะไม่ขอลงรายละเอียด ไม่งั้นจะยาวเกินไป ขอให้ผู้อ่านไปหาศึกษาเพิ่มเติมด้วยตนเองเพราะไม่ได้ยากเกินไปครับ ประการแรก ขอแจงคำสั่งที่จะใช้งานก่อนนะครับ มี 2 คำสั่งง่ายๆ คือ

   mysqldump --user=ยูสเซอร์ --password="พาสเวิร์ด" ชื่อฐานข้อมูล > เซฟไฟล์.sql
   mysql --user=ยูสเซอร์ --password="พาสเวิร์ด" ชื่อฐานข้อมูล < เซฟไฟล์.sql

แค่เนี้ยครับ... ใช้แค่นี้.. แต่.. ยังมีรายละเอียดทางเทคนิคอีกหน่อยครับ... คำ สั่งแรก ก็จะ Dump ฐานข้อมูลออกมาเป็น Text โดยใน Text นั้นจะได้ออกมาเป็นชุดคำสั่ง MySQL ที่สั่งตั้งแต่ Create database ต่อด้วย Create table ต่อด้วย Insert ฯลฯ ไปเรื่อยๆ จนตลอดข้อมูลในทุกๆ Table ของทั้ง Databse โดยที่ ไฟล์ที่ได้ จะออกมาเป็น Text ที่เป็นรหัส UTF-8 ขอ *ย้ำ* นะครับ ว่า UTF-8 จำไว้ให้ดีตรงนี้ MySQL ตั้งแต่ Version 4.1 เป็นต้นมา ได้เปลี่ยนการบันทึกข้อมูลใน Field ที่เป็น char และ varchar ทั้งหมดจากที่เคยเข้ารหัสตาม Locale ของ OS ไปเป็น UTF-8 เพื่อรองรับข้อมูล String ได้ทุกภาษา ทำให้ข้อจำกัดเรื่องที่ฐานข้อมูลบันทึกได้แค่ไม่เกิน 2 ภาษาหมดไป การทำ เช่นนี้ ทำให้ทุกๆ Client ที่เชื่อมต่อเข้ามา จึงจำเป็นต้องแจ้ง 1 ครั้งทันทีก่อนสิ่งอื่นใดว่าตนเองจะรับข้อมูลรหัสใด ด้วยคำสั่ง SET NAMES charset เมื่อแจ้งแล้ว MySQL จะทำการ Convert ทุกๆ Filed ที่จะส่งข้อมูลให้เป็น CharSet ตามที่ Client ร้องขอ แต่... ถ้ามีการ Dump มาจาก MySQL ต่ำกว่า Version 4.1 ลงไป จึงจำเป็นต้องดูด้วยเสมอว่า เครื่องนั้น Locale อะไร ซึ่งใช้วิธีไม่ยากคือ เมื่อ Dump ไฟล์มาได้แล้ว ก็ใช้ kate หรือ kedit หรือ kwrite (ผมใช้ KDE) เปิดไฟล์ดู ดูว่า Field ที่เป็น char หรือ varchar สามารถอ่านออกได้รู้เรื่องหรือไม่ ถ้าไม่ออก ก็ลองเปลี่ยน CharSet ของ kwriter/kate/kedit ดูเป็น tis-620, windowsd-874, iso8859-11, utf8 จนกว่าจะเจอที่อ่านรู้เรื่อง เรื่อง CharSet ที่จำเป็นต้องย้ำ เพราะต้องจดจำไว้ ก่อนจะเอาข้อมูลกลับขึ้นไป ต้องปรับให้ตรงกันก่อน แต่ถ้า Dump ออกจาก MySQL Version 4.1 ขึ้นไป แล้วเอาไปขึ้น MySQL 4.1 ขึ้นไปเหมือนกัน ก็ไม่จำเป็นต้องทำอะไรเลย เพราะรับเป็น UTF-8 ด้วยกันอยู่แล้ว ทีนี้... ถ้าฐานข้อมูลที่ได้ Dump ออกมาจาก MySQL ก่อน Version 4.1 จะต้องทำอะไรเพิ่ม ก็ทำแค่นี้ครับ เปิดไฟล์ดูลองปรับ Encoding จนรู้รหัส แล้วไปเพิ่มก่อนบรรทัดแรก ก่อนที่จะมีคำสั่งอื่นใดว่า

   SET NAMES รหัสที่ได้

แค่ เนี้ยครับ เพื่อให้เวลาเอาข้อมูลขึ้น MySQL จะได้รู้ว่า คำสั่งอะไรๆ ที่ตามมา ข้อมูลทั้งหมดจะส่งเป็น CharSet นี้นะ แล้ว MySQL ก็จะรับข้อมูลเข้าไป ก่อนจะบันทึกลง Disk จะทำการ Convert เป็น UTF8 เสียก่อนนั่นเอง แต่ถ้าไม่ระบุล่ะก็ เละแน่นอนครับ รหัสคลาดเคลื่อนกันไปหมดเลย ที่นี้.. การนำฐานข้อมูลขึ้น ก็ต้อง DROP database ทิ้งเสียก่อนนะครับ ไม่งั้นจะ Duplicate ครับ ผมใช้วิธีการนี้ ก็เปิดไฟล์ที่ Dump มาได้ แล้วใส่เป็นคำสั่งแรก (แต่ถ้ามี SET NAMES ก่อน ต้องให้ SET NAMES เป็นคำสั่งแรก ส่วน DROP เป็นคำสั่งถัดมา) แล้วก็เพิ่มไปบรรทัดหนึ่งว่า

   DROP ชื่อฐานข้อมูล

แค่้เนี้ยครับ พอจะเอาขึ้นเรียกคำสั่งตามข้างต้นครับ ง่ายไหมครับ? ผมมี Script ที่จะ Dump ฐานข้อมูลทุกๆ วันแล้วเขียนลง CD-RW ไว้ทุกๆ วันตอน 06:02 ผมจะให้ดูตัวอย่างการนำไปประยุกต์ใช้นะครับ ต่อไปนี้เป็น Script ที่ผมใช้งานครับ


  1. !/bin/sh

CURRENTDIR=`pwd` BACKUPPATH=/home/chakr/mysql-backup # Directory ที่จะใช้เป็นที่ดำเนินการ Backup ชั่วคราว MySQLUser=root # ยูสเซอร์ แน่นอน ต้องเป้น root MySQLPasswd="....." # พาสเวิร์ดของ root FileOwner=chakr # ไฟล์ที่ Dump ได้ จะกำหนดให้ใครเป็น Owner FileGroup=root # และเป็น Group ไหน

CDRWDEVICE=/dev/hdb # CD-RW ผมต่ออยู่ไหน CDRWSPEED=4 # กำหนดความเร็วที่จะใช้เขียนแผ่น CDRWSIZE=650 # กำหนดขนาดไฟล์รวมสูงสุด

DATE=`date '+%m%d'` # เก็บวันที่ เดือน ปี /usr/bin/play /data/compaccessed.wav # ส่งเสียงออกลำโพงเสียหน่อย ว่าจะเริ่ม Backup แล้วนะ

mkdir $BACKUPPATH/$DATE # สร้าง Directory ด้วยชื่อวันที่ เดือน ปี

  1. เริ่ม Dump เลย 4 ฐานข้อมูล ได้แก่ mysql sicomacc loanman และ saha

mysqldump --user=$MySQLUser --password="$MySQLPasswd" mysql > $BACKUPPATH/$DATE/mysql.sql mysqldump --user=$MySQLUser --password="$MySQLPasswd" sicomacc > $BACKUPPATH/$DATE/sicomacc.sql mysqldump --user=$MySQLUser --password="$MySQLPasswd" loanman > $BACKUPPATH/$DATE/loanman.sql mysqldump --user=$MySQLUser --password="$MySQLPasswd" saha > $BACKUPPATH/$DATE/saha.sql

rm -f $BACKUPPATH/$DATE.zip cd $BACKUPPATH/$DATE zip -9 -r $BACKUPPATH/$DATE # ทำการบีบ zip ซะ ที่ไม่เอาเป็น tar ก็เพราะเผื่อเปิดบน Windows ได้ด้วย chmod 660 $BACKUPPATH/$DATE.zip chown $FileOwner:$FileGroup $BACKUPPATH/$DATE.zip

cd "$CURRENTDIR" rm -r -f $BACKUPPATH/$DATE # zip เสร็จแล้วก็จัดแจงลบไฟล์ที่ Dump ได้ออกไปเสีย ปล่อยไว้ก็เป็นขยะ

DATASIZE=`du -sB 1048576 "$BACKUPPATH" | sed -e 's/[^0-9]//g'` # ตรวจสอบว่าไฟล์ที่ Backup ไว้ทุกวัน รวมกันแล้วได้ขนาดเท่าไหร่

while [ $CDRWSIZE -le $DATASIZE ] # เข้า While loop เพื่อลบไฟล์ zip ที่เก่าที่สุดออกจนกว่าขนาดรวมทั้งหมดจะไม่เกิน $CDRWSIZE หรือ 650 MB นั่นเอง ไม่งั้นเขียนแผ่นไม่ได้ do

 cd "$BACKUPPATH"
 OLDESTBACKUP=`ls -1 | sed -n '1 p'`  # หาชื่อไฟล์ซึ่งเป็น วันที่ เดือน ปี.zip อยู่แล้ว ว่าอันไหนเก่าที่สุด
 rm -f "$BACKUPPATH1/$OLDESTBACKUP"  # ลบมันทิ้งไปเสีย 1 ไฟล์
 DATASIZE=`du -sB 1048576 "$BACKUPPATH" | sed -e 's/[^0-9]//g'`  # ดูขนาดรวมใหม่อีกครั้ง

done

if [ $DATASIZE -gt 0 ] # ตรวจดูว่า ขนาดรวมต้องใหญ่กว่า 0 ไบท์ then

 mkisofs -o ~/Backup.iso -J -R -V Backup "$BACKUPPATH"   # สร้างไฟล์ CD Image เป็น ISO9660
 if test -f ~/Backup.iso  # ตรวจดูว่า สร้างไฟล์เรียบร้อยดี
 then
   umount /mnt/cdrom   # ทำการ Unmount CD-ReWriter เพื่อความแน่ใจว่าไม่ถูก Mount ค้างไว้อยู่
   play $CURRENTDIR/processing_standby.wav &  # กระแดะส่งเสียงเสียหน่อย เพื่อจะได้รู้ว่า จะลบแผ่นแล้วนะ
   cdrdao blank --device $CDRWDEVICE   # ลบแผ่น CD-RW
   play $CURRENTDIR/filesrec.wav &  # ส่งเสียงอีกที จะเริ่มเขียนแล้วนะ
   cdrecord dev=$CDRWDEVICE speed=$CDRWSPEED -dao ~/Backup.iso  # เขียนแผ่น CD-RW
   rm -f ~/Backup.iso   # ลบไฟล์ CD Image ทิ้ง เพราะเขียนแผ่นเสร็จแล้ว
 else
   play $CURRENTDIR/warn_unauthusedcommcode.wav &
 fi

else

 play $CURRENTDIR/procedureisnotrecomm.wav &

fi

/usr/bin/play /data/transfer_data.wav

exit 0


Script ผม จะทำให้ได้แผ่น CD-RW ที่มีฐานข้อมูลที่ Dump มา zip ไว้ย้อนหลังไปหลายเดือนเท่าที่ขนาดรวมแล้วเกือบๆ 650 MB นั่นเองครับ แล้วผมก็ไปเพิ่มใน /etc/crontab ให้มา execute Script ผมทุกวัน เวลา 06:02 แค่นั้นเองครับ การ Dump ออกมาเป็น Text แล้ว zip จะทำให้ขนาดไฟล์เล็กลงอย่างมหาศาลเลยครับ เป็น 1,000 เท่าตัวเลย เพราะ Text file จะสามารบีบอัดได้สูงมากนั่นเอง แค่แผ่น CD-RW จึงเพียงพอสำหรับ Backup ฐานข้อมูลประชากรจังหวัดชลบุรีทั้งจังหวัดได้ทุกวันย้อนหลังถึง 4 เดือนเลยครับ (จากของจริงที่ยังใช้งานอยุ่ทุกวันนี้ เครื่องเขียนที่ Server ตัวนั้นยังเป็น 2x อยู่เลย คิดดู)

ขอจบการโม้แต่เพียงเท่า นี้ก่อนนะครับ มาตอบไม่ทันใจไปหน่อยก็ต้องเข้าใจกันนะครับ มีอะไรก็ให้ทิ้งคำถามไว้ หลังสิ้นเดือนจะมาตอบให้ครับ เดี๋ยวจะต้องจากไปไกลอีกแล้วครับ

รับข้อมูลจาก "http://wiki.opentle.org/DumpDB"
เครื่องมือส่วนตัว