1. 首页 > 国产数据库教程 > 达梦DM教程 > 正文

DM教程FG079-达梦数据库读写分离实施

本文档详细介绍DM数据库读写分离实施的方法和技巧,包括读写分离概念、读写分离类型、读写分离原理、读写分离规划、读写分离部署建议、读写分离管理建议、部署步骤、读写分离配置、读写分离管理等内容,风哥教程参考DM官方文档《DM8读写分离》手册,适合DBA人员进行DM数据库读写分离的实施和管理。

Part01-基础概念与理论知识

1.1 DM数据库读写分离概念

DM数据库读写分离是指将数据库的读操作和写操作分离到不同的数据库实例上,从而提高数据库的整体性能和可用性。通过读写分离,可以将读操作分发到多个备数据库,减轻主数据库的负担,同时提高系统的并发处理能力。

读写分离的重要性:

  • 提高性能:将读操作分发到多个备数据库,减轻主数据库的负担
  • 提高可用性:当主数据库发生故障时,备数据库可以继续提供读服务
  • 提高扩展性:可以通过增加备数据库的数量,提高系统的读处理能力
  • 负载均衡:将读操作均匀分布到多个备数据库,实现负载均衡

1.2 DM数据库读写分离类型

DM数据库读写分离类型:

# 读写分离类型
#
# 1. 基于应用层的读写分离
##
# 概念
– 在应用层实现读写分离
– 应用程序根据SQL语句的类型,将读操作发送到备数据库,将写操作发送到主数据库
– 不需要修改数据库配置
– 实现简单,灵活度高
##
# 优点
– 实现简单
– 灵活度高
– 不需要修改数据库配置
##
# 缺点
– 应用程序需要修改
– 维护成本高
– 容易出现代码错误
#
# 2. 基于中间件的读写分离
##
# 概念
– 使用数据库中间件实现读写分离
– 中间件接收应用程序的请求,根据SQL语句的类型,将读操作分发到备数据库,将写操作分发到主数据库
– 应用程序不需要修改
– 实现复杂,但是维护成本低
##
# 优点
– 应用程序不需要修改
– 维护成本低
– 集中管理读写分离逻辑
##
# 缺点
– 实现复杂
– 中间件成为性能瓶颈
– 增加系统复杂性
#
# 3. 基于数据库集群的读写分离
##
# 概念
– 使用数据库集群实现读写分离
– 集群中的主节点处理写操作,备节点处理读操作
– 应用程序通过集群地址访问数据库 风哥提示:
– 实现简单,维护成本低
##
# 优点
– 实现简单
– 维护成本低
– 高可用性
##
# 缺点
– 集群配置复杂
– 成本高
– 灵活性差

1.3 DM数据库读写分离原理

DM数据库读写分离原理:

  1. 主备复制:主数据库将事务日志传输到备数据库,并在备数据库上应用这些日志,保持主备数据库数据一致
  2. 读写分发:根据SQL语句的类型,将读操作分发到备数据库,将写操作分发到主数据库
  3. 负载均衡:将读操作均匀分布到多个备数据库,实现负载均衡
  4. 故障检测:监控主备数据库的状态,当备数据库发生故障时,将读操作分发到其他备数据库
  5. 故障切换:当主数据库发生故障时,将写操作切换到备数据库
风哥提示:读写分离是提高数据库性能和可用性的重要技术,选择合适的读写分离类型对于保证系统的稳定性和性能至关重要。

Part02-生产环境规划与建议

2.1 DM数据库读写分离规划

生产环境DM数据库读写分离规划:

# 读写分离规划
#
# 规划步骤
1. 分析业务需求:分析业务的读操作和写操作比例、并发量等
2. 确定读写分离类型:根据业务需求选择合适的读写分离类型 学习交流加群风哥微信: itpux-com
3. 设计网络架构:设计合理的网络架构,确保主备数据库之间的通信畅通
4. 设计存储架构:设计合理的存储架构,确保数据的安全性和可靠性
5. 设计监控架构:设计合理的监控架构,确保能够及时发现和处理故障
6. 制定部署计划:制定详细的部署计划,包括时间、人员、步骤等
#
# 读写分离规划示例
##
# 业务需求
– 读操作:写操作 = 9:1
– 并发量:5000用户
– 读操作响应时间要求:< 100ms - 写操作响应时间要求:< 200ms ## # 读写分离类型选择 - 选择基于中间件的读写分离 - 使用DM数据库集群作为后端 - 1主3备架构 ## # 网络架构 - 主数据库和备数据库位于同一机房 - 网络带宽:10Gbps - 网络延迟:< 1ms ## # 存储架构 - 主数据库和备数据库使用SSD存储 - 存储冗余:RAID 10 - 存储容量:2TB ## # 监控架构 - 使用Prometheus + Grafana进行监控 - 配置告警机制,及时通知故障 - 定期进行故障演练

2.2 DM数据库读写分离部署建议

DM数据库读写分离部署建议:

部署建议:

  • 硬件要求:选择高性能的服务器,确保足够的CPU、内存和存储资源
  • 网络要求:确保主备数据库之间的网络带宽足够,网络延迟低,建议使用万兆网络
  • 存储要求:选择可靠的存储设备,确保数据的安全性和可靠性,建议使用SSD存储
  • 软件要求:使用最新版本的DM数据库软件,确保安全性和稳定性
  • 中间件要求:选择性能稳定的数据库中间件,如DM的DMMAL或第三方中间件
  • 操作系统要求:使用稳定版本的操作系统,建议使用Linux系统
  • 网络配置:配置静态IP地址,确保网络连接稳定
  • 防火墙配置:开放必要的端口,确保主备数据库之间的通信畅通
  • 学习交流加群风哥QQ113257174

  • 时间同步:配置NTP服务,确保主备数据库之间的时间同步

2.3 DM数据库读写分离管理建议

DM数据库读写分离管理建议:

  • 监控管理:部署完善的监控系统,及时发现和处理读写分离故障
  • 备份管理:建立完善的备份策略,确保数据的安全性
  • 故障演练:定期进行故障演练,确保读写分离的可靠性
  • 补丁管理:及时应用数据库补丁,确保系统的安全性和稳定性
  • 性能优化:定期进行性能优化,提高读写分离的效率
  • 文档管理:记录读写分离的配置和操作步骤,便于后续参考
  • 人员培训:对运维人员进行培训,提高其读写分离管理能力

Part03-生产环境项目实施方案

3.1 DM数据库读写分离部署步骤

3.1.1 基于中间件的读写分离部署

# 基于中间件的读写分离部署步骤
#
# 1. 环境准备
##
# 服务器配置
– 主数据库:16核CPU,64GB内存,1TB SSD
– 备数据库1:16核CPU,64GB内存,1TB SSD
– 备数据库2:16核CPU,64GB内存,1TB SSD
– 备数据库3:16核CPU,64GB内存,1TB SSD
– 中间件服务器:8核CPU,32GB内存,500GB SSD
– 网络:10Gbps以太网
##
# 软件配置
– DM数据库版本:DM8
– 中间件:DM DMMAL或ProxySQL
– 操作系统:Oracle Linux 9.3
#
# 2. 主备复制配置
##
# 配置主数据库
$ ./DMInstall.bin
$ dminit path=/dm/fgdata db_name=fgedudb
SQL> alter database mount;
SQL> alter database add archivelog ‘dest=/dm/arch,type=local,file_size=1024,space_limit=10240’;
SQL> alter database archivelog;
SQL> alter database open;
SQL> sp_set_para_value(1, ‘INSTANCE_NAME’, ‘PRIMARY’); 更多视频教程www.fgedu.net.cn
SQL> sp_set_para_value(1, ‘PORT_NUM’, 5236);
SQL> sp_set_para_value(0, ‘RLOG_SEND_APPLY_MON’, 1);
##
# 配置备数据库
$ ./DMInstall.bin
$ dmrman
RMAN> restore database ‘/dm/fgdata/fgedudb/dm.ini’ from backupset ‘/dm/backup/full.bak’;
RMAN> recover database ‘/dm/fgdata/fgedudb/dm.ini’ with archivedir ‘/dm/arch’;
RMAN> recover database ‘/dm/fgdata/fgedudb/dm.ini’ update db_magic;
SQL> sp_set_para_value(1, ‘INSTANCE_NAME’, ‘STANDBY1’);
SQL> sp_set_para_value(1, ‘PORT_NUM’, 5236);
SQL> sp_set_para_value(0, ‘RLOG_SEND_APPLY_MON’, 1);
SQL> sp_set_para_value(0, ‘ALTER_MODE_STATUS’, 0);
SQL> sp_set_para_value(0, ‘ENABLE_OFFLINE_TS’, 2);
##
# 配置主备关系
— 主数据库执行
SQL> alter database primary database to standby database ‘STANDBY1’ with ip ‘192.168.1.2’ port 5236;
SQL> alter database primary database to standby database ‘STANDBY2’ with ip ‘192.168.1.3’ port 5236;
SQL> alter database primary database to standby database ‘STANDBY3’ with ip ‘192.168.1.4’ port 5236;
— 备数据库执行
SQL> alter database standby database to primary database ‘PRIMARY’ with ip ‘192.168.1.1’ port 5236;
#
# 3. 中间件配置
##
# 安装中间件
$ ./DMMALInstall.bin
##
# 配置中间件
# dmmal.ini
[MAL]
MAL_HOST = 192.168.1.5
MAL_PORT = 9341
[BACKEND_SERVERS]
SERVER1 = 192.168.1.1:5236,MASTER
SERVER2 = 192.168.1.2:5236,SLAVE
SERVER3 = 192.168.1.3:5236,SLAVE
SERVER4 = 192.168.1.4:5236,SLAVE
[LOAD_BALANCE]
LOAD_BALANCE_MODE = ROUND_ROBIN
#
# 4. 启动服务
##
# 启动主数据库
$ systemctl start DmServicefgedudb
##
# 启动备数据库
$ systemctl start DmServicefgedudb # 备数据库1 更多学习教程公众号风哥教程itpux_com
$ systemctl start DmServicefgedudb # 备数据库2
$ systemctl start DmServicefgedudb # 备数据库3
##
# 启动中间件
$ systemctl start DmMALService
#
# 5. 测试读写分离
##
# 连接中间件
$ disql SYSDBA/SYSDBA@192.168.1.5:9341
##
# 执行写操作
SQL> insert into fgedu.t_user(id, name) values(1, ‘test’);
SQL> commit;
##
# 执行读操作
SQL> select * from fgedu.t_user;
##
# 检查读写分离状态
SQL> select * from v$mal_status;

