Discuz在使用的过程中,可能会遇到由于访问量过大或者被攻击而导致的数据库无法链接,DZ官方提供了一个主从数据库的方案,来优化这一问题。

本文章由个人经验与官方文档混合编写,使用了MySQL8.0

操作前请备份数据库,备份网站,以防止出问题无法恢复

一、主MySQL设置

1.编辑主MYSQL 服务器的MySQL配置文件my.cnf,在[mysqld]下面添加以下参数:
log-bin=mysql-bin //开启MYSQL二进制日志

server-id=1 //服务器ID不能重复

binlog-do-db=dzx3 //需要做主从备份的数据库名字

expire-logs-days = 7 //只保留7天的二进制日志,以防磁盘被日志占满

注:如果您使用的是宝塔的MySQL,只需要在mysqld管理-配置修改中的[mysqld]中添加即可,在添加前,请检查上方4个配置项是否存在,如果存在则无需填写!

2.在主服务器添加一个用于主从复制的帐号:

登陆MySQL命令行(mysql -u root -p) 密码可在宝塔-数据库-root密码中查看

执行

create user '账号'@'从服务器IP' identified by '密码';

grant all privileges on *.* to '账号'@'从服务器IP' with grant option;

revoke all privileges on *.* from '账号'@'从服务器IP';

例如:帐号是 rep,密码是 123,IP 是 192.168.1.3,则执行代码为

create user 'rep'@'192.168.1.3' identified by '123';

grant all privileges on *.* to 'rep'@'192.168.1.3' with grant option;

revoke all privileges on *.* from 'rep'@'192.168.1.3';

IP可为非同一网络的服务器,但必须打开两边的数据库端口(3306)

3、重启MySQL ,让配置生效

二、关闭论坛访问,复制数据库备份到从库服务器

1、登录论坛后台,“全局—站点信息”,关闭论坛访问
2、登录MySQL命令行(mysql -u root -p) 密码可在宝塔-数据库-root密码中查看
3、在主MySQL服务器上执行命令,把数据库设置成只读状态:
FLUSH TABLES WITH READ LOCK;
4、执行命令,并且记下file及position的值:
show master status;

(宝塔面板可以直接在当前状态中查看File与Position)

5、备份需要做主从备份的数据库,用导出成SQL或者直接复制数据库文件方式都可以

(宝塔面板直接备份数据库)

6、回到MYSQL命令行窗口,解封数据库只读状态,执行:
UNLOCK TABLES;
7、登录论坛后台,“全局—站点信息”,开放论坛访问
8、将刚才备份出来的数据复制到从库服务器

(宝塔面板备份过的数据库文件下载到从服务器的备份目录)

三、从MySQL服务器设置

1、编辑 从MYSQL服务器的MySQL配置文件my.cnf,在[mysqld]下面添加以下参数:
server-id=2 //服务器ID不能重复

master-port=3306 //主库的端口

replicate-do-db=dzx3 //需要做复制的数据库名

replicate-ignore-table=dzx3.pre_common_session //自动跳过的表,session表没必要做复制

slave-skip-errors = 1032,1062,126,1114,1146,1048,1396 //自动跳过的错误代码,以防复制出错被中断
2、将主库上备份的数据库恢复到从库

(宝塔面板用导入功能导入刚刚下载的数据库备份文件)

3、重启从库MySQL
4、登录从库的MySQL命令行,执行:
change master to master_host='192.168.1.2', master_user='rep', master_password='123', master_log_file='file的值', master_log_pos=position的值;

//设置连接信息,file及position的值是之前记录下来,position的值没有单引号,其他的值要单引号

5、执行:
start slave; //启动从库连接
6、查看从库状态:
show slave status\G; //查看连接情况,是不是两个YES,两个YES为成功

1670834001945.png

四、修改Discuz配置文件

打开X3的配置文件,config/config_global.php:

编辑

$_config['db']['common']['slave_except_table'] = '';

改为

$_config['db']['common']['slave_except_table'] = 'common_session,forum_attachment,forum_attachment_0,forum_attachment_1,forum_attachmen_9,forum_attachment_4,forum_attachment_2,forum_attachment_3,forum_attachment_5,forum_attachment_6,forum_attachment_7,forum_attachment_8';

(此处的attachment是在后期测试时发现远程附件的情况下使用主从会导致无法上传,您也可以尝试只填写)

$_config['db']['common']['slave_except_table'] = 'common_session';

然后在刚才编辑的那行下面加入从库配置:

$_config['db']['1']['slave']['1']['dbhost'] = '192.168.1.2';

$_config['db']['1']['slave']['1']['dbuser'] = 'root';

$_config['db']['1']['slave']['1']['dbpw'] = 'password';

$_config['db']['1']['slave']['1']['dbcharset'] = 'utf8';

$_config['db']['1']['slave']['1']['pconnect'] = '0';

$_config['db']['1']['slave']['1']['dbname'] = 'discuz';

$_config['db']['1']['slave']['1']['tablepre'] = 'pre_';

$_config['db']['1']['slave']['1']['weight'] = '1'; //从库权重,越大分配率越高

从库

$_config['db']['1']['slave']['2']['dbhost'] = '192.168.1.3;

$_config['db']['1']['slave']['2']['dbuser'] = 'root';

$_config['db']['1']['slave']['2']['dbpw'] = 'password';

$_config['db']['1']['slave']['2']['dbcharset'] = 'utf8';

$_config['db']['1']['slave']['2']['pconnect'] = '0'; //不同局域网的机子建议开启持久链接,加快网页加载

$_config['db']['1']['slave']['2']['dbname'] = 'discuz';

$_config['db']['1']['slave']['2']['tablepre'] = 'pre_';

$_config['db']['1']['slave']['2']['weight'] = '1';

也可以添加更多的从库

然后,如果有

$_config['db']['slave'] = '';

改为

$_config['db']['slave'] = 'true';

再进行测试,主从就完成啦

部分题外话:
[2022-12-12]如果数据库被攻击,从库占用cpu100%或者关闭,导致数据库没有正常执行同步指令,请不用担心,待从库正常后主库会自动尝试再次同步,您也可以断开网站与从库的链接加快这一步骤,另外,请确保主库不会死亡/重启,否者将无法正常同步,需要重新复制数据库至从库

最后修改:2022 年 12 月 17 日
如果觉得我的文章对你有用,请随意赞赏