欢迎访问 快意信息网,社会信息中心 mobile mip

当前位置:快意信息网 > 能源 >

数据库的同步模式 ... 能源

能源     来源:网络     标签:[db:词语]     发布:2020-10-18 00:20     手机版     MIP

[db:词语]

众所周知,随着用户量的增多,数据库操作往往会成为一个系统的瓶颈所在,而且一般的系统“读”的压力远远大于“写”,因此我们可以通过实现数据库的读写分离来提高系统的性能。


通过设置主从数据库实现读写分离,主数据库负责“写操作”,从数据库负责“读操作”,根据压力情况,从数据库可以部署多个提高“读”的速度,借此来提高系统总体的性能。


要实现读写分离,就要解决主从数据库数据同步的问题,在主数据库写入数据后要保证从数据库的数据也要更新。

主从数据库同步的实现思路如图:

主服务器master记录数据库操作日志到Binary log,从服务器开启i/o线程将二进制日志记录的操作同步到relay log(存在从服务器的缓存中),另外sql线程将relay log日志记录的操作在从服务器执行。
记住这张图,接下来基于这个图实际设置主从数据库。


首先要有两个数据库服务器master、slave(也可以用一个服务器安装两套数据库环境运行在不同端口,slave也可以举一反三设置多个),我们穷人就买虚拟云服务器玩玩就行 0.0。以下操作假设你的两台服务器上都已经安装好了mysql服务。


可以看到下图表示配置没问题,这里面的File名:master-bin.000001 我们接下来在从数据库的配置会使用:


mysql create user repl; mysql GRANT REPLICATION SLAVE ON *.* TO 'repl'@'从xxx.xxx.xxx.xx' IDENTIFIED BY 'mysql'; mysql flush privileges;

这个配置的含义就是创建了一个数据库用户repl,密码是mysql, 在从服务器使用repl这个账号和主服务器连接的时候,就赋予其REPLICATION SLAVE的权限, *.* 表面这个权限是针对主库的所有表的,其中xxx就是从服务器的ip地址。
进入从数据库后执行:


mysql change master to master_host='主xxx.xxx.xxx.xx',master_port=3306,master_user='repl',master_password='mysql',master_log_file='master-bin.000001',master_log_pos=0;

这里面的xxx是主服务器ip,同时配置端口,repl代表访问主数据库的用户,上述步骤执行完毕后执行start slave启动配置:


可以看到状态如下:

这里看到从数据库已经在等待主库的消息了,接下来在主库的操作,在从库都会执行了。我们可以主库负责写,从库负责读(不要在从库进行写操作),达到读写分离的效果。


可以看到从数据库也有testsplit这张表了,这里就不上图了,亲测可用。在主数据库插入数据,从数据库也可以查到。
至此已经实现了数据库主从同步


上面我们已经有了两个数据库而且已经实现了主从数据库同步,接下来的问题就是在我们的业务代码里面实现读写分离,假设我们使用的是主流的ssm的框架开发的web项目,这里面我们需要多个数据源。

在此之前,我们在项目中一般会使用一个数据库用户远程操作数据库(避免直接使用root用户),因此我们需要在主从数据库里面都创建一个用户mysqluser,赋予其增删改查的权限:

mysql GRANT select,insert,update,delete ON *.* TO 'mysqluser'@'%' IDENTIFIED BY 'mysqlpassword' WITH GRANT OPTION;

然后我们的程序里就用mysqluser这个用户操作数据库:


#主数据库地址 jdbc.master.url=jdbc:mysql://xxx.xxx.xxx.xx:3306/testsplit?useUnicode=true characterEncoding=utf8 #从数据库地址 jdbc.slave.url=jdbc:mysql://xxx.xxx.xxx.xx:3306/testsplit?useUnicode=true characterEncoding=utf8 #数据库账号 jdbc.username=mysqluser jdbc.password=mysqlpassword

这里我们指定了两个数据库地址,其中的xxx分别是我们的主从数据库的ip地址,端口都是使用默认的3306


在spring-dao. 中配置数据源(这里就不累赘介绍spring的配置了,假设大家都已经配置好运行环境),配置如下:


? version="1.0" encoding="UTF-8"? beans ns="http://www.spring work.org/schema/beans" ns:xsi="http://www.w3.org/2001/ Schema-instance" ns:context="http://www.spring work.org/schema/context" xsi:schemaLocation="http://www.spring work.org/schema/beans http://www.spring work.org/schema/beans/spring-beans.xsd" !-- 配置整合mybatis过程 -- !-- 1.配置数据库相关参数properties的属性:${url} -- context:property-placeholder location="classpath:jdbc.properties" / !-- 扫描dao包下所有使用注解的类型 -- context:component-scan -package="c n.xzchain.testsplit.dao" / !-- 2.数据库连接池 -- bean id="abstractDataSource" abstract="true" destroy-method="close" !-- c3p0连接池的私有属性 -- property name="maxPoolSize" value="30" / property name="minPoolSize" value="10" / !-- 关闭连接后不自动commit -- property name="autoCommitOnClose" value="false" / !-- 获取连接超时时间 -- property name="checkoutTimeout" value="10000" / !-- 当获取连接失败重试次数 -- property name="acquireRetryAttempts" value="2" / /bean !--主库配置-- bean id="master" parent="abstractDataSource" !-- 配置连接池属性 -- property name="driverClass" value="${jdbc.driver}" / property name="jdbcUrl" value="${jdbc.master.url}" / property name="user" value="${jdbc.username}" / property name="password" value="${jdbc.password}" / /bean !--从库配置-- bean id="slave" parent="abstractDataSource" !-- 配置连接池属性 -- property name="driverClass" value="${jdbc.driver}" / property name="jdbcUrl" value="${jdbc.slave.url}" / property name="user" value="${jdbc.username}" / property name="password" value="${jdbc.password}" / /bean !--配置动态数据源,这里的targetDataSource就是路由数据源所对应的名称-- bean id="dataSourceSelector" property name="targetDataSources" map entry value-ref="master" key="master" /entry entry value-ref="slave" key="slave" /entry /map /property /bean !--配置数据源懒加载-- bean id="dataSource" property name="targetDataSource" ref bean="dataSourceSelector" /ref /property /bean !-- 3.配置SqlSessionFactory对象 -- bean id="sqlSessionFactory" !-- 注入数据库连接池 -- property name="dataSource" ref="dataSource" / !-- 配置MyBaties全局配置文件:mybatis-config. -- property name="configLocation" value="classpath:mybatis-config. " / !-- 扫描entity包 使用别名 -- property name="typeAliasesPackage" value="cn.xzchain.testsplit.entity" / !-- 扫描sql配置文件:mapper需要的 文件 -- property name="mapperLocations" value="classpath:mapper/*. " / /bean !-- 4.配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -- bean !-- 注入sqlSessionFactory -- property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" / !-- 给出需要扫描Dao接口包 -- property name=" Package" value="cn.xzchain.testsplit.dao" / /bean /beans

说明:
首先读取配置文件jdbc.properties,然后在我们定义了一个基于c3p0连接池的父类“抽象”数据源,然后配置了两个具体的数据源master、slave,继承了abstractDataSource,这里面就配置了数据库连接的具体属性,然后我们配置了动态数据源,他将决定使用哪个具体的数据源,这里面的关键就是DataSourceSelector,接下来我们会实现这个bean。下一步设置了数据源的懒加载,保证在数据源加载的时候其他依赖的bean已经加载好了。接着就是常规的配置了,我们的mybatis全局配置文件如下


PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd" configuration !-- 配置全局属性 -- settings !-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 -- setting name="useGeneratedKeys" value="true" / !-- 使用列别名替换列名 默认:true -- setting name="useColumnLabel" value="true" / !-- 开启驼峰命名转换:Table{create_time} - Entity{createTime} -- setting name="mapUnderscoreToCamelCase" value="true" / !-- 打印查询语句 -- setting name="logImpl" value="STDOUT_LOGGING" / /settings plugins plugin interceptor="cn.xzchain.testsplit.dao.split.DateSourceSelectInterceptor" /plugin /plugins /configuration

这里面的关键就是DateSourceSelectInterceptor这个拦截器,它会拦截所有的数据库操作,然后分析sql语句判断是“读”操作还是“写”操作,我们接下来就来实现上述的DataSourceSelector和DateSourceSelectInterceptor


DataSourceSelector就是我们在spring-dao. 配置的,用于动态配置数据源。代码如下:


protected determineCurrentLookupKey() { return DynamicDataSourceHolder.getDataSourceType(); }

