ในเนื้อหาตอนที่แล้ว เราได้รู้เกี่ยวกับการตั้งเวลาการทำงานของ
script คำสั่ง ด้วย Cron job มาแล้ว ทบทวนได้ที่
การตั้งเวลาทำงาน ด้วย Cron Job และ Event Scheduler ตอนที่ 1 http://niik.in/895
https://www.ninenik.com/content.php?arti_id=895 via @ninenik
เนื้อหาต่อไปนี้จะเป็นภาคต่อที่พูดถึงเรื่องการใช้งาน Event Scheduler หรือการตั้งเวลา
ให้ทำคำสั่ง SQL ไม่ว่าจะเป็นการ เพิ่ม ลบ แก้ไข ข้อมูล หรือแม้แต่เรียกใช้ฟังก์ชั่น ให้ทำการ
คิวรี่ข้อมูล SQL ตามเงื่อนไขที่กำหนด
ในเนื้อหา เราจะจัดการเกี่ยวกับ Event Scheduler ผ่าน phpMyAdmin โครงสร้างตารางข้อมูล
สำหรับทดสอบจะใช้ดังนี้
ตาราง tbl_testcron
CREATE TABLE `tbl_testcron` ( `id_cron` int(11) NOT NULL, `test_val` varchar(100) NOT NULL, `date_val` datetime NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; ALTER TABLE `tbl_testcron` ADD PRIMARY KEY (`id_cron`); ALTER TABLE `tbl_testcron` MODIFY `id_cron` int(11) NOT NULL AUTO_INCREMENT; COMMIT;
เปิดใช้งาน Event Scheduler ใน MySQL
เราสามารถเปิดใช้งาน event scheduler โดยเมื่อเข้าไปใน phpMyAdmin ให้เราเลือก
ชื่อฐานข้อมูลที่้ต้องการในที่นี้จะใช้ dbname ชื่อ test แล้วเลือกไปที่แท็บ คำสั่ง SQL
SET GLOBAL event_scheduler = "ON"
รันคำสั่ง sql ด้านบนเพื่อเปิดใช้งาน หรือเปลี่ยนค่าเป็น OFF แล้วรันคำสั่งอีกครั้งเพื่อปิด
หรือจะไปที่แท็บ Events แล้วเลือก ปิด/เปิดใช้งาน โดยคลิกที่ปุ่มตามรูปด้านล่างก็ได้
ถ้าในขณะที่ event ที่มีการกำหนดไว้ ทำงานอยู่ หากเราทำการปิดใช้งาน ที่ปุ่มข้างต้น
หรือใช้คำสั่ง
SET GLOBAL event_scheduler = "OFF"
จะทำให้ event ทั้งหมดหยุดทำงานทันที และหากกลับมาเปิดใช้งาน event ก็เริ่มทำงานต่อตามปกติ
การเพิ่ม Event Scheduler
สมมติในที่นี้ เราจะทำการเพิ่มข้อมูล เข้าไปยังตาราง tbl_testcron ทุกๆ 10 วินาที โดยใช้คำสั่งที่ใช้งาน
เป็นดังนี้
INSERT INTO tbl_testcron (test_val,date_val) VALUES ('test',NOW())
เราสามารถทำได้ด้วย 2 วิธี ดังนี้
วิธีที่ 1 เพิ่มโดยใช้หน้าต่าง Add event ของ phpMyAdmin
เมื่อเราเลือกที่ปุ่มสร้าง Event ใหม่ โดยคลิกเลือก Add event ก็จะแสดงหน้าต่างสำหรับ
กำหนดค่าการสร้าง event ใหม่
หน้าต่างกำหนดการสร้าง event ใหม่
รูปแบบหน้าต่างกำหนดค่าการสร้าง event ตามรูปด้านบน เป็นของกรณีเลือก Event type เป็น ONE TIME
ซึ่งจะทำงานเมื่อถึง ณ เวลาที่กำหนดไว้เท่านั้น เช่น สมมติกำหนดไว้ที่เที่ยงของวันที่ 19 มีนาคม ก็จะกำหนด
ค่าในส่วนของ Execute at เท่ากับ 2019-03-19 12:00:00 (ในส่วนของเวลา เราสามารถกำหนดค่าเพิ่มได้ถึงหน่วยไมโคร
เช่น 2019-03-19 12:00:00.000000 )
ต่อไปมาดูหน้าต่างกรณีเลือก Event type เป็น RECURRING หรือการกำหนดเวลาแบบทำซ้ำ หน้าตากำหนด
ค่าก็แสดงในลักษณะด้านล่าง
รายละเอียดการกำหนดค่าต่างๆ ใน Event
Event name
ชื่อ event ที่ต้องการ ต้องไม่ซ้ำ สมมติเราจะใช้เป็น EV1,EV2....EVn
Status
ประกอบไปด้วย 3 ค่าคือ ENABLED | DISABLED | SLAVESIDE_DISABLED
โดยหลักๆ เราจะใช้เฉพาะ ENABLED กับ DISABLE ส่วนค่า SLAVESIDE_DISABLED จะใช้สำหรับกรณีมีการ
ใช้งาน mysql server หลายๆตัวพร้อมกัน อย่างเช่น ตัวหลักหรือที่เรียกว่า MASTER ไว้สำหรับ
เขียนข้อมูล แล้วก็มีตัวรองหรือ SLAVE ที่ถูก copy ทำซ่ำขึ้นมา สำหรับไว้ดึงข้อมูลมาอ่านอย่างเดียว
ซึ่งถ้ากำหนดให้เป็น SLAVESIDE_DISABLED ตัวที่เป็น SLAVE จะมี status เป็น DISABLED
ENABLED จะเป็นค่าเริ่มต้น หากเราเพิ่ม event โดยให้ค่า status เป็น ENABLED ตัว event จะเข้าสู่โหมด
ทำงานทันที่ที่มีการเพิ่ม event เข้าไป
DISABLED จะเป็นสถานะ ยังไม่เปิดใช้งาน หรือ ปิดใช้งาน หรือ หยุดทำงานเมื่อทำงาน
เสร็จตามกำหนดเวลาเรียบร้อยแล้ว
Event type
ประกอบด้วย 2 ค่า ตามที่ได้กล่าวไปข้างต้น ONE TIME (ทำครั้งเดียวตามเวลาที่กำหนด ใช้ร่วมกับ *Execute at )
กับ RECURRING (ทำซ้ำช่วงเวลาที่กำหนด ใช้ร่วมกับ **Execute every)
*Execute at
ใช้ร่วมกับ Event type ที่เป็น ONE TIME โดยเป็นการกำหนดเวลาที่จะเริ่มทำงานรูปแบบ
0000-00-00 00:00:00 หรือแบบมีไมโครวินาที 0000-00-00 00:00:00.000000
**Execute every
ใช้ร่วมกับ Event type ที่เป็น RECURRING เป็นการกำหนด ระยะห่างของช่วงเวลาที่ต้องการ
โดยนับจากวันที่เริ่ม event (ที่กำหนดใน Start) หรือถ้าจะให้ใช้คำที่เข้าใจง่ายคือ
"ทำซ้ำ นับจากวันที่เริ่ม Start อีก x" โดยประกอบด้วยค่าต่างๆ ดังนี้
- YEAR ทุกๆ x ปี เป็นตัวเลข
- QUARTER ทุกๆ 1/4 ของปี หรือทุก 3 เดือน เป็นตัวเลข (ไม่ใช่เดือน 3 , 6 , 9 หรือ 12) อย่างเช่นกำหนด 1 QUARTER ถ้าเริ่มวันที่ 1 เมษายน ทำซ้ำในอีกทุกๆ 3 เดือนข้างหน้า คือ 1 กรกฎาคม ถ้ากำหนด 2 QUARTER ก็คือทุก 6 เดือน
- MONTH ทุกๆ x เดือน เป็นตัวเลข เช่น 13 MONTH ทำซ้ำในอีกทุกๆ 13 เดือนข้างหน้า
- DAY ทุกๆ x วัน เป็นตัวเลข เช่น 45 DAY ทำซ้ำในอีกทุกๆ 45 วันข้างหน้า
- HOUR ทุกๆ x ชั่วโมง เป็นตัวเลข เช่น 15 HOUR ทำซ้ำในอีกทุกๆ 15 ชั่วโมงข้างหน้า
- MINUTE ทุกๆ x นาที เป็นตัวเลข เช่น 5 MINUTE ทำซ้ำในอีกทุกๆ 5 นาทีข้างหน้า
- WEEK ทุกๆ x สัปดาห์ เป็นตัวเลข เช่น 8 WEEK ทำซ้ำในอีกทุกๆ 8 สัปดาห์ข้างหน้า
- SECOND ทุกๆ x วินาที เป็นตัวเลข เช่น 72 SECOND ทำซ้ำในอีกทุกๆ 72 วินาทีข้างหน้า
-- สำหรับค่าในส่วนนี้จะเป็นการกำหนดสองค่า พร้อมกัน เป็นตัวเลข คั่นด้วย : เช่น 5:10
- YEAR_MONTH ทุกๆ x ปี x เดือน เช่น 1:6 YEAR_MONTH ทำซ้ำในอีกทุกๆ 1 ปี 6 เดือน หรือก็คืออีก 18 เดือน
- DAY_HOUR ทุกๆ x วัน y ชั่วโมง
- DAY_MINUTE ทุกๆ x วัน y นาที
- DAY_SECOND ทุกๆ x วัน y วินาที
- HOUR_MINUTE ทุกๆ x ชั่วโมง y นาที
- HOUR_SECOND ทุกๆ x ชั่วโมง y วินาที
- MINUTE_SECOND ทุกๆ x นาที y วินาที
**Start
วันที่เริ่ม event รูปแบบ 0000-00-00 00:00:00 หรือแบบมีไมโครวินาที 0000-00-00 00:00:00.000000
**End
วันที่สิ้นสุด event รูปแบบ 0000-00-00 00:00:00 หรือแบบมีไมโครวินาที 0000-00-00 00:00:00.000000
หากกำหนดส่วนนี้ จะมีความสัมพันธ์กับ การติ้กเลือก On completion preserve ซึ่งหมายถึง เมือถึงกำหนดเวลาสิ้นสุด
แล้ว จะยังให้คง event ที่สร้างไว้หรือไม่ หากไม่ติ้กเลือก event ที่สร้าง จะถูกลบออกอัตโนมัติ เมื่อทำงานเสร็จ
แต่ถ้าติ้กเลือก event ที่สร้างไว้จะยังคงอยู่ ไม่ถูกลบ แม้จะทำงานเสร็จแล้วก็ตาม
หากไม่กำหนดวันสิ้นสุด End ตัว event ก็จะทำงานไปเรื่อยๆ ไม่สิ้นสุด จนกว่าจะปิดหรือลบ event ออก
Definition
กำหนดคำสั่ง SQL ในการทำงาน ตัวอย่าง
INSERT INTO tbl_testcron (test_val,date_val) VALUES ('test',NOW())
กรณีกำหนดหลายคำสั่งพร้อมกัน เช่น เพิ่มข้อมูล แล้วอัพเดท รายการที่เพิ่งเพิ่ม ก็จะเป็น
BEGIN INSERT INTO tbl_testcron (test_val,date_val) VALUES ('test',NOW()); UPDATE tbl_testcron SET test_val=CONCAT(test_val,' ',LAST_INSERT_ID()) WHERE id_cron=LAST_INSERT_ID(); END
On completion preserve
สัมพันธ์กับ End หมายถึง จะยังให้คง event ที่สร้างไว้หรือไม่ หากไม่ติ้กเลือก event ที่สร้าง จะถูกลบออกอัตโนมัติ
เมื่อทำงานเสร็จ แต่ถ้าติ้กเลือก event ที่สร้างไว้จะยังคงอยู่ ไม่ถูกลบ และสถานะ จะเปลี่ยนเป็น DISABLED
ส่วนกรณีที่ Event type เป็น ONE TIME หากไม่ติ้กเลือก ค่านี้ แล้วถ้า event ทำงานเสร็จในเวลาที่ระบุ ก็จะถูกลบออก
ทันที หากติ้กเลือกส่วนนี้ event ก็จะยังคงอยู่
Definer
ผู้ใช้ที่สร้าง event
Comment
หมายเหตุ หรือคำอธิบายที่ต้องการกำหนดเพิ่มเติมเพื่อช่วยจำ event ที่สร้างใช้ทำอะไร กำหนดหรือไม่ก็ได้
ในการกำหนดผ่านหน้าต่างสร้าง event ใหม่นี้ เราไม่ต้องระบุ Definer ก็ได้ เพราะจะเป็นการดึงค่า ผู้ใช้ในขณะนั้นเป็นผู้สร้าง
สำหรับ Start ถ้าเราไม่กำหนด ระะบจะใช้ค่าวันที่เวลาปัจจุบันในตอนนั้น ซึ่งจะมีผลต่อการกำหนด ช่วงเวลาที่เหมาะสมอาจไม่
ตรงตามต้องการ ยกตัวอย่าง สมมติเราต้องการทำงานทุก วินาทีที่ 0,5,10 ,15....55 เวลาเรากำหนดค่าใน **Execute every
ก็จะใช้เป็น 5 SECOND แล้วถ้าเราไม่กำหนดวันที่เวลา Start ปรากฎว่าวันที่ในขณะนั้นเป็น
2019-03-19 12:00:01 เมื่อเพิ่มค่าอีกทุกๆ 5 วินาที ก็จะทำซ้ำอีกครั้งที่เวลา 2019-03-19 12:00:06 ซึ่งไม่ตรงตามช่วง
เวลาที่เราต้องการ ดังนั้น เราควรกำหนด Start เข้าไปด้วยเป็น 2019-03-19 12:00:00
อีกหนึ่งปัญหาที่พบ ในการกำหนดแบบวิธีที่ 1 นี้คือ ถ้าต้องกำหนดเป็นแบบ 2 ค่า เช่น '1:5' MINUTE_SECOND เมื่อเรากรอก
1:5 เข้าไปในส่วนของ **Execute every ปรากฏว่า phpMyAdmin กำหนดค่าไม่ถูกต้องตอนทำคำสั่ง ดังนั้น ก็กรณีกำหนดแบบ
สองค่า ให้ใช้วิธีที่ 2 ที่อธิบายในหัวข้อต่อไปแทน
ตัวอย่างการเพิ่ม event ให้เพิ่มข้อมูลทุกๆ 10 วินาที
หลังจากเราเพิ่ม event แล้ว ก็จะปรากฎตาราง event ที่เราได้สร้าง เราสามารถแก้ไข
ส่งออก หรือลบ event ที่สร้างได้ในส่วนนี้ สมมติเรากดแก้ไข จะได้เป็น
สังเกตส่วนของ Definer ที่เราไม่ได้กรอกให้ตอนสร้าง ค่าที่ขึ้นมา ให้แก้ไข ก็จะเป็นค่าของผู้ใช้ในตอน
สร้างขณะนั้น เราสามารถแก้ไขค่าต่างๆ ในหน้าต่างนี้ได้ หรือจะปิดเป็น DISABLED ไม่ให้ทำงานก็ได้
ถ้าเราต้องการดููคำสั่ง SQL ในการสร้าง event ที่เราสร้าง ก็สามารถกด export ก็จะได้ชุดคำสั่ง ที่เราสามารถ
นำมาปรับแก้เป็นค่าที่ต้องการได้
ผลลัพธ์ จะเห็นว่า ตาราง tbl_testcron จะมีการเพิ่มข้อมูลมาทุกๆ 10 วินาที
วิธีที่ 2 เพิ่มโดยกำหนดคำสั่ง SQL
สำหรับวิธีการเพิ่ม event ในวิธีนี้ จะทำให้เราปรับค่าได้มากขึ้น และรองรับการกำหนด ค่าในส่วนหน่วยเวลาสองค่าพร้อมกันได้
เช่น '1:2' MINUTE_SECOMD โดยเราต้องไปเพิ่ม event ในส่วนแท็บ SQL และใช้ชุดคำสั่งดังต่อไปนี้
CREATE EVENT Syntax
CREATE [DEFINER = { user | CURRENT_USER }] EVENT [IF NOT EXISTS] event_name ON SCHEDULE schedule [ON COMPLETION [NOT] PRESERVE] [ENABLE | DISABLE | DISABLE ON SLAVE] [COMMENT 'string'] DO event_body; schedule: AT timestamp [+ INTERVAL interval] ... | EVERY interval [STARTS timestamp [+ INTERVAL interval] ...] [ENDS timestamp [+ INTERVAL interval] ...] interval: quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE | DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}
ตัวอย่างคำสั่ง กรณี ONE TIME
CREATE DEFINER=CURRENT_USER EVENT `EV1` ON SCHEDULE AT '2019-03-19 23:47:59' ON COMPLETION PRESERVE DISABLE DO INSERT INTO tbl_testcron (test_val, date_val) VALUES ('test',NOW())
กรณี ONE TIME แบบ มีคำสั่ง SQL มากกว่า 1 คำสั่ง ON
delimiter | CREATE DEFINER=CURRENT_USER EVENT `EV1` ON SCHEDULE AT '2019-03-19 23:47:59' ON COMPLETION PRESERVE DISABLE DO BEGIN INSERT INTO tbl_testcron (test_val,date_val) VALUES ('test',NOW()); UPDATE tbl_testcron SET test_val=CONCAT(test_val,' ',LAST_INSERT_ID()) WHERE id_cron=LAST_INSERT_ID(); END | delimiter ;
สังเกตว่า กรณีมีคำสั่ง SQL มากกว่า 1 คำสั่ง เราจำเป็นต้องกำหนด ตัวคั่น โดยใช้ delimiter ในรูปแบบ
delimiter | # แทรกคำสั่งในการสร้าง event | delimiter ;
หากไม่กำหนดัวคั่น จะทำให้เกิด error ขึ้น ทำให้ไม่สามารถสร้าง event ด้วยคำสั่ง sql ได้
ข้างตัน เราใช้ | เป็นตัวคั่น ในการที่จะเลือกว่าควรใช้สัญลักษณ์ใดๆ นั้น ให้พิจารณาว่า ในคำสั่งสร้าง event ที่เราจะ
แทรกเข้ามา ต้องไม่มีเครื่องหมายดังกล่าว
ตัวอย่างการใช้ตัวคั่นรูปแบบอื่นๆ เช่น
delimiter $$$ # แทรกคำสั่งในการสร้าง event $$$ delimiter ;
ตัวอย่างคำสั่ง กรณี RECURRING
CREATE DEFINER=CURRENT_USER EVENT `EV1` ON SCHEDULE EVERY 10 SECOND STARTS '2019-03-19 12:00:00' ENDS '2019-03-19 23:00:00' ON COMPLETION PRESERVE ENABLE COMMENT 'เพิ่มรายการทุกๆ 10 วินาที' DO INSERT INTO tbl_testcron (test_val, date_val) VALUES ('test',NOW())
กรณี RECURRING แบบ มีคำสั่ง SQL มากกว่า 1 คำสั่ง และกำหนดเวลาแบบมี สองค่า '1:2' MINUTE_SECOND
delimiter | CREATE DEFINER = CURRENT_USER EVENT `EV1` ON SCHEDULE EVERY '1:2' MINUTE_SECOND STARTS '2019-03-19 12:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN INSERT INTO tbl_testcron (test_val,date_val) VALUES ('test',NOW()); UPDATE tbl_testcron SET test_val=CONCAT(test_val,' ',LAST_INSERT_ID()) WHERE id_cron=LAST_INSERT_ID(); END | delimiter ;
ในตัวอย่างจะเห็นว่าเรามีการกำหนดเวลาทำซ้ำแบบ 2 ค่าคือ MINUTE_SECOND โดยใช้รูปแบบค่าเป็น
'1:2' MINUTE_SECOND ซึ่งมีค่าเท่ากับ 1 นาที กับอีก 2 วินาที หรือก็คือ 62 วินาที
การใช้ฟังก์ชั่น DATETIME ใน mySQL ในการกำหนดวันที่
ด้วยรูปแบบการใช้งานสร้าง event โดยใช้คำสั่ง SQL ทำให้เราสามารถใช้ฟังก์ชั่นในการกำหนดวันที่และเวลาที่ต้องการ
แทนการกำหนดค่าในรูปแบบเต็มได้ เช่น สมมติวันนี้วันที่ 20 มีนาคม เราต้องการให้ เริ่มที่วันที่ 23 เวลาเดียวกันนี้ ก็จะใช้เป็น
ON SCHEDULE AT NOW() + INTERVAL 3 DAY
ถ้าขณะนี้เวลา 12:00:00 ค่าจากคำสั่งด้านบนก็จะสร้างวันที่แล้วเวลาเป็นค่าเท่ากับ
ON SCHEDULE AT '2019-03-23 12:00:00'
ค่าอื่นๆ
CURDATE()+INTERVAL 1 DAY // จะได้เป็น 2019-03-21 00:00:00 CURDATE()+INTERVAL 1 DAY + INTERVAL 8 HOUR // จะได้เป็น 2019-03-21 08:00:00 CURDATE()+INTERVAL 1 DAY + INTERVAL 8 HOUR + INTERVAL 30 MINUTE // จะได้เป็น 2019-03-21 08:30:00
ปรับแต่งค่าได้ตามต้องการ โดยสามารถไปใช้ในส่วนของการกำหนด Start และ End ได้ด้วย เช่น
ON SCHEDULE EVERY 10 SECOND STARTS CURDATE()+INTERVAL 1 DAY + INTERVAL 8 HOUR ENDS CURDATE()+INTERVAL 1 DAY + INTERVAL 12 HOUR
เท่ากับ ให้เริ่มพรุ่ง 8 โมงเช้า ถึงเที่ยง ทุกๆ 10 วินาที
การแก้ไข เปลี่ยนแปลงค่า Event
เราสามารถใช้รูปแบบ ดังต่อไปนี้ในการแก้ไข Event
ALTER EVENT Syntax
ALTER [DEFINER = { user | CURRENT_USER }] EVENT event_name [ON SCHEDULE schedule] [ON COMPLETION [NOT] PRESERVE] [RENAME TO new_event_name] [ENABLE | DISABLE | DISABLE ON SLAVE] [COMMENT 'string'] [DO event_body]
การเปลี่ยนชื่อ Event
ALTER EVENT EV1 RENAME TO EV2
การ DISABLED หรือ ENABLED พร้อมกับเปลี่ยนชื่อกลับ
ALTER EVENT EV2 RENAME TO EV1 DISABLE
การให้ทำคำสั่งใดๆ เมื่อถึงเวลาที่กำหนด เข่น แก้ไขให้ทำคำสั่งใหม่เป็น พรุ่งนี้ 8 โมงให้ล้างข้อมูลตาราง tbl_testcron
ALTER EVENT EV1 ON SCHEDULE AT CURDATE()+INTERVAL 1 DAY + INTERVAL 8 HOUR DO TRUNCATE TABLE tbl_testcron
ทั้งหมด เป็นแนวทางในการใช้งาน Event Scheduler สามารถนำไปปรับประยุกต์ใช้งานเพิ่มเติมได้
นอกจากความเข้าใจในการกำหนดรูปแบบเวลาในการทำงาน ให้สอดคล้องกับช่วงเวลาที่ต้องการแล้ว สิ่งสำคัญก็คือ
การใช้คำสั่ง SQL ได้อย่างถูกต้องและครอบคลุม ก็จะทำให้เรานำความสามารถของ Event Scheduler ไปใช้ได้อย่าง
มีประสิทธิภาพ หวังว่าเนื้อหานี้ จะเป็นแนวทางเพื่อปรับใช้ได้ไม่มากก็น้อย