software timestamp что это

Как работать с метками времени (timestamp) в PostgreSQL?

Тема работы с временными метками в PostgreSQL плохо раскрыта в русскоязычных профильных публикациях в Интернете и служит частым источником проблем в работе программистов. Предлагаю вашему вниманию перевод материала от Hubert Lubaczewski, автора популярного зарубежного блога depesz.com. Надеюсь, статья будет для вас полезна!

software timestamp что это. Смотреть фото software timestamp что это. Смотреть картинку software timestamp что это. Картинка про software timestamp что это. Фото software timestamp что это

Время от времени в IRC или в почтовых рассылках кто-нибудь задает вопросы, которые показывают глубокое непонимание (или недостаток понимания) меток времени, особенно тех, которые учитывают часовые пояса. Так как я уже сталкивался с этим ранее, позвольте мне рассказать, что такое timestamps, как с ними работать и с какими наиболее распространенными загвоздками вы можете столкнуться.

У нас есть два типа данных, которые мы можем использовать:

Давайте представим, что у вас есть временная метка “2014-04-04 20:00:00″. О чем она вам говорит? К сожалению, не о многом. Всё зависит от того, о какой точке планеты идет речь. Восемь вечера 4-го апреля – это разный момент времени в Лос Анджелесе, Чикаго, Лондоне, Варшаве или Москве. В этом проблема часовых поясов.

Конечно, вы можете подумать: «Я всегда буду в одном часовом поясе, мне не нужно заморочек с поддержкой разных временных зон. В моем часовом поясе даты и времени будет вполне достаточно, чтобы отметить какой-либо момент времени, ведь именно так мы делаем в «реальной жизни».

Но так ли это на самом деле?

Представим, что у вас есть метка ‘2013-10-27 02:00:00′, и вы знаете, что ваше приложение привязано к польскому времени. В этом случае, вам уже не повезло, потому что это может быть 2 часа ночи по центрально-европейскому летнему времени (CEST) или на час больше, по обычному центрально-европейскому времени. Всё из-за сезонного перевода часов.

Я считаю, что использование временных меток без часового пояса почти всегда является багом, и его нужно исправлять. Проблем становится еще больше, если, записи в вашем приложении поступают из разных часовых поясов (например, приложение-планировщик).

Так что самое очевидное решение – использовать метки времени с часовыми поясами (timestamptz).

Во-первых, это не займет больше места на диске:

Как же это работает? Метка должна знать часовой пояс, так почему же для этого не требуется больше места?

Дело в том, что она не знает часовой пояс. Внутри, все значения в колонках timestamptz указаны в формате UTC (всемирное координированное время).

У UTC есть приятные особенности: у него нет смещения (он сам является отправной точкой, от которой считаются смещения других часовых поясов), и у него нет разницы между летним и зимним временем. Так что любая временная метка в формате UTC всегда гарантированно указывает только на одну точку во времени.

Но если всё время указывать по UTC, то как я узнаю время в нужном мне часовом поясе?

Каждый раз, когда речь идет о значениях timestamptz, если часовой пояс не указан, то PostgreSQL использует заранее сконфигурированное время. И вы можете конфигурировать его разными способами:

Следующие два способа меняют значение по-умолчанию для выбранной базы данных и пользователя.

Последний способ можно использовать, если вы хотите, чтобы ваше соединение с базой данных работало с иными настройками.

Примите во внимание, как при этом меняется вывод now():

Так что каждый раз, когда вы просматриваете или меняете значения timestamptz, PostgreSQL конвертирует их в/из UTC.

Это значит, что значения можно легко сравнивать (все они в одном часовом поясе, нет сдвигов на летнее или зимнее время, так что сравнение всегда возможно).

Что произошло? Почему не показывается 8 вечера?

Причина проста – в запрос я вставил timestamp в каком-то часовом поясе. Внутри, метка была сконвертирована в UTC, а затем, снова сконвертирована (возможно, даже без UTC, я не уверен) в мой обычный часовой пояс, которым является:

Если бы у меня был установлен часовой пояс Лос Анджелеса, то результат запроса был бы таким:

Важно понимать, что выводимое значение всегда принимает во внимание настройку часового пояса.

Есть еще один способ получить 20:00 в Лос Анджелесе:

Очень важно добавлять “::timestamp» после значения, иначе мы получим что-то странное:

Что здесь произошло? Откуда взялось 11:00?

Значение в кавычках (2014-04-04 20:00:00) воспринимается как timestamptz, что значит 8 вечера в моём часовом поясе:

И только после перевода значения в мой часовой пояс PG считывает “at time zone …», которая используется для отображения времени в выбранном часовом поясе.

Таким образом, timestamp at time zone выдаёт значение timestamptz, которое показывает момент, когда местное время в выбранном часовом поясе было таким, как указано в команде.

А timestamptz at time zone выдаёт значение timestamp, которое показывает, каким было время в выбранном часовом поясе в указанный момент времени.

Это звучит немного путанно, поэтому давайте я приведу примеры:

Интересно то, что мы можем использовать это для перевода времени из одного часового пояса в другой, даже если Pg не находится ни в одном из них.

Допустим, мы хотим узнать, который час в Лос Анджелесе, когда в Москве — 8 утра. Моё местное время следующее:

Пользы от него мало.

Для начала нам нужно определить точку во времени (в формате timestamptz), которая показывает 8 утра в Москве:

Это говорит мне о том, что она соответствует 6 утра в моём часовом поясе. Но мы хотим узнать время в Лос Анджелесе. Я мог бы написать ‘2014-04-04 06:00:00+02′ в часовом поясе ‘LA’, но можно сделать по-другому:

Надеюсь, теперь вам всё ясно. Я сам довольно долго пытался разобраться в этом вопросе, и наконец-то всё понял 🙂

У всего этого есть один интересный побочный эффект: не так-то просто добавить индексы к функциям, работающим с timestamptz. Например, вы не можете создать индекс, который будет использоваться для получения дня недели:

Как показано в примере выше, причина очень проста – одна и та же точка во времени может относиться к разным дням недели в зависимости от часового пояса. А поскольку to_char() использует текущий часовой пояс, он может выдавать разные значения для одних и тех же исходных данных в зависимости от настроек часового пояса в системе:

Одна и та же точка во времени, но разные дни. Это могут быть разные месяцы или даже разные года, в зависимости от того, где это было.

Временная метка (без часового пояса) здесь “проявляет” сильную сторону – так как в ней не указан часовой пояс, её можно спокойно использовать для извлечения информации.

Но мы же знаем, как переводить timestamptz в timestamp. Нужно просто указать ей часовой пояс. Поэтому мы можем попробовать сделать так:

Но, к сожалению, ничего не выходит. Дело в том, что to_char слишком разносторонний. Вы можете использовать to_char вот так:

На этот раз мы получаем другие результаты не из-за часового пояса, а из-за локали.

Правильным решением проблемы индексирования будет написать свою собственную функцию, которая будет вызывать to_char в абсолютно постоянной «среде», а затем ее уже индексировать. Вот так:

А теперь мы можем использовать ее для индексирования:

Это безопасно, потому что сама функция заставляет часовой пояс принимать значение «Poland», и она вызывает to_char таким образом, чтобы игнорировать значение локали (другими словами, в формате to_char нет префикса TM).

Естественно, чтобы воспользоваться этим индексом, все запросы должны также использовать эту функцию:

Еще одна важная вещь при работе с часовыми поясами – получение времени Unix, или так называемой эпохи. В целом, это просто:

Интересно то, что оно не зависит от часового пояса:

Причина, известная не всем, кроется в том, что время Unix всегда принимается в часовом поясе UTC. Это значит, что, когда вы извлекаете эпоху из временной метки timestamp, PG предполагает, что она находится в UTC. Из чего вытекают следующие потенциальные проблемы:

В первом случае Pg получает «точку во времени», которая внутренне конвертируется в UTC (а когда отображается – преобразовывается в мой часовой пояс, +2).

Во втором случае временная метка находится в моём часовом поясе, но предполагается, что это UTC (без конвертации!), и эпоха берется от значения ‘2014-04-04 21:19:01.456205 UTC’, а не ‘2014-04-04 21:19:01.456205+02′.

Короче говоря, старайтесь избегать timestamp и используйте timestamptz.

