达梦读写分离集群DMRWC搭建方法

本文详细介绍了如何在Linux环境下部署达梦数据库的读写分离集群,包括操作系统配置、用户与权限设置、端口规划、数据库安装、主备库初始化、备份与恢复、配置归档和MAL系统、启动与验证集群状态,以及客户端连接集群的步骤。同时强调了在修改配置后需重启服务以使变更生效。
摘要由CSDN通过智能技术生成

读写分离集群部署

操作系统要求

数据库软件安装目录 /home/dmdba/dmdbms
实例安装目录 /dmdata
归档日志存放目录 /dmarch
备份文件存放目录 /dmbak

用户与组

新建用户组 dinstall

groupadd dinstall

新建用户 dmdba

useradd  -g dinstall -m -d /home/dmdba -s /bin/bash  dmdba

修改 dmdba 用户密码

passwd dmdba

用户资源限制

执行以下命令,修改 dmdba 用户资源限制:

vim /etc/security/limits.conf

文件末尾添加如下内容:

dmdba soft core unlimited
dmdba hard core unlimited
dmdba soft nofile 65536
dmdba hard nofile 65536
dmdba soft nproc  65536
dmdba hard nproc  65536
dmdba soft stack  65536
dmdba hard stack  65536

用户环境变量

执行以下命令,修改 dmdba 用户环境变量:

vi /home/dmdba/.bash_profile

文件末尾添加如下内容:

export DM_HOME=/home/dmdba/dmdbms
export PATH=$PATH:$DM_HOME/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DM_HOME/bin

端口规划

搭建 2 节点主备集群,端口规划如下:(实际中可以按需要修改端口号)

主机名 public ip private ip 实例名 端口 用途
dmdsc1 192.168.218.133 10.0.0.11 dmrw1 5236 数据库实例 dmrw1 监听端口
dmdsc1 192.168.218.133 10.0.0.11 dmrw1 61141 MAL 系统监听 TCP 连接的端口
dmdsc1 192.168.218.133 10.0.0.11 dmrw1 52141 实例本地的守护进程监听 TCP 连接的端口
dmdsc1 192.168.218.133 10.0.0.11 dmrw1 33141 实例监听守护进程 TCP 连接的端口
dmdsc2 192.168.218.132 10.0.0.12 dmrw2 5236 数据库实例 dmrw2 监听端口
dmdsc2 192.168.218.132 10.0.0.12 dmrw2 61141 MAL 系统监听 TCP 连接的端口
dmdsc2 192.168.218.132 10.0.0.12 dmrw2 52141 实例本地的守护进程监听 TCP 连接的端口
dmdsc2 192.168.218.132 10.0.0.12 dmrw2 33141 实例监听守护进程 TCP 连接的端口
防火墙集群之间需开放以上所有端口,集群对客户端只需要开通数据库实例监听端口。

安装数据库

软件安装目录为/home/dmdba/dmdbms,实例初始化目录/home/dmdba/dmdbms/dmrw,初始化脚本如下:

./dminit path=/home/dmdba/dmdbms db_name=dmrw page_size=32

初始化的实例必须先启动一次,才能脱机备份。

主库脱机备份

执行以下命令,确认主库 dmap 服务已启动:

ps -ef|grep dmap

dmap服务
若未启动,则先启动 DMAP 服务,dmdba 到安装目录的 bin 下执行以下命令:

./DmAPService start

关闭数据库后,使用 dmrman 工具脱机备份主库,dmdba 用户到安装目录的 bin 下执行以下命令:

./dmrman

执行 backup 全库:

backup database '/home/dmdba/dmdbms/dmrw/dm.ini' backupset '/home/dmdba/bakfull';

backup全库

备库还原

拷贝主库备份到备库合适目录:

scp -r /home/dmdba/bakfull 192.168.218.132:/home/dmdba

scp 备份文件
关闭数据库后,使用 dmrman 工具还原备库,dmdba 用户到安装目录的 bin 下执行:
./dmrman

执行 restore:

restore database '/home/dmdba/dmdbms/dmrw/dm.ini' from backupset '/home/dmdba/bakfull';

执行 recover。

recover database '/home/dmdba/dmdbms/dmrw/dm.ini' from backupset '/home/dmdba/bakfull';

执行 recover update db_magic。

