Andy Niu �����ĵ�

Andy Niu

Andy Niu Help  1.0.0.0
Mysql常见错误

模块

 复制有关的错误
 

变量

 Error_1045
 
 navicat执行utf8格式的sql脚本第一行报错
 
 执行SQL文件DELIMITER报错
 
 Error_1130
 
 Error_1172
 
 Error_1265
 
 Error_1418
 
 Error_2002
 

详细描述

变量说明

Error_1045
ERROR 1045 access denied for user 'root'@'localhost' using password yes
原因是:root的密码错误了。
解决思路:关闭mysql服务,重新启动mysql服务,启动mysql的时候,指定不需要校验密码。
然后登陆mysql,修改密码,退出。再重新启动mysql服务。
1、关闭mysql
2、启动mysql,指定不需要校验密码
    C:\Program Files\MySQL\MySQL Server 5.1\bin>mysqld --defaults-file="C:\Program
    Files\MySQL\MySQL Server 5.1\my.ini" --console --skip-grant-tables
3、再开一个窗口,root登陆,修改密码
    C:\Program Files\MySQL\MySQL Server 5.1\bin>mysql -uroot mysql 
    (解释: -uroot mysql 后面这个mysql指的是连接到mysql库,因为跳过权限验证,所以这时候可以不用密码就可以登录mysql)
    mysql>
    mysql> UPDATE user SET Password=PASSWORD('newpassword') where USER='root'; 
    mysql> FLUSH PRIVILEGES; 
    mysql> quit 
    特别注意:修改密码之后,不要忘记FLUSH PRIVILEGES; 否者还是密码错误。
4、再重新启动mysql 
5、linux下面类似,执行 service mysql start --skip-grant-tables;
6、特别注意:1045是密码错误,using password yes 表示使用了密码,但是密码错误。
    using password no 表示没有输入密码。
    要与1130错误区分,1130是远程连接的用户没有权限,不允许连接。
    mysql服务先检查,远程连接的用户是否有权限(也就是是否允许连接),然后检查用户名和密码。
参见
Error_1130
ERROR 1130 (00000): Host '172.16.1.9' is not allowed to connect to this MySQL server
错误原因是:不允许从其他主机连接mysql服务
解决办法是:本机登录,授权,允许从其他主机登录。如下:
grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;
flush privileges;

上面赋予的权限过大,可以使用下面的方法,赋予适当的权限。
允许myuser使用mypassword从任何主机连接到mysql服务器
GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'%' IDENTIFIED BY 'mypassword' WITH GRANT OPTION;
FLUSH PRIVILEGES;

允许用户myuser从ip为10.22.4.45的主机连接到mysql服务器,并使用mypassword作为密码
GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'10.22.4.45' IDENTIFIED BY 'mypassword' WITH GRANT OPTION;
FLUASH PRIVILEGES;

允许myuser从ip为10.22.4.45的主机连接到mysql服务器的test数据库,并使用mypassword作为密码;
GRANT ALL PRIVILEGES ON test.* TO 'myuser'@'10.22.4.45' IDENTIFIED BY 'mysqlpassword' WITH GRANT OPTION;
FLUSH PRIVILEGES;
参见
Error_1172
1172 - Result consisted of more than one row
错误原因:使用select aaa into bbb,而select出来的记录个数大于1,而bbb只接受一个。
注:select出来的记录个数为0没有关系。

怎么解决?
对于每一条记录的Id都要处理,使用游标。
Error_1265
1265 - Data truncated for column xxx
错误原因:字面意思是数据发生截断,也就是说插入或者修改记录的时候,字段取值与字段类型不匹配,或者不满足字段的约束条件。
比如:
mysql> desc t1;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| c1    | int(11)      | NO   |     | 0       |       |
| c2    | double       | YES  |     | NULL    |       |
| c3    | varchar(100) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
3 rows in set

mysql> insert into t1(c1,c2,c3) value(1,'hhh','hello');
1265 - Data truncated for column 'c2' at row 1

c2是double,插入'hhh'
Error_1418
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA 
in its declaration and binary logging is enabled (you *might* want to use the less safe 
log_bin_trust_function_creators variable)
错误的原因:
Mysql配置了复制,复制功能也就意味着Master数据的变化,会同步到Slave。对于函数,Mysql要求函数不能修改数据。
解决办法:
1、创建函数的时候,明确说明我不会修改数据。创建函数的时候有5个选项:
    a、DETERMINISTIC 确定性的
    b、NO SQL 没有包含SQl语句,当然也不会修改数据
    c、READS SQL DATA 只是读取数据,当然也不会修改数据
    d、MODIFIES SQL DATA 要修改数据
    e、CONTAINS SQL 包含了SQL语句
