mysql5.6 TIME,DATETIME,TIMESTAMP
【背景】
5.6.4以后时间类型(TIME,DATETIME,TIMESTAMP)支持微秒
DATETIME范围 :'1000-01-01 00:00:00.000000' to '9999-12-31 23:59:59.999999'
TIMESTAMP范围: values is '1970-01-01 00:00:01.000000' to'2038-01-19 03:14:07.999999'
1) 5.6 支持指定小数精度
use test
CREATE TABLE fractest( c1 TIME(2), c2 DATETIME(2), c3 TIMESTAMP(2) );
INSERT INTO fractest VALUES ('17:51:04.777', '2014-09-08 17:51:04.777', '2014-09-08 17:51:04.777');
SELECT * FROM fractest;
+-------------+------------------------+------------------------+
| c1 | c2 | c3 |
+-------------+------------------------+------------------------+
| 17:51:04.78 | 2014-09-08 17:51:04.78 | 2014-09-08 17:51:04.78 |
+-------------+------------------------+------------------------+
2)5.6.4以前 插入的数据支持微秒,但插入存储的数据会忽略微秒
use test
CREATE TABLE fractest( c1 TIME, c2 DATETIME, c3 TIMESTAMP );
INSERT INTO fractest VALUES ('17:51:04.777', '2014-09-08 17:51:04.777', '2014-09-08 17:51:04.777');
SELECT * FROM fractest;
+----------+---------------------+---------------------+
| c1 | c2 | c3 |
+----------+---------------------+---------------------+
| 17:51:04 | 2014-09-08 17:51:04 | 2014-09-08 17:51:04 |
+----------+---------------------+---------------------+
3)5.6时间函数(CURTIME(), SYSDATE(), or UTC_TIMESTAMP())可以指定微秒精度
mysql> select CURTIME(2);
+-------------+
| CURTIME(2) |
+-------------+
| 11:26:56.43 |
+-------------+
4)存储
5.6.4以前,TIME,DATETIME,TIMESTAMP 分别固定占用3,8,4字节
5.6.4以后,TIME,DATETIME,TIMESTAMP占有大小取决于微秒的精度。
| TIME | 3 bytes + fractional seconds storage |
| DATETIME | 5 bytes + fractional seconds storage |
| TIMESTAMP | 4 bytes + fractional seconds storage |
而微秒的存储长度和精度的关系如下
| Fractional Seconds Precision | Storage Required |
|---|---|
| 0 | 0 bytes |
| 1, 2 | 1 byte |
| 3, 4 | 2 bytes |
| 5, 6 | 3 bytes |
例如上例中的c1 TIME: 占4字节,c2 DATETIME占6字节,TIMESTAMP 占7字节,TIMESTAMP占用5字节
相关函数可以参考my_datetime_packed_to_binary
5)新老时间类型在源码中的表现
5.6 内部增加了一些新的时间类型
MYSQL_TYPE_TIMESTAMP2
MYSQL_TYPE_DATETIME2,
MYSQL_TYPE_TIME2,
用于支持微秒的存储。
而老的时间类型
MYSQL_TYPE_TIMESTAMP,
MYSQL_TYPE_DATETIME,
MYSQL_TYPE_TIME
仍然保留和支持,从而兼容老的时间数据
5.6 新建的表时间字段默认使用新的类型,参考如下代码
sql/sql_yacc.yy:6514
| DATETIME type_datetime_precision
{ $$= MYSQL_TYPE_DATETIME2; }
6)binlog与新时间类型
binlog的Table_map_log_event中会记录表的元数据信息,包括库,表,列信息等。新时间类型的微秒精度信息就作为列的元数据(m_field_metadata)进行存储。类似的大字段列的列元数据存储大字段的实际长度(Field_blob::do_save_field_metadata)。
【问题重现】
1 master 上执行
use zy
CREATE TABLE t1 (id int primary key, c1 TIME, c2 DATETIME, c3 TIMESTAMP );
set sql_log_bin=0;
alter table t1 modify c3 timestamp(4);
set sql_log_bin=1;
INSERT INTO t1 VALUES (10, '17:51:04.98887', '2014-09-08 17:51:04.866666', '2014-09-08 17:51:04.777');
2 slave上执行
show slave status\G
Last_Errno: 1677
Last_Error: Column 3 of table 'zy.t1' cannot be converted from type 'timestamp' to type 'timestamp'
【分析】
1)先尝试修复,修改slave_type_conversions='ALL_LOSSY';参数slave_type_conversions可以参考 http://dev.mysql.com/doc/refman/5.5/en/replication-options-slave.html#sysvar_slave_type_conversions
mysql> show variables like 'slave_type_conversions'; +------------------------+-------+ | Variable_name | Value | +------------------------+-------+ | slave_type_conversions | | +------------------------+-------+ 1 row in set (0.00 sec) mysql> set global slave_type_conversions='ALL_LOSSY'; Query OK, 0 rows affected (0.00 sec) show slave status\G Last_Errno: 1610 Last_Error: Could not execute Write_rows event on table zy.t1; Corrupted replication event was detected, Error_code: 1610; handler error No Error!; the event's master log mysql-bin.000002, end_log_pos 550
发现备库用备库的表结构信息解析binlog行数据(unpack_row)时出错,因此,此方法修复失败。
2)查看源码:
Rows_log_event::do_apply_event
table_def::compatible_with
can_convert_field_to
....
if (field->real_type() == source_type)//本例主备类型一致
{
if (metadata == 0) // Metadata can only be zero if no metadata was provided // 本例主库精度为4
{
/*
If there is no metadata, we either have an old event where no
metadata were supplied, or a type that does not require any
metadata. In either case, conversion can be done but no
conversion table is necessary.
*/
DBUG_PRINT( "debug" , ("Base types are identical, but there is no metadata"));
*order_var= 0;
DBUG_RETURN( true );
}
DBUG_PRINT( "debug" , ("Base types are identical, doing field size comparison"));
if (field->compatible_field_size(metadata, rli, mflags, order_var))
DBUG_RETURN(is_conversion_ok(*order_var, rli));
else
DBUG_RETURN( false );
}
else if (metadata == 0 && //这里有对新老时间类型的兼容处理
((field->real_type() == MYSQL_TYPE_TIMESTAMP2 &&
source_type == MYSQL_TYPE_TIMESTAMP) ||
(field->real_type() == MYSQL_TYPE_TIME2 &&
source_type == MYSQL_TYPE_TIME) ||
(field->real_type() == MYSQL_TYPE_DATETIME2 &&
source_type == MYSQL_TYPE_DATETIME)))
{
/*
TS-TODO: conversion from FSP1>FSP2.
Can do non-lossy conversion
from old TIME, TIMESTAMP, DATETIME
to new TIME(0), TIMESTAMP(0), DATETIME(0).
*/
*order_var= -1;
DBUG_RETURN( true);
}
上面代码进行类型兼容性判断,本例由于精度不一致在is_conversion_ok处会返回失败。
mysql5.6 TIME,DATETIME,TIMESTAMP的更多相关文章
- MySQL5日期类型DATETIME和TIMESTAMP相关问题详解
MySQL5日期类型DATETIME和TIMESTAMP相关问题详解 MySQL5的日期类型有三种:DATETIME.DATE和TIMESTAMP,除了DATE用来表示一个不带时分秒的是日期,另外两个 ...
- 转 数据库中的 date datetime timestamp的区别
转 数据库中的 date datetime timestamp的区别 DATETIME, DATE和TIMESTAMP类型是相关的.本文描述他们的特征,他们是如何类似的而又不同的. DATETIME类 ...
- Mysql 实战关于date,datetime,timestamp类型使用
最近在做一个项目 项目中 不同的小伙伴同时在不同的业务模块中用到了date,datetime,timestamp这三个类型 特别是datetime,timestamp这两个 如果不能理解到位 其实很 ...
- mysql的日期存储字段比较int,datetime,timestamp区别
1.首先是我们分析datetime长度是8个字节,INT的长度是4个字节,存储空间上比datatime少. 2.int存储索引的空间也比datetime少,排序效率高,查询速度比较快. 3.方便计算, ...
- mysql中时间类型datetime,timestamp与int的区别
在mysql中存储时间,我们可以用datetime 格式,timestamp格式,也可以用int格式.那么我们设计的时候该如何考虑呢? 首先,我觉得应该明白这几个格式究竟是如何的,然后看看他们的区别, ...
- mysql5.7 版本中 timestamp 不能为零日期 以及sql_mode合理设置
---恢复内容开始--- 摘要: mysql5.7版本相比较之前的版本有很多的特性的增加以及默认配置的改变,在使用中难免会遇到与之前的使用习惯或者项目需求不符的情况.就需要调整相应的变量的值,比如sq ...
- Mysql时间存储类型优缺点?DATETIME?TIMESTAMP?INT?
TIMESTAMP 4个字节储存;值以UTC格式保存;.时区转化 ,存储时对当前的时区进行转换,检索时再转换回当前的时区. DATETIME 8个字节储存;实际格式储存;与时区无关;datetime ...
- MySQL中Date,DateTime,TimeStamp和Time的比较
名称 显示格式 显示范围 应用场景 后台取值 Date YYYY-MM-DD 1601-01-01 到 9999-01-01 当业务需求中只需要精确到天时, 可以用这个时间格式 @JSONField( ...
- Mysql中date,time,datetime,timestamp的区别
区别: timestamp:时间戳.北京时间1970年01月01日08时00分00秒 起至现在的总秒数. datetime:带时分秒的完整时间,例如:1970-01-01 10:00:00 date: ...
随机推荐
- 【MySQL】MySQL 5.7+ 版本的初始化
MySQL 5.7.7以上二进制包就不包括原data目录的初始化系统表,官网说明: http://dev.mysql.com/doc/refman/5.7/en/data-directory-init ...
- win8系统安装xampp后apache无法启动
根据提示判断为端口被占用: 处理方法: 右击左下角windows图标,选择运行,调了同cmd; 依次排除80及443端口占用情况: netstat -ano|findstr "80" ...
- [珠玑之椟]浅谈代码正确性:循环不变式、断言、debug
这个主题和代码的实际写作有关,而且内容和用法相互交织,以下只是对于其内容的一个划分.<编程珠玑>上只用了两个章节20页左右的篇幅介绍,如果希望能获得更多的实例和技巧,我比较推崇<程序 ...
- VC++ 在控件上写字时 字体的设置技巧
//人物照片下方的文字 CFont* nFont = &afxGlobalData.fontRegular; CFont* oFont = pDc->SelectObject(nFont ...
- iOS定位到崩溃代码行数
不知道大家是不是在代码调试过程中经常遇到项目崩溃的情况: 比如: 数组越界: 没有实现方法选择器: 野指针: 还有很多很多情况.......昨天学到了一种可以直接定位到崩溃代码行数的一个命令,记录一下 ...
- poj 2239 Selecting Courses (二分匹配)
Selecting Courses Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8316 Accepted: 3687 ...
- zendstudio 声明变量类型,让变量自动方法提示
zendstudio 行内注释, 显式声明变量类型,让变量自动方法提示 $out = []; /* @var $row \xxyy\SizeEntity */ foreach ($rows[ 'lis ...
- 2016 小马哥 IOS
2016 小马哥 IOS 最新视频完整版 链接:http://pan.baidu.com/s/1c1EQlBM 密码:mxkt
- [转]Theano下用CNN(卷积神经网络)做车牌中文字符OCR
Theano下用CNN(卷积神经网络)做车牌中文字符OCR 原文地址:http://m.blog.csdn.net/article/details?id=50989742 之前时间一直在看 Micha ...
- nginx日志中访问最多的100个ip及访问次数
nginx日志中访问最多的100个ip及访问次数 awk '{print $1}' /opt/software/nginx/logs/access.log| sort | uniq -c | sort ...