Archive for 八月 2010

admin账户下安装mysql

安装MySQL相信大家都会安装,但是如果现在你只有机器的admin账户,你不能够su到root下去,那么你怎么才能安装好mysql列。
至少我安装起来感觉缚手缚脚的,最终还是安装成功运行起来了,特别把一些需要注意的点记录下来。

1、my.cnf放在哪里?
从reference上抄录如下:
On Unix, Linux and Mac OS X, MySQL programs read startup options from the following files, in the specified order (top items are used first).
File Name     Purpose
/etc/my.cnf     Global options
/etc/mysql/my.cnf     Global options (as of MySQL 5.1.15)
SYSCONFDIR/my.cnf     Global options
$MYSQL_HOME/my.cnf     Server-specific options
defaults-extra-file     The file specified with –defaults-extra-file=path, if any
~/.my.cnf     User-specific options

~ represents the current user’s home directory (the value of $HOME).
前面的那些目录都没有权限,那么就只好在$HOME下放一个.my.cnf

2、目录配置
目录当然需要放在/home/admin下了,我这边的目录在[mysqld]组下设置如下:
basedir=/home/admin/mysql/mysql/
datadir=/home/admin/mysql/mysqldata/mydata
socket=/home/admin/mysql/mysqldata/sock/mysql.sock
pid-file=/home/admin/mysql/mysqldata/sock/mysql.pid
tmpdir=/home/admin/mysql/mysqldata/tmpdir
log-error=/home/admin/mysql/mysqldata/log/error.log
slow_query_log_file=/home/admin/mysql/mysqldata/log/slow-query.log
log-bin=/home/admin/mysql/mysqldata/binlog/mysql-bin
relay-log=/home/admin/mysql/mysqldata/relaylog/mysql-relay-bin
innodb_data_home_dir = /home/admin/mysql/mysqldata/innodb_ts
innodb_log_group_home_dir = /home/admin/mysql/mysqldata/innodb_log
本来basedir没有在这个.my.cnf里面,结果就出错了。
唉,还好 ./support-files/mysql.server 和 mysqld_safe是脚本,用bash -x 调试模式执行的时候仔细看还是能够找到对应的错误

对应的[client]需要指定:
socket = /home/admin/mysql/mysqldata/sock/mysql.sock

3、用户配置:
用户之前是用的mysql账户运行的,现在要用admin运行,所以修改[mysqld]组如下:
user=admin

4、./support-files/mysql.server修改
作为起停MySQL的脚本,它的basedir和datadir我都设置了
basedir=/home/admin/mysql/mysql/
datadir=/home/admin/mysql/mysqldata/mydata/

5、[mysqld_safe]设置
pid-file=/home/admin/mysql/mysqldata/sock/mysql.pid
本来我只设置了pid,并且在一台机器上启动MySQL成功了。但是在第二台机器上启动的时候失败了。
找了半天,才在mysqld_safe脚本里面找到出错的地方:
/home/admin/mysql/mysql//bin/mysqld_safe: line 137: /var/log/mysqld.log: Permission denied
对应的错误日志不对,于是,在.my.cnf的[mysqld_safe]组里加上
log-error=/home/admin/mysql/mysqldata/log/error.log
启动MySQL,没有异常。大功告成!

另外,也要注意把MySQL的bin目录加入到PATH里面去!

其实这里面最需要注意的就是出错的时候:
bash -x ./support-files/mysql.server start
或者
bash -x /home/admin/mysql/mysql//bin/mysqld_safe –datadir=/home/admin/mysql/mysqldata/mydata –pid-file=/home/admin/mysql/mysqldata/sock/mysql.pid &
查看到底是哪里出错了。根据具体的错误来定位和修改。

may your success!

双slave的server_id相同的问题

前段时间新来了一个机器,想要替换一个应用的备机。
已有的架构是这样的:A和B两个MySQL相互作为备机,A的性能比较好,B的性能比较差。
现在买了一台新的机器,新的机器c性能比较好,准备用来替换B。
安装MySQL和配置等等都不细说,比较顺利的。

