Skip to content


discuzX2 读写分离及配置mysql复制

之前配置了fastcgi双机负载均衡discuzx2,现在做读写分离

主服务器ip:192.168.0.17
从服务器ip:192.168.0.23

1.主服务器设置
确保在服务器和从服务器上安装的MySQL版本与6.5节,“不同MySQL版本之间的复制兼容性”所示的表兼容。理想情况,应在主服务器和从服务器上使用最近版本的MySQL。
在主服务器上为服务器设置一个连接账户。该账户必须授予REPLICATION SLAVE权限。如果账户仅用于复制(推荐这样做),则不需要再授予任何其它权限。
假定你的从服务器ip为192.168.0.23,想要创建用户名为repl的一个账户,从服务器可以使用该账户从你的域内的任何主机使用密码slavepass来访问主服务器。要创建该账户,可使用GRANT语句:

  1. GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.0.23' IDENTIFIED BY 'slavepass';

更新权限

  1. flush privileges;

确保主服务器主机上my.cnf文件的[mysqld]部分包括一个log-bin选项。该部分还应有一个server-id=Master_id选项,其中master_id必须为1到232–1之间的一个正整数值。例如:

  1. log-bin=/opt/mysql/var_log/mysql-bin
  2. expire_logs_days = 10
  3. server-id=1
  4. binlog-do-db=discuzx
  5. log-slave-updates

2.从服务器设置
停止用于从服务器的服务器并在其my.cnf文件中添加下面的行:
slave_id值同Master_id值一样,必须为1到232–1之间的一个正整数值。并且,从服务器的ID必须与主服务器的ID不相同。例如:

  1. [mysqld]
  2. server-id=2
  3. replicate-do-db=discuzx
  4. replicate-ignore-table=discuzx.pre_common_session
  5. slave-net-timeout=60
  6. master-connect-retry=10
  7. slave-skip-errors
  8.  
  9. #concurrent_insert=2
  10. low-priority-updates=1
  11. max_write_lock_count=1
  12.  
  13. master-host=192.168.0.17
  14. master-port=3306
  15. master-user=repl
  16. master-password=slavepass

3.在主服务器上先锁表,禁止写入操作

  1. FLUSH TABLES WITH READ LOCK;

备份数据库

  1. cd /opt/mysql/
  2. tar -cvf ./mysql-snapshot.tar ./var/discuzx

4.从服务器解压

  1. scp -P 6022 ./mysql-snapshot.tar c1g@192.168.0.23:.
  2.  
  3. tar -xvf ./mysql-snapshot.tar
  4. mv ./var/discuzx /opt/mysql/var/

5.设置同步
进入master上的mysql,查看master状态

SHOW MASTER STATUS;

  1. File Position Binlog_Do_DB Binlog_Ignore_DB
  2. mysql-bin.000001 6416812 discuzx

File列显示日志名,而Position显示偏移量。在该例子中,二进制日志值为mysql-bin.000001,偏移量为6416812。记录该值。以后设置从服务器时需要使用这些值。它们表示复制坐标,从服务器应从该点开始从主服务器上进行新的更新。

取得快照并记录日志名和偏移量后,可以在主服务器上重新启用写活动:

在从服务器上执行下面的语句,用你的系统的实际值替换选项值:

  1. CHANGE MASTER TO
  2. MASTER_HOST='192.168.0.17',
  3. MASTER_USER='repl',
  4. MASTER_PASSWORD='slavepass',
  5. MASTER_LOG_FILE='mysql-bin.000001',
  6. MASTER_LOG_POS=6416812;

启动从服务器线程并查看状态:

  1. START SLAVE;
  2. show slave status;
  3. //Slave_IO_Running 与 Slave_SQL_Running 状态都要为Yes
  4. //Seconds_Behind_Master为主服务器同频延迟

查看进程

  1. show processlist;
  1. //应该有两行state值为:
  2. Has read all relay log; waiting for the slave I/O thread to update it
  3. Waiting for master to send event

复制从I/O线程状态
下面列出了从服务器的I/O线程的State列的最常见的状态。该状态也出现在Slave_IO_State列,由SHOW SLAVE STATUS显示。这说明你可以只通过该语句仔细浏览所发生的事情。
· Connecting to master

线程正试图连接主服务器。

· Checking master version

建立同主服务器之间的连接后立即临时出现的状态。

· Registering slave on master

建立同主服务器之间的连接后立即临时出现的状态。

· Requesting binlog dump

建立同主服务器之间的连接后立即临时出现的状态。线程向主服务器发送一条请求,索取从请求的二进制日志文件名和位置开始的二进制日志的内容。

· Waiting to reconnect after a failed binlog dump request

如果二进制日志转储请求失败(由于没有连接),线程进入睡眠状态,然后定期尝试重新连接。可以使用–master-connect-retry选项指定重试之间的间隔。

· Reconnecting after a failed binlog dump request

