【背景】

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的更多相关文章

  1. MySQL5日期类型DATETIME和TIMESTAMP相关问题详解

    MySQL5日期类型DATETIME和TIMESTAMP相关问题详解 MySQL5的日期类型有三种:DATETIME.DATE和TIMESTAMP,除了DATE用来表示一个不带时分秒的是日期,另外两个 ...

  2. 转 数据库中的 date datetime timestamp的区别

    转 数据库中的 date datetime timestamp的区别 DATETIME, DATE和TIMESTAMP类型是相关的.本文描述他们的特征,他们是如何类似的而又不同的. DATETIME类 ...

  3. Mysql 实战关于date,datetime,timestamp类型使用

    最近在做一个项目 项目中 不同的小伙伴同时在不同的业务模块中用到了date,datetime,timestamp这三个类型 特别是datetime,timestamp这两个 如果不能理解到位  其实很 ...

  4. mysql的日期存储字段比较int,datetime,timestamp区别

    1.首先是我们分析datetime长度是8个字节,INT的长度是4个字节,存储空间上比datatime少. 2.int存储索引的空间也比datetime少,排序效率高,查询速度比较快. 3.方便计算, ...

  5. mysql中时间类型datetime,timestamp与int的区别

    在mysql中存储时间,我们可以用datetime 格式,timestamp格式,也可以用int格式.那么我们设计的时候该如何考虑呢? 首先,我觉得应该明白这几个格式究竟是如何的,然后看看他们的区别, ...

  6. mysql5.7 版本中 timestamp 不能为零日期 以及sql_mode合理设置

    ---恢复内容开始--- 摘要: mysql5.7版本相比较之前的版本有很多的特性的增加以及默认配置的改变,在使用中难免会遇到与之前的使用习惯或者项目需求不符的情况.就需要调整相应的变量的值,比如sq ...

  7. Mysql时间存储类型优缺点?DATETIME?TIMESTAMP?INT?

    TIMESTAMP 4个字节储存;值以UTC格式保存;.时区转化 ,存储时对当前的时区进行转换,检索时再转换回当前的时区. DATETIME 8个字节储存;实际格式储存;与时区无关;datetime  ...

  8. MySQL中Date,DateTime,TimeStamp和Time的比较

    名称 显示格式 显示范围 应用场景 后台取值 Date YYYY-MM-DD 1601-01-01 到 9999-01-01 当业务需求中只需要精确到天时, 可以用这个时间格式 @JSONField( ...

  9. Mysql中date,time,datetime,timestamp的区别

    区别: timestamp:时间戳.北京时间1970年01月01日08时00分00秒 起至现在的总秒数. datetime:带时分秒的完整时间,例如:1970-01-01 10:00:00 date: ...

随机推荐

  1. Extract QQ from iPhone and analyze it

    QQ is one of the most popular chat App in the world. Now let me show you how to extract QQ from iPho ...

  2. PIC32MZ tutorial -- 32-bit Timer

    The microcontroller is PIC32MZ2048ECH144 on the PIC32MZ EC Starter Kit. This microcontroller has fou ...

  3. c#基础-oop(面向对象理解)

    OOP-面向对象 封装,继承多态 一个桌子,用面向对象来描述一下它这个桌子项目 定义桌子类 对象:桌子 桌子的属性:名字,材质,体积 桌子的方法;放东西(方法) 现在桌子要放书,放花瓶,放文件(这里就 ...

  4. Django模板格式

    变量 {{ 变量名称 }} 块 {% block 块名称 %} 判断 根据布尔值判断: {% if 布尔值 %} 操作 {% endif %} 根据两者是否相等判断: {% ifequals 变量1 ...

  5. smarty模板的安装配置

    第一步:下载Smarty模版源码包了    百度一下“Smarty下载”,下载最新版本的Smarty模版第二部:解压缩,将下载好的Smarty包解压缩    右键->解压到当前文件夹...你懂的 ...

  6. VC++ 标准C++中的string类的用法总结

    相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有没有这样使用起来非常方便的类呢?答案是肯 ...

  7. Allegro转换PADS终极篇(转载)

    Allegro转换PADS终极篇.....http://www.eda365.com/forum.php?mod=viewthread&tid=86947&fromuid=190625 ...

  8. [转]Python学习资料和教程pdf

    开发工具: Python语言集成开发环境 Wingware WingIDE Professional v3.2.12 Python语言集成开发环境 Wingware WingIDE Professio ...

  9. Selenium2+python自动化31-生成测试报告

    前言 最近小伙伴们总有一些测试报告的问题,网上的一些资料生成报告的方法,我试了都不行,完全生成不了,不知道他们是怎么生成的,同样的代码,有待研究. 今天小编写一下可以生成测试报告的方法.个人觉得也是最 ...

  10. RHEL7网络管理之nmcli

    在RHEL7中默认使用NetworkManager 守护进程来监控和管理网络设置.nmcli是命令行的管理NetworkManager的工具,会自动把配置写到/etc/sysconfig/networ ...