怎么理解DETERMINISTIC确定性的?
可以认为输入相同,方法执行过程,输出也是相同的。也就是方法的可重入性。不可重入的方法:
方法内使用了静态的数据,使用了malloc和free,使用了标准I/O函数。
创建函数必须明确指出a、b、c三个选项中的一个,才能执行成功。如下:
    mysql> show variables like 'log_bin%';
    +---------------------------------+-------+
    | Variable_name                   | Value |
    +---------------------------------+-------+
    | log_bin                         | ON    |
    | log_bin_trust_function_creators | OFF   |
    | log_bin_trust_routine_creators  | OFF   |
    +---------------------------------+-------+
    3 rows in set
    mysql> create function fun1 (num int(9)) returns int(9)
    begin
    return 1;
    end;
    1418 - This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA 
    in its declaration and binary logging is enabled (you *might* want to use the less safe 
    log_bin_trust_function_creators variable)
    mysql> create function fun1 (num int(9)) returns int(9) reads sql data
    begin
    return 1;
    end;
    Query OK, 0 rows affected
    mysql> drop function fun1;
    Query OK, 0 rows affected
    mysql> create function fun1 (num int(9)) returns int(9) deterministic
    begin
    return 1;
    end;
    Query OK, 0 rows affected
2、告诉Mysql,信任我,方法不会修改数据,Mysql不再检查,即使修改了数据。这个时候要靠你信守承诺,否则后果自负。
    mysql> drop function fun1;
    Query OK, 0 rows affected
    mysql> set global log_bin_trust_function_creators=on;
    Query OK, 0 rows affected
    mysql> show variables like 'log_bin%';
    +---------------------------------+-------+
    | Variable_name                   | Value |
    +---------------------------------+-------+
    | log_bin                         | ON    |
    | log_bin_trust_function_creators | ON    |
    | log_bin_trust_routine_creators  | ON    |
    +---------------------------------+-------+
    3 rows in set
    mysql> create function fun1 (num int(9)) returns int(9) modifies sql data
    begin
    return 1;
    end;
    Query OK, 0 rows affected
3、要想mysql服务重启之后,还起作用,需要在[mysqld]增加配置项,如下:
    log_bin_trust_function_creators=on      //注意后面没有分号,否则有些mysql版本会启动失败
    注:低版本的mysql可能不支持on的语法,需要使用log_bin_trust_function_creators=1
参见
Error_2002
ERROR 2002 (HY000): mysql Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

错误原因:/var/lib/mysql目录中socket文件不存在。
连接mysql服务器有两种方式:tcp连接,通过socket文件连接。通过socket文件,启动mysql服务,mysql服务会自动生成一个sock文件,
生成的sock文件默认放在 --datadir=/var/lib/mysql,mysql默认从/var/lib/mysql目录读取sock文件。

解决办法:
1、看看/var/lib/mysql/mysql 有没有mysql.sock文件
2、没有mysql.sock,重启mysql服务,看看有没有。
3、没有的话,ps aux|grep mysql|grep -v 'grep' 查看mysql服务生成的sock在哪个目录,看看这个目录有没有。
4、如果mysql服务生成在其他目录,解决办法有:
方法一、修改mysql服务生成的目录,在my.cnf 中[mysqld] socket
方法二、mysql从/var/lib/mysql/读取sock文件,建立一个软连接,或者copy过来
方法三、修改mysql读取的目录,在my.cnf 中[mysql] socket
方法四、启动指定socket,mysql -uroot -p123456 --socket='/var/lib/mysql/mysql.sock'

注意:
1、通过socket,只能在本地机器上连接。
2、使用-hlocalhost就是经过socket,不经过网络,通过netstat 看不到tcp连接,可以认为mysql与mysql.sock文件交互,向里面写数据,从里面读取数据。
3、使用-h127.0.0.1就是经过tcp,通过netstat 可以看到连接。
navicat执行utf8格式的sql脚本第一行报错
1、navicat执行utf-8格式的sql脚本,报错1064-You have an error in your SQL syntax... at line 1
2、错误原因:utf-8格式的文件开头有三个字符,这三个字符是不可见的,通过文件属性可以看到 大小比实际长度多出3个字符。
    这三个字符不可见,navicat无法识别这三个字符。
3、怎么解决?
    使用notepad++,格式-->转为UTF-8无BOM 编码格式,可以看到大小就是实际长度
    注意:转为UTF-8编码格式,大小比实际长度多出三个字节。
执行SQL文件DELIMITER报错
1、运行SQL文件报错,详细信息如下:
    [Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER' at line 1
    [Err] DELIMITER ;
    [Msg] Finished - Unsuccessfully
2、执行的SQL文件内容是:
    -- ----------------------------
    -- Procedure structure for `vms_getchncode_bydevcode_chnseq`
    -- ----------------------------
    DROP PROCEDURE IF EXISTS `vms_getchncode_bydevcode_chnseq`;
    DELIMITER ;;
    CREATE DEFINER=`root`@`localhost` PROCEDURE `vms_getchncode_bydevcode_chnseq`(in iDomId varchar(100), in iDevCode varchar(100), in iChnSeq int)
    BEGIN
            declare vDevId int default 0;
            
            select devid into vDevId from device where domainid=iDomId and devicecode=iDevCode and fast=1;
    
            select device.domainid, device.devicecode from device,dev_chn where device.devid=dev_chn.devid and device.parentdevid= vDevId and dev_chn.channelsequence= iChnSeq and device.fast=1 and dev_chn.fast=1;
    END
    ;;
    DELIMITER ;
3、错误原因是:最后多了一个DELIMITER ;
    去掉DELIMITER ;就可以了。
Copyright (c) 2015~2016, Andy Niu @All rights reserved. By Andy Niu Edit.