ทำให้ cronjob รองาน rsync ก่อนหน้านี้ให้เสร็จ


11

ฉันใช้ rsync เพื่อสำรองข้อมูลบางอย่างจากเซิร์ฟเวอร์หนึ่งไปอีกเซิร์ฟเวอร์หนึ่ง ทุกอย่างทำงานได้ดี แต่อาจใช้เวลานานกว่าจะเสร็จสิ้นทั้งนี้ขึ้นอยู่กับจำนวนข้อมูลที่มีการถ่ายโอน

มีวิธีการรับประกันเพื่อให้แน่ใจว่าคำสั่ง rsync ไม่เริ่มก่อนที่คำสั่งก่อนหน้านี้จะเสร็จสิ้นโดยใช้ cronjob

ตัวอย่างเช่นทุกชั่วโมงที่ฉันรันคำสั่ง rsync แต่ความเป็นไปได้ที่การถ่ายโอนจะใช้เวลามากกว่า 1 ชั่วโมงจึงจะเสร็จสมบูรณ์ดังนั้นรายการถัดไปจะเริ่มก่อนที่คำสั่งก่อนหน้าจะเสร็จสิ้น


หากงานอาจใช้เวลานานกว่าหนึ่งชั่วโมงในการทำให้เสร็จและคุณกำลังกำหนดเวลาไว้ใกล้กว่าระยะเวลาแสดงว่าคุณกำลังจัดตารางงานผิดพลาด ลองหาวิธีลดเวลาหรือเพิ่มช่วงเวลาระหว่างงาน หากคุณทำการสำรองข้อมูลระยะไกลอย่างต่อเนื่องคุณอาจต้องการพิจารณาแผนการกู้คืนความเสียหายใหม่
vgoff

คำตอบ:


11

คุณสามารถใช้การล็อคบางชนิด สิ่งนี้จะพิมพ์จำนวนกระบวนการ rsync ที่ยังทำงานอยู่:

pgrep -cx rsync

และสิ่งนี้จะเรียกใช้ rsync ต่อเมื่อไม่มีกระบวนการ rsync อื่นอยู่:

pgrep -cx rsync || rsync ...

การใช้-xจะป้องกันไม่ให้ชื่อที่ไม่ต้องการจับคู่โดยไม่ตั้งใจ (เช่น "fooba rsync hronizator" หรือ "not_an_ rsync _totally" - ใช้งานได้เหมือนpgrep -c ^rsync$)


ในกรณีที่ไม่ชัดเจน -c นับจำนวนกระบวนการที่มีชื่อ rsync หากนี่ไม่ใช่ 0 ดังนั้นเชลล์จะตีความผลลัพธ์ว่าเป็นจริง (ไม่ใช่เท็จ) | | | "หรือบรรทัด" ดูไอเท็มแรกเป็นจริงและไม่ต้องรันไอเท็มที่สอง rsync
ปล้น

13

คุณสามารถใช้คำสั่งflockเพื่อช่วยให้คุณทำเช่นนี้ในกรณีflock -nนี้อาจเป็นสิ่งที่คุณต้องการเพราะมันจะทำให้เกิดความล้มเหลวทันทีของคำสั่งถ้ามันไม่ได้ล็อคเช่น

30 * * * *  /usr/bin/flock -n /tmp/myRsyncJob.lck /path/to/your/rsyncScript 

โดยทั่วไปชื่อไฟล์ที่คาดเดาได้ใน / tmp มักเป็นอันตรายเนื่องจากสภาพการแข่งขันและการเข้าถึงไดเรกทอรี / tmp ในวงกว้าง ในกรณีนี้ปลอดภัยหรือไม่?
mc0e

ในกรณีนี้ชื่อที่คาดเดาได้ไม่เพียง แต่จะปลอดภัยเท่านั้น นั่นคือสิ่งที่ทำให้ล็อค (คำนาม) ล็อค (คำกริยา) กล่าวอีกนัยหนึ่งสถานะของการล็อคจะขึ้นอยู่กับไฟล์ที่มีชื่อเฉพาะที่คาดเดาได้ แต่เพียงผู้เดียว หากชื่อไฟล์นั้นไม่สามารถคาดเดาได้หรือถ้ามันเปลี่ยนแบบไดนามิกฝูงก็จะอนุญาตให้ rsync รันทับตัวเองเอาชนะเป้าหมาย อย่างไรก็ตามคุณสามารถลดความกังวลของคุณและ IMO "ถูกต้อง" ได้อีกเล็กน้อยโดยใส่ไฟล์ล็อคไว้ที่อื่นเช่น/var/runแทน
Evan de la Cruz

3

