MySQL数值类型在binlog中需要注意的细节(r12笔记第69天)

   
MySQL里的数值类型分得很细,光整型数据就有多种数据类型。tinyint,smallint,mediumint,int(integer),还有范围最大的bigint,它们对应的数值范围也大大不同,大体来说就是下面的数值范围,从有符号数和无符号数来区别对待。

类型名称 有符号数(signed) 无符号数(Unsigned)
tinyint -129~127 0~255
smallint -32768~32767 0~65535
mediumint -8388608~8388607 0~16777215
int(integer) -2147483648~2147483647 0~4294967295
bigint
-9223372036854775808~

9223372036854775807

0~18446744073709551615

   这一点上Oracle做得很大气,直接一个number类型,精度也包了,两者在这个地方风格截然不同。

  
对于MySQL的数据类型,我们来说说bigint,如果按照无符号数,最大的值为18446744073709551615,这是一个相当大的数字,如果从有符号数据的角度来看就是-1,那么问题来了,在MySQL的binlog里面是否会区分signed还是unsigned呢,如果不区分,这类问题该怎么应对。

  

  我做了如下的测试,使用conv来做进制转换。

> select conv(-1,10,2);
+------------------------------------------------------------------+
| conv(-1,10,2)                                                    |
+------------------------------------------------------------------+
| 1111111111111111111111111111111111111111111111111111111111111111 |
+------------------------------------------------------------------+

> select conv(18446744073709551615,10,2);
+------------------------------------------------------------------+
| conv(18446744073709551615,10,2)                                  |
+------------------------------------------------------------------+
| 1111111111111111111111111111111111111111111111111111111111111111 |
+------------------------------------------------------------------+从机制转换的结果来看,两者是没有差别的,如果是实际的场景中,这可是天壤之别。

我们换一个角度来转换一下。

> select conv(repeat(1,64),2,-10);
+--------------------------+
| conv(repeat(1,64),2,-10) |
+--------------------------+
| -1                       |
+--------------------------+

> select conv(repeat(1,64),2,10);
+-------------------------+
| conv(repeat(1,64),2,10) |
+-------------------------+
| 18446744073709551615    |
+-------------------------+这么看来,让人有些担忧,如果达到这种数据的临界点,会发生什么意料之外的结果呢。

我们来创建一个表,指定两个字段,一个为有符号类型,一个为无符号类型,然后对应的数字,从binlog来看看解析出来的结果。

create table t1 (id int unsigned not null auto_increment primary key, col1 bigint unsigned, col2 bigint signed) engine=innodb;接着我们切一下日志,查看一下master对的状态,得到日志的偏移量和binlog名字。

> flush logs; show master status;
+---------------+----------+
| File          | Position |
+---------------+----------+
| binlog.000031 |      107 |
+---------------+----------+这个时候我们插入两列值,一个无符号,一个有符号。

insert into t1 (col1, col2) values (18446744073709551615, -1);然后使用flush logs再次切换日志。

查看数据的情况,可以从输出看出两者是有明显的差别的。

> select * from t1;
+----+----------------------+------+
| id | col1                 | col2 |
+----+----------------------+------+
|  1 | 18446744073709551615 |   -1 |
+----+----------------------+------+我们从binlog来解析一下。

mysqlbinlog -vv binlog.000031

得到的部分日志如下:

### INSERT INTO test.t1
### SET
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
###   @2=-1 (18446744073709551615) /* LONGINT meta=0 nullable=1 is_null=0 */
###   @3=-1 (18446744073709551615) /* LONGINT meta=0 nullable=1 is_null=0 */
# at 268
#170519 18:54:47 server id 13386  end_log_pos 295       Xid = 76
COMMIT/*!*/;这样看来对于binlog中,有符号数和无符号数都会按照无符号数来转换,当然直接看数据类型是没有标识有符号和无符号的差别的。所以如果是单纯要解析binlog处理数据就需要考虑到这个地方的差别,对此一种思路是查看information_schema中的列信息来做出更加明确的判断。

参考资料:https://mariadb.com/resources/blog/sign-row-based-binary-logging-and-integer-signedness-mysql-and-mariadb

时间: 2024-09-20 06:18:49

MySQL数值类型在binlog中需要注意的细节(r12笔记第69天)的相关文章