Последнее, о чём я хотел бы сказать – это не баг или потенциальная проблема, а скорее функциональность, о которой многие не знают.

Как вы видели, PostgreSQL использует timestamp (и timestamptz) с точностью до микросекунд. Многие люди настаивают на том, чтобы точность была только до секунды, хотя лично мне это не нравится.

И timestamp, и timestamptz (и другие виды данных, относящиеся ко времени) могут иметь дополнительную точность (“precision”).

Давайте я приведу простой пример:

Конечно, вы можете использовать это и в таблицах:

Отлично! Вам не нужно менять “now()» или что-либо еще, просто добавьте точность к типу данных, и она всё скорректирует.

Я упомянул, что мне это не нравится. Причина проста – в любой достаточно нагруженной системе секунда – слишком низкий уровень точности. Тем более, что хранение данных с точностью до микросекунды ничего мне не стоит, но может быть полезным. С другой стороны, если данные до микросекунд, то как мне сделать, чтобы значения отображались без долей секунды?

Все просто: я использую (в запросах SELECT) фунуции to_char(), или date_trunc, или даже приведение к типу timestamptz(0):

Более подробно о том, как работать с timestamps, мы собираемся рассказать на конференции PG Day’16 Russia в июле 2016 года! Готовьте свои вопросы, мы постараемся на них ответить.

Источник

Datetime или timestamp

На днях я столкнулся с тем, что многие разработчики не знают в чём отличие типов данных DATETIME и TIMESTAMP в MySQLе, а так же как хранить дату и время, если необходимо учитывать разные часовые пояса для разных пользователей веб-приложения. Поэтому хочу дать ниже разъяснения с пояснениями.

DATETIME
Хранит время в виде целого числа вида YYYYMMDDHHMMSS, используя для этого 8 байтов. Это время не зависит от временной зоны. Оно всегда отображается при выборке точно так же, как было сохранено, независимо от того какой часовой пояс установлен в MySQL. Даю пример:

mysql> create table `dt1` ( col datetime NOT NULL );
mysql> SET @@session.time_zone=’+00:00′;
mysql> select now();
+———————+
| now() |
+———————+
| 2009-06-04 18:13:56 |
+———————+

mysql> insert into dt1 values(now());

mysql> insert into dt1 values(now());

TIMESTAMP
Хранит 4-байтное целое число, равное количеству секунд, прошедших с полуночи 1 января 1970 года по усреднённому времени Гринвича (т.е. нулевой часовой пояс, точка отсчёта часовых поясов). При получении из базы отображается с учётом часового пояса. Часовой пояс может быть задан в операционной системе, глобальных настройках MySQL или в конкретной сессии. Запомните, что сохраняется всегда количество секунд по UTC (универсальное координированное время, солнечное время на меридиане Гринвича), а не по локальному часовому поясу. Пример:

Ещё одно отличие! TIMESTAMP по умолчанию NOT NULL, а его значение по умолчанию равно NOW().

mysql> insert into dt1 values(null);
ERROR 1048 (23000): Column ‘col’ cannot be null
mysql> insert into tm1 values(null);
Query OK, 1 row affected (0.00 sec)
mysql> select * from tm1;
+———————+
| col |
+———————+
| 2009-06-04 18:25:08 |
| 2009-06-04 18:25:26 |
| 2009-06-04 18:32:50 |
+———————+

Дополнение. Для тех, кого смущает использование функции NOW().

Источник

SO_TIMESTAMPING в картинках. Прием пакета

software timestamp что это. Смотреть фото software timestamp что это. Смотреть картинку software timestamp что это. Картинка про software timestamp что это. Фото software timestamp что это

Бывает, что приложению требуется узнать точное время приема или отправки сетевого пакета. Например, для синхронизации часов (см. PTP, NTP) или тестирования задержек в сети (см. RFC2544).

Наивным решением будет запоминать в приложении время сразу после получения пакета от ядра (или перед отправкой ядру):

Ясно, что полученное таким образом время может заметно отличаться от момента, когда пакет был получен сетевым устройством. Для получения более точного времени нужна поддержка от операционной системы, драйвера и/или сетевого устройства.

