Mysql Errors

Mysql Errors

Mysql Errors

1 ERROR 1044

1.1 42000

  • 错误信息

    MariaDB [mysql]>  grant select on information_schema.* to 'test'@'%';
    ERROR 1044 (42000): Access denied for user 'root'@'localhost' to database 'information_schema'
    
  • 原因

    information_schema是一个视图库,里面所有对象都是以视图的形式存在的,而且是在实例启动时自动加载和创建的。 Mariadb 不允许 对该库进行任何的操作。

  • 解决

    对于information_schema库的问题,我们可以针对其源表进行授权 。informat_schema库的源表是 mysql库。只要 让test用户拥有查询mysql库的权限,自然就可以查询information_schema库了。

    grant select on mysql.* to 'test'@'%';
    

2 ERROR 1045

2.1 28000

2.1.1 无登录权限

  • 错误信息

    ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
    

    在有些情况下,mysql 使用root 用户登录时,会出现这种情况。具体原因不明。咱不会读源码, 不然这个问题一定给它搞清楚。蛋疼。

  • 解决方法 解决这个问题的方法,不同的版本中操作方法也不一样。主要是通过修改mysql.user 中保存的密码 , 但是不同的版本还会有些小的区别,早期版本,只要更新mysql.user表就可以,但是mysql 5.6 / 5.7,除了手动更新mysql.user,还要另外执行一个操作。下面是主要操作流程:

    # 修改参数实现免认证登录数据库
    将/etc/my.cnf 中的[mysqld] 下面加上一行skip-grant-tables,保存退出编译文件。
    
    # 重启mysql,不同版本的操作系统中命令不一样,此处以CentOS 7 为例
    systemctl restart mysqld
    
    # 手动更新mysql.user.authentication_string 或者 mysql.user.password 字段
    update mysql.user set authentication_string=password('您的密码') where user='root';
    flush privileges;
    
    # 5.5 之前的版本中,到这一步,再重启Mysql,就可以了。但是5.6、5.7以后还要额外操作:
    # 关闭mysql
    systemctl stop mysqld
    
    # 取消免密登录,修改/etc/my.cnf 将skip-grant-tables 参数注释或者删除。
    
    # 编译文件initfile.txt,在文件中添加如下一句SQL:
    SET PASSWORD FOR 'root'@'localhost' = PASSWORD('密码');
    
    # 启动mysql 指定--init-file参数,参数值即在上一步中编译的文件名,在启动时执行脚本中的命令
    # 如果不通过这种方式,仍会遇到错误
    mysqld --init-file=initfile.txt
    
    # 重启mysql
    systemctl restart mysqld
    
    

2.1.2 无文件访问权限

  • 错误信息
MySQL [ypsx_order0]> select * into outfile '/tmp/a.xls' from order0;
ERROR 1045 (28000): Access denied for user 'order_read'@'%' (using password: YES)

当将一张表中的数据通过 select outfile 方式将数据备份至文件系统时出现。

  • 分析原因

其实这个问题也并没有跳出圈外。仍旧是权限问题,只不过是是否有访问文件的权限。 Mysql.user表中列出了一个用户所可以拥有的所有权限,其中包含一个 File_Priv 字段,这个字段代表用户是否有写文件的权限。只有拥有这个权限,才有可能进行下一 步–> 写文件,当然写文件前还要判断Mysql用户是否有文件路径有写权限等。

  • 解决方法

    update mysql.user set File_priv=’Y’ where user=’xxxx’;
    

