RAC

RAC属于OLAP还是OLTP:

  • OLTP要求很高的内存效率,RAC不是,但是RAC可以接受更多的并发
  • OLAP需要大量的并行,RAC可以提供,但是会产生大量的insterconnect数据

RAC在OLAP下的应用:

  • 实例容错
  • 负载均衡
  • 业务分离

RAC业务分离

使用RAC进行实例级别的冗余架构,应用可以按照任意或者随机的连接到某个实例上进行业务操作,即使某个实例down掉了,并不会影响业务的正常操作。

但是,当数据块分布到不同实例的内存里时,实例之间就会出现数据块的复制问题,这里买涉及到一系列的内存管理机制,Oracle称之为 cache fusion,这种内存间的数据块传递的代价也是比较大的,甚至出现长时间的等待。

基于这个原因,为了能够高效的利用RAC架构,可以通过一种技术,将某类或者几类的业务分配到某一个或者几个实例上,另外的业务分配到其他的实例上。这样做的目的就是将操作相似的业务集中起来,数据块尽可能的集中在小范围的内存中,避免了由于cache fusion导致的等待事件。

例如:

根据系统业务需求,分为数据加载业务、数据查询业务,数据加载业务要分配到实例1、实例2上,数据查询业务要分配到实例3、实例4上。这样达到了业务分隔的目的。

  1. 查看当前RAC所有实例
    1. select * from gv$instance;
  1. 假如查询出的当前rac实例为:rac11、rac12、rac13、rac14这4个实例。我们可以通过使用service的方式,来达到业务分割的目的,创建两个服务:rac_loadrac_query。其中rac_load分配rac11、rac12,rac_query分配rac13、rac14

  2. 查看当前crs状态

    1. crs_stat -t
  1. 手工加入两个服务
    1. srvctl add service-d rac -s rac_load -r "rac11,rac12"
    2. srvcrl add service-d rac -s rac_query -r "rac13,rac14"


其中-r参数表示优先使用的实例。我们在创建服务时,可以指定业务优先选择使用的实例和备用选择的实例。服务首先会使用优先实例,当优先实例不可用时,将使用可用实例。
因为我们这里只是将服务做实例分割,同一组实例中并不需要设置优先级,所有将每个服务使用的实例都设置为优先使用,那么客户端将随机连接任何一个实例上的服务。

  1. 将服务加入到crs资源中后,状态默认是OFFLINE的,可以使用不带参数的crs_stat查看crs中服务状态
    1. crs_stat
  1. 检查服务的运行状态
    1. srvctl status service -d rac -s "rac_load,rac_query"
  1. 启动服务
    1. srvctl start service -d rac -s "rac_load,rac_query"
    2. srvctl status service -d rac -s "rac_load,rac_query"
  1. 此时服务的状态变成了ONLINE。同时,他们已经注册到了监听器里,可以被用户使用了
    1. lsnrctl status