Начиная с версии 2.6.30 Линукс поддерживает опцию сокета SO_TIMESTAMPING. Она позволяет пользовательскому сокету получать временные метки для отправляемых и принимаемых пакетов. Временные метки могут быть сняты самим ядром, драйвером или сетевым устройством (см. список поддерживающих устройств и драйверов). О том, что это вообще такое и как этим пользоваться, стоит почитать в Documentation/networking/timestamping.txt

В этой статье я расскажу о том, как пакеты доставляются от сетевого устройства пользователю, когда при этом снимаются временные метки, как они доставляются пользователю и насколько они точны. Приведенные примеры кода ядра взяты из версии 4.1.

Начальные знания

struct sk_buff

software timestamp что это. Смотреть фото software timestamp что это. Смотреть картинку software timestamp что это. Картинка про software timestamp что это. Фото software timestamp что это

Самые интересные для нас поля struct skb_shared_info :

struct net_device и struct sock

Мы не станем подробно рассматривать эти структуры. Сейчас достаточно понять, что первая позволяет ядру общаться с устройством, а вторая — с пользовательским сокетом. Для принятого пакета: skb->dev указывает на устройство, которым он был получен; skb->sk на сокет, которому будет доставлен. Для отправляемого — наоборот.

SOFTIRQ

Когда процессор получает прерывание, он вызывает соответствующий ему обработчик. Выполнение обработчика происходит в контексте прерывания — для обслуживающего прерывание процессора почти все прерывания выключены. То есть обработчик прерывания не будет прерван, пока не завершится сам. Чем меньше процессор находится в контексте прерывания, тем скорее он сможет обслужить новые прерывания и отреагировать на события от других устройств.

Несмотря на то, что обработчику прерывания может требоваться много процессорного времени, обычно большая часть его работы может подождать. Именно поэтому действия обработчика прерывания принято разделять на верхнюю(Top Half) и нижнюю(Bottom Half) половины. Top Half в контексте прерывания выполняет срочные действия и планирует для выполнения Bottom Half. Bottom Half будет запущена ядром позже вне контекста прерывания и может быть прервана во время работы другими прерываниями.

SOFTIRQ — Механизм ядра, позволяющий запланировать отложенный вызов функции. Часто используется для реализации Bottom Half. Всего в ядре v4.1 десять разных SOFTIRQ (см. список), обработчики для которых определяются при компиляции ядра. Во время своего выполнения обработчик может быть прерван только аппаратным прерыванием. Для каждого процессора своя маска запланированных SOFTIRQ, т.е обработчик будет вызван на том же процессоре, с которого был запланирован. (На самом деле, можно ухитриться и указать на каком конкретно процессоре запланировать SOFTIRQ.) Одно и то же SOFTIRQ может быть запланировано и
выполнено независимо на двух разных процессорах. При отправке и получении пакетов используются два из них: NET_RX_SOFTIRQ с обработчиком net_rx_action и NET_TX_SOFTIRQ с обработчиком net_tx_action. (см. net_rx_action и net_tx_action)

Прием пакета

Для общения с сетевыми устройствами Линукс использует смесь прерываний и поллинга (polling). (см. NAPI)

Вот как это выглядит:

Top Half

poll_list * — список, создаваемый ядром для каждого ядра процессора(как одно из полей struct softnet_data ). Он хранит устройства, с которых NET_RX_SOFTIRQ предстоит получить пакеты.

Bottom Half

software timestamp что это. Смотреть фото software timestamp что это. Смотреть картинку software timestamp что это. Картинка про software timestamp что это. Фото software timestamp что это

Эта функция проходит по списку poll_list и для каждого устройства dev, пока на нем есть пакеты, вызывает виртуальную функцию драйвера napi->poll (см. include/linux/netdevice.h.), которая:

Стоит отметить, что net_rx_action() позволяет обрабатывать не более netdev_budget (экспортируется в /proc/sys/net/core/netdev_budget ) пакетов за раз и ограничивает время своего выполнения 2/HZ секундами(на x86 по умолчанию HZ = 1000, т.е ограничение времени = 2мс).

netif_receive_skb()

netif_receive_skb() — это функция, начиная с которой пакет попадает из драйвера в ядро. (На самом деле, она просто служит оберткой для других функций, которые и выполняют всю работу.) Посмотрим, что же делает ядро с полученным skb:

Обычно пакет обрабатывается тем процессором, на котором был запланирован SOFTIRQ, а это тот процессор, на который пришло прерывание. Некоторые сетевые карты шлют только одно прерывание только одному процессору, не позволяя распараллелить обработку пакетов на многопроцессорных системах. Для решения этой проблемы был придуман Receive Packet Steering (RPS).

__netif_receive_skb_core()

Прежде всего эта функция снимает временную метку, если она не была снята в netif_receive_skb_internal() :

Теперь мы имеем skb, который содержит:

Остается доставить его всем желающим получателям.

В зависимости от требуемого L3 протокола и устройства получатели могут регистрироваться в нескольких местах:

Частые пользователи всех 4-х списков — AF_PACKET сокеты, каждый из них при системном вызове bind регистрирует в соответствующем списке обработчик. (Обработчика зовут packet_rcv ) На самом деле есть еще куча получателей, но мы ограничимся только теми, которые доставляют пакет сокетам в пространстве пользователя.

Важное различие: ip_recv зарегистрирована как обработчик всего один раз в ptype_base сколько бы AF_INET сокетов вы не создали, а packet_rcv регистрируется для каждого AF_PACKET сокета по разу в каком-нибудь из списков.

Тестирование Задержек

Мы видели, что для принимаемых пакетов дважды снимаются временные метки: сетевой картой(Thard), ядром сразу при получении (Tsoft). Подводя итог, посмотрим чем вызываются задержки между ними и моментом доставки пакета пользователю(Tuser):

Если за один вызов NET_RX_SOFTIRQ не удалось обработать наш пакет(был превышен netdev_budget или ограничение по времени 2/HZ), то ядро позволит выполняться другим процессам, пока аппаратное прерывание или ksoftirqd снова не вызовут `do_softirq()`. Также не стоит забывать о том, что есть и другие SOFTIRQ, на выполнение которых тоже уходит время.

В зависимости от того, что это за сокеты, доставка может занимать разное время.

Чтобы примерно оценить, насколько велики эти задержки и насколько они предсказуемы, воспользуемся программой rxtest. Эта программа:

Проверка проводилась на Core i7 с Linux 4.0 с сетевой картой Intel 82599ES под управлением драйвера ixgbe.

В моем случае сетевая карта имеет свои аппаратные часы и снимает временные метки по ним. И нет никакой гарантии, что эти часы как-то синхронизированы с jiffies ядра. Для того, чтобы это исправить, запустим программу phc2sys из linuxptp:

Её нужно держать открытой на протяжении всей проверки. Она будет заниматься подстройкой часов сетевой карты под системное время и выводить текущее расхождение часов. В моем случае абсолютное значение расхождения не превышало 10нс.

Это приведет к тому, что сетевая карта будет снимать временные метки для всех пакетов типа Sync протокола PTP. Почему именно Sync PTP? Потому что наша сетевая карта не умеет снимать временные метки для всех пакетов. Ей обязательно нужно указать какой-нибудь тип пакетов протокола PTP. (Это свзязано с тем, что поддержка аппаратных временных меток в Linux была введена для работы протокола PTP, позволяющего синхронизировать время с точностью до наносекунд.)