3.1.2 基于应用层的读写分离部署

# 基于应用层的读写分离部署步骤
#
# 1. 环境准备
##
# 服务器配置
– 主数据库:16核CPU,64GB内存,1TB SSD
– 备数据库1:16核CPU,64GB内存,1TB SSD
– 备数据库2:16核CPU,64GB内存,1TB SSD
– 应用服务器:8核CPU,32GB内存,500GB SSD
– 网络:10Gbps以太网
##
# 软件配置
– DM数据库版本:DM8
– 应用程序:Java应用
– 操作系统:Oracle Linux 9.3
#
# 2. 主备复制配置 from DB视频:www.itpux.com
##
# 配置主数据库
$ ./DMInstall.bin
$ dminit path=/dm/fgdata db_name=fgedudb
SQL> alter database mount;
SQL> alter database add archivelog ‘dest=/dm/arch,type=local,file_size=1024,space_limit=10240’;
SQL> alter database archivelog;
SQL> alter database open;
SQL> sp_set_para_value(1, ‘INSTANCE_NAME’, ‘PRIMARY’);
SQL> sp_set_para_value(1, ‘PORT_NUM’, 5236);
SQL> sp_set_para_value(0, ‘RLOG_SEND_APPLY_MON’, 1);
##
# 配置备数据库
$ ./DMInstall.bin
$ dmrman
RMAN> restore database ‘/dm/fgdata/fgedudb/dm.ini’ from backupset ‘/dm/backup/full.bak’;
RMAN> recover database ‘/dm/fgdata/fgedudb/dm.ini’ with archivedir ‘/dm/arch’;
RMAN> recover database ‘/dm/fgdata/fgedudb/dm.ini’ update db_magic;
SQL> sp_set_para_value(1, ‘INSTANCE_NAME’, ‘STANDBY1’);
SQL> sp_set_para_value(1, ‘PORT_NUM’, 5236);
SQL> sp_set_para_value(0, ‘RLOG_SEND_APPLY_MON’, 1);
SQL> sp_set_para_value(0, ‘ALTER_MODE_STATUS’, 0);
SQL> sp_set_para_value(0, ‘ENABLE_OFFLINE_TS’, 2);
##
# 配置主备关系
— 主数据库执行
SQL> alter database primary database to standby database ‘STANDBY1’ with ip ‘192.168.1.2’ port 5236;
SQL> alter database primary database to standby database ‘STANDBY2’ with ip ‘192.168.1.3’ port 5236;
— 备数据库执行
SQL> alter database standby database to primary database ‘PRIMARY’ with ip ‘192.168.1.1’ port 5236;
#
# 3. 应用程序配置
##
# 配置数据源
# application.properties
spring.datasource.master.url=jdbc:dm://192.168.1.1:5236/fgedudb
spring.datasource.master.username=SYSDBA
spring.datasource.master.password=SYSDBA
spring.datasource.slave1.url=jdbc:dm://192.168.1.2:5236/fgedudb
spring.datasource.slave1.username=SYSDBA
spring.datasource.slave1.password=SYSDBA
spring.datasource.slave2.url=jdbc:dm://192.168.1.3:5236/fgedudb
spring.datasource.slave2.username=SYSDBA
spring.datasource.slave2.password=SYSDBA
##
# 实现读写分离
// 配置类
@Configuration
public class DataSourceConfig {
@Bean
@Primary
public DataSource masterDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(“jdbc:dm://192.168.1.1:5236/fgedudb”);
config.setUsername(“SYSDBA”);
config.setPassword(“SYSDBA”);
return new HikariDataSource(config);
}
@Bean
public DataSource slave1DataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(“jdbc:dm://192.168.1.2:5236/fgedudb”);
config.setUsername(“SYSDBA”);
config.setPassword(“SYSDBA”);
return new HikariDataSource(config);
}
@Bean
public DataSource slave2DataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(“jdbc:dm://192.168.1.3:5236/fgedudb”);
config.setUsername(“SYSDBA”);
config.setPassword(“SYSDBA”);
return new HikariDataSource(config);
}
@Bean
public DataSource routingDataSource() {
Map targetDataSources = new HashMap<>();
targetDataSources.put(“master”, masterDataSource());
targetDataSources.put(“slave1”, slave1DataSource());
targetDataSources.put(“slave2”, slave2DataSource());
RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setDefaultTargetDataSource(masterDataSource());
routingDataSource.setTargetDataSources(targetDataSources);
return routingDataSource;
}
}
// 路由数据源
public class RoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceType();
}
}
// 数据源上下文
public class DataSourceContextHolder {
private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>();
public static void setDataSourceType(String dataSourceType) {
CONTEXT_HOLDER.set(dataSourceType);
}
public static String getDataSourceType() {
return CONTEXT_HOLDER.get();
}
public static void clearDataSourceType() {
CONTEXT_HOLDER.remove();
}
}
// 读写分离注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
String value() default “master”;
}
// 读写分离切面
@Aspect
@Component
public class DataSourceAspect {
@Before(“@annotation(com.example.demo.annotation.DataSource)”)
public void before(JoinPoint point) {
MethodSignature signature = (MethodSignature) point.getSignature();
DataSource dataSource = signature.getMethod().getAnnotation(DataSource.class);
if (dataSource != null) {
DataSourceContextHolder.setDataSourceType(dataSource.value());
}
}
@After(“@annotation(com.example.demo.annotation.DataSource)”)
public void after(JoinPoint point) {
DataSourceContextHolder.clearDataSourceType();
}
}
##
# 使用读写分离
// 写操作
@DataSource(“master”)
public void saveUser(User user) {
userRepository.save(user);
}
// 读操作
@DataSource(“slave1”)
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
#
# 4. 测试读写分离
##
# 启动应用程序
$ java -jar demo.jar
##
# 执行写操作
POST /api/users
{
“id”: 1,
“name”: “test”
}
##
# 执行读操作
GET /api/users/1
##
# 检查读写分离状态
SQL> select * from v$rlog_send; — 主数据库执行
SQL> select * from v$rlog_apply; — 备数据库执行