客户端连接:

  1. 在客户端我们只要让数据加载的业务连接到rac_load服务,而数据查询业务连接到rac_query服务,这样两种业务就分别在各自的两个实例上运行,达到互不干涉的目的。所有的加载业务,都连接到rac_load服务上,运行在实例rac11、rac12上;所有的查询业务,都连接到rac_query服务上,运行在实例rac13、rac14上

  2. 客户端需要将tnsnames.ora文件中的相关内容修改成下面的样子 ```

    此处的名称可以自定义

    RAC_LOAD= (DESCRIPTION=

    1. # 这里配置的地址要匹配service的实例地址
    2. (ADDRESS = (PROTOCOL = TCP)(HOST = server1-vip)(port = 1521))
    3. (ADDRESS = (PROTOCOL = TCP)(HOST = server2-vip)(port = 1521))
    4. (LOAD_BALANCE = yes)
    5. (FAILOVER = ON)
    6. (CONNECT_DATA=
    7. (SERVER = DEDICATED)
    8. # service_name要写服务名
    9. (SERVICE_NAME = rac_load)
    10. )

    )

RAC_QUERY= (DESCRIPTION= (ADDRESS = (PROTOCOL = TCP)(HOST = server3-vip)(port = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = server4-vip)(port = 1521)) (LOAD_BALANCE = yes) (FAILOVER = ON) (CONNECT_DATA= (SERVER = DEDICATED) (SERVICE_NAME = rac_query) ) )

  1. 数据加载业务连接字串`RAC_LOAD`来连接到RAC上,这样它将只是用到实例rac11rac12,对应主机地址server1-vipserver2-vip
  2. 而数据查询业务将使用`RAC_QUERY`连接字串连接到RAC,它将会使用rac13rac14实例。
  3. 但是这里面还有一个问题,就是并行问题。并行是一个特例,即使我们按照上面的配置进行了业务分割,但是oracle仍然会在所有的实例上启动并行进程,不论它是从哪个实例发出来的。
  4. 如果希望数据加载使用的并行操作也限制在rac11rac12,查询使用的并行操作限制在rac13rac14上,可以通过2个初始化参数来达到目的:`instance-group``parallel_instance_group`
  5. 这实际上是将并行和特定的实例捆绑在一起的一种方法。
  6. `instance-group``parallel_instance_group`设置成相同的值,就达到了并行和实例捆绑。
  7. <a name="161e4484"></a>
  8. ## RAC负载均衡
  9. 对于负载均衡,可以在客户端设置,也可以在服务器端设置,或者在两端同时设置。
  10. 客户端的负载均衡:比如有一个RAC,包含4个节点,希望业务在这4个节点上实现负载均衡,那么在客户端的`tnsnames.ora`文件里就可以设置:

RAC= (DESCRIPTION=

  1. # 将rac的所有实例都配置上
  2. (ADDRESS = (PROTOCOL = TCP)(HOST = server1-vip)(port = 1521))
  3. (ADDRESS = (PROTOCOL = TCP)(HOST = server2-vip)(port = 1521))
  4. (ADDRESS = (PROTOCOL = TCP)(HOST = server3-vip)(port = 1521))
  5. (ADDRESS = (PROTOCOL = TCP)(HOST = server4-vip)(port = 1521))
  6. # 此处配置成yes(或者on、true),客户端将随机的分配到某个实例上来实现负载均衡
  7. # 如果配置成no(或者off、false),客户端将先从第一个实例开始连,第一个连接不上,才依次连接第二个、第三个
  8. (LOAD_BALANCE = yes)
  9. (FAILOVER = ON)
  10. (CONNECT_DATA=
  11. (SERVER = DEDICATED)
  12. (SERVICE_NAME = rac_query)
  13. )
  14. )
  1. 服务器端的负载均衡:
  2. rac架构下的服务器端(rac的各个实例),也有一套负载均衡机制,它的机制就是让服务注册到RAC架构下的所有监听器上面,这样就可以实现服务在各个监听器上的负载均衡。这种服务器端的负载均衡是由数据库的两个参数文件设定的:`LOCAL_LISTENER``REMOTE_LISTENER`
  3. 通过在每个实例上指定本地的监听器和远程的监听器,就可以让服务在实例间进行交叉注册,达到负载均衡的目的
  4. <a name="c9459f66"></a>
  5. ## RAC实例容错
  6. RAC架构中,客户端通过使用`tnsnames.ora`文件中的连接字符串发起连接,在这里面允许设置`FAILOVER`(故障切换)。
  7. FAILOVER的方式有两种:
  8. 一种称为连接时的FAILOVER,它是指当用户按照`tnsnames.ora`文件中配置的信息,尝试去连接一个指定的监听器失败时,将自动连接另外的一个地址,它的前提是连接字串找在哪个配置了多地址列表。
  9. 例如:

sales.us.acme.com= (DESCRIPTION= (LOAD_BALANCE=on)

  1. # 开启实例容错(默认值就是on)
  2. (FAILOVER=on)
  3. (ADDRESS=(PROTOCOL=tcp)(HOST=sales1-server)(PORT=1521))
  4. (ADDRESS=(PROTOCOL=tcp)(HOST=sales2-server)(PORT=1521))
  5. (CONNECT_DATA=(SERVICE_NAME=sales.us.acme.com))
  6. )
  1. 用户会随机选择`sales1-server``sales2-server`去尝试连接(如果设置了`LOAD_BALANCE=on`就会随机选择,否则是从上向下顺序选择),如果失败了,且配置了`FAILOVER=on`,会去连接另一个,直到成功。
  2. 这个参数的默认值就是`on`,可以不需要再`tnsnames.ora`中显式配置,它是一个自动切换的过程。
  3. 另一种`FAILOVER`方式是发生在会话连接已经建立之后。此时发生的FAILOVER,被称作 TAF Transparent Application Failover),当用户在一个实例上操作失败时,允许重新连接到另一个实例上继续进行操作。
  4. TAF 有两种工作模式:会话模式和 SELECT模式。
  5. 在会话模式里,当会话在某个实例上操作失败时,TAF可以重新创建会话并连接到新的实例上。
  6. SELECT模式里,如果一个正在执行的查询在某个实例上发生故障,TAF将会在另一个实例上重新执行这个查询。
  7. TAF对于活动的事务是无法保证它的完整性的,所以当一个活动的事务出现故障时,TAF只能使它回滚,无法进行FAILOVER
  8. TAF默认值是`none`,也就是不启用,需要手工设置。
  9. TAF的配置参数:
  10. - BACKUP:指定一个备用的连接信息,当需要使用TAF预先连接功能时,需要提供这个信息
  11. - TYPETAF的工作模式
  12. - 会话模式:如果一个会话丢失连接,TAF会在BACKUP实例上重新创建一个会话,但它不会重新执行select操作,仅仅是自动创建一个会话
  13. - SELECT模式:如果一个SELECT正在执行时失败,TAF会重新执行它
  14. - NONE:不使用TAF(默认值)
  15. - METHODTAF的工作方式
  16. - BASIC:当故障发生时,将会话FAILOVERBACKUP实例上
  17. - PRECONNECT:提前和BACKUP实例创建连接,缺点是这样将导致BACKUP实例上有更多的连接,优点是它提供了更快的切换时间
  18. - RETRIES:当发生一次FAILOVER后,这个参数指定重连的次数(如果DELAY项指定了),默认值是5
  19. - DELAY:指定RETRIES的间隔时间(如果RETRIES指定了),默认值1
  20. TAF可以在`tnsnames.ora`文件中设定,比如:

sales.us.acme.com= (DESCRIPTION= (LOAD_BALANCE=on) (FAILOVER=on) (ADDRESS= (PROTOCOL=tcp) (HOST=sales-server) (PORT=1521) ) (ADDRESS= (PROTOCOL=tcp) (HOST=sales2-server) (PORT=1521) ) (CONNECT_DATA= (SERVICE_NAME=sales.us.acme.com) ) (FAILOVER_METHOD=

  1. # 使用select模式
  2. (TYPE=select)
  3. # 使用basic方式
  4. (METHOD=basic)
  5. # 重试20次
  6. (RETRIES=20)
  7. # 重试间隔15秒
  8. (DELAY=15)
  9. )
  10. )

```