但是安装好以后,配置复制的时候出现了问题,change master以后可以复制,但是数据库监控一直报错。
show slave status\G显示的Seconds_Behind_Master:的复制延迟一下子是0,一下子是90多w秒。
以前我们也遇到过类似的问题,具体原因不大记得了(唉,就是没有文档记录的错阿),最后好像是通过重做复制修复了。
尝试重新change master以后还是没有好转。查看错误日志显示如下:
100817 19:45:45 [Note] Slave I/O thread: Failed reading log event, reconnecting to retry, log ‘mysql-bin.000033’ at postion 271148235
100817 19:45:45 [Note] Slave: received end packet from server, apparent master shutdown:
100817 19:45:45 [Note] Slave I/O thread: Failed reading log event, reconnecting to retry, log ‘mysql-bin.000033’ at postion 271148235
100817 19:45:45 [Note] Slave: received end packet from server, apparent master shutdown:
并且不断的在刷,每秒钟有十来条记录。
通过对应的binlog file和binlog position去查看主机对应的记录都没有问题。并且主机到备机的复制只是时断时续,并没有一直停着不往前走。
实在没有办法,最后停掉了复制。这个事情因为并不是那么紧急,所以也暂时放在一边了。

偶尔的机会,我在备机B上也发现了同样的错误,也是Slave: received end packet from server, apparent master shutdown的错误。
并且change master以后,出现的频率变的非常高。
看了一下my.cnf配置文件,注意到B和C配置的server_id都是2,因为C当时是计划替换B的所以server_id也配置为一样了。
是不是这个问题引起的列?试试就知道了,把C的server_id配置成3,数据库B和数据库C检查复制状态,好了!

想起数据库复制的那一块代码。数据库连接master,请求复制开始的时候需要几个参数:
1、四个字节的数据文件开始位置
2、两个字节的binlog flag(目前还没有用上)
3、2个字节的binlog file名字字符串长度
4、4个字节的server_id
5、n个字节的binlog file名字字符串(在前面3里记录了它的长度)
这里向主机申请的时候,需要填写自己的server_id,来通知master连上来的是谁。
如果现在有两个slave连上来并都申明自己的server_id为2,MySQL的master就有点无所适从了。
初步怀疑是slave的IO线程连上以后,master过了一段时间(ms级别的)才发现,然后把新的连接断掉,所以slave io线程才会报警:
100817 19:45:45 [Note] Slave I/O thread: Failed reading log event, reconnecting to retry, log ‘mysql-bin.000033’ at postion 271148235
100817 19:45:45 [Note] Slave: received end packet from server, apparent master shutdown:
说收到主机发起的end packet(主机每次发送一个event过来,如果1、收到的包数据有误或者2、不能由接收到的包解出正确的event来,slave io判定复制有问题,
而其中end packet属于第一种情况
对应的代码为sql/slave.cc的read_event函数:
/* Check if eof packet */
if (len < 8 && mysql->net.read_pos[0] == 254)
{
sql_print_information(“Slave: received end packet from server, apparent ”
“master shutdown: %s”,
mysql_error(mysql));
DBUG_RETURN(packet_error);
}

由于MySQL的io有自动重连的机制,所以MySQL的io线程又连主机,并且还连上了。
master过了一段时间(ms级别的)又发现已经有了server_id=2的slave连着的,把它重新断掉了。
看了一下master的代码sql/sql_parse.cc的dispatch_command函数:
mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
unregister_slave(thd,1,1);
发送binlog以后,它会做一个unregister_slave,它认为是同一个slave change master连接过来,“理所当然的”它就把前面的连接给干掉了。
周而复始,就产生了这样的错误。
解决的办法很简单,就是不要用同样的server_id的slave同时连一台master。server_id可以设置的很大,所以不要顾虑,赶紧重设吧。

不知道有没有人想过为什么server_id不能设置为0
在my.cnf里面是没有办法设置server_id=0的,不信的话,你试试,正常情况下,它不会让你start slave的。代码如下sql/slave.cc的start_slave_thread函数:
if (!server_id)
{
if (start_cond)
pthread_cond_broadcast(start_cond);
if (start_lock)
pthread_mutex_unlock(start_lock);
sql_print_error(“Server id not set, will not start slave”);
DBUG_RETURN(ER_BAD_SLAVE);
}
不过,我还真的没有测试过这种情况,呵呵。
当然,server_id设置为0的情况也有,但是不是你或者我,而是mysqlbinlog,它的server_id可以设置为0.
原因如下:如果mysqlbinlog的server_id为0的话,它就会把正常的slave给停掉了。万一它的server_id为5,它连上去以后就会把真正的server-id为5的slave断掉了。
server_id设置为0我印象中还有一个不同点,是关于MySQL master发送binlog是否会停止的,但是就是想不起来了,老了。代码也没有找到确凿的证据;先这样把

may your success!