Como corrigir o problema de suspensão do segundo bissexto sem reiniciar

Como corrigir o problema de suspensão do segundo bissexto sem reiniciar

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 ntpdou ptp? Caso contrário, atualize seu tzdatapacote.

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"

informação relacionada