recover database '/home/dmdba/dmdbms/dmrw/dm.ini' update db_magic;

配置实例的配置文件 dm.ini

修改实例的 dm.ini 文件参数,执行以下命令:
vi /home/dmdba/dmdbms/dmrw/dm.ini
主库修改以下参数值:

INSTANCE_NAME = dmrw1
MAL_INI = 1
ARCH_INI = 1
ALTER_MODE_STATUS = 0
ENABLE_OFFLINE_TS = 2

备库修改以下参数值:

INSTANCE_NAME = dmrw2
MAL_INI = 1
ARCH_INI = 1
ALTER_MODE_STATUS = 0
ENABLE_OFFLINE_TS = 2

配置归档配置文件 dmarch.ini

在实例目录下新建文件 dmarch.ini,执行以下命令:

vi /home/dmdba/dmdbms/dmrw/dmarch.ini

主库添加以下内容:

[ARCHIVE_TIMELYE]  
ARCH_TYPE     = TIMELY  #即时归档类型
ARCH_DEST     = dmrw2   #即时归档目标实例名(主库侧填写备库实例名)
[ARCHIVE_LOCAL1]
ARCH_TYPE     = LOCAL #本地归档类型
ARCH_DEST     = /home/dmdba/dmdbms/arch  #本地归档文件存放路径
ARCH_FILE_SIZE    = 128 #单位 MB,本地单个归档文件最大值
ARCH_SPACE_LIMIT  = 10240    #单位 MB,0 表示无限制,范围 1024~4294967294 MB

备库添加以下内容:

[ARCHIVE_TIMELY]  
ARCH_TYPE     = TIMELY  #即时归档类型
ARCH_DEST     = dmrw1   #即时归档目标实例名(备库侧填写主库实例名)
[ARCHIVE_LOCAL1]
ARCH_TYPE     = LOCAL #本地归档类型
ARCH_DEST     = /home/dmdba/dmdbms/arch  #本地归档文件存放路径
ARCH_FILE_SIZE    = 128 #单位 MB,本地单个归档文件最大值
ARCH_SPACE_LIMIT  = 10240    #单位 MB,0 表示无限制,范围 1024~4294967294 MB

配置MAL系统配置文件 dmmal.ini

在实例目录下新建文件 dmmal.ini,执行以下命令。

vi /home/dmdba/dmdbms/dmrw/dmmal.ini

主备库文件内容要相同。

MAL_CHECK_INTERVAL   = 5  #MAL 链路检测时间间隔
MAL_CONN_FAIL_INTERVAL  = 5  #判定 MAL 链路断开的时间
[MAL_INST1]
  MAL_INST_NAME = dmrw1 #与 dm.ini 中的 INSTANCE_NAME 一致
  MAL_HOST     = 10.0.0.11  #MAL 系统监听 TCP 内部网络 IP
  MAL_PORT     = 61141 #MAL 系统监听 TCP 连接的端口
  MAL_INST_HOST   = 192.168.218.133  #实例的对外服务 IP 地址
  MAL_INST_PORT   = 5236 #与 dm.ini 中的 PORT_NUM 一致
  MAL_DW_PORT   = 52141 #实例对应的守护进程监听 TCP 端口
  MAL_INST_DW_PORT = 33141
[MAL_INST2]
  MAL_INST_NAME = dmrw2 #与 dm.ini 中的 INSTANCE_NAME 一致
  MAL_HOST      = 10.0.0.12  # MAL 系统监听 TCP 内部网络 IP
  MAL_PORT          = 61141 #MAL 系统监听 TCP 连接的端口
  MAL_INST_HOST         = 192.168.56.12  #实例的对外服务 IP 地址
  MAL_INST_PORT         = 5236 #与 dm.ini 中的 PORT_NUM 一致
  MAL_DW_PORT  = 52141 #实例对应的守护进程监听 TCP 端口
  MAL_INST_DW_PORT = 33141

配置守护进程配置文件 dmwatcher.ini

在实例目录下新建文件 dmwatcher.ini,执行以下命令:

vi /home/dmdba/dmdbms/dmrw/dmwatcher.ini

主备库文件内容要相同。