TAF不推荐使用(oracle默认值也是none)。因为使用TAF后,实例出现问题时会被oracle接管替换实例,运维人员无法立即发现问题,会存在风险。不如不使用TAF,实例出现问题时出现警告,由人为进行干预。

Data Guard

Data Guard用来做数据文件的冗余。

主数据库产生的redo日志生成归档文件,传递到standby数据库中,standby数据库使用归档文件做数据恢复即可。

Data Guard属于OLAP还是OLTP:

  • 是一个容错方案,对于OLTP非常适合
  • OLAP数据量太大,只能选择关键数据创建DG

海量数据应该选择其他的备份方式

Data Guard保护模式:

  • 最高数据保护模式
  • 最高性能模式
  • 最高可用性模式

最大数据保护模式:是保护模式中最安全的一种,它保证在任何时候数据都不会丢失。为了保护主、备数据库中的数据实时保持一致,Oracle要保证当事务提交时,日志必须同时写到主数据库和至少一个Standby数据库上,只有这样,才能保证主、备上的数据实时一致。

这种保护模式带来的一个问题就是,当日志无法同步地写到至少一个Standby数据库时,主数据库将会被强制Shutdown。这样做的目的是,如果standby数据库无法写入日志,则主数据库就不可以发生任何改变,否则就会导致主、备数据库的数据不一致。

