MySQL致命错误:无法打开和锁定权限表:文件格式不正确'user'。

15

MySQL (Percona 5.6)无法启动。

我遇到过这个错误好几次了。每次都必须删除MySQL数据目录并重新安装MySQL。

有没有其他方法可以修复MySQL?(特别是不会丢失数据的方法?)

/var/log/mysql/error.log

150214 16:36:39 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
2015-02-14 16:36:40 0 [Warning] Using unique option prefix key_buffer instead of key_buffer_size is deprecated and will be removed in a future release. Please use the full name instead.
2015-02-14 16:36:40 0 [Warning] 'THREAD_CONCURRENCY' is deprecated and will be removed in a future release.
2015-02-14 16:36:40 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2015-02-14 16:36:40 1018 [Warning] Using unique option prefix myisam-recover instead of myisam-recover-options is deprecated and will be removed in a future release. Please use the full name instead.
2015-02-14 16:36:40 1018 [Note] Plugin 'FEDERATED' is disabled.
/usr/sbin/mysqld: Incorrect file format 'plugin'
2015-02-14 16:36:40 1018 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
2015-02-14 16:36:40 1018 [Note] InnoDB: Using atomics to ref count buffer pool pages
2015-02-14 16:36:40 1018 [Note] InnoDB: The InnoDB memory heap is disabled
2015-02-14 16:36:40 1018 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2015-02-14 16:36:40 1018 [Note] InnoDB: Memory barrier is not used
2015-02-14 16:36:40 1018 [Note] InnoDB: Compressed tables use zlib 1.2.8
2015-02-14 16:36:40 1018 [Note] InnoDB: Using Linux native AIO
2015-02-14 16:36:40 1018 [Note] InnoDB: Using CPU crc32 instructions
2015-02-14 16:36:40 1018 [Note] InnoDB: Initializing buffer pool, size = 256.0M
2015-02-14 16:36:40 1018 [Note] InnoDB: Completed initialization of buffer pool
2015-02-14 16:36:40 1018 [Note] InnoDB: Highest supported file format is Barracuda.
2015-02-14 16:36:40 1018 [Note] InnoDB: The log sequence numbers 714340126 and 714340126 in ibdata files do not match the log sequence number 716513090 in the ib_logfiles!
2015-02-14 16:36:40 1018 [Note] InnoDB: Database was not shutdown normally!
2015-02-14 16:36:40 1018 [Note] InnoDB: Starting crash recovery.
2015-02-14 16:36:40 1018 [Note] InnoDB: Reading tablespace information from the .ibd files...
2015-02-14 16:36:40 1018 [Note] InnoDB: Restoring possible half-written data pages 
2015-02-14 16:36:40 1018 [Note] InnoDB: from the doublewrite buffer...
InnoDB: Last MySQL binlog file position 0 292596, file name binlog.000056
2015-02-14 16:36:40 1018 [Note] InnoDB: 128 rollback segment(s) are active.
2015-02-14 16:36:40 1018 [Note] InnoDB: Waiting for purge to start
2015-02-14 16:36:40 1018 [Note] InnoDB:  Percona XtraDB (http://www.percona.com) 5.6.21-70.1 started; log sequence number 716513090
2015-02-14 16:36:40 1018 [Note] Recovering after a crash using binlog
2015-02-14 16:36:40 1018 [Note] Starting crash recovery...
2015-02-14 16:36:40 1018 [Note] Crash recovery finished.
2015-02-14 16:36:40 1018 [Note] RSA private key file not found: /var/lib/mysql//private_key.pem. Some authentication plugins will not work.
2015-02-14 16:36:40 1018 [Note] RSA public key file not found: /var/lib/mysql//public_key.pem. Some authentication plugins will not work.
2015-02-14 16:36:40 1018 [Note] Server hostname (bind-address): '*'; port: 3306
2015-02-14 16:36:40 1018 [Note] IPv6 is available.
2015-02-14 16:36:40 1018 [Note]   - '::' resolves to '::';
2015-02-14 16:36:40 1018 [Note] Server socket created on IP: '::'.
2015-02-14 16:36:40 1018 [ERROR] Fatal error: Can't open and lock privilege tables: Incorrect file format 'user'
150214 16:36:40 mysqld_safe mysqld from pid file /tmp/mysqld.pid ended

1
你可以尝试启动 mysql_upgrade(如日志中建议的);或者最终使用 mysql_install_db - guido
你可能有一些包出了问题... 你是否偶然间安装了普通的MySQL(而不是Percona),然后又切换回Percona?当你成功运行后,备份你的“mysql”数据库,以防万一需要恢复。 - ROunofF
3个回答

30

我使用ruby.b的答案解决了这个问题。

你需要修复你的主机表。为此,请输入以下命令以绕过特权系统启动你的服务器:

在一个终端窗口中运行:

$ sudo mysqld --skip-grant-tables

打开另一个终端并执行以下命令

$ mysql
mysql> use mysql
mysql> repair table host use_frm;
mysql> exit

并重新启动mysql服务

$ sudo service mysql restart

非常感谢。在我的情况下,我不得不修复用户表而不是主机表,所以我执行了:repair table user use_frm; 然后它就起作用了! - Rejinderi
非常感谢您提供的解决方案。对于我使用xampp的phpMyAdmin,它非常有效。 - Amol J
你必须使用在日志中出现错误的表名(请查看日志),而不是使用主机名。这对我来说有效。例如:repair table db use_frm; 对我有效。 - undefined

18

感谢 John 指导我正确的方向,但在我的系统上我还需要跨越一些障碍。希望这能对某人有所帮助。

这是一个损坏的特权表,可能由升级或停电引起。我的系统为 OpenSUSE 13.2 ,MySQL 版本为 5.6。简单重新安装无法解决问题,必须在重新安装之前删除所有 MySQL 的痕迹,或者......

关闭所有 MySQL 实例。

$ systemctl stop mysql.service
$ pkill -9 mysqld

启动服务器,绕过权限系统

$ sudo mysqld_safe --user=root --skip-grant-tables

启动MySQL命令行工具

$ mysql

如果您收到了

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

mysqld_safe正在以其套接字文件的不同位置运行。使用以下命令进行查找。

$ sudo find / -type s

我的MySQL套接字文件路径是 /var/run/mysql/ 在 my.cnf 文件中编辑 socket 行,并记录下您现有的套接字设置。 我的修改后的行变成了

socket=/var/run/mysql/mysql.sock

回到“关闭所有MySQL实例”(指南顶部)并跟随它们执行直到“启动MySQL命令行工具”。希望您可以成功打开mysql。从mysql命令行。

mysql> use mysql
mysql> repair table user use_frm;
mysql> exit

关闭所有MySQL实例

$ systemctl stop mysql.service
$ pkill -9 mysqld

重新编辑my.cnf文件,并将socket行恢复到原始设置。

我不得不重置mysql数据目录中的2个文件的权限。

$ chown mysql:mysql server2.err
$ chown mysql:mysql server2.pid

启动MySQL服务器

$ systemctl start mysql.service

我接着在另一个表格(db)上遇到了同样的原始错误。

[ERROR] Fatal error: Can't open and lock privilege  tables: Incorrect file format 'db'

我不得不多次重复上述过程,修改"修复"命令,直到所有权限表都被修复。

mysql> repair table db use_frm;

3
mysqld_safe --user=root --skip-grant-tables 使我的生命得救了!! - joninx
非常感谢您的回答!我还需要继续处理“host”表,但是我已经解决了这个问题 :) - Jamie M

0

如果你正在运行Docker,以下是@John Linhart的设置建议:

首先,从mysql容器中选择适当的标签启动一个新的 Docker 容器(与你用来编写数据库的相同)。

$ docker run --rm -it -v <named_volume>:/var/lib/mysql mysql:<tag> /bin/bash

这将使用正确命名的卷(或已挂载的卷)在新容器中启动,并将您作为root用户放入shell中。但是,mysqld守护程序将拒绝以root身份运行,因此我们将以mysql用户身份运行它:

$ whoami
root
$ which mysqld
/usr/sbin/mysqld
$ su mysql
$ whoami
mysql
$ /usr/sbin/mysqld --skip-grant-tables
....

现在要运行SQL命令,我们将从新终端连接到正在运行的容器:

$ docker ps 
CONTAINER ID [...]
abc123 [...]
$ docker exec -it abc123 /bin/bash
# We're on the container now!
$ whoami
root
$ mysql
...

然后从那里继续。完成后,通过exit将容器留在第二个终端上。运行mysqld的终端不会响应CMD+C,因此我们将通过Docker停止容器:

$ docker ps
CONTAINER ID [...]
abc123 [...]
$ docker stop abc123

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接