MySQL数值类型存储长度及范围

  MySQL设置数值型列时,需要考虑到数值的范围,所以,数值类型就必然需要考虑,以下为MySQL数值类型的存储长度,当然存储长度基本决定着其值域范围.本文节选自MySQL官方网站,仅做汇总摘要整理. 一.TINYINT 1个字节存储,范围有符号-128-127,无符号0-255.还有一个类型是BOOL型,相当于TINYINT(1). 二.SMALLINT 2个字节存储,范围带符号的范围是-32768到32767.无符号的范围是0到65535. 三.MEDIUMINT 3个字节存储,范围带符号的

MYSQL如何识别一个binlog中的一个事物

原创水平有限 测试版本5.7.14 设置GTID_MODE=ON ON(3): Both new and replicated transactions must be GTID transactions(生成的是GTID事物,slave也只能应用GTID事物) 设置binlog格式为row模式 做如下操作 mysql> insert into test values(1,2); Query OK, 1 row affected (0.01 sec) mysql> insert into te

MYSQL列类型参考

mysql|参考    本附录介绍MySQL提供的每种列类型.关于利用每种类型的详细说明请参阅第2 章.除非另有说明,否则所列出的类型早在MySQL3.21.0 中就已经有了.    按下列约定给出类型名说明:    方括号( [ ]) 可选信息.    M 最大显示宽度.除非另有说明,否则M 应该是一个1到255 之间的整数.    D 有小数部分的类型的小数位数.D 为一个0 到30 之间的整数.D 应该小于等于M - 2.否则,M 的值将调整为D + 2.    在ODBC 术语中,M 和

MySQL中二进制日志binlog中的事件类型

MySQL binlog记录的所有操作实际上都有对应的事件类型的,譬如STATEMENT格式中的DML操作对应的是QUERY_EVENT类型,ROW格式下的DML操作对应的是ROWS_EVENT类型. 首先,看看源码中定义的事件类型 源码位置:mysql-5.7.14/libbinlogevents/include/binlog_event.h enum Log_event_type {   /**     Every time you update this enum (when you ad

MySQL binlog中的事件类型详解_Mysql

MySQL binlog记录的所有操作实际上都有对应的事件类型的,譬如STATEMENT格式中的DML操作对应的是QUERY_EVENT类型,ROW格式下的DML操作对应的是ROWS_EVENT类型. 首先,看看源码中定义的事件类型 源码位置:mysql-5.7.14/libbinlogevents/include/binlog_event.h enum Log_event_type { /** Every time you update this enum (when you add a ty

MySQL中如何禁用binlog中的语句

MySQL复制是异步的,也就是说是非同步的过程,它不会校验数据库中数据的一致性,只要SQL语法正确并且没有错误就能成功执行 MASTERtest 12:20:40>create table tab01 -> (id int(10) primary key , -> name varchar(20)); Query OK, 0 rows affected (0.03 sec) MASTERtest 12:21:32> MASTERtest 12:21:49>show maste

MySQL运维案例分析:Binlog中的时间戳

背景 众所周知,在Binlog文件中,经常会看到关于事件的时间属性,出现的方式都是如下这样的. #161213 10:11:35 server id 11766 end_log_pos 263690453 CRC32 0xbee3aaf5 Xid = 83631678 我们清楚地知道,161213 10:11:35表示的就是时间值,但除此之外呢?还能知道它的什么信息呢? 案例分析 先从一个典型的案例入手来讲述其中的细节,比如曾经在Galera Cluster碰到的一个问题,可以先看一段Binlo

cstring-MFC对话框串口编程中转化组合框数值类型

问题描述 MFC对话框串口编程中转化组合框数值类型 实现在对话框类设置串口参数并连接串口,现在在校验位对应的组合框里添加了数据N/E/O,分别表示无校验,奇校验,偶校验 int index=m_ctrlParity.GetCurSel(); m_ctrlParity.GetLBText(index,m_strParity); 这里得到的数据类型m_strParity是CString型,但在打开串口时,用到的数据是char型,怎么转化得到呢?网上都是CString转Char _* 解决方案 CSt

实例解析Ruby中的数值类型以及常量_ruby专题

数值类型(Number)整型(Integer) 整型分两种,如果在31位以内(四字节),那为Fixnum实例.如果超过,即为Bignum实例. 整数范围从 -230 到 230-1 或 -262 到 262-1.在这个范围内的整数是类 Fixnum 的对象,在这个范围外的整数存储在类 Bignum 的对象中. 您可以在整数前使用一个可选的前导符号,一个可选的基础指标(0 对应 octal,0x 对应 hex,0b 对应 binary),后跟一串数字.下划线字符在数字字符串中被忽略. 您可以获取一