最大保护模式损害了系统的可用性。

最大性能模式:它是对数据库性能影响最小的,也是Data Guard默认的保护模式。

它区别于最大数据保护模式的地方是,它并不需要日志信息实时的传递到Standby数据库上。

比如,当主数据库上的日志信息无法传递到Standby数据库上时,主数据库并不会收到任何影响,相关的服务会不断的尝试向standby实例传递日志信息,直到成功为止。

最大性能模式损害了系统的数据安全性。

最高可用性模式:正常情况下,它的工作机制和最大数据保护模式一样,唯一的区别在于,当redo日志无法写入到standby数据库上时,并不会导致主数据库Shutdown。

此时,Data Guard保护模式将自动切换到最高性能模式,这样主数据库依然可以继续使用,直到故障恢复。

当所有的日志全部都传递到Standby数据库上后,Data Guard又自动的将保护模式切换回最高可用性模式。

最高可用性模式是前两种模式的折中方案。

选择DG的保护模式:

一般情况下,对于本地的Standby数据库,因为本地的网络环境会比较好,所以可以选择最高可用性模式,尽量的保证数据一致性。对于远程的standby数据库,可以选择最高性能模式。

一般不要选最大数据保护模式。

Data Guard中Standby数据库的类型:

  • 物理Standby数据库
  • 逻辑Standby数据库

物理Standby数据库:指的是在物理结构上,Standby数据库和主数据库完全一致,包括从数据块到文件,再到数据库中的对象都和主数据库保持一致。物理Standby数据库时通过应用主数据库传过来的Redo日志来实现数据同步的。

在工作模式下,物理Standby数据库时处于Mount状态的,这样就可以不断的应用来自主数据库的Redo日志。

物理standby数据库可以以只读的方式打开。比如需要做一个大的查询或者报表,又不希望在主数据库上去查,可以以只读方式打开Standby数据库,运行需要执行的SQL。在这个过程中,Standby数据库依然会接收来自主数据库的Redo日志,但是不会应用它,直到我们将Standby数据库重新变成Mount状态后,才会继续应用这些Redo日志。

物理Standby数据库也可以使用读写的方式打开。当物理Standby数据库以读写方式打开时,它是不接收来自主数据库的日志。当我们完成读写工作之后,必须使用回闪(flashback)方式,将数据库闪回到以读写方式打开之前的时刻,回闪完成后,数据库就像没有发生任何事情一样,继续执行它的standby功能。

物理Standby数据库是使用比较多的一种standby方式,简单易用而且高效。

逻辑Standby数据库:是从Redo日志中抽取出SQL语句,重新再Standby数据库中执行,达到数据的同步。

逻辑standby数据库运行的状态是open的,允许对数据库的结构进行修改。

因为是重新执行SQL语句,所以要求数据库是打开的状态,这样才可以执行SQL。同时用户可以在standby数据库中进行其他操作,也就是可以改变standby数据库的逻辑结构,这样都不影响从主数据库向standby数据库同步。

逻辑standby数据库的优点:

  • 几乎可以当做一个正常的数据库使用,比如可以创建新的用户、新的对象,这样就可以分担一部分主数据库的工作
  • 依然扮演着数据容灾的角色

从效率上讲,物理standby数据库毫无疑问要优于逻辑standby数据库。