原因
今天发现mysql数据库磁盘满了, 看到很多的binlog文件很大, 而且修改时间又是在很久, 之前于是就备份了一下binlog日志, 然后把binlog日志删除了。最终导致在进行了一个个mysql的写操作之后mysql挂了, 而且无法重启.
通过ps -ef|grep mysql 命令来查看mysql进程, 发现进程在, 但是想kill
进程的时候发现, 进程又不存在了, 然后再次打开查看mysql进程发现进程id又不一样了, 此时感觉到这个mysql应该是不断在重启, 而又不断的重启失败。
此时想查看mysql的启动报错日志, 但是又不知道路径, 于是通过以下命令来查看mysql的日志路径:
vim /etc/my.cnf
发现mysqld模块下面如下的配置
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
default_authentication_plugin=mysql_native_password
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
然后通过命令 vim /var/log/mysqld.log来查看mysql的报错日志
具体的报错如下:
space name jxtms/CostManage, which is outside the tablespace bounds. B
yte offset 0, len 16384, i/o type read. If you get this error at mysqld startup, please check that your my.cnf matches the ibdata files that you have in the MySQL server.
通过那个报错以为是my.cnf中没有匹配ibdata files的路径, 于是在my.cnf加了一下配置, 但是发现还是没有用, 还是在不断
innodb_data_file_path = ibdata1:76M;ibdata2:12M:autoextend:max:500M
然后就试了试mysql日志中推荐的强制恢复mysql的操作, 官方地址如下:
https://dev.mysql.com/doc/refman/8.0/en/forcing-innodb-recovery.html
主要就是在mysqld中加一下如下的配置, 其中后面的值从1-6, 从1到6风险主键增加, 官方文档也说必须先备份一下你的数据, 这里我都无法启动了不知道如何备份, 幸运的是我同事在前两天备份过数据库, 而且我们是开发库, 问题不是很大.
[mysqld]
innodb_force_recovery = 1
但是我设置了该配置从1一直到6都无济于事, 一直还是处于不断重启中, 然后就放弃了这个办法。最终同事用这个方法成功了, 原因居然是我没有把这个配置innodb_force_recovery = 1放在配置文件my.cnf下面的[mysqld]模块的第一行,而是最后一行, 导致这个配置没有生效。
像下面这样就可以了.
然后重启数据库就能启动了, 但是重启以后,还是无法访问有问题的表空间对应的数据库, 其他数据库是能访问的.此时只能新建一个同名字的数据库, 然后把数据重新到导入里面。然后把innodb_force_recovery给蛛丝注释掉, 再次重启mysql即可.
附加知识
binlog二进制日志是mysql-server层的,主要是做主从复制,时间点恢复使用。redo log重做日志是InnoDB存储引擎层的,用来保证事务安全。undo log回滚日志保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读。redo log。redo log在事务没有提交前,每一个修改操作都会记录变更后的数据,保存的是物理日志->数据。
binlog是一个二进制格式的文件,用于记录用户对数据库更新的SQL语句信息,但对库表等内容的查询不会记录由于是二进制文件,需使用mysqlbinlog解析查看主要作用:用于数据库的主从复制及数据的增量恢复ROW (行模式) :
记录哪条数据修改了记录的是修改的那条记录的全部数据,即使只更新了-个字段, binlog里也会记录所有字段的数据Statement (语句模式) :每一条会修改数据的sq都会记录在binlog中作用:用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步。