insert..select报ERROR 126

root@test >insert into test_insertselect(goods_remark,gmt_create) 
select goods_remark,gmt_create from test_insertselect;
ERROR 126 (HY000): Incorrect key file for table '/tmp/#sql_6360_0.MYI'; try to repair it

用perror工具查看具体详细错误

$perror 126
OS error code 126:  Required key not available
MySQL error code 126: Index file is crashed

是从OS层抛出错误,和mysql可能没有关系。我们知道insert..select方式,mysql先会创建myisam类型的临时表,再把临时表数据回写到源表

root@test >show table status like 'test_insertselect' \G;
*************************** 1. row ***************************
           Name: test_insertselect
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 16777553
 Avg_row_length: 40
    Data_length: 679477248
-rw-rw---- 1 mysql dba  7486504960 Jul  2 11:31 #sql_6360_0.MYD
-rw-rw---- 1 mysql dba        1024 Jul  2 11:31 #sql_6360_0.MYI

为什么源表只有679M,但insert..select时,创建临时表会7486M呢?

源表里面有varchar类型的字段。而在创建临时表的时候,mysql默认将这些字段全部转换成char类型(参考http://blog.csdn.net/zbszhangbosen/article/details/7441889)

验证一下:

root@test >alter table test_insertselect modify goods_remark char(1);
Query OK, 16777216 rows affected (2 min 4.33 sec)
Records: 16777216  Duplicates: 0  Warnings: 0
 
root@test >insert into test_insertselect(goods_remark,gmt_create) 
select goods_remark,gmt_create from test_insertselect;
Query OK, 16777216 rows affected (1 min 44.96 sec)
Records: 16777216  Duplicates: 0  Warnings: 0

写入成功

-rw-rw---- 1 mysql dba  184549376 Jul  2 11:48 #sql_6360_0.MYD
-rw-rw---- 1 mysql dba       1024 Jul  2 11:48 #sql_6360_0.MYI

MYD文件大小始终维持在184M左右


2 Responses to “insert..select报ERROR 126”

  1. viva17说道:

    你好,我有个困扰了很久的问题想请教下,我公司有2个机房A和B,用VPN相通的,在A里有1主1从(生产环境,运行良好),现在在B机房也搭建1主1从(只用于我做试验),现把B的主库做为A的从的从,总的结构就是1->2->(vpn)->3->4链式从库,同步过程中,只有A接受写操作,问题出在2->3这个环节:Last_Error: Error ‘Field ‘xxx’ doesn’t have a default value’ on query…这个问题在1->2的时候并没出现,按理说也不该在2->3的时候出现吧。因为:这4台机器mysql版本,安装方式,配置文件都是一样的,变量sql_mode,binlog_format值也都是一样的。唯一不同的可能就是操作系统一个centos5.3一个5.4,还有机器配置有差别,网上搜了很多,找不到原因,能帮忙看看吗,谢谢?

Post a Comment