一次故障解决过程梳理

故障原因:
mysql主键设置为int(9),但数据量已经大于int(9)的范围了

解决过程中的坑:
因为更改字段类型太慢(亿级数据量),就新建了个相同结构的表,然后更改代码中的sql准备把应用启动起来。

问题1:因为shell脚本是在notepad++中修改的,修改后没有保存,导致一直没有生效-------更改了什么东西一些要确认更新才行
问题2:使用一个权限比较低的用户上传到Linux后,项目文件也在这个用户下,导致cd一个目录时没有权限  ----使用chown更改权限后,居然还cd不进去,这种情况不应该发生,但对这个代码不熟,原因不确定

临时解决办法是将Mysql 主键的字段类型更改为bigint(22).

digest:

The "BIGINT(20)" specification isn‘t a digit limit. It just means that when the data is displayed,
if it uses less than 20 digits it will be left-padded with zeros.

CREATE TABLE foo ( bar INT(20) ZEROFILL );
INSERT INTO foo (bar) VALUES (1234);
SELECT bar from foo;

+----------------------+
| bar                  |
+----------------------+
| 00000000000000001234 |
+----------------------+

unsinged可以增加数据长度。但也有问题就是id相减时,如果用负就会报错或溢出
unsigned关键字只能用于整数,不能应用于浮点型和字符型
binary只能应用于varchar,char,不能应用于整数和浮点型

把整数类型设置unsigned示例

mysql> CREATE TABLE t ( a INT UNSIGNED, b INT UNSIGNED )
ENGINE=INNODB;
Query OK, 0 rows affected (0.06 sec)
mysql> INSERT INTO t SELECT 1,2;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM t\G;
*************************** 1. row ***************************
a: 1
b: 2

id相关为负时出现的异常,视os不同,现象也略有不同:

mysql> SELECT a -b FROM t\G;
*************************** 1. row ***************************
a - b: 4294967295
1 row in set (0.00 sec)
mysql> SELECT a-b FROM t;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in ‘(`test`.`t`.`a` - `test`.`t`.`b`)‘

The "BIGINT(20)" specification isn‘t a digit limit. It just means
that when the data is displayed, if it uses less than 20 digits it will be
left-padded with zeros.
2^64 is the hard limit for the BIGINT type, and has 20 digits itself, hence BIGINT(20) just means everything less than 10^20 will be
left-padded with spaces on display.
This is kind of getting off topic though, so...

Not to keep riding a dead horse, but I wanted to chime in on this quickly.

Here‘s the full column definition:

`term_id` bigint(20) NOT NULL auto_increment

The ‘20‘ is the maximum display width.
However, this does NOT limit  the range of values that can be stored in this column, which for
bigint is: -9223372036854775808 to 9223372036854775807

If its unsigned (which this one is not), a bigint has this range: 0
to 18446744073709551615

If you specify zerofill as one of the options in the column
definition, values will be left-padded with zeros. Displaying the
value without zerofill will left-pad with spaces.

More info here:
http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html
http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html

http://lists.automattic.com/pipermail/wp-hackers/2008-March/018522.html

See http://dev.mysql.com/doc/refman/5.1/en/numeric-types.html

INT is a four-byte signed integer. BIGINT is an eight-byte signed integer.

The 20 in INT(20) and BIGINT(20) means almost nothing. It‘s a hint for display width, it has nothing to do with storage. Practically, it affects only the ZEROFILL option:

CREATE TABLE foo ( bar INT(20) ZEROFILL );
INSERT INTO foo (bar) VALUES (1234);
SELECT bar from foo;

+----------------------+
| bar                  |
+----------------------+
| 00000000000000001234 |
+----------------------+

It‘s a common source of confusion for MySQL users to see INT(20) and assume it‘s a size limit, something analogous to CHAR(20).

http://stackoverflow.com/questions/3135804/types-in-mysql-bigint20-vs-int20

mysql使用无符号数及相关问题:

MySQL数据类型:UNSIGNED注意事项
1. UNSIGNED
UNSIGNED属性就是将数字类型无符号化,与C、C++这些程序语言中的unsigned含义相同。例如,INT的类型范围是-2 147 483 648 ~ 2 147 483 647, INT UNSIGNED的范围类型就是0 ~ 4 294 967 295。
在MYSQL中整型范围:

类型 大小 范围(有符号) 范围(无符号) 用途
TINYINT 1 字节 (-128,127) (0,255) 小整数值
SMALLINT 2 字节 (-32 768,32 767) (0,65 535) 大整数值
MEDIUMINT 3 字节 (-8 388 608,8 388 607) (0,16 777 215) 大整数值
INT或INTEGER 4 字节 (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值
源文档 <http://www.cnblogs.com/bukudekong/archive/2011/06/27/2091590.html>

看起来这是一个不错的属性选项,特别是对于主键是自增长的类型,因为一般来说,用户都希望主键是非负数。然而在实际使用中,UNSIGNED可能会带来一些负面的影响,示例如下:
mysql> CREATE TABLE t ( a INT UNSIGNED, b INT UNSIGNED )
ENGINE=INNODB;
Query OK, 0 rows affected (0.06 sec)
mysql> INSERT INTO t SELECT 1,2;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM t\G;
*************************** 1. row ***************************
a: 1
b: 2
1 row in set (0.00 sec)
我们创建了一个表t,存储引擎为InnoDB。表t上有两个UNSIGNED的INT类型。输入(1,2)这一行数据,目前看来都没有问题,接着运行如下语句:
SELECT a - b FROM t
这时结果会是什么呢?会是-1吗?答案是不确定的,可以是-1,也可以是一个很大的正值,还可能会报错。在Mac操作系统中(windows中也会),MySQL数据库提示如下错误:
mysql> SELECT a-b FROM t;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in ‘(`test`.`t`.`a` - `test`.`t`.`b`)‘
这个错误乍看起来非常奇怪,提示BIGINT UNSIGNED超出了范围,但是我们采用的类型都是INT UNSIGNED啊!而在另一台Linux操作系统中,运行的结果却是:

mysql> SELECT a -b FROM t\G;
*************************** 1. row ***************************
a - b: 4294967295
1 row in set (0.00 sec)

在发生上述这个问题的时候,有开发人员跑来和笔者说,他发现了一个MySQL的Bug,MySQL怎么会这么“傻”呢?在听完他的叙述之后,我写了如下的代码并告诉他,这不是MySQL的Bug,C语言同样也会这么“傻”。
#include
int main(){
unsigned int a;
unsigned int b;
a = 1;
b = 2;
printf(a - b: %d\n,a-b);
printf(a - b: %u\n,a-b);
return 1;
}

上述代码的运行结果是:
a - b: -1
a - b: 4294967295
可以看到,在C语言中a-b也可以返回一个非常巨大的整型数,这个值是INT UNSIGNED的最大值。难道C语言也发生了Bug?这怎么可能呢?
在实际的使用过程中,MySQL给开发人员的印象就是存在很多Bug,只要结果出乎预料或者有开发人员不能理解的情况发生时,他们往往把这归咎于MySQL的 Bug。和其他数据库一样,MySQL的确存在一些Bug,其实并不是MySQL数据库的Bug比较多,去看一下Oracle RAC的Bug,那可能就更多了,它可是Oracle的一款旗舰产品。因此,不能简单地认为这个问题是MySQL的Bug。
对于上述这个问题,正如上述所分析的,如果理解整型数在数据库中的表示方法,那么这些就非常好理解了,这也是为什么之前强调需要看一些计算机组成原理方面相关书籍的原因。将上面的C程序做一些修改:
#include
int main(){
unsigned int a;
unsigned int b;
a = 1;
b = 2;
printf(a - b: %d,%x\n,a-b,a-b);
printf(a - b: %u,%x\n,a-b,a-b);
return 1;
}
这次不仅打印出a-b的结果,也打印出a-b的十六进制结果,运行程序后的结果如下所示:
a - b: -1,ffffffff
a - b: 4294967295,ffffffff
可以看到结果都是0xFFFFFFFF,只是0xFFFFFFFF可以代表两种值:对于无符号的整型值,其是整型数的最大值,即4 294 967 295;对于有符号的整型数来说,第一位代表符号位,如果是1,表示是负数,这时应该是取反加1得到负数值,即-1。

这个问题的核心是,在MySQL数据库中,对于UNSIGNED数的操作,其返回值都是UNSIGNED的。而正负数这个问题在《MySQL技术内幕:InnoDB存储引擎》中有更深入的分析,有兴趣的可以进一步研究。
那么,怎么获得-1这个值呢?这并不是一件难事,只要对SQL_MODE这个参数进行设置即可,例如:
mysql>SET sql_mode=‘NO_UNSIGNED_SUBTRACTION‘;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT a-b FROM t\G;
*************************** 1. row ***************************
a-b: -1
1 row in set (0.00 sec)
后面会对SQL_MODE进一步讨论,这里不进行深入的讨论。笔者个人的看法是尽量不要使用UNSIGNED,因为可能会带来一些意想不到的效果。另外,对于INT类型可能存放不了的数据,INT UNSIGNED同样可能存放不了,与其如此,还不如在数据库设计阶段将INT类型提升为BIGINT类型。

以上文字摘自<http://tech.it168.com/a2012/0808/1382/000001382732.shtml>
本人遇到的类似问题:(linux上)
当(a-b)在where子句后时也会出现相同的情况
以下是php使用Mysql查询的结果(每组的第一行是第二行[1]-[2]的结果)
86374
a
Array ( [1] => 1351843032 [2] => 1351756658 )
-2567
Array ( [1] => 1351843032 [2] => 1351845599 )
86374
Array ([1] => 1351843032 [2] => 1351756658 )
86374
Array ( [1] => 1351843032 [2] => 1351756658 )
-105849
Array ( [1] => 1351650809 [2] => 1351756658 )
86374
Array ( [1] => 1351843032 [2] => 1351756658 )
86374
Array ( [1] => 1351843032 [2] => 1351756658 )

下面在mysql语句中查询select * from table where (a-b)>86374;

结果(按正常思路来讲,结果应该为空,但在Linux是却现出以下结果 ):

Array ( [1] => 1351843032 [2] => 1351845599 )

Array ( [1] => 1351650809 [2] => 1351756658 )

而这个结果恰是[1]-[2]为负数的那两行。

结论:如果使用unsigne并且在where子句后出现两列相减值小于0((a-b)<0),在查询时,linux上的Mysql会将负数转换成unsigned后再进行查询( (-2576+4294967295+1)>86374, (-105849+4294967295+1)>86374 )。

http://www.cnblogs.com/blankqdb/archive/2012/11/03/blank_qdb.html

时间: 2024-11-04 18:09:35

一次故障解决过程梳理的相关文章

[转]线上GC故障解决过程记录

排查了三四个小时,终于解决了这个GC问题,记录解决过程于此,希望对大家有所帮助.本文假定读者已具备基本的GC常识和JVM调优知识,关于JVM调优工具使用可以查看我在同一分类下的另一篇文章: http://my.oschina.net/feichexia/blog/196575 背景说明 发生问题的系统部署在Unix上,发生问题前已经跑了两周多了. 其中我用到了Hadoop源码中的CountingBloomFilter,并将其修改成了线程安全的实现(详情见:AdjustedCountingBloo

一次线上GC故障解决过程记录

排查了三四个小时,终于解决了这个GC问题,记录解决过程于此,希望对大家有所帮助.本文假定读者已具备基本的GC常识和JVM调优知识,关于JVM调优工具使用可以查看我在同一分类下的另一篇文章: http://my.oschina.net/feichexia/blog/196575 背景说明 发生问题的系统部署在Unix上,发生问题前已经跑了两周多了. 其中我用到了Hadoop源码中的CountingBloomFilter,并将其修改成了线程安全的实现(详情见:AdjustedCountingBloo

主板故障导致服务器不定时频繁重启故障解决过程全记录

服务器:HP DL385 G7 操作系统:suse10 sp3 数据库:oracle 11g R2 集群软件:VCS 双机主备 环境:两台服务器使用VCS软件做的oracle主备切换数据库 故障现象: 1.两台数据库主机不定期频繁重启,每次重启时在操作系统message日志中均没有任何记录: 2.系统启动时,message 日志出现与硬件相关的错误信息 message 日志信息: ----------------------------------------------------------

企业案例 【故障修复】mysql主从故障解决过程

由于配置有zabbix监控,某日收到zabbix监控主从报警,,查看mysql状态, showslave status \G; slave复制状态有误,SLAVE_SQL_RUNNING为NO, 接着看下面的错误信息,提示有一个表插入数据,提示表不存在, 随后在从库上检查该库该表,发现都存储,就纳闷了. 再回头看报错有新发现,提示的表明是大写,我刚才检查的小写, ok,再次进入从数据库使用大写查询表,果然报错,看来是大小写问题引起的. 查资料发现mysql参数有忽略大小写的参数lower_cas

(转)625某电商网站数据库宕机故障解决实录(下)

1.4开始进行故障恢复***** 1.重新初始化建库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 [[email protected] data]# mkdir mysql [[email protected] data]# chown -R mysql.mysql mysql [ro[email protected] data]# /install/mysql/sc

(转)625某电商网站数据库宕机故障解决实录(上)

625某电商网站数据库特大故障解决实录(上) 原文:http://oldboy.blog.51cto.com/2561410/1431161 这是一次,惊心动魄的企业级电商网站数据库在线故障解决实录,故障解决的过程遇到了很多问题,思想的碰撞,解决方案的决策,及实际操作的问题困扰,老男孩尽量原汁原味的描述恢复的全部过程及思想思维过程!老男孩教育版权所有,本内容禁止商业用途. 目录: 625某电商网站数据库特大故障解决实录... 1 1接到电商客户报警... 1 1.1与客户初步沟通... 1 1.

【故障解决】enq: PS - contention

[故障解决]enq: PS - contention 一.1  BLOG文档结构图       一.2  前言部分   一.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① 等待事件 enq: PS - contention的解决办法 ② 一般等待事件的解决办法     Tips:        ① 若文章代码格式有错乱,推荐使用QQ或360浏览器,也可以下载pdf格式的文档来查看,pdf文档下载地址:htt

【故障解决】ORA-06502错误解决

[故障解决]ORA-06502: PL/SQL: numeric or value error: character string buffer too small 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① EXPDP和IMPDP基于scn的导出 ② ora-06502的解决方法   Tips: ① 若文章代码格式有错乱,推荐使用QQ或360浏览器

mysql的三个故障解决小结

mysql使用过程中经常会遇到的三个故障,在此小结一下. 1.MySQl服务无法启动 我们在使用mysql的过程中,常会遇到MySQl服务无法启动,具体报错信息:Starting MySQL ERROR.The server quit without updating PID file (/[FAILED]l/mysql/) 对这样的错误,网上的分析解释有很多,有人分析把skip-federated这个参数屏蔽就可以了,也有人认为删除mysql-bin.index这个文件就可以启动服务.或者检查