启动 mysql 服务器:root 和普通用户拥有相同的权限

启动 mysql 服务器:root 和普通用户拥有相同的权限

已从 stackoverflow 引导到这里,正在重新发布问题并在帖子末尾添加 my.cnf。

到目前为止,在我使用 Linux 的 10 多年经验中,我遇到的所有权限问题都已成功解决chmod -R 777 /path/where/the/problem/has/occured(每个谎言都有其道理:)

这次这个技巧不起作用了,所以我向你寻求帮助。我正在用 zc.buildout (www.buildout.org) 从头编译 mysql 服务器。我确实通过执行启动了它/home/toinbis/.../parts/mysql/bin/mysqld_safe,这有效。问题是我将从监督员 (supervisord.org) 脚本中启动它,当在部署服务器上使用时,它需要以 root 权限启动(以便使用相同脚本启动的 nginx 服务器可以访问 80 端口)。问题是,sudo /home/toinbis/.../parts/mysql/bin/mysqld_safe失败,在 mysql 错误日志中生成错误,如下所示(apache 和 nginx 按预期工作)。

http://lists.mysql.com/mysql/216045提示“有两个错误:缺少一个表和一个 mysqld 无权访问的文件系统”。Mysqldatadir 和所有 mysql 服务器二进制文件都有 777 个权限,talbe mysql.plugin 确实存在并且有 777 个权限(为什么Can't open the mysql.plugin table?),“sudo touch mysql_datadir/tmp/file”确实创建了文件(为什么 Can't create/write to file /home/toinbis/.../runtime/mysql_datadir/tmp/ib4e9Huz?)。

chgrp -R mysql mysql_datadir并且将“root、toinbis、mysql”用户添加到 mysql 组(cat /etc/group | grep mysql 输出mysql:x:124:root,toinbis,mysql)没有效果 - 当我以普通用户身份启动它时,它会启动,而以 root 身份启动时 - 它会失败。即使以 root 身份启动,mysql 服务器是否会尝试以其他用户(比如说“mysql”)身份运行?但即使在这种情况下,将 mysql 用户添加到 mysql 组并使所有 mysql_datadirs 文件都属于 mysql 组也应该可以让事情顺利进行。

我确实知道以 root 身份启动 nginx 并以 mysql(仅作为用户)可能是一个更好的主意,但是这个错误让我非常恼火,因此我投入了足够的精力,不仅“让事情正常运转”,而且还让事情完全按照我最初的意愿运转,这样就可以证明它是可能的。

这是产生的错误:

091213 20:02:55 mysqld_safe Starting mysqld daemon with databases from /home/toinbis/.../runtime/mysql_datadir
/home/toinbis/.../parts/mysql/libexec/mysqld: Table 'plugin' is read only
091213 20:02:55 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
/home/toinbis/.../parts/mysql/libexec/mysqld: Can't create/write to file '/home/toinbis/.../runtime/mysql_datadir/tmp/ib4e9Huz' (Errcode: 13)
091213 20:02:55  InnoDB: Error: unable to create temporary file; errno: 13
091213 20:02:55 [ERROR] Plugin 'InnoDB' init function returned error.
091213 20:02:55 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
091213 20:02:55 [ERROR] Can't start server : Bind on unix socket: Permission denied
091213 20:02:55 [ERROR] Do you already have another mysqld server running on socket: /home/toinbis/.../runtime/var/pids/mysql.sock ?
091213 20:02:55 [ERROR] Aborting

091213 20:02:55 [Note] /home/toinbis/.../parts/mysql/libexec/mysqld: Shutdown complete

091213 20:02:55 mysqld_safe mysqld from pid file /home/toinbis/.../runtime/var/pids/mysql.pid ended

我的 my.cnf (basedir 和 datadir(包括 tempdir) 有chmod -R 777 permissions):

[client]
socket          = /home/toinbis/.../runtime/var/pids/mysql.sock
port            = 8002

[mysqld_safe]
socket          = /home/toinbis/.../runtime/var/pids/mysql.sock
nice            = 0

[mysqld]
#
# * Basic Settings
#

socket          = /home/toinbis/.../runtime/var/pids/mysql.sock
port            = 8002
pid-file        = /home/toinbis/.../runtime/var/pids/mysql.pid
basedir         = /home/toinbis/.../parts/mysql
datadir         = /home/toinbis/.../runtime/mysql_datadir
tmpdir          = /home/toinbis/.../runtime/mysql_datadir/tmp
skip-external-locking
bind-address            = 127.0.0.1
log-error =/home/toinbis/.../runtime/logs/mysql_errorlog

#
# * Fine Tuning
#
key_buffer              = 16M
max_allowed_packet      = 32M
thread_stack            = 128K
thread_cache_size       = 8
myisam-recover          = BACKUP
#max_connections        = 100
#table_cache            = 64
#thread_concurrency     = 10