[GRP_RW] 
DW_TYPE    = GLOBAL  #全局守护类型
DW_MODE    = AUTO   #自动切换模式
DW_ERROR_TIME     = 10  #远程守护进程故障认定时间
INST_RECOVER_TIME  = 60         #主库守护进程启动恢复的间隔时间
INST_ERROR_TIME   = 10  #本地实例故障认定时间
INST_OGUID         = 453331 #守护系统唯一 OGUID 值
INST_INI           = /home/dmdba/dmdbms/dmrw/dm.ini #dm.ini 配置文件路径
INST_AUTO_RESTART  = 1   #打开实例的自动启动功能
INST_STARTUP_CMD   = /home/dmdba/dmdbms/bin/dmserver #命令行方式启动

以 Mount 方式启动数据库实例

使用 dmdba 用户,到数据库安装目录的 bin 下执行以下命令(主备库都执行):

./dmserver /home/dmdba/dmdbms/dmrw/dm.ini mount

在新的终端使用 disql 工具连接数据库:
./disql SYSDBA/SYSDBA
主备库都修改 oguid,执行以下命令:

sp_set_oguid(453331);

主库修改数据库模式为 primary,执行以下命令:

alter database primary;

备库修改数据库模式为 standby,执行以下命令:

alter database standby;

启动守护进程
dmdba 用户下,到数据库安装目录的 bin 下执行以下命令(主备库都执行):

./dmwatcher /home/dmdba/dmdbms/dmrw/dmwatcher.ini

守护进程启动后,会将 Mount 的实例 Open。
启动确认监视器
守护进程配置为自动切换时,必须配置确认监视器。在主备服务器以外的服务器上(需安装有 DM 数据库软件,且与主备心跳网络端口开放)。
新建确认监视器配置文件 dmmonitor.ini,执行以下命令:
vi /home/dmdba/dmdbms/dmmonitor.ini
添加以下内容:

MON_DW_CONFIRM    = 1   #确认监视器模式
MON_LOG_PATH    = /home/dmdba/dmdbms/log  #监视器日志文件存放路径
MON_LOG_INTERVAL  = 60 #每隔 60 s 定时记录系统信息到日志文件
MON_LOG_FILE_SIZE   = 32 #每个日志文件最大 32 MB
MON_LOG_SPACE_LIMIT  = 0  #不限定日志文件总占用空间
[GRP_RW] 
 MON_INST_OGUID    = 453331 #组 GRP_RW 的唯一 OGUID 值
#以下配置为监视器到组 GRP_RW 的守护进程的连接信息,以“IP:PORT”的形式配置
#IP 对应 dmmal.ini 中的 MAL_HOST,PORT 对应 dmmal.ini 中的 MAL_DW_PORT
 MON_DW_IP     = 10.0.0.11:52141
 MON_DW_IP     = 10.0.0.12:52141

执行以下命令,启动监视器。

./dmmonitor /home/dmdba/dmdbms/dmmonitor.ini

启动后输入 show 命令查看集群状态。

注册服务
以上启动为前台方式启动,仅用户搭建过程中验证配置。配置没问题后需要将实例,守护进程和确认监视器注册为系统服务。

使用 root 用户,到数据库安装目录的script/root下。

注册守护进程服务(主备库都执行)。

./dm_service_installer.sh -t dmwatcher -p dmrw -watcher_ini /home/dmdba/dmdbms/dmrw/dmwatcher.ini

注册数据库实例服务(主备库都执行):

./dm_service_installer.sh -t dmserver -p dmrw -dm_ini /home/dmdba/dmdbms/dmrw/dm.ini

注册监视器服务(只需在监视器服务器上执行):

./dm_service_installer.sh -t dmmonitor -p confirm -monitor_ini /home/dmdba/dmdbms/dmmonitor.ini

以服务方式启动
执行以下命令,启动数据库实例:
systemctl start DmServicedmrw
执行以下命令,启动守护进程:
systemctl start DmWatcherServicedmrw
执行以下命令,启动监视器:
systemctl start DmMonitorServiceconfirm

验证主备集群同步状态
监视器查看读写分离集群状态
集群任意节点,配置普通监视器配置文件 dmmonitor.ini,执行以下命令:
vi /home/dmdba/dmmonitor.ini
添加以下内容:

MON_DW_Confirm    = 0   #普通监视器模式
MON_LOG_PATH    = /home/dmdba/dmdbms/log  #监视器日志文件存放路径
MON_LOG_INTERVAL  = 60 #每隔 60 s 定时记录系统信息到日志文件
MON_LOG_FILE_SIZE   = 32 #每个日志文件最大 32 MB
MON_LOG_SPACE_LIMIT  = 0  #不限定日志文件总占用空间
[GRP_RW] 
 MON_INST_OGUID    = 453331 #组 GRP_RW 的唯一 OGUID 值
#以下配置为监视器到组 GRP_RW 的守护进程的连接信息,以“IP:PORT”的形式配置
#IP 对应 dmmal.ini 中的 MAL_HOST,PORT 对应 dmmal.ini 中的 MAL_DW_PORT
 MON_DW_IP     = 10.0.0.11:52141
 MON_DW_IP     = 10.0.0.12:52141

执行以下命令,启动监视器:

./dmmonitor /home/dmdba/dmmonitor.ini

输入 show 命令查看集群状态:

show查看

其中守护进程状态 WSTATUS 为 OPEN,实例状态 ISTATUS 为 OPEN,归档类型 RTYPE 为 TIMELY,归档状态 RSTAT 为VALID。

disql 客户端验证
使用 disql 客户端登录主库,创建测试表,插入数据,执行以下命令:

./disql SYSDBA/SYSDBA@192.168.218.133:5236

SQL 提示符下执行以下命令:

create table test(id int);
insert into test values (1);
commit;

使用 disql 客户端登录备库,查询测试表验证,执行以下命令:

./disql SYSDBA/SYSDBA@192.168.218.132:5236

SQL 提示符下执行以下命令:

select * from test;

查询结果正确

重启集群
读写分离集群重启与主备相同:

关闭监视器:systemctl stop DmMonitorServiceconfirm
关闭主库守护进程:systemctl stop DmWatcherServicedmrw
关闭备库守护进程:systemctl stop DmWatcherServicedmrw
关闭主库实例:systemctl stop DmServicedmrw
关闭备库实例:systemctl stop DmServicedmrw
启动主库实例:systemctl start DmServicedmrw
启动备库实例:systemctl start DmServicedmrw
启动主库守护进程:systemctl start DmWatcherServicedmrw
启动备库守护进程:systemctl start DmWatcherServicedmrw
启动监视器:systemctl start DmMonitorServiceconfirm
定制备份策略
备份与单机相同,详见定制备份策略部分。

客户端连接集群
客户端主机上需要配置 dm_svc.conf 文件(未安装 DM 数据库的机器新建即可),文件路径:

32 位的 DM 安装在 Win32 操作平台下,此文件位于 %SystemRoot%\system32 目录;
64 位的 DM 安装在 Win64 操作平台下,此文件位于 %SystemRoot%\system32 目录;
32 位的 DM 安装在 Win64 操作平台下,此文件位于 %SystemRoot%\SysWOW64 目录;
在 Linux 平台下,此文件位于/etc 目录。
文件内容:

#全局配置区
DMRW=(192.168.218.133:5236,192.168.218.132:5236)
TIME_ZONE=(+480) #表示+8:00 时区
LOGIN_ENCRYPT=(0)
DIRECT=(Y)
#服务配置区
[DMRW]
TIME_ZONE=(+540) #表示+9:00 时区
SWITCH_TIME=(3) #在服务器之间切换的次数
SWITCH_INTERVAL=(10) #在服务器之间切换的时间间隔,单位为毫秒
RW_SEPARATE=(1) #启用读写分离
RW_PERCENT=(25) #读事务分发到主库的比例

客户端程序连接数据库时,需要指定 IP 端口处替换为服务名即可,例如:disql SYSDBA/SYSDBA@DMRW。

注意
当修改了 dm_svc.conf 内容后,需要重启客户端程序,修改的配置才能生效。

达梦社区地址:https://eco.dameng.com

