基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
原生 Oracle 数据库迁移到 OceanBase 数据库 MySQL 模式租户中存在 TIMESTAMP 精度问题的原因和解决方法
更新时间:2026-05-18 09:11
问题现象
原生 Oracle 数据库中 TIMESTAMP 字段数据 2024-02-06 14:45:29.799176 迁移到 OceanBase 数据库 MySQL 模式中的 TIMESTAMP 字段后,数据变为 2024-02-06 14:45:30,精度丢失。
原生 Oracle 数据库中测试数据。
SQL> create table test_timestamp (n1 int, t1 timestamp);
Table created.
SQL> insert into test_timestamp (n1,t1) values (1,current_timestamp);
1 row created.
SQL> commit;
Commit complete.
SQL> ALTER SESSION SET nls_timestamp_format='YYYY-MM-DD HH24:MI:SS.FF';
Session altered.
SQL> select * from test_timestamp;
N1
----------
T1
--------------------------------
1
2024-02-06 14:45:29.799176
OceanBase 数据库 MySQL 模式租户中手动创建的表的 DDL。
create table test_timestamp (n1 int, t1 timestamp);
问题原因
原生 MySQL 数据库中 TIMESTAMP 默认的精度是秒级别(0 小数位),OceanBase 数据库 MySQL 模式租户中同样如此。
适用版本
OceanBase 数据库所有版本。
解决方法
原生 Oracle 数据库中 TIMESTAMP 字段迁移到 OceanBase 数据库 MySQL 模式租户时,手动在 OceanBase 数据库 MySQL 模式租户中创建表时建议使用 DATETIME(6)。 采用 OMS 从原生 Oracle 数据库迁移表结构到 OceanBase 数据库 MySQL 模式租户时,也是默认自动将其转换为 DATETIME(6)。 需要注意,TIMESTAMP 在原生 MySQL 数据库中会有存储范围的上限 ('2038-01-19 03:14:07'): 如下为 MySQL 官方文档 13.2.2 The DATE, DATETIME, and TIMESTAMP Types: The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in '*YYYY-MM-DD hh:mm:ss*' format. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'. The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC. TIMESTAMP 在原生 MySQL 数据库中会有存储范围的上限 ('2038-01-19 03:14:07') 演示如下。
Server version: 8.0.31 MySQL Community Server - GPL
-- 指定精度为 6 后则无精度丢失
mysql> create table test_timestamp3 (n1 int, t1 timestamp(6));
Query OK, 0 rows affected (0.03 sec)
mysql> INSERT into test_timestamp3 VALUES (2, '2099-04-01 12:30:45.123456' );
ERROR 1292 (22007): Incorrect datetime value: '2099-04-01 12:30:45.123456' for column 't1' at row 1
mysql> INSERT into test_timestamp3 VALUES (2, '2037-04-01 12:30:45.123456' );
Query OK, 1 row affected (0.00 sec)
mysql> INSERT into test_timestamp3 VALUES (2, '2038-01-18 12:30:45.123456' );
Query OK, 1 row affected (0.01 sec)
mysql> INSERT into test_timestamp3 VALUES (2, '2038-01-19 12:30:45.123456' );
ERROR 1292 (22007): Incorrect datetime value: '2038-01-19 12:30:45.123456' for column 't1' at row 1
mysql> INSERT into test_timestamp3 VALUES (2, '2038-04-01 12:30:45.123456' );
ERROR 1292 (22007): Incorrect datetime value: '2038-04-01 12:30:45.123456' for column 't1' at row 1
参考
在 OceanBase 数据库 MySQL 模式租户中 TIMESTAMP 数据类型 文档中,可以看到在 OceanBase 数据库 MySQL 模式租户中无存储范围的上限 ('2038-01-19 03:14:07') 问题。 TIMESTAMP 值可以包括秒的小数位部分,精度最高可达微秒(6 位),格式为 YYYY-MM-DD hh:mm:ss[.fraction],范围是 0000-00-00 00:00:00.000000 到 9999-12-31 23:59:59.999999。
测试如下。
MySQL [test]> INSERT into test_timestamp3 VALUES (2, '9099-04-01 12:30:45.123456' );
Query OK, 1 row affected (0.005 sec)
MySQL [test]> SELECT * FROM test_timestamp3;
+------+----------------------------+
| n1 | t1 |
+------+----------------------------+
| 1 | 2024-02-06 14:45:29.799176 |
| 2 | 2023-04-01 12:30:45.123456 |
| 2 | 2043-04-01 12:30:45.123456 |
| 2 | 2099-04-01 12:30:45.123456 |
| 2 | 9099-04-01 12:30:45.123456 |
+------+----------------------------+
5 rows in set (0.001 sec)