#
# * Query Cache Configuration
#
query_cache_limit       = 1M
query_cache_size        = 16M

#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
#log            = /home/toinbis/.../runtime/logs/mysql_logs/mysql.log
#
# Error logging goes to syslog. This is a Debian improvement :)
#
# Here you can see queries with especially long duration
#log_slow_queries       = /home/toinbis/.../runtime/logs/mysql_logs/mysql-slow.log
#long_query_time = 2
#log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
#server-id               = 1
#log_bin                 = /home/toinbis/.../runtime/mysql_datadir/mysql-bin.log
#binlog_format           = ROW
#read_only               = 0
#expire_logs_days        = 10
#max_binlog_size         = 100M
#sync_binlog             = 1
#binlog_do_db           = include_database_name
#binlog_ignore_db       = include_database_name

#
# * InnoDB
#
innodb_data_file_path = ibdata1:10M:autoextend
innodb_buffer_pool_size=64M
innodb_log_file_size=16M
innodb_log_buffer_size=8M
innodb_flush_log_at_trx_commit=1
innodb_file_per_table
innodb_locks_unsafe_for_binlog=1


[mysqldump]
quick
quote-names
max_allowed_packet      = 32M

[mysql]
#no-auto-rehash # faster start of mysql but no tab completion

[isamchk]
key_buffer              = 16M

任何想法都值得感激!

问候,

PS 抱歉,超链接有点乱,这是我的第一篇帖子,SF 的反垃圾信息功能不允许我正确发布帖子 :)

答案1

首先?不要为此使用 777。不要。守护进程不以 root 身份运行是有原因的(滔天如果其中任何一个发生缓冲区溢出,则会出现安全问题——如果有人设法通过 SQL 注入或其他方式进入您的网站,他们就刚刚获得了您的机器的权限)。打开端口后,使用包装器脚本放弃权限。Nginx 也不需要以 root 身份运行。

其次,您的问题似乎是路径问题,而不是权限问题。除非您已将/.../本文中所有位置的实际路径替换,否则这就是您的问题。如果您这样做了,请使用完整路径更新问题。

答案2

首先问一个愚蠢的问题。你确定没有另一个 mysql 在运行吗?尽管权限合理(尽管权限为 777),但只读错误几乎总是文件被另一个进程锁定的迹象。你可以使用 lsof 来查明是否有其他东西在干扰你的文件:

$ lsof /home/toinbis/.../runtime/var/pids/mysql.sock

或者

$ sudo lsof | grep mysqld

如果仍然出现错误,请尝试上述操作,如果有任何匹配项,则说明问题所在。

如果失败,请重新构建,并且永远不要以非 root 用户身份启动。这有什么区别吗?

如果你想作弊,可以使用 buildout_script 创建一个包装脚本(http://pypi.python.org/pypi/buildout_script/0.2a1

它需要一个模板,例如:

#! /bin/sh
sudo -u mysql_or_your_username_here {buildout[bin-directory]}/mysqld_safe $@

这样,mysqld_safe 就永远不会以 root 身份运行,从而避免了此错误。我觉得这很令人反感,但您的整个设置是我永远不会做的事情,所以我认为它会很有帮助!:)

我相信 Gentoo 和系统级配置工具(例如 puppet、chef-solo 或 kokki)更适合您。

答案3

您的主目录是否通过 NFS 挂载,挂载时是否使用将 root 权限压缩为“nobody”的配置?如果是这样,请以另一个用户身份启动,或者不要将数据存储在 NFS 中,或者在没有 root_squash 的情况下导出 NFS 共享。

答案4

我正在使用 zc.buildout(www.buildout.org)从头开始编译 mysql 服务器。

看起来你已经陷入困境了!:)

你从源代码编译 MySQL 服务器有什么特别的原因吗?我发现这个 MySQL“buildout”脚本,这可能与您正在做的事情有关:它似乎下载了 MySQL 服务器和一个包来为 Python 提供 MySQL 支持,然后在非标准位置编译并安装它们。

无论如何,MySQL 特别建议不要从源代码进行编译,因为它们为各种不同的平台提供了自己优化的二进制包。

如果您要部署到一个良好的包管理系统,那么您的“buildout”脚本只需要调用目标系统的包管理器。这将通过几个命令为您提供供应商推荐和批准的安装(无需 chmod -R 777!)。对于 RHEL/CentOS 系统,该过程大致如下:

yum install mysql-server (MySQL-python?)
[edit /etc/my.cnf]
chkconfig mysqld on && service mysqld start
[lock down the server by adjusting the grants]

看看这是多么简单、可重复 :)。除非您有非常好的理由,否则与非标准安装位置和 chmod -R 777 游戏相比,使用系统内置的包管理绝对是更好的选择。

相关内容