已从 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 游戏相比,使用系统内置的包管理绝对是更好的选择。