AccuracySec في مؤقتات systemd — الانحراف الذي لم يقسه أحد
مؤقتات systemd تتأخر عمدًا — الافتراضي AccuracySec=1min يجمع الاستيقاظات في دفعة، مقيسًا: 10 إطلاقات غدت 5 على صندوق خامل، وكل علامة أصيبت بجانب جار مشغول.
AccuracySec في مؤقتات systemd هو البحث الذي يوصلك إلى هنا، لأن مؤقتك OnCalendar=*:0/15 يواصل الإطلاق عند :07 من الدقيقة وjournalctl -u يقول إن كل شيء على ما يرام. وكل شيء فعلًا على ما يرام — لقد زح systemd استيقاظك عمدًا. هذه التدوينة هي النسخة المقيسة: ما الذي يمنحك إياه الافتراضي، وما الذي يكلّفك إياه، والسطر الوحيد الذي يعيد إليك جدولك.
لجعل مؤقت systemd يطلق في موعده بالضبط: اضبط
AccuracySec=1s(أو أقل) في قسم[Timer]بالمؤقت. الافتراضي دقيقة واحدة — يحاذي systemd كل استيقاظ إلى شبكة خشنة ويطلق متأخرًا حتى 60 s كي يجمع عدة مؤقتات في استيقاظ CPU واحد. تحقق من التأخير الحقيقي بـsystemctl show your.timer -p LastTriggerUSec— يتحدّث عند كل إطلاق.
آخر اختبار 2026-11-14 · systemd 262 (262.1-1-arch) · آلة Arch افتراضية جديدة. كل مؤقت أدناه اشتغل فعلًا؛ وكل إيصال منقول من الصندوق كما هو.
*:*:00/15)، والمؤقت نفسه، وصندان. خامل: تتجمّع عشر علامات في خمسة إطلاقات — النافذة تبتلع كل علامة ثانية. جار مشغول: كل علامة تهبط على موعدها، لأن استيقاظًا موجودًا سلفًا داخل النافذة.لماذا يطلق مؤقت systemd لديّ متأخرًا؟
جملة الأطروحة: المؤقت الافتراضي في systemd قد يطلق حتى 60 ثانية بعد موعده المجدول، وlist-timers يسمّي ذلك «الإطلاق التالي» بلا اعتراض. ليست علّة ولا انحراف ساعة — إنه AccuracySec، افتراضيه 1min، ووظيفته كلها أن تتيح للمجدول التأخر.
$ sudo systemctl show accA.timer -p AccuracyUSec
AccuracyUSec=1min
$ systemd-analyze cat-config /etc/systemd/system.conf 2>/dev/null | grep -i DefaultTimerAccuracy
#DefaultTimerAccuracySec=1min
تحقق: منقول من آلة المنصّة — Arch أصلي بلا إعداد مستخدم، فيبلّغ المؤقت الافتراضي المُجمَّع. وانتبه إلى هجاء الخاصية: ملف الوحدة يقول AccuracySec=، ويكشفها systemd 262 باسم AccuracyUSec.
الآلية، في فقرة واحدة: حين يحين زمن إطلاق المؤقت لا يوقظ systemd الـ CPU فورًا. إنه يحسب نافذة — من اللحظة المجدولة إلى AccuracySec بعدها — ويطلق في أي نقطة داخلها تتيح له تقاسم الاستيقاظ مع مؤقتات أخرى، أو مدّ نوم الـ CPU. تقويمك *:0/15 يقول «أربع مرات في الدقيقة»؛ ويسمعه المجدول «أربع فرص لركوب مشترك» — وعلى صندوق هادئ يأخذ واحدة منها تقريبًا.
كم يتأخر الافتراضي، مقيسًا؟
التجربة، في فقرة واحدة: مؤقت مجدول OnCalendar=*:*:00/15 — أربعة إطلاقات مقصودة في الدقيقة — بدقة المصنع، شُغِّل مرتين على آلة Arch الافتراضية الجديدة نفسها. مرة وحده على صندوق خامل، ومرة بجانب مؤقت مشغول كل ثانيتين. كل إطلاق يسجّل زمن تنفيذه الحقيقي؛ والإيصالات هي الأختام الزمنية الخام.
الصندوق الخامل أولًا — الظروف التي يعيش فيها معظم مؤقتات الصيانة الروتينية فعلًا:
accA 1794634092.128787380
accA 1794634125.384544834
accCo 1794634125.384546104 ← co-timer mark was :30 of the previous minute
accA 1794634152.127459587
accCo 1794634186.135416303 ← co-timer mark was :30 of the previous minute
accA 1794634186.135424133
accA 1794634212.133508500
تحقق: مرّت 10 علامات، واشتغلت الخدمة 5 مرات — فجوات 26–34 s (المتوسط 30.0) على تقويم يقول كل 15. وبالقياس إلى أقرب علامة هبط كل إطلاق متأخرًا 12.1 و0.4 و12.1 و1.1 و12.1 s: نصف الجدول، مُجمَّعًا على خمسة استيقاظات.
المؤقت نفسه، والتقويم نفسه — جار مشغول واحد (مؤقت كل ثانيتين، AccuracySec=1us):
accA sched=1794633795101333 mono=193094591 exec=1794633795.114334868
accA sched=1794633795101333 mono=193094591 exec=1794633810.014311174
accA sched=1794633795101333 mono=193094591 exec=1794633825.116389742
⋮ (6 fires, 6 marks — every one on its mark)
تحقق: مع استيقاظ مخطَّط له كل ثانيتين سلفًا، يقع كل واحد من تلك الاستيقاظات داخل نافذة الـ 60 ثانية للمؤقت الافتراضي — فيطلقه المجدول عند أول استيقاظ متاح: على العلامة، متأخرًا 119 ms في أسوأ الأحوال. الرخاء ما انكمش؛ بل أُنفِق على جدول الجار.
ذلك الزوج من الإيصالات هو الآلية كلها في شاشة واحدة: النافذة عرضٌ لا موعد نهائي — يمكن لـ systemd أن يطلق في أي لحظة داخلها، وهو يطلق عند أقرب استيقاظ CPU تغطيه النافذة. صندوق مشغول: استيقاظ موجود فورًا، فيبدو مؤقتك دقيق الموعد. صندوق هادئ: لا استيقاظ موجود، فيخطط المجدول واحدًا عند الحافة البعيدة للنافذة، ويركب كل إطلاق في الطابور داخلها ذلك الاستيقاظ. الحواسيب الخاملة والخوادم المعزولة — حيث يعمل معظم بدائل cron — هي الحالة الهادئة. ولهذا نجد الوحدة نفسها «سليمة على حاسوبي المكتبي، متأخرة على الـ NAS».
ماذا يغيّر AccuracySec فعلًا؟
التقويم نفسه، والآلة نفسها، وسطر واحد: AccuracySec=100ms. صارت نافذة الاستيقاظ بعرض عُشر الثانية، وليهبط المؤقت حيث أشار التقويم:
accB 1794634230.114374054
accB 1794634245.119370330
accB 1794634260.114446983
تحقق: ثلاثة إطلاقات، ثلاث علامات — متأخر 116 ms في المتوسط، و119 ms في أسوأ الأحوال، والنافذة 100 ms؛ والزائد عليها ~15 ms رخاوة إرسال تحملها كل آلة افتراضية. ذاك هو القرص كله: عرض النافذة، لا شيء غيره.
والتجميع نفسه مرئي في المؤقت الشريك. المجدول عند :30 بدقة الافتراضي على الصندوق المشغول لم ينتظر نافذة كاملة قط — أطلق بعد علامته بـ 15 ms، راكبًا الاستيقاظ الذي كان يصنعه مؤقت الـ 15 ثانية المجاور أصلًا. مؤقتان، استيقاظ واحد:
accCo sched=1794633810000832 mono=207994091 exec=1794633810.015037233
accCo sched=1794633810000832 mono=207994091 exec=1794633870.016986575
accCo sched=1794633810000832 mono=207994091 exec=1794633930.020077789
(accA exec at the same instants: 1794633795.114, 1794633810.014 …)
تحقق: علامة الشريك :30 هي أيضًا علامة من علامات مؤقت الـ 15 ثانية — الاستيقاظ عند :30.000 كان مخطَّطًا سلفًا، فانضم إليه الشريك متأخرًا 15 ms. وعلى الصندوق الخامل فعل الحيلة نفسها بلا جار عند :30، هابطًا على استيقاظ المؤقت A ضمن 1.2 µs (الإيصال أعلاه). النافذة نفسها، وركوبٌ أذكى.
«systemd ليس متأخرًا. إنه ركوب مشترك — استيقاظ واحد في الدقيقة، وأربعة ركاب. والـ AccuracySec هو درجة امتلاء الحافلة المطلوبة.»
كيف تجعل مؤقتًا يطلق في موعده؟
سطر واحد في قصاصة drop-in، بلا إعادة تشغيل لشيء سوى وحدة المؤقت:
$ sudo systemctl cat accB.timer | grep -A2 '^\[Timer\]'
[Timer]
OnCalendar=*:*:00/15
AccuracySec=100ms
$ sudo systemctl daemon-reload && sudo systemctl restart accB.timer
$ sudo systemctl show accB.timer -p AccuracyUSec,LastTriggerUSec
AccuracyUSec=100ms
LastTriggerUSec=Sat 2026-11-14 05:33:45 UTC
تحقق: systemctl show يطبع النافذة الفعّالة — القصاصة drop-in تغلب الافتراضي المُجمَّع، وLastTriggerUSec يتحدّث عند كل إطلاق. إيصال ما قبل/ما بعد هو استعلام واحد، بلا حفر في السجل.
إلى أي حد تخفض: شغّل المؤقت C قيمة AccuracySec=1us على تقويم كل ثانيتين وفاء بـ 11 إطلاقًا في 22 s مع اهتزاز لا يتجاوز 23 ms في أسوأ الأحد عشر — جدولة دون الميلي ثانية متاحة إن أردتها. لكن انظر عمود الثمن قبل أن تعتمدها في كل مؤقتاتك:
ماذا تكلفك الدقة؟
الصندوق الخامل وفى بعشر علامات بخمسة استيقاظات؛ ومؤقت الـ 1 µs كان سيطلب خمسة وسبعين في النافذة نفسها. على المحمول، ذاك هو الفارق الذي بُني الافتراضي ليتجنّبه — التجميع ليس كسلًا، بل هو انضباط الطاقة نفسه الذي يجمع تفريغات القرص. الخوادم لا تبالي؛ وبطاريتك تبالي. درجات معقولة: 1s للمواعيد النهائية التي يلحظها البشر، و1min (الافتراضي) لأشغال الصيانة التي لا يلحظها أحد، ولا شيء تحت 100ms إلا إذا قست السبب — وعندها تتفوق خدمة طويلة الأمد بحلقة نوم على سرب مؤقتات. و1us على محمول هو كيف تحوّل بطارية إلى مِدفأة يدين.
القرص، بنظرة واحدة
| AccuracySec | التقويم | المجدولة | المنطلقة | ماذا حدث |
|---|---|---|---|---|
1min (الافتراضي) | *:*:00/15، صندوق خامل | 10 | 5 | فجوات 26–34 s، متوسط 30.0 — نصف الإطلاقات |
1min (الافتراضي) | *:*:00/15، جار مشغول | 6 | 6 | كل علامة، متأخرة ≤119 ms |
100ms | *:*:00/15 | 3 | 3 | كل علامة، متأخرة ≤119 ms |
1us | *:*:00/2 | 11 | 11 | كل علامة، متأخرة ≤22.7 ms |
وصفة المنصّة — أعد إنتاج هذه الإيصالات على أي آلة افتراضية
يصلح أي مؤقت خدمته تسجّل زمن بدئها بنفسها: ExecStart=/bin/sh -c 'echo timer-run $(date +%%s.%N) >>/var/lib/stamps.log' (اهرب من %% في ملفات الوحدات). شغّل مؤقتًا واحدًا OnCalendar=*:*:00/15 بدقة المصنع على صندوق خامل لدقيقتين — عُدّ الإطلاقات؛ ثم أضف جارًا *:*:00/2 وشاهد العلامات تستقيم. قارن إطلاقًا بإطلاق عبر systemctl show your.timer -p LastTriggerUSec الذي يتحدّث عند كل إطلاق. أما متغيّرا البيئة TRIGGER_TIMER_REALTIME_USEC/_MONOTONIC_USEC داخل الخدمة فيحملان ختم تنشيط وحدة المؤقت، لا جدول كل إطلاق — فلا تستخدمهما لهذا.
مقيسًا: آلة Arch افتراضية جديدة واحدة (systemd 262، 262.1-1-arch، نواة 7.2.11-arch1-1) — المؤقت نفسه *:*:00/15 شُغِّل خاملًا وبجانب جار مشغول، إضافة إلى تجريبات دقة 100 ms و1 µs؛ والإيصالات أختام date +%s.%N خام منقولة بلا تحرير. وفحص سقف journald في تدوينة الأسبوع الماضي «استخدام journalctl للقرص — التفريغ مؤقت، SystemMaxUse يسدّ» (2026-11-13) اشتغل من مؤقت يشبه حالة الخامل تمامًا — وهكذا كسبت هذه المنصّة مكانها في الجدول.
منصّة موثّقة يدويًا · systemd 262 (262.1-1-arch) · آلة Arch افتراضية جديدة · آخر اختبار 2026-11-14
سطرٌ واحد يضبط جدولك — AccuracySec=1s. إيصالٌ واحد يثبته — LastTriggerUSec.