我们的生产 mysql 服务器刚刚崩溃,无法恢复。它给出了一个段错误。我尝试重新启动,但不知道还能尝试什么。以下是堆栈跟踪:
140502 14:13:05 [注意] 插件‘FEDERATED’已被禁用。 InnoDB:日志扫描已超过检查点 lsn 108 1057948207 140502 14:13:06 InnoDB:数据库未正常关闭! InnoDB:开始崩溃恢复。 InnoDB:从 .ibd 文件读取表空间信息... InnoDB:从双写中恢复可能半写的数据页 InnoDB:缓冲区... InnoDB:正在进行恢复:扫描至日志序列号 108 1058059648 InnoDB:1 个事务必须回滚或清理 InnoDB:总共需要撤消 15 行操作 InnoDB:Trx id 计数器为 0 562485504 140502 14:13:06 InnoDB:开始将一批日志记录应用到数据库…… InnoDB:进度百分比:4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 InnoDB:应用批次完成 InnoDB:在后台启动未提交事务的回滚 140502 14:13:06 InnoDB: 回滚 ID 为 0 562485192 的 trx,需要撤消 15 行 140502 14:13:06 InnoDB:已启动;日志序列号 108 1058059648 140502 14:13:06 InnoDB:文件 ../../../storage/innobase/fsp/fsp0fsp.c 第 1593 行中线程 1873206128 中的断言失败 InnoDB:断言失败:frag_n_used > 0 InnoDB:我们故意产生一个内存陷阱。 InnoDB:向 http://bugs.mysql.com 提交详细的错误报告。 InnoDB:如果你反复遇到断言失败或崩溃,即使 InnoDB:mysqld 启动后,可能会出现 InnoDB:InnoDB 表空间损坏。请参阅 InnoDB:http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html InnoDB:关于强制恢复。 140502 14:13:06 — mysqld 收到信号 6; 这可能是因为你遇到了 bug。这个二进制文件也可能 或者它所链接的某个库已损坏、构建不正确, 或配置错误。此错误也可能由硬件故障引起。 我们将尽力收集一些有助于诊断的信息 问题,但既然我们已经崩溃了,肯定出了问题 这可能会失败。 密钥缓冲区大小=16777216 读取缓冲区大小=131072 最大使用连接数=0 最大线程数=151 线程连接=0 mysqld 可能会使用最多 key_buffer_size + (read_buffer_size + sort_buffer_size) *max_threads = 345919 K 内存字节数 希望没问题;如果不行,请减少等式中的一些变量。 thd:0x0 尝试回溯。您可以使用以下信息来查找 mysqld 死机了。如果此后没有看到任何消息,则表示发生了一些问题 大错特错…… stack_bottom = (无)线程堆栈 0x30000 140502 14:13:06 [注意] 事件调度程序:已加载 0 个事件 140502 14:13:06 [注意] /usr/sbin/mysqld:已准备好连接。 版本:'5.1.41-3ubuntu12.10' 套接字:'/var/run/mysqld/mysqld.sock' 端口:3306 (Ubuntu) /usr/sbin/mysqld(my_print_stacktrace+0x2d) [0xb7579cbd] /usr/sbin/mysqld(handle_segfault+0x494) [0xb7245854] [0xb6fc0400] /lib/tls/i686/cmov/libc.so.6(中止+0x182) [0xb6cc5a82] /usr/sbin/mysqld(+0x4867e9) [0xb74647e9] /usr/sbin/mysqld(btr_page_free_low+0x122) [0xb74f1622] /usr/sbin/mysqld(btr_compress+0x684) [0xb74f4ca4] /usr/sbin/mysqld(btr_cur_compress_if_useful+0xe7) [0xb74284e7] /usr/sbin/mysqld(btr_cur_pessimistic_delete+0x332) [0xb7429e72] /usr/sbin/mysqld(btr_node_ptr_delete+0x82) [0xb74f4012] /usr/sbin/mysqld(btr_discard_page+0x175) [0xb74f41e5] /usr/sbin/mysqld(btr_cur_pessimistic_delete+0x3e8) [0xb7429f28] /usr/sbin/mysqld(+0x526197) [0xb7504197] /usr/sbin/mysqld(row_undo_ins+0x1b1) [0xb7504771] /usr/sbin/mysqld(row_undo_step+0x25f) [0xb74c210f] /usr/sbin/mysqld(que_run_threads+0x58a) [0xb74a31da] /usr/sbin/mysqld(trx_rollback_or_clean_all_without_sess+0x3e3) [0xb74ded43] /lib/tls/i686/cmov/libpthread.so.0(+0x596e) [0xb6f9f96e] /lib/tls/i686/cmov/libc.so.6(克隆+0x5e) [0xb6d65a4e] http://dev.mysql.com/doc/mysql/en/crashing.html 上的手册页包含 这些信息应该可以帮助您找出导致崩溃的原因。
有什么建议吗?
答案1
哎哟。
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html
InnoDB: about forcing recovery.
检查建议的网页:http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html。
基本上,尝试以恢复模式启动 MySQL 服务器并备份崩溃的表。
编辑您的/etc/my.cnf
并添加:
innodb_force_recovery = 1
...看看您是否可以进入数据库并获取数据/找到损坏的表。
通常,当发生这种情况时,需要重建(至少重建一张或两张损坏的表)。
从http://chepri.com/mysql-innodb-corruption-and-recovery/:
- 停止
mysqld
(service mysql stop
)。 - 备份
/var/lib/mysql/ib*
添加以下行
/etc/my.cnf
:innodb_force_recovery = 1
(他们建议 4,但最好从 1 开始,如果无法启动则增加)
重新开始
mysqld
(service mysql start
)。- 转储所有表:
mysqldump -A > dump.sql
- 删除所有需要恢复的数据库。
- 停止
mysqld
(service mysql stop
)。 - 消除
/var/lib/mysql/ib*
- 注释掉
innodb_force_recovery
/etc/my.cnf
- 重启
mysqld
。查看mysql错误日志。默认情况下,它应该是/var/lib/mysql/server/hostname.com.err
查看它如何创建新ib*
文件。 - 从转储恢复数据库:
mysql < dump.sql
答案2
我在使用 mysql:5.7 docker 镜像时遇到了同样的错误。主要错误是尝试创建默认存在的 root 用户。更多信息:https://github.com/docker-library/mysql/issues/129
如上面的链接所示,解决方案是在启动 docker 镜像时不要在环境变量中设置 MYSQL_USER 和 MYSQL_PASSWORD。
答案3
我在 Laravel Homestead (Vagrant 在运行 Mac OS Sierra 10.12.4 (16E195) 时发生内核恐慌后发生了这种情况:
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.3 LTS
Release: 14.04
Codename: trusty
$ mysql -V
mysql Ver 14.14 Distrib 5.7.9, for Linux (x86_64) using EditLine
wrapper
以下是一些你可以尝试的资源,尽管所有的修复方法都不适合我:
https://dev.mysql.com/doc/refman/5.7/en/forcing-innodb-recovery.html
https://forums.mysql.com/read.php?22,603093,604631#msg-604631
我尝试在 mysql 配置中添加强制恢复(从 1 开始并逐渐增加,因为更高的数字可能会导致永久性损坏):
sudo nano /etc/mysql/my.cnf
[mysqld]
innodb_force_recovery = 1
#innodb-read-only=1
#innodb_purge_threads=0
#key_buffer_size=16M
#event-scheduler=disabled
在另一个窗口中运行:
tail -f /var/log/mysql/error.log
然后尝试在启用各种选项的情况下重新启动 mysqld:
sudo /etc/init.d/mysql restart
如果超时,您可以强制重新启动 mysql 进程:
# process id is first column with number, just ignore lines with grep because they list the process running 'grep mysql'
ps aux | grep mysql
sudo kill -9 <process-id>
sudo /etc/init.d/mysql restart
如果有效,日志将显示类似以下内容:
Version: '5.7.9' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)
如果失败,日志将显示类似以下内容:
InnoDB: Assertion failure in thread 140049488692992 in file log0recv.cc line 1420
当情况变得更糟时,我尝试删除可能已损坏的数据库:
sudo ls -alt /var/lib/mysql
事实证明,我一直在处理的数据库是列表顶部最近修改的数据库。幸运的是,我有当天的 SQL 转储,因此能够将其删除:
sudo rm -rf /var/lib/mysql/<database_name>
我保留了所有其他文件,但 mysql 仍然能够启动。
innodb_force_recovery = 1
更新:一旦 mysql 再次工作,请确保禁用它,否则当您尝试修改数据库和表时会收到错误。
然后我用 Sequel Pro 重新创建了数据库,重新导入了我的数据,并且能够继续前进,而不必丢弃其他项目的所有数据库。
展望未来,我必须假设任何 mysql 数据库都可能损坏,并尝试保留每日备份并将数据库重新创建脚本记录或编码到我的持续集成工具中。