没有遇到过这十个经典的MySQL数据库错误,你一定不是一个好的工程师。经常会遇到各种奇怪的报错信息,遇到报错会很慌张,急需解决问题的方法。像无头苍蝇一样,想都没想就把错误贴在百度上,希望能找到解决问题的好方法。我想以上应该是刚接触数据库的新手都会遇到的困境。今天小编就为大家罗列MySQL数据库中最经典的十大错误案例,以及解决问题的方法和处理方法。希望能给新手或者数据库爱好者一些帮助。我们可以冷静地处理未来的任何错误。在学习任何技术的同时,其实都是一个修身的过程。静下心来,尝试拥抱数据的世界!情况一:连接过多(连接过多,导致无法连接数据库,业务无法正常进行)问题恢复:mysql>showvariableslike'%max_connection%';|Variable_name|Value|max_connections|151|mysql>setglobalmax_connections=1;QueryOK,0rowsaffected(0.00sec)[root@node4~]#mysql-uzs-p123456-h192.168.56.132ERROR1040(00000):Toomanyconnections问题的解决方法:1.首先考虑在我们的MySQL数据库中参数文件,是对应的max_connections参数值设置过小,导致客户端连接数超过了数据库所能承受的最大值。这个值的默认大小是151,我们可以根据实际情况进行调整。对应解决方案:设置globalmax_connections=500,但是这个调整会有隐患,因为我们无法确认数据库是否能承受这么大的连接压力,就像一个人只能吃一个馒头,现在却非要让他吃一样吃10个,他肯定接受不了。如果反映在服务器上,可能会有宕机的可能。所以这也体现了我们上线一个新的业务系统的时候,一定要做好压力测试。确保数据库在以后进行了优化和调整。2、其次,可以限制InnoDB的并发处理数。如果innodb_thread_concurrency=0(意思是无限制),可以先改成16或者64看服务器压力。如果很大,可以先改小一点,减轻服务器压力,再慢慢增加。根据您的业务,我个人建议您可以先将其调整为16。MySQL的性能会随着连接数的增加而下降。MySQL5.7之前,需要让开发配合设置线程池,重用连接。MySQL5.7以后,数据库有了自己的线程池,连接数问题也相应解决了。另外,对于一些读取information_schema下表的监控程序,可以考虑关闭以下参数:innodb_stats_on_metadata=0setglobalinnodb_stats_on_metadata=0案例2主从复制错误类型Last_SQL_Errno:1062(从库和从库数据冲突masterdatabase)Last_Errno:1062Last_Error:CouldnotexecuteWrite_rowseventontabletest.t;Duplicateentry'4'forkey'PRIMARY',Error_code:1062;handlererrorHA_ERR_FOUND_DUPP_KEY;theevent'smasterlogmysql-bin.000014,end_log_pos1505对于这个报错,首先要考虑是否是由于来自库的错误操作。原来是我们在从库中对一个有主键的表插入了一条SQL语句,导致主库再次插入同一条SQL语句时,主从状态出现异常。发生主键冲突错误。解决方案:在保证主从数据一致性的前提下,可以在从库中跳过错误。一般使用percona-toolkit中的pt-slave-restart。在从库上完成如下操作:[root@zsbin]#./pt-slave-restart-uroot-proot1232017-07-20T14:05:30p=…,u=rootnode4-relay-bin.00000215061062之后最好在从库开启read_only参数,禁止从库写操作。Last_IO_Errno:1593(server-id冲突)Last_IO_Error:Fatalerror:TheslaveI/OthreadstopsbecausemasterandslavehaveequalMySQLserverids;theseidsmustbedifferentforreplicationtowork(orthe–replicate-same-server-idoptionmustbeusedonslavebutthisdoesnotalwaysmakesense;pleasecheckthemanualbeforeusingit)这个报错出现之后,就能一目了然看到两台机器的server-id是一样的。在构建主从复制的过程中,我们需要保证两台机器的server-ids是唯一的。这里再次强调一下server-id的命名规则(服务器ip地址最后一位+本次MySQL服务的端口号)。解决方法:在master和slave机器上设置不同的server-ids。Last_SQL_Errno:1032(从库数据少,更新主库时,从库报错)Last_SQL_Error:CouldnotexecuteUpdate_rowseventontabletest.t;Can'tfindingrecordin',Error_code:1032;handlererrorHA_ERR_KEY_NOT_FOUND;theevent'smasterlogmysql-bin.000014,end_7解决方法:根据错误信息,我们可以得到错误日志和位置号,然后我们可以找出主库执行了哪条sql,导致了主从错误。在主库执行:/usr/local/mysql/bin/mysqlbinlog–no-defaults-v-v–base64-output=decode-rows/data/mysql/mysql-bin.000014|grep-A101708>1.logcat1.log#17072014:20:15serverid3end_log_pos1708CRC320x97b6bdecUpdate_rows:tableid113flags:STMT_END_F###UPDATE`test`.`t`###WHERE###@1=4/*INTmeta=0nullable=0is_null=0*/###@2='dd'/*VARSTRING(60)meta=60nullable=1is_null=0*/###SET###@1=4/*INTmeta=0nullable=0is_null=0*/###@2='ddd'/*VARSTRING(60)meta=60nullable=1is_null=0*/#at1708#17072014:20:15serverid3end_log_pos1739CRC320xecaf1922Xid=654COMMIT/*!*/;DELIMITER;#EndoflogfileROLLBACK/*addedbymysqlbinlog*/;/*!COMPLETION03OLD_COMPLETION_TYPE*/;/*!50530SET@@SESSION.PSEUDO_SLAVE_MODE=0*/;获取SQL语句后,可以从库中反向执行SQL语句。从库中补全缺失的SQL语句并解决错误信息。在从库依次执行:mysql>insertintot(b)values('ddd');QueryOK,1rowaffected(0.01sec)mysql>stopslave;QueryOK,0rowsaffected(0.00sec)mysql>exitBye[root@node4bin]#./pt-slave-restart-uroot-proot1232017-07-20T14:31:37p=...,u=rootnode4-relay-bin.0000052831032案例三MySQL安装过程中的报错[root@zsdata]#/usr/local/mysql/bin/mysqld_safe–defaults-file=/etc/my.cnf&[1]3758[root@zsdata]#17072014:41:24mysqld_safeLoggingto'/data/mysql/error.log'.17072014:41:24mysqld_safeStartingmysqlddaemonwithdatabasesfrom/data/mysql17072014:41:25mysqld_safemysqldfrompidfile/data/mysql/node4.pidended17072014:41:24mysqld_safeStartingmysqlddaemonwithdatabasesfrom/data/mysql2017-07-2014:41:250[Warning]TIMESTAMPwithimplicitDEFAULTvalueisdeprecated.Pleaseuse–explicit_defaults_for_timestampserveroption(seedocumentationformoredetails)./usr/local/mysql/bin/mysqld:File'/data/mysql/mysql-bin.index'notfound(Errcode:13–Permissiondenied)2017-07-2014:41:254388[ERROR]中止解决方法:遇到此类错误信息时,一定要学会时时关注错误日志的内容。我们看到关键的错误点Permissiondenied,证明当前MySQL数据库的数据目录没有权限。.解决方法:[root@zsdata]#chownmysql:mysql-Rmysql[root@zsdata]#/usr/local/mysql/bin/mysqld_safe–defaults-file=/etc/my.cnf&[1]4402[root@zsdata]#17072014:45:56mysqld_safeLoggingto'/data/mysql/error.log'.17072014:45:56mysqld_safeStartingmysqlddaemonwithdatabasesfrom/data/mysql启动成功。如何避免此类问题,我个人建议在安装MySQL和初始化时,一定要加上-user=mysql,以免出现权限问题。./mysql_install_db–basedir=/usr/local/mysql/–datadir=/data/mysql/–defaults-file=/etc/my.cnf–user=mysql案例4忘记数据库密码的问题【root@zs~]#mysql-uroot-pEnterpassword:ERROR1045(28000):拒绝用户'root'@'localhost'(usingpassword:YES)[root@zs~]#mysql-uroot-pEnterpassword:ERROR1045(28000):拒绝访问user'root'@'localhost'(usingpassword:YES)我们可能刚刚接管了别人的MySQL数据库,还没有完整的交接文件。root密码可能会丢失或忘记。解决办法:目前无法进入数据库,所以要考虑能不能跳过权限。因为在数据库中,MySQL数据库中的user表记录了我们用户的信息。解决方法:在启动MySQL数据库的过程中,可以这样执行:/usr/local/mysql/bin/mysqld_safe–defaults-file=/etc/my.cnf–skip-grant-tables&这样启动,你不用输入密码,直接进入MySQL数据库。然后更改要更改的root密码。updatemysql.usersetpassword=password('root123')whereuser='root';案例5:truncate删除数据,导致自增ID自动清空,前端返回未找到错误。必须考虑截断和删除之间的区别。看实验演练:首先创建一个表:CREATETABLE`t`(`a`int(11)NOTNULLAUTO_INCREMENT,`b`varchar(20)DEFAULTNULL,PRIMARYKEY(`a`),KEY`b`(`b`))ENGINE=InnoDBAUTO_INCREMENT=300DEFAULTCHARSET=utf8插入三条数据:mysql>insertintot(b)values('aa');QueryOK,1rowaffected(0.00sec)mysql>insertintot(b)values('bb');QueryOK,1rowaffected(0.00sec)mysql>insertintot(b)values('cc');QueryOK,1rowaffected(0.00sec)mysql>select*fromt;+—–+——+|a|b|+——+——+|300|aa||301|bb||302|cc|+——–+——+3rowsinset(0.00sec)使用delete先删除整个表信息,再插入新值。原来truncate重置了自增初始值,自增属性从1开始记录,前端使用主键id查询时,会报错没有该数据。个人不建议使用truncate删除表。表空间虽然可以回收,但是会涉及到自增属性的问题。我们不想轻易进入这些坑。案例6阿里云MySQL配置文件在阿里云MySQL配置文件中,需要注意一个参数设置:lower_case_table_names=0;默认情况下。lower_case_table_names=1;是否区分大小写。如果提示找不到小写的表名,那么可以将远程数据库的表名改成小写,反之亦然。注意Mybatis的Mapper文件中的所有表名也要相应修改。案例7数据库总是中文乱码经常有同学问为什么我的数据库总是中文乱码。不知道一堆中文乱码是怎么回事?写数据库建表插入汉字时会出现这种问题。这个错误会涉及到数据库字符集的问题。解决办法:对于中文乱码的情况,只要记住老师告诉你的三个统一即可。也知道目前MySQL数据库中的字符集编码默认是UTF8。解决方法:数据终端,也就是我们用来连接数据库的工具,设置为utf8。在操作系统层面,可以通过cat/etc/sysconfig/i18n查看,设置为utf8。在数据库层面,在参数文件中mysqld下添加character-set-server=utf8。Emoji表情输入MySQL数据库报错:Causedby:java.sql.SQLException:Incorrectstringvalue:'ee...'forcolumn'CONTENT'atrow1atcom.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)atcom.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)atcom.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)atcom.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)atcom.mysql。jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)atcom.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734)atcom.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)atcom.mysql.jdbc。PreparedStatement.execute(PreparedStatement.java:1379)解决方法:对于表情插入的问题,肯定是字符集问题。解决方法:我们可以直接在参数文件中加入:vim/etc/my.cnf[mysqld]init-connect='SETNAMESutf8mb4'character-set-server=utf8mb4注意:utf8mb4是utf8的超集。案例8使用binlog_format=statement格式,跨库操作,导致数据库数据丢失,用户访问导致错误数据信息当前数据库二进制日志格式为:binlog_format=statement,设置binlog-do-db=mydb1(只同步mydb1库)。执行usemydb2;insertintomydb1.t1values('bb');在主数据库中;这条语句不会同步到从库。但是这样做会奏效;usemydb1;insertintomydb1.t1values('bb');因为那是在同一个图书馆里所做的。生产环境建议使用binlog格式asrow,谨慎使用binlog-do-db参数。案例九MySQL数据库连接超时的报错org.hibernate.util.JDBCExceptionReporter–SQLError:0,SQLState:08S01org.hibernate.util.JDBCExceptionReporter–Thelastpacketsuccessfullyreceivedfromtheserverwas43200millisecondsago.Thelastpacketsentsuccessfullytotheserverwas43200millisecondsago,whichislongerthantheserverconfiguredvalueof'wait_timeout'.Youshouldconsidereitherexpiringand/ortestingconnectionvaliditybeforeuseinyourapplication,increasingtheserverconfiguredvaluesforclienttimeouts,orusingtheConnector/Jconnection'autoReconnect=true'toavoidthisproblem.org.hibernate.event.def.AbstractFlushingEventListener–Couldnotsynchronizeddatabasestatewithsessionorg.hibernate.exception.JDBCConnectionException:CouldnotexecuteJDBCbatchupdatecom.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:Connection.close()已调用。Invalidoperationinthisstate.util.org.JDBCExceptionReporter–SQLError:0,SQLState:08003org.hibernate.util.JDBCExceptionReporter–Nooperationsallowedafterconnectionclosed.Connectionwasimplicitlyclosedduetunderlyingexception/error:**BEGINNESTEDEXCEPTION**大部分做DBA的同学可能会被开发者告知你的数据库报了这个错误,通过wait_timeout和wait_timeout这两个参数快速找出问题出在哪里交互超时。数据默认的配置时间是28800(8小时),也就是说过了这个时间,MySQL数据库为了节省资源,会在数据库端断开连接,MySQL服务器会断开连接,但是我们的程序使用它又对这个连接没有做任何判断,就挂了。解决思路:首先要了解这两个参数的特点。这两个参数必须同时设置,并且取值必须??一致。我们可以适当增加这个值。8小时太长,不适合生产环境。因为一个连接长时间不工作,还是会占用我们的连接数,消耗我们的系统资源。解决方法:可以在程序中适当判断。强烈建议在操作结束时更改应用逻辑以适当关闭连接,然后设置合理的超时值(根据业务情况判断)。Case10can'topenfile(errno:24)有时候,数据库运行的很好,突然报错,无法打开数据库文件。解决方法:首先,我们需要查看数据库的错误日志。然后判断是表损坏还是权限问题。也有可能是磁盘空间不足导致表无法正常访问;注意操作系统的限制;使用perror工具查看具体错误!linux:/usr/local/mysql/bin#./perror24OSerrorcode24:Toomanyopenfilesexceedsthemaximumnumberofopenfiles!ulimit-n查看系统最大打开文件数为65535,不能超过!肯定是数据库的最大打开文件数超过了限制!查看MySQL最大打开文件数限制命令:showvariableslike'open_files_limit';发现数值太小,改为2048,重启MySQL,应用正常。解决办法:修表;chownmysql权限清理磁盘中的垃圾数据。以后我们会继续总结MySQL中的各种错误处理思路和方法。希望与所有退伍军人和学生一起努力。多沟通多沟通!