线程正尝试重新连接主服务器。

· Waiting for master to send event

线程已经连接上主服务器,正等待二进制日志事件到达。如果主服务器正空闲,会持续较长的时间。如果等待持续slave_read_timeout秒,则发生超时。此时,线程认为连接被中断并企图重新连接。

· Queueing master event to the relay log

线程已经读取一个事件,正将它复制到中继日志供SQL线程来处理。

· Waiting to reconnect after a failed master event read

读取时(由于没有连接)出现错误。线程企图重新连接前将睡眠master-connect-retry秒。

· Reconnecting after a failed master event read

线程正尝试重新连接主服务器。当连接重新建立后,状态变为Waiting for master to send event。

· Waiting for the slave SQL thread to free enough relay log space

正使用一个非零relay_log_space_limit值,中继日志已经增长到其组合大小超过该值。I/O线程正等待直到SQL线程处理中继日志内容并删除部分中继日志文件来释放足够的空间。

· Waiting for slave mutex on exit

线程停止时发生的一个很简单的状态。

复制从SQL线程状态
下面列出了从服务器的SQL线程的State列的最常见的状态。
· Reading event from the relay log

线程已经从中继日志读取一个事件,可以对事件进行处理了。

· Has read all relay log; waiting for the slave I/O thread to update it

线程已经处理了中继日志文件中的所有事件,现在正等待I/O线程将新事件写入中继日志。

· Waiting for slave mutex on exit

线程停止时发生的一个很简单的状态。

I/O线程的State列也可以显示语句的文本。这说明线程已经从中继日志读取了一个事件,从中提取了语句,并且正在执行语句。

最后将master上的表解锁

  1. UNLOCK TABLES;

在主服务器上,SHOW PROCESSLIST的输出看上去应为:

  1. SHOW PROCESSLIST\G;
  1. //state状态应该为Has sent all binlog to slave; waiting for binlog to be updated

复制主线程状态
下面列出了主服务器的Binlog Dump线程的State列的最常见的状态。如果你没有在主服务器上看见任何Binlog Dump线程,这说明复制没有在运行—即,目前没有连接任何从服务器。
· Sending binlog event to slave

二进制日志由各种事件组成,一个事件通常为一个更新加一些其它信息。线程已经从二进制日志读取了一个事件并且正将它发送到从服务器。

· Finished reading one binlog; switching to next binlog

线程已经读完二进制日志文件并且正打开下一个要发送到从服务器的日志文件。

· Has sent all binlog to slave; waiting for binlog to be updated

线程已经从二进制日志读取所有主要的更新并已经发送到了从服务器。线程现在正空闲,等待由主服务器上新的更新导致的出现在二进制日志中的新事件。

· Waiting to finalize termination

线程停止时发生的一个很简单的状态。

6.从服务器添加discuzx用户
在从服务器增加c1g_formaster用户访问从服务器权限

7.设置discuzx读写分离
vi bbs/config/config_global.php

  1. $_config['db']['common']['slave_except_table'] = 'common_session';
  2. #不读从服务器的common_session表
  3.  
  4. $_config['db']['slave'] = array();
  5. $_config['db']['slave']['1']['dbhost'] = '192.168.0.23';  //mysql 从库的host
  6. $_config['db']['slave']['1']['dbuser'] = 'c1g_formaster';   //mysql 从库的数据库用户名
  7. $_config['db']['slave']['1']['dbpw'] = 'password';    //mysql 从库的数据库密码
  8. $_config['db']['slave']['1']['dbcharset'] = 'gbk';
  9. $_config['db']['slave']['1']['pconnect'] = '0';
  10. $_config['db']['slave']['1']['dbname'] = 'discuzx'; //mysql从库的数据库名
  11. $_config['db']['slave']['1']['tablepre'] = 'pre_';

8.运行效果
内网同步大概会占三四十兆流量;
可能由于我的从服务器还跑着php,负载比较大;
从库运行半天后在更新时会死锁,反而影响了论坛正常运行,还是切回单机;

==============2011-12-06 更新
清除slave设置
在sql里运行
stop slave;
reset slave; #这将清除 master.info,relay-log.info

关闭mysql,移险日志
cd /opt/mysql/var/
mv hostname-relay-bin.000609 hostname-relay-bin.000609.bak
mv hostname-relay-bin.index hostname-relay-bin.index.bak
重启mysql

====================
2011-12-19 更新
修改主服务器expire_logs_days位置放到log-bin下面
expire_logs_days = 10

参考:
http://www.discuz.net/thread-2348271-1-1.html
http://liuyu.blog.51cto.com/183345/d-4
http://dev.mysql.com/doc/refman/5.1/zh/replication.html
http://blog.lxneng.com/?cat=7

Posted in Discuz/Uchome/Ucenter, Mysql.

Tagged with , , .


No Responses (yet)

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.



Some HTML is OK

or, reply to this post via trackback.