
Descobri que após a última inserção do segundo bissexto (31/12/2016 23:59:60), nosso aplicativo CentOS7 que tem threads de trabalho dormindo por 1 segundo entre os trabalhos, começou a despertar os threads adormecidos imediatamente, em vez de em um segundo. Em geral, todos os que dormem acordam 1 segundo antes do horário esperado para acordar.
A solução mais simples e funcional é reiniciar a caixa. Mas isso não é desejável no nosso caso. Existe uma maneira de corrigir isso sem reiniciar?
PS. Para referência, aqui está um programa simples em C++ que reproduz o problema.
#include <boost/date_time.hpp>
#include <boost/thread.hpp>
#include <iostream>
using namespace std;
// this has to be run in a thread to be able to detect the issue
void check_thread()
{
size_t expected_delay = 1000;
cout << "Expected delay: " << expected_delay << " ms" << endl;
boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::universal_time();
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::universal_time();
size_t actual_delay = (t2 - t1).total_milliseconds();
cout << "Actual delay: " << actual_delay << " ms" << endl;
if (abs(expected_delay - actual_delay) > 900) {
cout << "Too big delay difference: " << (expected_delay - actual_delay) << endl;
cout << "Possible leap second issue" << endl;
}
else {
cout << "No issues found" << endl;
}
}
int main()
{
boost::thread_group g;
g.create_thread(check_thread);
g.join_all();
return 0;
}
Prédio:
g++ sleep_test.cpp -Wl,-Bstatic -lboost_thread -lboost_system -lboost_date_time -Wl,-Bdynamic -rdynamic -pthread
Responder1
A hora do seu sistema está sincronizada com ntpd
ou ptp
? Caso contrário, atualize seu tzdata
pacote.
Para sistemas não sincronizados por ntpd ou ptp é necessário um pacote tzdata atualizado que contenha o segundo bissexto de 31 de dezembro. O pacote tzdata atualizado foi lançado como parte do RHEA-2016-1982, e quaisquer sistemas que usam RHEL 7 que não sejam sincronizados por ntpd ou ptp devem ser atualizados para tzdata-2016g-2.el7, ou uma versão posterior, para receber esta correção.
Resolva problemas do Leap Second no Red Hat Enterprise Linux
Responder2
Além do que Troy disse, em sistemas RHEL7 que não atualizaram o tzdata no momento em que o segundo bissexto é aplicado e não executam o ntpd, é necessária uma etapa extra - definir manualmente o tempo 1 segundo à frente e depois revertê-lo:
date -s "+1 sec"
date -s "-1 sec"