3 ERROR 1055

  • 错误信息

    [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column
    'information_schema.PROFILING.SEQ' which is not functionally dependent on columns in GROUP BY clause;
    this is incompatible with sql_mode=only_full_group_by
    
  • 原因分析
    Mysql 中的SQL 语法并是严格按照SQL 95 标准的。在聚合操作时,group by 允许不包含所有select的非聚合 列. mysql 提供了一个参数可以使SQL 严格按照SQL 95标准编写,但是同时此参数是存在缺陷的。一些delete 等非聚合操作,从java 客户端发起时,有可能会引起错误:[err] 1055.
  • 解决方案
    简单的解决方案就是取消此参数设置。参数的设置方法如下:

    # 临时调整
    set @@sql_mode='参数列表,以逗号分隔'
    或者
    set global sql_mode='参数列表,以逗号分隔'
    # 永久调整  修改参数配置文件my.cnf
    sql_mode = '参数列表,不同参数之间以逗号分隔'
    
  • 操作示例
    在Mysql 里大部分的参数是分为全局和会话级别,全局分为临时与永久。一般临时调整就是通过set 命令调整。 全局调整,需要在参数文件中修改, 一般为/etc/my.cnf
    • 临时修改示例

      mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
      Query OK, 0 rows affected (0.00 sec)
      mysql> exit
      Bye
      [root@test ~]# mysql -D
      Reading table information for completion of table and column names
      You can turn off this feature to get a quicker startup with -A
      
      Welcome to the MySQL monitor.  Commands end with ; or g.
      Your MySQL connection id is 1814164
      Server version: 5.7.17 MySQL Community Server (GPL)
      
      Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
      
      Oracle is a registered trademark of Oracle Corporation and/or its
      affiliates. Other names may be trademarks of their respective
      owners.
      
      Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
      
      mysql> select @@sql_mode;
      +------------------------------------------------------------------------------------------------------------------------+
      | @@sql_mode                                                                                                             |
      +------------------------------------------------------------------------------------------------------------------------+
      | STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
      +------------------------------------------------------------------------------------------------------------------------+
      1 row in set (0.00 sec)
      
    • 永久修改示例

      # 修改之前
      sql_mode='ONLY_FULL_GROUP_BY,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
      # 修改之后
      sql_mode='NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
      

4 ERROR 1201

  • error code:ERROR 1201 (HY000): Could not initialize master info structure; more error messages can be found in the MySQL error log
  • Reason:

      出现这个问题的原因是之前曾做过主从复制!需要reset slave后再change
    
  • Solve:

    reset slave;
    

5 ERROR 1292

5.1 22007

  • 错误信息

    ERROR 1292 (22007): Truncated incorrect DOUBLE value: ''
    
  • 分析

    该错误是由于 MySQL 对字符值是否符合字段要求进行了严格的检查,但是有时候,这个 检查的结果却是错误的。就像下面示例:

    MariaDB [(none)]> update test.test set status=NULL where status=6;
    
    ERROR 1292 (22007): Truncated incorrect DOUBLE value: ''
    
    MariaDB [(none)]> desc test.test;
    +---------------------+--------------+------+-----+---------+----------------+
    | Field               | Type         | Null | Key | Default | Extra          |
    +---------------------+--------------+------+-----+---------+----------------+
    | id                  | bigint(20)   | NO   | PRI | NULL    | auto_increment |
    | status              | varchar(30)  | YES  |     | NULL    |                |
    +---------------------+--------------+------+-----+---------+----------------+
    2 rows in set (0.02 sec)
    

    从上面的查询结果来看,status 字段允许为空, 默认为空。我将该字段值更新为空字段并 没有违反该字段的约束条件。但是,错误就是么离奇的发生了。明明没有问题,却提示为错误 数据。

  • 查看SQL_MODE

      MariaDB [(none)]> show variables like 'sql_mode';
    +---------------+-------------------------------------------------------------------------------------------+
    | Variable_name | Value                                                                                     |
    +---------------+-------------------------------------------------------------------------------------------+
    | sql_mode      | STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
    +---------------+-------------------------------------------------------------------------------------------+
    
  • 解决 主要是把sql_mode中的strict_trans_tables去掉即可。

    set [global | session] variables sql_mode = 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
    

6 ERROR 1293

6.1 HY000

6.1.1 错误信息

ERROR 1293 (HY000) at line 35: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

6.1.2 原因

MySQL功能上的缺陷,不允许同一张表中的多个timestamp字段同时具有 on update current_timestamp() 的功能, 建表语句中只有第一个timestamp字段可以有这种属性,后面的不可以。在5.5及之前的版本中都 有这样的限制。5.6.5 以后取消了这种限制并扩展到了datetime类型字段上。 官方文档中有如下描述

  • MySQL 5.5

    One TIMESTAMP column in a table can have the current timestamp as the default value for initializing the column, as the auto-update value, or both. It is not possible to have the current timestamp be the default value for one column and the auto-update value for another column.
    
  • MySQL 5.6.5

    Previously, at most one TIMESTAMP column per table could be automatically initialized or updated to the current date and time. This restriction has been lifted. Any TIMESTAMP column definition can have any combination of DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses. In addition, these clauses now can be used with DATETIME column definitions. For more information, see Automatic Initialization and Updating for TIMESTAMP and DATETIME.
    

6.1.3 解决方法

  1. 升级mysql 到 5.6.5 及以上版本。
  2. 修改建表语句,只保留第一个timestamp字段使用current_timestamp()。

7 ERROR 1406

7.1 22001

7.1.1 unsinged 与signed

  • 错误信息

    ERROR 1406 (22001): Data too long for column 'seq_nextval('acct')' at row 1
    

    这是在调用函数时出现的一个问题。也就是说在函数处理过程中出现了超过了精度限制。经分析是bigint unsigned数据需要存储进bigint signed类型的变量中。 导致超过最大允许长度。而报出的一个错误,但是后面在测试过程中又没有报这个错误,而是直接返回了负数。

  • 原因分析

    MySQL 中的数字类型,分为unsigned 和signed 两种类型。以bigint 为例,bigint signed ,存储的取值范围是-9223372036854775807到9223372036854775807,而bigint unsigned ,取值范围是0-18446744073709551613。 当把18446744073709551613 赋值给signed类型变量时,就会超出精度,要么报错退出,要么返回负数或者是其他与原数不相等的数。

  • 测试验证
    • 准备测试数据

      /*建表*/
      drop table if exists sequences;
      create table sequences(
      sequence_name varchar(30) not null comment '序列名',
      prefix1       varchar(20) null comment '前缀1',
      prefix2       varchar(20) null comment '前缀2',
      prefix3       varchar(20) null comment '前缀3',
      start_with    bigint      not null comment '起始值',
      increment_by  bigint      not null default 1 comment '增长步长',
      max_value     bigint unsigned null default 18446744073709551613 comment '最大值',
      cycle         smallint    null  default 0 comment '是否循环使用:0-不循环,1-循环',
      current_value bigint      null ,
      primary key (sequence_name)
      );
      
      /* 插入测试数据 */
      insert into sequences(sequence_name,start_with,increment_by,current_value) values('acct',1,1,1);
      
      /* 查看测试数据 */
      mysql> select * from sequences where sequence_name='acct';
      +---------------+---------+---------+---------+------------+--------------+----------------------+-------+---------------+
      | sequence_name | prefix1 | prefix2 | prefix3 | start_with | increment_by | max_value            | cycle | current_value |
      +---------------+---------+---------+---------+------------+--------------+----------------------+-------+---------------+
      | acct          | NULL    | NULL    | NULL    |          1 |            1 | 18446744073709551613 |     0 |             1 |
      +---------------+---------+---------+---------+------------+--------------+----------------------+-------+---------------+
      1 row in set (0.00 sec)
      
      
    • 创建函数

      此步骤创建两个函数,一个在定义变量ma时,数据类型为bigint unsigned, 一个为bigint signed.

      • 函数1

        delimiter $$
        create function seq_unsigned (v_sequence_name varchar(30)) returns varchar(200)
        begin
        declare ma bigint(20) unsigned;
        
        select max_value into ma from sequences where sequence_name=v_sequence_name ;
        return ma;
        end $$
        delimiter ;
        
      • 函数2

        delimiter $$
        create function seq_signed (v_sequence_name varchar(30)) returns varchar(200)
        begin
        declare ma bigint(20);
        
        select max_value into ma from sequences where sequence_name=v_sequence_name ;
        return ma;
        end $$
        delimiter ;
        
    • 执行函数测试结果
      • 函数1

              select seq_unsinged('acct');
        +----------------------+
        | seq_unsigned('acct') |
        +----------------------+
        | 18446744073709551613 |
        +----------------------+
        1 row in set (0.00 sec)
        
      • 函数2

        select seq_signed('acct');
        +--------------------+
        | seq_signed('acct') |
        +--------------------+
        | -3                 |
        +--------------------+
        1 row in set (0.00 sec)
        

7.1.2 sql_mode语法校验

  • 分析

    Mysql 中默认执行的严格的语法校验。 当参数sql_mode 的值包含'STRICT_TRANS_TABLES' 时就会进行严格的语法检验。 当插入字段的数据超过该字段最大允许的长度时,就会报出如下错误:

    ERROR 1406 (22001): Data too long for column 'name' at row 1
    
  • 解决方法
    1. 将 STRICT_TRANS_TABLES 及相关的 NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO 一起从sql_mode参数中去除, 就不会再报错。此时Mysql 的处理规则为自动截取字段允许的最大长度,也就是说存储起来的数据是完整的。
    2. 调整表结构,增加字段允许的最大精度

      alter table <table_name> modify <column_name> <data_type>(precise) default ...
      如:
      alter table test modify id bigint(20) default 100 comment '测试';
      

8 ERROR 1548

错误信息:

Cannot load from mysql.proc. The table is probably corrupted.

内部表结构不对。需要升级更新:

mysql_upgrade -uroot -p

9 ERROR 1820

数据库版本:mysql Ver 14.14 Distrib 5.7.29, for Linux (x86_64) using EditLine wrapper

9.1 现象

mysql> show databases;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
mysql> set password for 'root'@'localhost' = password('root');
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

9.2 原因

5.7版本后开启了对用户密码复杂度校验,具体设置字段如下:

参数 说明
validate_password_dictionary_file 插件用于验证密码强度的字典文件路径。
validate_password_length 密码最小长度,参数默认为8,它有最小值的限制,最小值为:
  validate_password_number_count + validate_password_special_char_count
  + (2 * validate_password_mixed_case_count)
validate_password_mixed_case_count 密码至少要包含的小写字母个数和大写字母个数。
validate_password_number_count 密码至少要包含的数字个数
validate_password_policy 密码强度检查等级,0/LOW、1/MEDIUM、2/STRONG。有以下取值:
  Policy Tests Performed
  0 or LOW Length
  1 or MEDIUM Length; numeric, lowercase/uppercase, and special characters
  2 or STRONG Length; numeric, lowercase/uppercase, and special characters;
  默认是1,所以刚开始设置的密码必须符合长度,且必须含有数字,小写或大写字母,特殊字符
validate_password_special_char_count 密码至少要包含的特殊字符数。

9.3 解决方法

  1. 设置复杂密码(推荐)

    set password for 'root'@'localhost'=password('R00t123.,y_');
    
  2. 取消密码复杂度校验

    set global validate_password_policy=0;
    set global validate_password_mixed_case_count=0;
    set global validate_password_number_count=3;
    set global validate_password_special_char_count=0;
    set global validate_password_length=3;
    

10 ERROR 1872

10.1 错误信息

ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository

10.2 分析原因

  1. 配置了参数 log_slave_updates . 配置此参数后, 数据库相应的需要生成中继日志,如果没有配置,则不会生成,也就是说,log_slave_updates 依赖于relay_log。
    因此,在这种情况下,要求 配置relay_log 参数
  2. master.info 文件中的信息有误
  3. slave 信息变动 slave 信息发生变动,使用reset slave. 但是内存中的信息没有被清空。要清空内存与配置中的信息,需要执行reset slave all;
  4. …. 未知.

11 ERROR 2003

  • error code:ERROR 2003 (HY000): Can't connect to MySQL server on 'ip_address' (111)
  • Reason:

12 ERROR 2013

12.1 错误提示

mysqldump: Error 2013: Lost connection to MySQL server during query when dumping table `xxxxx` at row: 7114978

12.2 原因1

  • 原因

    mysqldump来不及接受mysql server端发送过来的数据,Server端的数据就会积压在内存中等待发送,
    这个等待不是无限期的,当Server的等待时间超过net_write_timeout(默认是60秒)时它就失去了耐心,
    mysqldump的连接会被断开,同时抛出错误Got error: 2013: Lost connection.
    
    增加net_write_timeout可以解决上述的问题的。在实践中发现,在增大 net_write_timeout后,
    Server端会消耗更多的内存,有时甚至会导致swap的使用(并不确定是不是修改 net_write_timeout所至)。
    建议在mysqldump之前修改net_write_timeout为一个较大的值(如1800),在 mysqldump结束后,
    在将这个值修改到默认的60。
    
  • 解决方法

    在sql命令行里面设置临时全局生效用类似如下命令:
    SET GLOBAL net_write_timeout=1800;
    

12.3 原因2

  • 原因
    由于MySQL无法解析ip地址,而报出的错误:
  • 解决方法
    在参数配置文件(默认为/etc/my.cnf) 中[mysqld] 下添加 skip-name-resove . 重启 MySQL即可。

Author: halberd

Created: 2020-04-02 Thu 17:40

Validate

原文地址:https://www.cnblogs.com/halberd-lee/p/11209123.html