Espero que você possa ajudar a explicar esse comportamento ou tentar reproduzir o problema para que eu possa ter certeza de preencher um relatório de bug.
Essencialmente, obtenho resultados diferentes dessas consultas:
# returns 0
select count(*) as COUNT_WITH_INDEX
from a
where id = 1 and begin_time='2018-11-04 01:01:00.000';
# returns 1
select count(*) as COUNT_WITHOUT_INDEX
from a ignore index (PRIMARY)
where id = 1 and begin_time='2018-11-04 01:01:00.000';
A principal diferença é o uso de ignore index (PRIMARY)
.
Caso a data não tenha se destacado para você imediatamente, essa data cai na hora "Atrasar" da transição de horário de verão para o fuso horário 'EUA/Central'. 01:01 ocorreu duas vezes em 2018-11-04. Eu só encontrei problemas com carimbos de data/hora que se enquadram nesta janela, então suspeito que seja um bug com a forma como as regras de horário de verão são aplicadas.
Independentemente de precisar ou não usar convert_tz()
para obter corretamente a data que desejo, ainda há o fato de obter resultados diferentes com e sem o PRIMARY
índice de chave.
Caso de teste completo:
create database if not exists test_dt;
use test_dt;
drop table if exists a;
CREATE TABLE `a` (
`id` int(11) NOT NULL,
`begin_time` timestamp(3) NOT NULL DEFAULT '0000-00-00 00:00:00.000',
PRIMARY KEY (`id`,`begin_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
set TIME_ZONE='+0:00';
insert into a values(1, '2018-11-04 06:01:00.000');
insert into a values(1, '2018-11-04 07:01:00.000');
set TIME_ZONE='US/Eastern';
select * from a;
# returns 0
select count(*) as COUNT_WITH_INDEX
from a
where id = 1 and begin_time='2018-11-04 01:01:00.000';
# returns 1
select count(*) as COUNT_WITHOUT_INDEX
from a ignore index (PRIMARY)
where id = 1 and begin_time='2018-11-04 01:01:00.000';
set TIME_ZONE='US/Central';
# repeat w/ Central if you like
Observação lateral: instale dados de fuso horário para usar fusos horários nomeados.
Testado em:: CentOS 7 com 5.6.36 e 5.6.43. Não tenho instalações 5.7 ou 8.0 à mão.
Outra observação lateral: o problema inicial que encontrei foi que as junções entre tabelas pai-filho não estavam retornando dados com PK composto (id, timestamp). Como os carimbos de data/hora são armazenados no formato UTC, não acho que as datas do horário de verão seriam um problema, mas aqui estou.
Você tem uma explicação para o comportamento? Você acha que é um bug?
Obrigado!
Editar informações adicionais por comentários
Que resultado você obtém se você largar o pk?
set TIME_ZONE='+0:00';
insert into a values(1, '2018-11-04 06:01:00.000');
insert into a values(1, '2018-11-04 07:01:00.000');
select * from a ;
select 'Set time_zone=US/Central' as msg;
set TIME_ZONE='US/Central';
+------------------+
| COUNT_WITH_INDEX |
+------------------+
| 1 |
+------------------+
1 row in set (0.00 sec)
drop index `primary` on a;
select count(*) as COUNT_DROPPED_PK
from a
where id = 1 and begin_time='2018-11-04 01:01:00.000';
+------------------+
| COUNT_DROPPED_PK |
+------------------+
| 2 |
+------------------+
1 row in set (0.00 sec)
set TIME_ZONE='+0:00';
select * from a;
+----+-------------------------+
| id | begin_time |
+----+-------------------------+
| 1 | 2018-11-04 06:01:00.000 |
| 1 | 2018-11-04 06:01:00.000 |
+----+-------------------------+
Aviso Se eu alterar o TZ para US/Central, soltar o PK e, em seguida, definir o TZ de volta para '+0:00', posso ver que os dados estão errados. Ambos os registros são 06:01
tempo, quando um foi inserido07:01
. Esse comportamento não é lógico para mim, pois os carimbos de data e hora devem sempre ser UTC no back-end.
1) Mostrar a saída do set TIME_ZONE='US/Eastern'; selecione * de a; 2) E se definir TIME_ZONE='-4:00';?
set TIME_ZONE='US/Eastern';
select * from a;
+----+-------------------------+
| id | begin_time |
+----+-------------------------+
| 1 | 2018-11-04 01:01:00.000 |
| 1 | 2018-11-04 02:01:00.000 |
+----+-------------------------+
set TIME_ZONE='-4:00';
select * from a;
+----+-------------------------+
| id | begin_time |
+----+-------------------------+
| 1 | 2018-11-04 02:01:00.000 |
| 1 | 2018-11-04 03:01:00.000 |
+----+-------------------------+
Eu tenho uma resposta que eu não gosto:
Isso explica porque obtenho resultados diferentes com e sem índice. Para mim, parece que a implementação está quebrada, mas não sei o que faria para uma correção fácil. /dar de ombros
Felizmente, podemos contornar o problema neste caso, mas estamos reconsiderando como lidar com isso no futuro.