要实现Spring Boot与达梦数据库读写分离集群,您需要进行以下步骤: 1. 配置数据源:打开Spring Boot项目的application.properties文件,配置主库和从库的数据源信息。例如: ``` # 主库数据源 spring.datasource.primary.url=jdbc:dme://localhost:5236/demo spring.datasource.primary.username=root spring.datasource.primary.password=root # 从库数据源 spring.datasource.secondary.url=jdbc:dme://localhost:5236/demo spring.datasource.secondary.username=root spring.datasource.secondary.password=root ``` 2. 配置数据源路由:使用Spring Boot提供的AbstractRoutingDataSource类,创建一个数据源路由器,根据SQL语句的类型(读/写)选择合适的数据源。例如: ``` public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { // 根据上下文选择合适的数据源 return DatabaseContextHolder.getDatabaseType(); } } ``` 3. 配置数据源上下文:使用ThreadLocal类保存当前线程的数据源类型,以便在数据源路由器中选择正确的数据源。例如: ``` public class DatabaseContextHolder { private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<>(); public static void setDatabaseType(DatabaseType databaseType) { contextHolder.set(databaseType); } public static DatabaseType getDatabaseType() { return contextHolder.get(); } public static void clearDatabaseType() { contextHolder.remove(); } } public enum DatabaseType { PRIMARY, SECONDARY } ``` 4. 配置事务管理器:使用Spring Boot提供的JpaTransactionManager类,为主库和从库分别配置事务管理器。例如: ``` @Configuration @EnableTransactionManagement public class TransactionConfig { @Autowired @Qualifier("primaryEntityManagerFactory") private EntityManagerFactory primaryEntityManagerFactory; @Autowired @Qualifier("secondaryEntityManagerFactory") private EntityManagerFactory secondaryEntityManagerFactory; @Bean(name = "primaryTransactionManager") public PlatformTransactionManager primaryTransactionManager() { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(primaryEntityManagerFactory); return transactionManager; } @Bean(name = "secondaryTransactionManager") public PlatformTransactionManager secondaryTransactionManager() { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(secondaryEntityManagerFactory); return transactionManager; } } ``` 5. 配置JPA和Hibernate:为主库和从库分别配置JPA和Hibernate。例如: ``` @Configuration @EnableJpaRepositories( basePackages = "com.example.demo.primary", entityManagerFactoryRef = "primaryEntityManagerFactory", transactionManagerRef = "primaryTransactionManager" ) @EnableTransactionManagement public class PrimaryDataSourceConfig { @Primary @Bean(name = "primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Primary @Bean(name = "primaryEntityManagerFactory") public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("primaryDataSource") DataSource dataSource) { return builder .dataSource(dataSource) .packages("com.example.demo.primary") .persistenceUnit("primary") .build(); } @Primary @Bean(name = "primaryJpaProperties") @ConfigurationProperties(prefix = "spring.jpa.primary") public JpaProperties primaryJpaProperties() { return new JpaProperties(); } @Primary @Bean(name = "primaryHibernateProperties") @ConfigurationProperties(prefix = "spring.jpa.primary.hibernate") public HibernateProperties primaryHibernateProperties() { return new HibernateProperties(); } } @Configuration @EnableJpaRepositories( basePackages = "com.example.demo.secondary", entityManagerFactoryRef = "secondaryEntityManagerFactory", transactionManagerRef = "secondaryTransactionManager" ) @EnableTransactionManagement public class SecondaryDataSourceConfig { @Bean(name = "secondaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryEntityManagerFactory") public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("secondaryDataSource") DataSource dataSource) { return builder .dataSource(dataSource) .packages("com.example.demo.secondary") .persistenceUnit("secondary") .build(); } @Bean(name = "secondaryJpaProperties") @ConfigurationProperties(prefix = "spring.jpa.secondary") public JpaProperties secondaryJpaProperties() { return new JpaProperties(); } @Bean(name = "secondaryHibernateProperties") @ConfigurationProperties(prefix = "spring.jpa.secondary.hibernate") public HibernateProperties secondaryHibernateProperties() { return new HibernateProperties(); } } ``` 6. 使用数据源:在需要使用数据源的地方,通过调用DatabaseContextHolder.setDatabaseType()方法设置当前线程的数据源类型,然后执行SQL语句即可。例如: ``` @Service public class UserService { @Autowired private UserRepository userRepository; @Transactional public void save(User user) { DatabaseContextHolder.setDatabaseType(DatabaseType.PRIMARY); userRepository.save(user); DatabaseContextHolder.setDatabaseType(DatabaseType.SECONDARY); userRepository.save(user); } } ``` 这样,就可以实现Spring Boot与达梦数据库读写分离集群了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值