IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 这也能造成故障?MySQL的datetime类型引发的线上问题 -> 正文阅读

[大数据]这也能造成故障?MySQL的datetime类型引发的线上问题

工作经历中见过一些平时很难注意到的细节,从而导致故障的场景。所以新开 这也能造成故障 系列,防微杜渐,安全生产无小事,要敬畏每一行代码。

datetime类型毫秒级四舍五入引发的问题,可能会造成数据写入后,实际读出的时间会多一秒。从而在大流量且对于时间匹配的场景下,极有可能造成资损类型的故障。下面我们来回顾如何发生的?

建立测试MySQL数据表如下:

mysql> describe test_date;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int(11)     | NO   | PRI | NULL    |       |
| date_0 | datetime    | YES  |     | NULL    |       |
| date_3 | datetime(3) | YES  |     | NULL    |       |
| date_6 | datetime(6) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+

插入测试数据:

insert into test_date values (1, '2022-09-30 23:59:59', '2022-09-30 23:59:59','2022-09-30 23:59:59');
insert into test_date values (2, '2022-09-30 23:59:59.000', '2022-09-30 23:59:59.000','2022-09-30 23:59:59.000');
insert into test_date values (3, '2022-09-30 23:59:59.499', '2022-09-30 23:59:59.499','2022-09-30 23:59:59.499');
insert into test_date values (4, '2022-09-30 23:59:59.500', '2022-09-30 23:59:59.500','2022-09-30 23:59:59.500');
insert into test_date values (5, '2022-09-30 23:59:59.998', '2022-09-30 23:59:59.998','2022-09-30 23:59:59.998');
insert into test_date values (6, '2022-09-30 23:59:59.9999', '2022-09-30 23:59:59.9999','2022-09-30 23:59:59.9999');
insert into test_date values (7, '2022-09-30 23:59:59.999989', '2022-09-30 23:59:59.999989','2022-09-30 23:59:59.999989');
insert into test_date values (8, '2022-09-30 23:59:59.999999', '2022-09-30 23:59:59.999999','2022-09-30 23:59:59.999999');
insert into test_date values (9, '2022-09-30 23:59:59.9999899', '2022-09-30 23:59:59.9999899','2022-09-30 23:59:59.9999899');
insert into test_date values (10, '2022-09-30 23:59:59.9999999', '2022-09-30 23:59:59.9999999','2022-09-30 23:59:59.9999999');

再次查询,结果如下:

mysql> select * from test_date;
+----+---------------------+-------------------------+----------------------------+
| id | date_0              | date_3                  | date_6                     |
+----+---------------------+-------------------------+----------------------------+
|  1 | 2022-09-30 23:59:59 | 2022-09-30 23:59:59.000 | 2022-09-30 23:59:59.000000 |
|  2 | 2022-09-30 23:59:59 | 2022-09-30 23:59:59.000 | 2022-09-30 23:59:59.000000 |
|  3 | 2022-09-30 23:59:59 | 2022-09-30 23:59:59.499 | 2022-09-30 23:59:59.499000 |
|  4 | 2022-10-01 00:00:00 | 2022-09-30 23:59:59.500 | 2022-09-30 23:59:59.500000 |
|  5 | 2022-10-01 00:00:00 | 2022-09-30 23:59:59.998 | 2022-09-30 23:59:59.998000 |
|  6 | 2022-10-01 00:00:00 | 2022-10-01 00:00:00.000 | 2022-09-30 23:59:59.999900 |
|  7 | 2022-10-01 00:00:00 | 2022-10-01 00:00:00.000 | 2022-09-30 23:59:59.999989 |
|  8 | 2022-10-01 00:00:00 | 2022-10-01 00:00:00.000 | 2022-09-30 23:59:59.999999 |
|  9 | 2022-10-01 00:00:00 | 2022-10-01 00:00:00.000 | 2022-09-30 23:59:59.999990 |
| 10 | 2022-10-01 00:00:00 | 2022-10-01 00:00:00.000 | 2022-10-01 00:00:00.000000 |
+----+---------------------+-------------------------+----------------------------+

对比测试用例和结果,就很明显了:发生了四舍五入的进位,从而导致插入的时间与查询的时间不匹配。

那么在实际应用中,可能只会具体到时分秒来匹配查询,但是查出来的时间却不一样,这样就会导致后续链路产生问题。

我们再看下 MySQL 文档中对此的描述:
在这里插入图片描述
官方文档链接如下:5.7
插入时间数据的小数位大于字段的精度时,静默四舍五入。所以以后需要注意此类问题。

当然你可能会问:为什么很少见到这个问题呢?

刚才也提到了,大流量且对时间敏感的场景,才有可能发生这个问题。

本次故障引发的逻辑就是:
MySQL中字段为 Datetime(0),不包含小数位。且从时间数值是由前端一路经过各种服务,未经额外加工头传到后端的,一直未出现问题。
但是当前端更换组件时(或调整逻辑),导致了传递的时间参数中毫秒不再是0。这就变成了导火索。

是不是很可怕,前端同学仅仅改了下组件,毫秒是不是0又有什么关系呢?但是最终却造成了问题。当然不会是前端背锅,但是这个问题提醒了我们:
往往故障都是由小细节引发的,且经过链路的放大,最终可能升级为大的资损故障

敬畏每一行代码,每一项变更。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 12:04:09  更:2022-10-31 12:07:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:22:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码