หากคุณยินดีที่จะพิจารณาเครื่องมืออื่น ๆ คุณยังสามารถมีลักษณะที่rdiff สำรอง มันใช้ librsync เพื่อสำรองข้อมูลและบันทึกจำนวนเดลตา / จำนวนที่กำหนดได้ นอกจากนี้ยังล็อกเพื่อให้กระบวนการ rdiff-backup หนึ่งกระบวนการสามารถรันได้ทุกเวลา


ฉันใช้ rdiff-backup เช่นกัน แต่คุณต้องระวังในการตั้งค่านี้เนื่องจากการสำรองข้อมูล rdiff ใช้เวลานานกว่าการทำ rsync เพียงอย่างเดียว
mgabriel

3

นี่คือสิ่งที่ฉันทำ สร้างสคริปต์ตัวหุ้มรอบ rsync เพื่อสร้างไฟล์ล็อค

script 1
- create lock file
- rsync
- remove lock file

script 2 (running later then script 1)
- check if lock file is there
    - if not run
    - if it is there wait 10 minutes in a loop. break out of lopp when the lock file is gone
- continue to run script

2
เพียงให้แน่ใจว่าได้ลบไฟล์ล็อคหลังจากรีบูตมิฉะนั้นคุณอาจจบลงด้วยกระบวนการที่ไม่ทำงานอีกครั้ง
John Gardeniers

2

คำตอบของฉันค่อนข้างเหมือนกับที่ไมค์บอก

ในสคริปต์คุณควรใส่อะไรแบบนี้:

  • สร้างไฟล์ล็อค
  • ตรวจสอบการมีอยู่ของไฟล์ล็อคเมื่อคุณเรียกใช้ในครั้งถัดไป

แต่มีสิ่งสำคัญอย่างหนึ่งที่คุณควรทำ และนั่นคือการใช้ระบบกับดัก

ดังนั้นสิ่งที่คุณสามารถทำได้คือแม้ว่าสคริปต์ของคุณจะถูกฆ่าหรือบางคนถูกฆ่าก็ตามคุณสามารถดักจับสัญญาณนั้นและลบไฟล์ล็อคเพื่อที่คุณจะไม่ได้ไฟล์ล็อคค้าง

คุณสามารถอ่านวิธีการใช้ว่ากว่าที่นี่

มีเพียงสิ่งเล็ก ๆ น้อย ๆ คุณไม่สามารถดักจับสัญญาณ 9 ได้ฉันหมายถึงถ้ามีคนทำkill -9คุณไม่สามารถดักจับสิ่งนั้นได้เนื่องจากสัญญาณนั้นโต้ตอบกับเคอร์เนลโดยตรงและไม่มีวิธีดักจับสิ่งนั้น

นอกจากนี้ตามคำแนะนำของ John คุณจำเป็นต้องลบไฟล์ล็อคทุกครั้งที่ระบบของคุณรีบูตเพื่อให้แน่ใจว่าไม่มีไฟล์เก่า

คุณสามารถทำได้ง่ายๆโดยใส่rm -f <FILE>คำสั่งเล็ก ๆใน /etc/rc.local


1

ดูที่ anacron (anachronistic cron) พร้อมสวิตช์ -s (เป็นอนุกรม) ทำให้เป็นอันดับทำให้แน่ใจว่าคำสั่งจะไม่ถูกเรียกอีกครั้งถ้าคำสั่งก่อนหน้ายังคงทำงานอยู่


คุณอาจเข้าใจผิดคำถาม
John Gardeniers

ฉันไม่คิดอย่างนั้น คำถามคือ "มีวิธีรับประกันใด ๆ เพื่อให้แน่ใจว่าคำสั่ง rsync ไม่เริ่มก่อนที่คำสั่งก่อนหน้านี้จะเสร็จสิ้นโดยใช้ cronjob หรือไม่" Anacron ทำงาน cronjobs ด้วยฟังก์ชันพิเศษ / แตกต่างกัน ทำให้เป็นอันดับทำให้มั่นใจได้ว่าคำสั่งใด ๆ ที่คุณโทรไม่ได้เริ่มจนกว่าคำสั่งก่อนหน้าจะเสร็จสิ้น
tu-Reinstate Monica-dor duh

ขอโทษด้วย. ฉันเป็นคนที่อ่านคำถามผิด
John Gardeniers


0

ฉันไม่สามารถแก้ปัญหาของ mgabriel ให้ทำงานบน OSX ได้เนื่องจาก pgrep เวอร์ชั่น OSX ดูเหมือนจะไม่มีตัวเลือก -c ฉันใช้สิ่งต่อไปนี้แทน:

[ $(pgrep ping | wc -l) -eq 0 ] && ping multiplay.co.uk || echo "Sorry, ping already in progress"

ฉันใช้คำสั่ง ping เป็นตัวอย่าง

หวังว่านี่จะช่วยได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.