3.2 DM数据库读写分离配置

DM数据库读写分离配置:

# 读写分离配置
#
# 1. 基于中间件的读写分离配置
##
# 中间件配置文件(dmmal.ini)
[MAL]
MAL_HOST = 192.168.1.5
MAL_PORT = 9341
MAL_LOG_PATH = /dm/log/mal
MAL_LOG_FILE_SIZE = 1024
MAL_LOG_SPACE_LIMIT = 10240
[BACKEND_SERVERS]
SERVER1 = 192.168.1.1:5236,MASTER
SERVER2 = 192.168.1.2:5236,SLAVE
SERVER3 = 192.168.1.3:5236,SLAVE
SERVER4 = 192.168.1.4:5236,SLAVE
[LOAD_BALANCE]
LOAD_BALANCE_MODE = ROUND_ROBIN
LOAD_BALANCE_WEIGHT = 1:1:1
[HEALTH_CHECK]
HEALTH_CHECK_INTERVAL = 10
HEALTH_CHECK_TIMEOUT = 30
#
# 2. 基于应用层的读写分离配置
##
# 应用程序配置(application.properties)
spring.datasource.master.url=jdbc:dm://192.168.1.1:5236/fgedudb
spring.datasource.master.username=SYSDBA
spring.datasource.master.password=SYSDBA
spring.datasource.master.driver-class-name=dm.jdbc.driver.DmDriver
spring.datasource.slave1.url=jdbc:dm://192.168.1.2:5236/fgedudb
spring.datasource.slave1.username=SYSDBA
spring.datasource.slave1.password=SYSDBA
spring.datasource.slave1.driver-class-name=dm.jdbc.driver.DmDriver
spring.datasource.slave2.url=jdbc:dm://192.168.1.3:5236/fgedudb
spring.datasource.slave2.username=SYSDBA
spring.datasource.slave2.password=SYSDBA
spring.datasource.slave2.driver-class-name=dm.jdbc.driver.DmDriver
##
# 数据库连接池配置
spring.datasource.hikari.maximum-pool-size=100
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.connection-timeout=30000
#
# 3. 基于数据库集群的读写分离配置
##
# 集群配置文件(dmmal.ini)
[MAL_INST1]
MAL_INST_NAME = DMSERVER1
MAL_HOST = 192.168.1.1
MAL_PORT = 61141
MAL_INST_HOST = 192.168.1.1
MAL_INST_PORT = 5236
MAL_DW_PORT = 52141
MAL_INST_DW_PORT = 33141
[MAL_INST2]
MAL_INST_NAME = DMSERVER2
MAL_HOST = 192.168.1.2
MAL_PORT = 61142
MAL_INST_HOST = 192.168.1.2
MAL_INST_PORT = 5236
MAL_DW_PORT = 52142
MAL_INST_DW_PORT = 33142
[MAL_INST3]
MAL_INST_NAME = DMSERVER3
MAL_HOST = 192.168.1.3
MAL_PORT = 61143
MAL_INST_HOST = 192.168.1.3
MAL_INST_PORT = 5236
MAL_DW_PORT = 52143
MAL_INST_DW_PORT = 33143
##
# 读写分离配置
SQL> alter system set ‘READ_WRITE_SEPARATION’ = ‘ON’;
SQL> alter system set ‘READ_LOAD_BALANCE’ = ‘ON’;

3.3 DM数据库读写分离管理

DM数据库读写分离管理:

# 读写分离管理
#
# 1. 读写分离状态管理
##
# 查看读写分离状态
SQL> select * from v$mal_status; — 中间件执行
SQL> select * from v$instance; — 数据库执行
##
# 启动读写分离
# 启动中间件
$ systemctl start DmMALService
# 启动数据库
$ systemctl start DmServicefgedudb
##
# 停止读写分离
# 停止中间件
$ systemctl stop DmMALService
# 停止数据库
$ systemctl stop DmServicefgedudb
#
# 2. 读写分离故障处理
##
# 中间件故障处理
# 检查中间件状态
$ systemctl status DmMALService
# 启动中间件
$ systemctl start DmMALService
# 检查中间件状态
$ systemctl status DmMALService
##
# 备数据库故障处理
# 检查备数据库状态
$ systemctl status DmServicefgedudb
# 启动备数据库
$ systemctl start DmServicefgedudb
# 检查备数据库状态
SQL> select * from v$rlog_apply;
##
# 主数据库故障处理
# 检查主数据库状态
$ systemctl status DmServicefgedudb
# 提升备数据库为主数据库
SQL> alter database primary;
# 更新中间件配置
# 修改dmmal.ini中的SERVER1为新的主数据库
# 重启中间件
$ systemctl restart DmMALService
#
# 3. 读写分离性能管理
##
# 监控读写分离性能
# 查看系统性能
$ top
$ free -h
$ iostat -x
# 查看数据库性能
SQL> select * from v$session where status = ‘ACTIVE’;
SQL> select * from v$sql where elapsed_time > 10000000;
# 查看中间件性能
$ netstat -tuln
$ ss -s
##
# 优化读写分离性能
# 优化网络参数
$ echo “net.core.rmem_max = 16777216” >> /etc/sysctl.conf
$ echo “net.core.wmem_max = 16777216” >> /etc/sysctl.conf
$ sysctl -p
# 优化数据库参数
SQL> sp_set_para_value(1, ‘BUFFER’, 4194304);
SQL> sp_set_para_value(0, ‘SORT_BUF_SIZE’, 67108864);
# 优化中间件参数
# 修改dmmal.ini中的LOAD_BALANCE_MODE为WEIGHTED
# 修改dmmal.ini中的LOAD_BALANCE_WEIGHT为2:1:1
#
# 4. 读写分离备份管理
##
# 主数据库备份
$ dmrman
RMAN> backup database ‘/dm/fgdata/fgedudb/dm.ini’ full to backupset ‘/dm/backup/full.bak’;
##
# 备数据库备份
$ dmrman
RMAN> backup database ‘/dm/fgdata/fgedudb/dm.ini’ full to backupset ‘/dm/backup/full_standby.bak’;
##
# 备份验证
$ dmrman
RMAN> validate backupset ‘/dm/backup/full.bak’;
#
# 5. 读写分离补丁管理
##
# 检查补丁状态
SQL> select * from v$version;
##
# 应用补丁
$ ./dm8_20250409_patch.bin
##
# 验证补丁
SQL> select * from v$version;

Part04-生产案例与实战讲解

4.1 DM数据库读写分离部署案例

以下是一个读写分离部署的案例:

#
# 读写分离部署案例
##
# 场景描述
某企业需要部署DM数据库读写分离,提高系统的性能和可用性。
##
# 需求分析
– 读操作:写操作 = 8:2
– 并发量:3000用户
– 读操作响应时间要求:< 100ms - 写操作响应时间要求:< 200ms - 可用性要求:99.99% ## # 架构设计 - 采用基于中间件的读写分离 - 使用DM DMMAL作为中间件 - 1主3备架构 - 主数据库和备数据库位于同一机房 - 网络使用10Gbps以太网 ## # 实施步骤 # 1. 环境准备 # # 服务器配置 - 主数据库:24核CPU,128GB内存,2TB SSD - 备数据库1:24核CPU,128GB内存,2TB SSD - 备数据库2:24核CPU,128GB内存,2TB SSD - 备数据库3:24核CPU,128GB内存,2TB SSD - 中间件服务器:16核CPU,64GB内存,1TB SSD - 网络:10Gbps以太网 # # 软件配置 - DM数据库版本:DM8 - 中间件:DM DMMAL - 操作系统:Oracle Linux 9.3 # 2. 主备复制配置 # # 配置主数据库 $ ./DMInstall.bin $ dminit path=/dm/fgdata db_name=fgedudb SQL> alter database mount;
SQL> alter database add archivelog ‘dest=/dm/arch,type=local,file_size=1024,space_limit=20480’;
SQL> alter database archivelog;
SQL> alter database open;
SQL> sp_set_para_value(1, ‘INSTANCE_NAME’, ‘PRIMARY’);
SQL> sp_set_para_value(1, ‘PORT_NUM’, 5236);
SQL> sp_set_para_value(0, ‘RLOG_SEND_APPLY_MON’, 1);
#
# 配置备数据库
$ ./DMInstall.bin
$ dmrman
RMAN> restore database ‘/dm/fgdata/fgedudb/dm.ini’ from backupset ‘/dm/backup/full.bak’;
RMAN> recover database ‘/dm/fgdata/fgedudb/dm.ini’ with archivedir ‘/dm/arch’;
RMAN> recover database ‘/dm/fgdata/fgedudb/dm.ini’ update db_magic;
SQL> sp_set_para_value(1, ‘INSTANCE_NAME’, ‘STANDBY1’);
SQL> sp_set_para_value(1, ‘PORT_NUM’, 5236);
SQL> sp_set_para_value(0, ‘RLOG_SEND_APPLY_MON’, 1);
SQL> sp_set_para_value(0, ‘ALTER_MODE_STATUS’, 0);
SQL> sp_set_para_value(0, ‘ENABLE_OFFLINE_TS’, 2);
#
# 配置主备关系
— 主数据库执行
SQL> alter database primary database to standby database ‘STANDBY1’ with ip ‘192.168.1.2’ port 5236;
SQL> alter database primary database to standby database ‘STANDBY2’ with ip ‘192.168.1.3’ port 5236;
SQL> alter database primary database to standby database ‘STANDBY3’ with ip ‘192.168.1.4’ port 5236;
— 备数据库执行
SQL> alter database standby database to primary database ‘PRIMARY’ with ip ‘192.168.1.1’ port 5236;
# 3. 中间件配置
#
# 安装中间件
$ ./DMMALInstall.bin
#
# 配置中间件
# dmmal.ini
[MAL]
MAL_HOST = 192.168.1.5
MAL_PORT = 9341
MAL_LOG_PATH = /dm/log/mal
MAL_LOG_FILE_SIZE = 1024
MAL_LOG_SPACE_LIMIT = 10240
[BACKEND_SERVERS]
SERVER1 = 192.168.1.1:5236,MASTER
SERVER2 = 192.168.1.2:5236,SLAVE
SERVER3 = 192.168.1.3:5236,SLAVE
SERVER4 = 192.168.1.4:5236,SLAVE
[LOAD_BALANCE]
LOAD_BALANCE_MODE = ROUND_ROBIN
LOAD_BALANCE_WEIGHT = 1:1:1
[HEALTH_CHECK]
HEALTH_CHECK_INTERVAL = 10
HEALTH_CHECK_TIMEOUT = 30
# 4. 启动服务
#
# 启动主数据库
$ systemctl start DmServicefgedudb
#
# 启动备数据库
$ systemctl start DmServicefgedudb # 备数据库1
$ systemctl start DmServicefgedudb # 备数据库2
$ systemctl start DmServicefgedudb # 备数据库3
#
# 启动中间件
$ systemctl start DmMALService
# 5. 测试读写分离
#
# 连接中间件
$ disql SYSDBA/SYSDBA@192.168.1.5:9341
#
# 执行写操作
SQL> create table fgedu.t_user(id number primary key, name varchar2(100));
SQL> insert into fgedu.t_user(id, name) values(1, ‘test’);
SQL> commit;
#
# 执行读操作
SQL> select * from fgedu.t_user;
#
# 检查读写分离状态
SQL> select * from v$mal_status;
# 6. 性能测试
#
# 执行压力测试
$ ./dmstress -U SYSDBA/SYSDBA@192.168.1.5:9341 -D fgedudb -n 100 -c 100 -t 3600
#
# 监控性能
$ top
$ free -h
$ iostat -x
# 7. 故障演练
#
# 模拟备数据库故障
$ systemctl stop DmServicefgedudb # 备数据库1
#
# 检查读写分离状态
SQL> select * from v$mal_status;
#
# 恢复备数据库
$ systemctl start DmServicefgedudb # 备数据库1
#
# 检查读写分离状态
SQL> select * from v$mal_status;
#
# 模拟主数据库故障
$ systemctl stop DmServicefgedudb # 主数据库
#
# 提升备数据库为主数据库
SQL> alter database primary; # 备数据库1
#
# 更新中间件配置
# 修改dmmal.ini中的SERVER1为192.168.1.2:5236,MASTER
# 修改dmmal.ini中的SERVER2为192.168.1.1:5236,SLAVE
#
# 重启中间件
$ systemctl restart DmMALService
#
# 检查读写分离状态
SQL> select * from v$mal_status;

4.2 DM数据库读写分离故障处理

以下是读写分离故障处理的案例:

#
# 读写分离故障处理案例
##
# 场景描述
读写分离出现故障,需要进行故障处理,确保读写分离的正常运行。
##
# 故障处理步骤
# 1. 检测故障
#
# 监控系统告警
– 收到读写分离故障告警
– 检查读写分离状态
#
# 确认故障
SQL> select * from v$mal_status; — 中间件执行
SQL> select * from v$instance; — 数据库执行
# 2. 分析故障原因
#
# 检查错误日志
$ tail -f /dm/log/DmMALService.log
$ tail -f /dm/log/DmServicefgedudb.log
#
# 检查网络状态
$ ping 192.168.1.1
$ telnet 192.168.1.1 5236
#
# 检查数据库状态
SQL> select * from v$instance;
SQL> select * from v$database;
# 3. 处理故障
#
# 中间件故障
– 重启中间件
– 检查中间件配置
– 检查网络连接
#
# 备数据库故障
– 重启备数据库
– 检查备数据库状态
– 检查主备复制状态
#
# 主数据库故障
– 提升备数据库为主数据库
– 更新中间件配置
– 重启中间件
# 4. 恢复读写分离
#
# 启动服务
$ systemctl start DmServicefgedudb # 备数据库
$ systemctl start DmMALService # 中间件
#
# 检查读写分离状态
SQL> select * from v$mal_status;
SQL> select * from v$rlog_apply;
#
# 验证数据同步
# 在主数据库上执行
SQL> insert into fgedu.t_user(id, name) values(2, ‘fgedu2’);
SQL> commit;
# 在备数据库上检查
SQL> select * from fgedu.t_user;
# 5. 预防措施
#
# 定期检查读写分离状态
SQL> select * from v$mal_status;
SQL> select * from v$rlog_apply;
#
# 定期备份
$ dmrman
RMAN> backup database ‘/dm/fgdata/fgedudb/dm.ini’ full to backupset ‘/dm/backup/full.bak’;
#
# 定期测试故障切换
# 模拟主数据库故障
$ systemctl stop DmServicefgedudb # 主数据库
# 提升备数据库为主数据库
SQL> alter database primary; # 备数据库
# 更新中间件配置
# 修改dmmal.ini中的SERVER1为新的主数据库
# 重启中间件
$ systemctl restart DmMALService
# 恢复原主数据库
$ systemctl start DmServicefgedudb # 原主数据库
# 将原主数据库设置为备数据库
SQL> alter database standby database to primary database ‘NEW_PRIMARY’ with ip ‘192.168.1.2’ port 5236;

4.3 DM数据库读写分离性能优化

以下是读写分离性能优化的案例:

#
# 读写分离性能优化案例
##
# 场景描述
读写分离性能较差,读操作响应时间较长,需要进行优化。
##
# 优化步骤
# 1. 分析性能问题
#
# 检查系统性能
$ top
$ free -h
$ iostat -x
$ netstat -tuln
#
# 检查数据库性能
SQL> select * from v$session where status = ‘ACTIVE’;
SQL> select * from v$sql where elapsed_time > 10000000;
#
# 检查中间件性能
$ netstat -tuln
$ ss -s
# 2. 优化网络性能
#
# 配置网络参数
# 增加网络缓冲区大小
$ echo “net.core.rmem_max = 16777216” >> /etc/sysctl.conf
$ echo “net.core.wmem_max = 16777216” >> /etc/sysctl.conf
$ echo “net.ipv4.tcp_max_syn_backlog = 4096” >> /etc/sysctl.conf
$ echo “net.ipv4.tcp_slow_start_after_idle = 0” >> /etc/sysctl.conf
$ sysctl -p
#
# 使用万兆网络
– 升级网络设备,使用10Gbps以太网
– 配置网络聚合(bonding)
# 3. 优化存储性能
#
# 使用SSD存储
– 主数据库和备数据库使用SSD存储
– 配置RAID 10
#
# 优化存储参数
# 调整IO调度器
$ echo “deadline” > /sys/block/sda/queue/scheduler
# 调整文件系统参数
$ mount -o noatime,nodiratime /dev/sda1 /dm/fgdata
# 4. 优化数据库参数
#
# 优化内存参数
SQL> sp_set_para_value(1, ‘BUFFER’, 4194304);
SQL> sp_set_para_value(0, ‘SORT_BUF_SIZE’, 67108864);
SQL> sp_set_para_value(0, ‘HASH_AREA_SIZE’, 67108864);
#
# 优化IO参数
SQL> sp_set_para_value(1, ‘DBWR_IO_SLAVES’, 4);
SQL> sp_set_para_value(1, ‘LOG_BUFFER’, 67108864);
#
# 优化主从复制参数
SQL> sp_set_para_value(0, ‘RLOG_SEND_THRESHOLD’, 1024);
SQL> sp_set_para_value(0, ‘RLOG_APPLY_THRESHOLD’, 1024);
SQL> sp_set_para_value(0, ‘RLOG_APPLY_PARALLEL’, 4);
# 5. 优化中间件参数
#
# 调整负载均衡策略
# 修改dmmal.ini中的LOAD_BALANCE_MODE为WEIGHTED
# 修改dmmal.ini中的LOAD_BALANCE_WEIGHT为2:1:1
#
# 调整健康检查参数
# 修改dmmal.ini中的HEALTH_CHECK_INTERVAL为5
# 修改dmmal.ini中的HEALTH_CHECK_TIMEOUT为15
# 6. 优化SQL语句
#
# 分析慢SQL
SQL> select * from v$sql where elapsed_time > 10000000 order by elapsed_time desc;
#
# 优化SQL语句
– 创建合适的索引
– 重写SQL语句
– 使用SQL提示
# 7. 验证优化效果
#
# 测试系统性能
$ top
$ free -h
$ iostat -x
#
# 测试数据库性能
SQL> select * from v$session where status = ‘ACTIVE’;
SQL> select * from v$sql where elapsed_time > 10000000;
#
# 测试读写分离性能
$ ./dmstress -U SYSDBA/SYSDBA@192.168.1.5:9341 -D fgedudb -n 100 -c 100 -t 3600
#
# 测试响应时间
# 执行读操作
SQL> select * from fgedu.t_user;
# 执行写操作
SQL> insert into fgedu.t_user(id, name) values(3, ‘test3’);
SQL> commit;

Part05-风哥经验总结与分享

5.1 DM数据库读写分离最佳实践

基于多年DM数据库运维经验,总结以下读写分离最佳实践:

  • 选择合适的读写分离类型:根据业务需求和系统架构选择合适的读写分离类型
  • 合理规划硬件资源:选择高性能的服务器和存储设备,确保足够的资源
  • 优化网络配置:确保主备数据库之间的网络带宽足够,网络延迟低
  • 配置合理的参数:根据实际情况调整数据库和中间件参数,优化性能
  • 建立完善的监控系统:部署完善的监控系统,及时发现和处理读写分离故障
  • 定期进行故障演练:定期进行故障演练,确保读写分离的可靠性
  • 建立完善的备份策略:建立完善的备份策略,确保数据的安全性
  • 文档化配置和操作:记录读写分离的配置和操作步骤,便于后续参考
  • 持续优化:持续进行性能优化,不断提高读写分离的效率
  • 人员培训:对运维人员进行培训,提高其读写分离管理能力
生产环境建议:读写分离是提高数据库性能和可用性的重要技术,需要根据业务需求和实际情况选择合适的读写分离类型,并定期进行测试和优化,确保系统的稳定性和性能。

5.2 DM数据库读写分离常见问题

DM数据库读写分离常见问题及解决方案:

#
# 问题1:读操作响应时间长
#
# 原因分析
– 备数据库性能不足
– 网络延迟大
– SQL语句性能差
– 中间件配置不合理
#
# 解决方案
– 提升备数据库配置
– 优化网络配置
– 优化SQL语句
– 调整中间件配置
#
# 问题2:数据不一致
#
# 原因分析
– 主备复制延迟
– 中间件配置错误
– 应用程序逻辑错误
#
# 解决方案
– 优化主备复制性能
– 检查中间件配置
– 修复应用程序逻辑
#
# 问题3:中间件故障
#
# 原因分析
– 中间件配置错误
– 网络故障
– 硬件故障
#
# 解决方案
– 检查中间件配置
– 检查网络连接
– 检查硬件状态
#
# 问题4:备数据库故障
#
# 原因分析
– 数据库故障
– 网络故障
– 硬件故障
#
# 解决方案
– 重启备数据库
– 检查网络连接
– 检查硬件状态
#
# 问题5:主数据库故障
#
# 原因分析
– 数据库故障
– 网络故障
– 硬件故障
#
# 解决方案
– 提升备数据库为主数据库
– 更新中间件配置
– 重启中间件

5.3 DM数据库读写分离优化建议

DM数据库读写分离优化建议:

  • 选择合适的读写分离类型:根据业务需求和系统架构选择合适的读写分离类型
  • 合理规划硬件资源:选择高性能的服务器和存储设备,确保足够的资源
  • 优化网络配置:确保主备数据库之间的网络带宽足够,网络延迟低
  • 配置合理的参数:根据实际情况调整数据库和中间件参数,优化性能
  • 建立完善的监控系统:部署完善的监控系统,及时发现和处理读写分离故障
  • 定期进行故障演练:定期进行故障演练,确保读写分离的可靠性
  • 建立完善的备份策略:建立完善的备份策略,确保数据的安全性
  • 文档化配置和操作:记录读写分离的配置和操作步骤,便于后续参考
  • 持续优化:持续进行性能优化,不断提高读写分离的效率
  • 学习新技术:不断学习新的读写分离技术,提高读写分离管理能力
风哥提示:读写分离是提高数据库性能和可用性的重要技术,DBA人员必须掌握读写分离的配置和管理方法,根据实际的业务需求和系统环境进行合理配置和优化,提高系统的可用性和可靠性。

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息