我们只要继承AbstractRoutingDataSource并且重写determineCurrentLookupKey()方法就可以动态配置我们的数据源。
编写DynamicDataSourceHolder,代码如下:


/**用来存取key,ThreadLocal保证了线程安全*/ private static ThreadLocal String contextHolder = new ThreadLocal String /**主库*/ public static final String DB_MASTER = "master"; /**从库*/ public static final String DB_SLAVE = "slave"; * 获取线程的数据源 * @return public static String getDataSourceType() { String db = contextHolder.get(); if (db == null){ //如果db为空则默认使用主库(因为主库支持读和写) db = DB_MASTER; return db; * 设置线程的数据源 * @param s public static void setDataSourceType(String s) { contextHolder.set(s); * 清理连接类型 public static void clearDataSource(){ contextHolder.remove();

这个类决定返回的数据源是master还是slave,这个类的初始化我们就需要借助DateSourceSelectInterceptor了,我们拦截所有的数据库操作请求,通过分析sql语句来判断是读还是写操作,读操作就给DynamicDataSourceHolder设置slave源,写操作就给其设置master源,代码如下:


import org.apache.ibatis.executor.Executor; import org.apache.ibatis.executor.keygen.SelectKeyGenerator; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlCommandType; import org.apache.ibatis.plugin.*; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import org.spring work.transaction.support.TransactionSynchronizationManager; import java.util.Locale; import java.util.Properties; * @author lihang * @date 2017/12/6. * @de ion 拦截数据库操作,根据sql判断是读还是写,选择不同的数据源 @Intercepts({@Signature(type = Executor.class,method = "update",args = {MappedStatement.class, .class}), @Signature(type = Executor.class,method = "query",args = {MappedStatement.class, .class, RowBounds.class, ResultHandler.class})}) public class DateSourceSelectInterceptor implements Interceptor{ /**正则匹配 insert、delete、update操作*/ private static final String REGEX = ".*insert\\\\u0020.*|.*delete\\\\u0020.*|.*update\\\\u0020.*"; @Override public intercept(Invocation invocation) throws Throwable { //判断当前操作是否有事务 boolean synchonizationActive = TransactionSynchronizationManager.isSynchronizationActive(); //获取执行参数 [] s = invocation.getArgs(); MappedStatement ms = (MappedStatement) s[0]; //默认设置使用主库 String lookupKey = DynamicDataSourceHolder.DB_MASTER;; if (!synchonizationActive){ //读方法 if (ms.getSqlCommandType().equals(SqlCommandType.SELECT)){ //selectKey为自增主键(SELECT LAST_INSERT_ID())方法,使用主库 if (ms.getId().contains(SelectKeyGenerator.SELECT_KEY_SUFFIX)){ lookupKey = DynamicDataSourceHolder.DB_MASTER; }else { BoundSql boundSql = ms.getSqlSource().getBoundSql( s[1]); String sql = boundSql.getSql().toLowerCase(Locale.CHINA).replace("[\\t\\n\\r]"," "); //如果是insert、delete、update操作 使用主库 if (sql.matches(REGEX)){ lookupKey = DynamicDataSourceHolder.DB_MASTER; }else { //使用从库 lookupKey = DynamicDataSourceHolder.DB_SLAVE; }else { //一般使用事务的都是写操作,直接使用主库 lookupKey = DynamicDataSourceHolder.DB_MASTER; //设置数据源 DynamicDataSourceHolder.setDataSourceType(lookupKey); return invocation.proceed(); @Override public plugin( target) { if (target instanceof Executor){ //如果是Executor(执行增删改查操作),则拦截下来 return Plugin.wrap(target,this); }else { return target; @Override public void setProperties(Properties properties) { }

通过这个拦截器,所有的insert、delete、update操作设置使用master源,select会使用slave源。

接下来就是测试了,我这是生产环境的代码,直接打印日志,小伙伴可以加上日志后测试使用的是哪个数据源,结果和预期一样,这样我们就实现了读写分离~

ps:我们可以配置多个slave用于负载均衡,只需要在spring-dao. 中添加slave1、slave2、slave3……然后修改dataSourceSelector这个bean,


entry value-ref="master" key="master" /entry entry value-ref="slave1" key="slave1" /entry entry value-ref="slave2" key="slave2" /entry entry value-ref="slave3" key="slave3" /entry /map /property

在map标签中添加slave1、slave2、slave3……即可,具体的负载均衡策略我们在DynamicDataSourceHolder、DateSourceSelectInterceptor中实现即可。

最后整理一下整个流程:
1.项目启动后,在依赖的bean加载完成后,我们的数据源通过LazyConnectionDataSourceProxy开始加载,他会引用dataSourceSelector加载数据源。
2.DataSourceSelector会选择一个数据源,我们在代码里设置了默认数据源为master,在初始化的时候我们就默认使用master源。
3.在数据库操作执行时,DateSourceSelectInterceptor拦截器拦截了请求,通过分析sql决定使用哪个数据源,“读操作”使用slave源,“写操作”使用master源。


现在很多读写分离中间件已经大大简化了我们的工作,但是自己实现一个小体量的读写分离有助于我们进一步理解数据库读写分离在业务上的实现,呼~

收起 展开全文
最近有很多朋友跟我聊到关于“在软件项目开发中如何合理使用设计模式”的问题,希望我能够给出一些相对比较完整的真实项目实例,为了满足大家的要求,在后续文章中,我将拿出几个较为复杂的实例与大家一起分享,有些...

        最近有很多朋友跟我聊到关于“在软件项目开发中如何合理使用设计模式”的问题,希望我能够给出一些相对比较完整的真实项目实例,为了满足大家的要求,在后续文章中,我将拿出几个较为复杂的实例与大家一起分享,有些项目是我参与开发的,有些项目是在我的指导下开发的,希望能给大家带来帮助!在此我也希望大家能够分享自己的一些设计模式使用心得和好的设计模式应用实例,可以整理一份给我(可发送到邮箱:weiliu_china@126.com),在下一本设计模式图书(有计划明年写一本《设计模式案例剖析》,暂定名)中我将选取部分实例加入其中,如有入选者,Sunny承诺送签名图书两本,,选择范围包括已经出版的《设计模式》、《设计模式实训教程》、《设计模式的艺术》,还包括马上要出版的《C#设计模式》和正在编写的《UML建模实训教程》,任君挑选,正版保证,假一罚十!

 

        从本文开始,我将介绍一个数据库同步系统的设计方案,该系统是我在2010年给某软件公司做设计模式内训时指导几位开发人员所开发的一个项目,系统以某省级移动公司应急管理系统数据备份(数据库同步)需求为原型,基本需求如下:

        为了在数据库发生故障的情况下不影响核心业务的运行,需要将生产数据库定期备份到应急数据库,以备生产数据库发生故障时,能切换到应急数据库,保证业务的正常运行。由于移动公司的数据量非常大,所以只需要对基础数据和关键数据进行备份,为了确保切换到应急数据库时保证核心业务能够运行,还需要备份整个数据库结构。

      系统目前需求仅要求支持Oracle数据库的同步,但系统设计时需要考虑以后可以方便地支持其他数据库。Oracle数据库的结构由各种数据库对象组成,要求完成对各种数据库对象的同步,包括表(包括约束)、索引、触发器、分区表、视图、存储过程、函数、包、数据库连接、序列、物化视图和同义词。各类数据库对象的同步有一定的顺序关系,总体流程如图1所示:

图1 数据库同步流程图

 

       数据库同步系统界面如图2所示:

图2 数据库同步系统界面

       用户在操作界面指定源数据库、目标数据库、控制数据库(用于读取配置信息)的数据库连接串,同时选取需要同步的数据库对象类型,对象类型存储在配置文件data _syn_config. 中,通过输入SQL语句可以获取需要同步的表数据。

       数据库对象同步的处理逻辑描述如下:

       (1) 对于一般的数据库对象,同步时先取出源数据库与目标数据库该类数据库对象进行对比,然后将对象更新到目标数据库。

       (2) 对于D 对象,由于数据库环境发生变化,需要手工调整,同步过程只记录新增的D 信息,而不执行创建操作。

       (3) 表的同步处理由于其包含数据,因此较为特殊,需先对表结构变化进行分析,再同步数据。表数据的同步有三种方式:增量同步、先Delete后Insert方式、临时表方式。

       (I) 增量同步。适用于可确定最后修改时间戳字段的情况。

       (II) 先Delete后Insert方式。即先删除表的数据,再将源数据库的该表数据插入到目标数据库,为确保数据安全,要求在一个事务内完成。

       (III) 临时表方式。用于最大限度保证数据的完整性,是一种在发生意外情况时,不丢失数据而使用的较为复杂的方式。

       由于对数据库结构修改无法做事务回滚,因此如果后面的步骤发生异常,需要通过手工编码方式来实现目标数据库结构变化的回滚。

       在本系统实现过程中使用了多种设计模式,下面对其进行简要分析(为了简化代码和类图,省略了关于包的描述,在实际应用中已将不同的类封装在不同包中):

 

         1. 建造者模式

       在本系统实现时提供了一个数据库同步流程管理器DBSynchronizeManager类,它用于负责控制数据库同步的具体执行步骤。用户在前台界面可以配置同步参数,程序运行时,需要根据这些参数来创建DBSynchronizeManager对象,创建完整DBSynchronizeManager对象的过程由类DBSynchronizeManagerBuilder负责,此时可以使用建造者模式来一步一步构造一个完整的复杂对象,类图如图3所示:

图3 建造者模式实例类图

       在图3中省略了抽象建造者,DBSynchronizeManagerDirector充当指挥者类,DBSynchronizeManagerBuilder充当建造者,DBSynchronizeManager充当复杂产品。

 

      2. 简单工厂模式

       DBSynchronizeManagerBuilder类的buildLife()方法可以创建一个初始的DBSynchronizeManager实例,再一步一步为其设置属性,为了保证在更换数据库时无须修改DBSynchronizeManagerBuilder类的源代码,在此处使用简单工厂模式进行设计,将数据库类型存储在配置文件中,如下片段代码所示:

…… dbSynchronizeManager dbType="oracle" /

       类图如图4所示:

图4 简单工厂模式实例类图

       使用简单工厂模式设计的工厂类DBSynchronizeManagerFactory代码如下所示:

public class DBSynchronizeManagerFactory { public static DBSynchronizeManager factory(String dbType) throws Exception { String className = DBSynConfigParser.getSynchronizeManagerClass(dbType); return (DBSynchronizeManager)Class.forName(className).newInstance(); }

       其中DBSynConfigParser类用于读取配置文件,在图4中,DBSynchronizeManagerFactory类充当数据库同步流程管理器的简单工厂,DBSynchronizeManager是抽象产品,而OracleDBSynchronizeManager为具体产品。

 

【作者:刘伟   http://blog.csdn.net/lovelion】 

收起 展开全文
1.Oracle Data Guard概述Oracle在版本7的时候,就支持Standby容灾备份数据库技术,并... Data Guard是Oracle的集成化灾难恢复解决方案,该技术可以维护生产数据库一个或多个同步备份,由一个生产数据库和若干备用数据

1.Oracle Data Guard概述 ? :namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /

Oracle在版本7的时候,就支持Standby容灾备份数据库技术,并在Oracle8版本开始支持日志从生产数据库到备用数据库的自动传输。Oracle9i版本把standby技术正式命名为Data Guard。

 

Data Guard是Oracle的集成化灾难恢复解决方案,该技术可以维护生产数据库一个或多个同步备份,由一个生产数据库和若干备用数据库组成,并形成一个独立的、易于管理的数据保护方案。Data Guard备用数据库可以与生产系统位于相同的数据中心,也可以是在地理位置上分布较远的远程灾难备份中心。

 

Data Guard的基本原理是,当某次事务处理对生产数据库中的数据作出更改时,Oracle数据库将在一个联机重做日志文件中记录此次更改。在Data Guard中可以配置写日志的这个过程,除了把日志记录到本地的联机日志文件和归档日志文件中,还可以通过网络,把日志信息发送的远程的备用数据库服务器上。这个备用日志文件写入过程可以是实时、同步的,以实现零数据丢失(最大保护模式);也可以是异步的,以减少对网络带宽的压力(最大可用性模式);或者是通过归档日志文件、一个日志文件的批量传输模式,以减少对生产系统的性能影响(最大性能模式)。当备份数据库接收到日志信息后,Data Guard可以自动利用日志信息实现数据的同步。当主数据库打开并处于活动状态时,备用数据库可以执行恢复操作,如果主数据库出现了故障,备用数据库即可以被激活并接管生产数据库的工作

 

                 Oracle Dataguard数据库灾备原理图

 

2.物理备用数据库和逻辑备用数据库

当备用数据库接收到从生产数据库传输过来的日志时,根据处理日志方法的不同,可以把Data Guard分为物理备用数据库和逻辑备用数据库两种。物理备用数据库,就是备用数据库处于Mount的状态下,直接利用数据恢复技术,把日志文件中记录的数据变更应用在备用数据库的数据文件上,从而实现与生产数据库的数据同步,在进行数据同步的时候,物理备用数据库是不能打开的、也无法提供数据查询等服务,物理备用数据库也可以通过只读的方式打开,但是,一旦物理备用数据库以只读方式打开后,就只能接收日志,而无法进行数据的同步;逻辑备用数据库,数据库是处于正常的打开状态的,当它接收到新的日志信息后,利用日志挖掘器的功能,把日志中记录的变更信息,转换成具体的SQL语句,并在逻辑备用数据库上执行这些SQL语句,从而实现与生产数据库的数据同步,逻辑备用数据库支持在数据同步的同时,进行数据的查询、报表等操作。Oracle从9i R2开始支持逻辑备用数据库。

3.物理备用数据库的数据保护级别

Oracle Data Guard 支持多种级别的数据保护模式:最大性能模式,最大可用性模式,最大保护模式。分别对应于“重要信息系统灾难恢复指南”中的5级,5级6级自适应,6级的数据保护级别。其中对应6级的最大保护模式可以实现实时数据实时同步和0数据丢失。另外,Oracle Data Guard 可以设置延时应用时间窗口,从而防范错误操作、黑客攻击等人为错误导致的数据损坏。

保护模式和重做传输

要确定适当的数据保护模式,企业需要根据用户对系统响应时间的要求来估量它们对数据保护的业务要求。下表从数据丢失风险的角度概述了各种模式的适用性。

保护模式

在出现灾难时数据丢失的风险

重做传输机制

最大保护

零数据丢失

LGWR SYNC

最高可用性

零数据丢失

LGWR SYNC

最高性能

最小数据丢失 — 通常为几秒

LGWR ASYNC 或 ARCH

 

最大保护模式

 

最大保护模式为主数据库提供了最高水平的数据保护,从而确保了一个全面的零数据丢失灾难恢复解决方案。当在最大保护模式下运行时,重做记录由日志写入器 (LGWR) 进程从主数据库同步地传输到备用数据库,并且直到确认事务数据在至少一个备用服务器上的磁盘上可用时,才在主数据库上提交事务。强烈建议,这种模式应至少配置两个备用数据库。当最后参与的备用数据库不可用时,主数据库上的处理将停止。这就确保了当主数据库与其所有备用数据库失去联系时,不会丢失事务。

 

由于重做传输的同步特性,这种最大保护模式可能潜在地影响主数据库响应时间。可以通过配置一个低延迟网络,并为它分配足够应付高峰事务负载的带宽来将这种影响减到最小。需要这种最大保护模式的企业有股票交易所、货币交易所、金融机构等。

 

最高可用性模式

 

最高可用性模式拥有仅次于最高水平的主数据库数据可用性。如同最大保护模式一样,重做数据由 LGWR 从主数据库同步地传输到备用数据库,直到确认事务数据在备用服务器的磁盘上可用时,事务才在主数据库上完成。不过,在这种模式下(与最大保护模式不同),如果最后参与的备用数据库变为不可用 — 例如由于网络连接问题,处理将在主数据库上继续进行。备用数据库与主数据库相比,可能暂时落在后面,但当它再次变为可用时,备用数据库将使用主数据库上累积的归档日志自动同步,而不会丢失数据。

 

由于同步重做传输,这种保护模式可潜在地影响响应时间和吞吐量。可以通过配置一个低延迟网络,并为它分配足够应付高峰事务负载的带宽来将这种影响减到最小。

 

最高可用性模式适用于想要确保获得零数据丢失保护,但不想让生产数据库受网络/备用服务器故障影响的企业。如果又一个故障随后影响了生产数据库,然后最初的网络/备用服务器故障得到解决,那么这些企业将接受数据丢失的可能性。

 

最高性能模式

 

最高性能模式是默认的保护模式。它与最高可用性模式相比,提供了稍微少一些的主数据库数据保护,但提供了更高的性能。在这种模式下,当主数据库处理事务时,重做数据由 LGWR 进程异步传输到备用数据库上。另外,也可以将主数据库上的归档器进程 (ARCH) 配置为在这种模式下传输重做数据。在任何情况下,均先完成主数据库上的写操作,主数据库的提交操作不等待备用数据库确认接收。如果任意备用目标数据库变为不可用,则处理将在主数据库上继续进行,这对性能只有很小的影响或没有影响。

在主数据库出现故障的情况下,尚未被发送到备用数据库的重做数据会丢失。但是,如果网络有足够的吞吐量来跟上重做流量高峰,并且使用了 LGWR 进程来将重做流量传输到备用服务器,则丢失的事务将非常少或者为零。

当主数据库上的可用性和性能比丢失少量数据的风险更重要时,应该使用最高性能模式。这种模式还适合于 WAN 上的 Data Guard 部署,在 WAN 中,网络的内在延迟可能限制同步重做传输的适用性。

4. ? :namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" / 10g Data Guard存在的不足

建设灾难备份数据库,需要投入基础设施(如机房、场地、人员)、硬件、软件等成本。因此,能否最大程度地充分发挥灾备系统的资源利用率,是很多企业的重要考虑因素。

物理备用数据库所需要的硬件资源不高、数据同步的速度也快,但是,在进行数据同步的同时,数据库是无法打开提供查询访问服务的,而如果用只读方式打开物理备用数据库,则数据同步就无法同时进行,因此,无法满足企业近实时数据查询的需要;而逻辑备用数据库,数据同步的同时、数据库是正常打开的,是可以在数据同步的同时提供对外查询服务的,但是,逻辑备用数据库在使用上存在一定的限制,例如:不支持long、long raw以及用户自定义的数据类型,一般需要为每个表创建关键字或唯一索引等。此外,由于逻辑备用数据库不仅要执行生产数据库上所发生的所有数据变更SQL语句,还需要额外的日志分析工作,因此,硬件资源的配置也相对较高。

 

有没有办法,把逻辑备用数据库和物理备用数据库的优势结合在一起,既能发挥物理备用数据库同步速度快、耗用资源低,又能够在数据同步的同时,可以进行数据查询,从而充分发挥备用系统的资源利用率呢?这就是Oracle11g Active Data Guard的功能。

 

5.Oracle11g Active Data Guard的功能增强

11g以前的Data Guard物理备用数据库,可以以只读的方式打开数据库,但是这时Media Recovery利用日志进行数据同步的过程就停止了,如果物理备用数据库处于恢复的过程中数据库就不能打开查询,也就是说日志应用和只读打开两个状态是互相排斥的,而Oracle11g Active Data Guard功能解决了这个矛盾,在利用日志恢复数据的同时可以用只读的方式打开数据库,用户可以在备用数据库上进行查询、报表等操作,这类似逻辑备用数据库的功能,但是,数据同步的效率更高、对硬件的资源要求更低。这样可以更大程度地发挥物理备用数据库的硬件资源的效能(比如对于实时要求比较高的报表服务)。

Oracle11g Active Data Guard除了可以运行在只读打开和日志同步应用的场景下,还可以切换到Snapshot Standby状态下运行。运行在Snapshot Standby状态下的物理备用数据库可以用读写的模式打开数据库,但是同时没有破坏它作为物理备用数据库的功能,这个特性可以用来在物理备用数据库上面执行某些测试,等测试完成,把数据库再切换到Physical standby状态下,又可以自动利用日志实现数据同步了。当然在Snapshot Standby以读写方式打开的时候它只能接收生产数据库传过来的日志,但是不能应用这些日志进行数据同步。

例如:把数据库从数据同步和只读打开状态切换到快照备用状态,只需要在备用数据库上执行Alter data convert to snapshot standby;而把数据库从快照备用切换会只读同步状态,只需要执行Alter data convert to physical standby就可以了

 

收起 展开全文
一、双写模式 我们采取MySQL作为主要的数据存储,利用MySQL的事务特性维护数据一致性,使用ElasticSearch进行数据汇集和查询,此时es与数据库的同步方案就尤为重要。 保证es与数据库的同步方案: 1、首先添加商品入...
之前写了三篇关于秒杀的文章,里面提到了通过分布式缓存来缓解数据库压力。最近有朋友私信回复问,缓存和数据库是如何进行...读缓存的同步:缓存预加载模式提前将数据从数据库加载到缓存,如果数据库有写更新,同步更新
Navicat 是一套快速、可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设。它可以用来对本机或远程的 MySQL、SQL Server、SQLite、Oracle 及 PostgreSQL 数据库进行管理及开发。 日常...
 客服QQ1793040 ----------------------------------------------------------     ...关于HKROnline SyncNavigator 注册机价格...HKROnline SyncNavigator 8.4.1 企业版数据同步软件 自2009年第一个版本开发...
随着信息技术的飞速发展,企业信息化建设的不断深入,使得企业业务系统数量不断增加。这时,各业务系统之间数据交互,各子...下面浅谈下Oracle数据库之间数据同步方案,不涉及方案的好坏选择,可供参考。 Oracle 提
主流数据库均支持这种完全的同步模式。已经有人提到MySQL的Semi-sync功能(从MySQL5.6开始官方支持,此前的版本可以考虑Google出的非官方补丁),就是基于这种原理。 不过,一般不建议使用这种同步模式。
一类是主数据库(master)一类是从数据库(slave),主数据库可以进行读写操作,当发生写操作的时候自动将数据同步到从数据库,而从数据库一般是只读的,并接收主数据库同步过来的数据,一个主数据库可以有多个从...
DataGurd: 主要备库的方式,就是数据库对数据库的备份方式,主要是解决容灾的。...主要是基于触发器的原理来触发数据同步的,因此,高级复制无法实现用户,数据库级别的对象复制,只能做些表、索引和存储过程的复制。
接“设计模式综合实例分析之数据库同步系统(一)“。 3. 享元模式和单例模式 在数据库同步系统中,抽象类DB Synchronizer表示需要同步的数据库对象,对于不同的数据库对象类型,提供了不同的子类实现,在...
缓存同步机制整理 同步目的 使数据库数据和缓存中的数据在一定时间内保持一致 缓存形式 内存文件(磁盘) 缓存更新的常用模式 预留缓存Cache-aside 访问数据库之前先检查缓存中是否有缓存,如果没有在...
如果你曾经使用过数据库镜像,你会发现可用性模式的概念和镜像的概念(异步操作模式和同步操作模式)非常相似。 异步提交模式 使用此可用性模式的可用性副本称为“异步提交副本”。当辅助副本处于异步提交
 2、主从服务器都开启SQL Server的代理服务,并设置为开机自动启动 3、在数据库配置管理其中把SQL Server服务和SQL Server的代理服务的登录信息设置为上边添加的系统用户,并设置好密码。(记得主从服务器都需要...
当某次事务处理对生产数据库中的数据作出更改时,Oracle数据库将在一个联机重做日志文件中记录此次更改。在DataGuard中可以配置写日志的这个过程,除了把日志记录到本地的联机日志文件和归档日志文件中,还可以通过...
容灾数据复制技术的比较   一、概述 近几年来,容灾已经成为信息数据中心建设的热门课题。很多容灾技术也快速发展起来,对用户来说也有很广阔的选择余地。但由于容灾方案的技术复杂性和多样性,一般用户很难搞清...
了解 MySQL 集群之前,先看看单节点数据库的弊病: 大型互联网程序用户群体庞大,所以架构需要特殊设计。 单节点数据库无法满足大并发时性能上的要求。 单节点的数据库没有冗余设计,无法满足高可用。 单节点 ...
Mongodb配置主从模式,进行数据的同步与备份1. 背景 做数据库的人都知道要对数据做备份,避免数据库单点部署,以防止数据遭到毁灭性破坏。 mongodb提供的Master/slave主从模式,刚好能支持这种双机热备份,还有读写...

本文标签:[db:词语]

本文地址:http://www.k0358.com/nengyuan/gzkmjlnms.html 转载请注明出处

上一篇: 猎豹移动:微软发布8月例行更新 Windows 10亦受影响
下一篇: 腾讯云自主可控数据库TDSQL的架构演进

本站所有文章均来自搜索引擎和其他站点公开内容,如有侵权或表述不当,请联系并标明身份和情况后立即删除,E-mail:ainba_cn@163.com
copyright © 2012-2019 www.k0358.com 快意信息网 - 快意信息网,社会信息中心 移动版 MIP