文章目录
- 1、show engine innodb status命令
- 2、前置知识
- 3、无符号数、有符号数
- 4、innodb关于有符号数的规定
- 5、为什么会有这个规定
1、show engine innodb status命令
最近在使用mysql的show engine innodb status命令分析死锁,发现了一个有意思的点。就是红框里圈出来的这个。
红框的数据所代表的是sql语句需要获取的行锁。实际上,这个值应该是-1才对,很纳闷,为什么会展示7fffffff呢?其实这个事和innodb的一条关于有符号数的规定有关系。
2、前置知识
hex 7fffffff,代表16进制的int最大值,要分析为什么是这个数,得先了解计算机的二进制相关的原码、反码和补码的知识,我搜了一篇文章,讲的挺清晰的。不了解这块知识的,可以先补一下。原码、反码、补码
3、无符号数、有符号数
测试中,我用的是表t。表t中的列如果没有特殊设置,默认是有符号数,意思是这一列,你可以存负数。但是如果你设置了列为无符号数列,对应的建表语句中就会出现UNSIGNED关键字。如下:
id
int(11) UNSIGNED NOT NULL
此时这一列,不允许插入负数。
当我们没加UNSIGNED关键字的时候,smallint存储的是:-32768~32767
如果加了UNSIGNED关键字,smallint存储的是:0~65535。
4、innodb关于有符号数的规定
innodb的规定是:如果表中的列存储有符号数据,此时数据对应的二进制数首位的0和1要互换。举个例子,就拿我们上面的数据来说。
7fffffff,这个数是int的最大值2147483647,换算成二进制是:
01111111 11111111 11111111 11111111
此时按照mysql的规定,首位的0要变成1,就是下面这个样子
11111111 11111111 11111111 11111111
这个数是补码,对应的原码就是-1,(大家补完上面原码、反码、补码的知识后,就知道为什么是-1了)
5、为什么会有这个规定
我没有找到官方对这一规定的描述,查了查资料。innodb这么搞,据说是节省空间,不用专门搞字段识别一个列是否存储的是有符号数。如果有大佬找到了官方关于这个规定的解释,希望能在评论区贴一下