Тем временем шлем с другого конца кабеля по 10 PTP Sync пакетов в секунду. (Я брал примеры PTP пакетов с https://wiki.wireshark.org/Protocols/ptp и слал их с помощью tcpreplay.)

Результат выполнения rxtest:

При этом тестируемому сетевому интерфейсу не был присвоен ip-адрес и наши пакеты не попадали на обработку протоколом IP. Этим можно объяснить совсем небольшую задержку Tuser — Tsoft.

Адекватного исследования задержек и их зависимости от разных параметров (netdev_budget, частота принимаемых пакетов, нагрузка на процессор, конфигурация ядра, количество и тип открытых сокетов) хватило бы на целую статью. Цель этой статьи — полить воду рассмотреть механизм доставки пакетов и то, чем вызываются задержки.

На этом все. Буду рад любым отзывам и критике.

Источник

Timestamp

Timestamp может ссылаться на time code или digitally signed timestamp, который предназначен для подтверждения существования определённого документа в определённое время, как часть электронной подписи.

Timestamp очень полезен для журналирования событий.

Многие источники также используют термин timestamp, имея в виду POSIX-время, количество секунд прошедшее с 00:00:00 UTC 1 января, 1970 года.

Содержание

История

Идея использования временно́й печати (перевод автора «timestamping») информации актуальна довольно давно. Например, когда Роберт Гук открыл свой закон в 1660 году, он не хотел его публиковать, но хотел иметь право на авторство. Поэтому он сначала выпустил анаграмму ceiiinosssttuv и позднее опубликовал перевод ut tensio sic vis (лат: упругость, как сила). Похожая ситуация случилась с Галилеем, в его исследованиях фаз Венеры сперва была опубликована анаграмма. Современный пример, современной исследовательской организации может позднее понадобиться доказать, что их идея была разработана до определённой даты. Один из способов решения — перенести всё на компьютер и записать в лабораторную тетрадь зашифрованный ключ целостности данных. В дальнейшем, для проверки, что файл в хранилище не изменялся, вам надо будет пересчитать зашифрованный ключ и сравнить его с ключом в лабораторной тетради.

Доверие электронной отметке времени

software timestamp что это. Смотреть фото software timestamp что это. Смотреть картинку software timestamp что это. Картинка про software timestamp что это. Фото software timestamp что это

software timestamp что это. Смотреть фото software timestamp что это. Смотреть картинку software timestamp что это. Картинка про software timestamp что это. Фото software timestamp что это

Электронная отметка — это способ достоверно следить за временем создания и модификации документа. «Достоверно» здесь значит, что никто, даже владелец этого документа, не в состоянии изменить однажды созданную информацию так, чтоб её целостность не нарушилась. Административная сторона включает прозрачную сборку управления отметками времени, их создание и обновление.

Защищённая отметка времени — это отметка, выданная при свидетелях. Trusted third party (TTP) ведёт себя как timestamping authority (TSA). Это используется для подтверждения существования определённых данных до определённого момента времени (контракты, данные исследования, медицинские записи и т. п.) без возможности дописывания задним числом. Сложные TSA могут использоваться для повышения надёжности и уменьшения уязвимости.

Создание временной метки

Эта техника основана на цифровых подписях и хеш-функциях. Сначала хеш вычисляется из данных. Хеш — своего рода цифровая контрольная сумма файла оригинальных данных: другая строка битов для установленных данных. Если оригинальные данные были изменены, то это будет результат полностью в другом хеше. Этот хеш посылается TSA, TSA генерирует timestamp для хеша и вычисляет хеш этого объединения. Этот хеш, например, может быть подписан в цифровой форме с приватным ключом TSA. Этот подписанный хеш и timestamp возвращаются на подписанную сторону timestamp, который хранит их с оригинальными данными (см. диаграмму).

Впоследствии оригинальные данные не могут быть вычислены из хеша (поскольку хеш-функция является функцией в одну сторону (необратимой)), TSA никогда не видит оригинальные данные, которые допускается использовать в этом методе для конфиденциальных данных.

Проверка временной метки

software timestamp что это. Смотреть фото software timestamp что это. Смотреть картинку software timestamp что это. Картинка про software timestamp что это. Фото software timestamp что это

software timestamp что это. Смотреть фото software timestamp что это. Смотреть картинку software timestamp что это. Картинка про software timestamp что это. Фото software timestamp что это

Все, кто доверяет создателю временной метки (TSA), могут убедиться, что документ уже существовал на момент времени, который был представлен создателем. Также является неопровержимым тот факт, что оригинальные данные принадлежали лицу, запросившему электронную отметку времени, именно в момент создания этой электронной отметки. Для доказательства этого (см. диаграмму) вычисляется хеш оригинальных данных, к нему добавляется timestamp, полученный от TSA, и вычисляется хеш этого объединения, назовём его хешем A.

Затем проверяется цифровая подпись TSA путём дешифрования подписанного хеша, полученного от TSA, с помощью открытого ключа TSA. В результате получается дешифрованный хеш, который назовём хешем B. Если хеш A идентичен хешу B, значит, электронная отметка времени не подвергалась изменениям и была выпущена TSA. Если хеши не совпадают, можно утверждать, что либо электронная отметка времени была изменена, либо она не была выпущена TSA.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *