在MySQL作为应用系统的后台数据库时,我们常常见到这样的架构,一拖二、一拖三等等。这是用MySQL的读写分离技术,实现数据的写入和读取分别在不同的库上,提升了数据库服务能力。

  同样,在Oracle作为后台数据库的架构中,我们也可以这么做。实现的方式有很多种。
  有基于RAC架构的,使用其中某个节点作为读库;
  有基于Streams数据复制技术的,实时将数据复制到另外一个库供读取;
  有使用第三方数据复制软件的,如Golden Gate(已经被Oracle收入囊中)、DSG的,也是实时复制数据到另外一个库中。
  还有使用Logical standby技术,实时复制数据到一个库,且该库是对应用而言是只读的。
  我们这里介绍最后一个方法,利用dataguard技术中的logical standby实现Oracle数据库的读写分离。
  一、创建物理standby
  配置主库(也就是主要执行写操作的数据库)的初始化参数
  *.log_archive_config='dg_config=(webdb,webdg)'
  *.log_archive_dest_2='service=webdb_standby lgwr sync affirm  valid_for=(online_logfiles,primary_role) db_unique_name=webdg'
  *.log_archive_dest_state_2='enable'
  修改主库的tnsnames.ora文件
  在tnsnames.ora文件中增加一个条目,名称为webdb_standby。这个就是log_archive_dest_2中service的名称。这里的主库版本是10g,所以使用LGWR进程将日志传输到备用节点上,而在11g中使用的进程将是LNS。
WEBDB_STANDBY =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.65.3)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = webdb)
)
)
WEBDB_READER =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.65.3)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = webreader)
)
)
  配置备用库(读库)的初始化参数
  *.db_unique_name='webdg'
  *.fal_client='webdb_standby'
  *.fal_server='webdb_primary'
  *.log_archive_config='dg_config=(webdb,webdg)'
  *.log_archive_dest_1='location=+VG2 valid_for=(all_logfiles,all_roles) db_unique_name=webdg'
  修改备用库的tnsnames.ora文件
WEBDB_PRIMARY =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.65.4)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = webdb)
)
)
WEBDB_STANDBY =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.65.3)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = webdb)
)
)
  在tnsnames.ora文件中增加两个条目,名称为webdb_standby和webdb_primary,分别是fal_client和fal-_server参数对应的值,用于检测归档日志gap。
备份主库的数据库和控制文件

  这里我们可以使用原有的全库备份,再新备份控制文件用于standby。
  Backup current ontrolfile for standby format ‘/u03/webdb_rman/ctl.standby’;
  在备用库上恢复主库数据文件
  restore database;
  在备用库上添加standby logfile
  ALTER DATABASE ADD STANDBY LOGFILE group 21 ('+VG2/webdb/standby_redo21.log')  SIZE 52428800 reuse;
  ALTER DATABASE ADD STANDBY LOGFILE group 22 ('+VG2/webdb/standby_redo22.log')  SIZE 52428800 reuse;
  ALTER DATABASE ADD STANDBY LOGFILE group 23 ('+VG2/webdb/standby_redo23.log')  SIZE 52428800 reuse;
  ALTER DATABASE ADD STANDBY LOGFILE group 24 ('+VG2/webdb/standby_redo24.log')  SIZE 52428800 reuse;
  ALTER DATABASE ADD STANDBY LOGFILE group 25 ('+VG2/webdb/standby_redo25.log')  SIZE 52428800 reuse;
  ALTER DATABASE ADD STANDBY LOGFILE group 26 ('+VG2/webdb/standby_redo26.log')  SIZE 52428800 reuse;
  ALTER DATABASE ADD STANDBY LOGFILE group 27 ('+VG2/webdb/standby_redo27.log')  SIZE 52428800 reuse;
  ALTER DATABASE ADD STANDBY LOGFILE group 28 ('+VG2/webdb/standby_redo28.log')  SIZE 52428800 reuse;
  ALTER DATABASE ADD STANDBY LOGFILE group 29 ('+VG2/webdb/standby_redo29.log')  SIZE 52428800 reuse;
  ALTER DATABASE ADD STANDBY LOGFILE group 30 ('+VG2/webdb/standby_redo30.log')  SIZE 52428800 reuse;
  ALTER DATABASE ADD STANDBY LOGFILE group 31 ('+VG2/webdb/standby_redo31.log')  SIZE 52428800 reuse;
  在备用库上做恢复操作
  recover database;
  /u03/webdb_rman@db3=>webdb$rman target /
  Recovery Manager: Release 10.2.0.4.0 - Production on Mon May 14 10:08:06 2012
  Copyright (c) 1982, 2007, Oracle.  All rights reserved.
  connected to target database: WEBDB (DBID=2446281945, not open)
  RMAN> recover database;
  Starting recover at 14-MAY-12
  using target database control file instead of recovery catalog
  allocated channel: ORA_DISK_1
  channel ORA_DISK_1: sid=4384 devtype=DISK
  starting media recovery
  恢复出错后直接退出。
  重启备用库到实时恢复模式
  startup nomount;
  alter database mount standby database;
  alter database recover managed standby database using current logfile disconnect from session;
  检查主库上保护模式和保护级别
  在主库上sqlplus中执行下列SQL
  select protection_mode,protection_level from v$database;
  结果应该是两个列的值是一致的,才是正常状态。
  SQL> select protection_mode,protection_level from v$database;
  PROTECTION_MODE      PROTECTION_LEVEL
  -------------------- --------------------
  MAXIMUM AVAILABILITY MAXIMUM AVAILABILITY
  如果protection_level的值是RESYNCHRONIZATION,如下所示
  SQL> select protection_mode,protection_level from v$database;
  PROTECTION_MODE      PROTECTION_LEVEL
  -------------------- --------------------
  MAXIMUM AVAILABILITY RESYNCHRONIZATION
  这表示DATAGUARD的模式是有问题的,需要解决后才能进行下一步操作。
  二、转换为逻辑 standby
  创建用于读库的初始化参数文件和密码文件
  在备用库的操作系统上$ORACLE_HOME/dbs目录下,准备两个文件,分别是逻辑库webreader的初始化参数文件和密码文件。
  密码文件orapwwebreader由orapwwebdb直接复制。
  初始化参数文件initwebreader.ora从initwebdb.ora复制后做些修改操作,修改的参数项只要是下面列出的这些。
/u01/app/oracle/product/10.2.0/db/dbs@db3=>webreader$more initwebreader.ora
*.audit_file_dest='/u01/app/oracle/admin/webreader/adump'
*.background_dump_dest='/u01/app/oracle/admin/webreader/bdump'
*.core_dump_dest='/u01/app/oracle/admin/webreader/cdump'
*.user_dump_dest='/u01/app/oracle/admin/webreader/udump'
*.db_name='webreader'
*.db_unique_name='webdg'
*.fal_client='webdb_reader'
*.fal_server='webdb_primary'
*.log_archive_config='dg_config=(webdb,webdg)'
*.log_archive_dest_1='location=+VG2/ valid_for=(all_logfiles,all_roles) db_unique_name=webdg'
  创建用于读库的tnsname条目
  在备用库的操作系统上$ORACLE_HOME/network/admin/tnsnames.ora文件中增加一个新的条目webdb_reader。
  WEBDB_READER =
  (DESCRIPTION =
  (ADDRESS_LIST =
  (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.65.3)(PORT = 1521))
  )
  (CONNECT_DATA =
  (SERVICE_NAME = webreader)
  )
  )
  增加读库的侦听对象
  在备用库的操作系统上$ORACLE_HOME/network/admin/listener.ora文件中,增加新实例webreader的侦听对象。
/u01/app/oracle/product/10.2.0/db/network/admin@db3=>webreader$more listener.ora
# listener.ora Network Configuration File: /u01/app/oracle/product/10.2.0/db/network/admin/listener.ora
# Generated by Oracle configuration tools.
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = webdb)
(ORACLE_HOME = /u01/app/oracle/product/10.2.0/db)
)
(SID_DESC =
(SID_NAME = webdg)
(ORACLE_HOME = /u01/app/oracle/product/10.2.0/db)
)
(SID_DESC =
(SID_NAME = webreader)
(ORACLE_HOME = /u01/app/oracle/product/10.2.0/db)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = db3)(PORT = 1521))
)
)
  在备用库上取消恢复管理模式
  alter database recover managed standby database cancel ;
  在主库上创建logical standby的数据字典
  EXECUTE DBMS_LOGSTDBY.BUILD;
  这一步一定要执行成功,并且必须在其他操作之前执行,否则后面执行 alter database recover to logical standby webreader; 会一直等待。
  注意:
  该过程会自动启用primary 数据库的补充日志(supplemental logging)功能(如果未启用的话)。
  该过程执行需要等待当前所有事务完成,因此如果当前有较长的事务运行,可能该过程执行也需要多花一些等待时间。
  该过程是通过闪回查询的方式来获取数据字典的一致性,因此oracle 初始化参数UNDO_RETENTION 值需要设置的足够大。
  切换物理Standby为逻辑Standby
  我们将读库,也就是logical standby数据库名称定义为webreader。
  alter database recover to logical standby webreader;
  注意:
  这一步很关键。如果执行成功了,目标基本就实现了。
  但很可能会遇到两种错误。
  执行操作一直hang。这是因为密码文件中sys密码不一致,需要建立与主库一致的密码文件。
  备库监听没有包含standby的实例信息,需要在监听文件中添加实例信息。在监听器参数文件的配置中,我们已经添加了所有实例的侦听信息。即使多加了也不影响监听器的正常运行。
  正常的执行过程应该如下所示:
  SQL> alter database recover managed standby database cancel ;
  Database altered.
  SQL> alter database recover to logical standby webreader;
  alter database recover to logical standby webreader
  *
  ERROR at line 1:
  ORA-16254: change db_name to WEBREADER in the client-side parameter file (pfile)
  ORA-17503: ksfdopn:2 Failed to open file +VG1/webdb/temp01.dbf
  ORA-15173: entry 'temp01.dbf' does not exist in directory 'webdb'
  这一步执行不成功,也会完成。在关闭打开后可以正常使用。
/u01/home/oracle@db3=>webdb$export ORACLE_SID=webreader
/u01/home/oracle@db3=>webreader$sqlplus / as sysdba
SQL*Plus: Release 10.2.0.4.0 - Production on Mon May 14 10:55:53 2012
Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.
Connected to an idle instance.
SQL> startup open
ORACLE instance started.
Total System Global Area 5.1540E+10 bytes
Fixed Size                  2179936 bytes
Variable Size            6425676960 bytes
Database Buffers         4.5097E+10 bytes
Redo Buffers               14594048 bytes
Database mounted.
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open
SQL> alter database open resetlogs;
Database altered.
  备用库上临时文件处理
  在备用库上临时文件需要重建,我选择新增一个临时文件。在不同的环境中,临时文件可能会有很多个。
  alter tablespace temp add tempfile '+VG2/webdb/temp02.dbf' size 10240M;
  调整主库上log_archive_dest_2的参数值
  在物理standby模式下,这个参数的service值是指向webdb_standby的,现在在逻辑standby模式下,它需要修改为指向webdb_reader。
  alter system set log_archive_dest_2='service=webdb_reader lgwr sync affirm  valid_for=(online_logfiles,primary_role) db_unique_name=webdg';

oracle的读写分离实现的更多相关文章

  1. Oracle读写分离架构

    读写分离是架构分布式系统的一个重要思想.不少系统整体处理能力并不能同业务的增长保持同步,因此势必会带来瓶颈,单纯的升级硬件并不能一劳永逸.针对业务类型特点,需要从架构模式上进行一系列的调整,比如业务模 ...

  2. C#操作SqlServer MySql Oracle通用帮助类Db_Helper_DG(默认支持数据库读写分离、查询结果实体映射ORM)

    [前言] 作为一款成熟的面向对象高级编程语言,C#在ADO.Net的支持上已然是做的很成熟,我们可以方便地调用ADO.Net操作各类关系型数据库,在使用了多年的Sql_Helper_DG后,由于项目需 ...

  3. Oracle 19c Data Guard DML Redirection ADG备库上执行DML重定向(未来更好的进行读写分离)

    资料来自官方网站: https://docs.oracle.com/en/database/oracle/oracle-database/19/sbydb/managing-oracle-data-g ...

  4. MySQL+Amoeba实现数据库主从复制和读写分离

    MySQL读写分离是在主从复制的基础上进一步通过在master上执行写操作,在slave上执行读操作来实现的.通过主从复制,master上的数据改动能够同步到slave上,从而保持了数据的一致性.实现 ...

  5. mysql+mycat搭建稳定高可用集群,负载均衡,主备复制,读写分离

    数据库性能优化普遍采用集群方式,oracle集群软硬件投入昂贵,今天花了一天时间搭建基于mysql的集群环境. 主要思路 简单说,实现mysql主备复制-->利用mycat实现负载均衡. 比较了 ...

  6. CYQ.Data V5 数据库读写分离功能介绍

    前言 好多年没写关于此框架的新功能的介绍了,这些年一直在默默地更新,从Nuget上的记录就可以看出来: 这几天在看Java的一些东西,除了觉的Java和.NET的相似度实在太高之外,就是Java太原始 ...

  7. 利用mysql-proxy进行mysql数据库的读写分离

    实验系统:CentOS 6.6_x86_64 实验前提:防火墙和selinux都关闭 实验说明:本实验共有4台主机,IP分配如拓扑 实验软件:mariadb-10.0.20 mysql-proxy-0 ...

  8. MySQL + Atlas --- 部署读写分离

    阅读目录 1. 数据库用户配置 2. 主从数据库连接 3. Atlas配置 4. 读写分离测试 序章 Atlas是360团队弄出来的一套基于MySQL-Proxy基础之上的代理,修改了MySQL-Pr ...

  9. Amoeba+Mysql实现数据库读写分离

    一.Amoeba 是什么 Amoeba(变形虫)项目,专注 分布式数据库 proxy 开发.座落与Client.DB Server(s)之间.对客户端透明.具有负载均衡.高可用性.sql过滤.读写分离 ...

随机推荐

  1. suoi21 高能显示屏 (cdq分治)

    可以把翻倍的操作看作是一个查询和修改(增加刚查询得来的值)的符合操作,然后做cdq就行了 #include<bits/stdc++.h> #define pa pair<int,in ...

  2. 【poj2396】 Budget

    http://poj.org/problem?id=2396 (题目链接) 题意 给出一个矩阵,给出每一行每一列的和,以及若干限制条件,限制了其中每一个元素的上下界,求一种可行的方案使得每一行每一列数 ...

  3. HDU 3081 Marriage Match II (二分图,并查集)

    HDU 3081 Marriage Match II (二分图,并查集) Description Presumably, you all have known the question of stab ...

  4. A1054. The Dominant Color

    Behind the scenes in the computer's memory, color is always talked about as a series of 24 bits of i ...

  5. bug8 eclipse项目导入到myeclipse时 Target runtime com.genuitec.runtime.generic

    1.新导入的工程,出问题很大可能是jdk的版本问题导致,检查一下,发现jdk果然不一致,修改了jdk版本,但异常没有消除 2.网上查询下解决方案,原来在工程目录下的settings,有个文件也需要修改 ...

  6. linux下怎样查看哪些进程占用swap空间

    for i in `cd /proc;ls |grep "^[0-9]"|awk ' $0 >100'` ;do awk '/Swap:/{a=a+$2}END{print ...

  7. eclipse卸载自带maven

    1.在eclipse的安装目录下,找到   features和plugins文件夹,删除这两个文件夹下maven对应的jar和文件夹(windows用户建议用如下搜索:*maven*和*m2e*) 2 ...

  8. 函数和常用模块【day06】:random模块(三)

    本节内容 1.简述 2.random模块 3.string模块 4.生成随机数 一.简述 我们经常会使用一些随机数,或者需要写一些随机数的代码,今天我们就来整理随机数模块:random模块 二.ran ...

  9. hadoop HA 配置 + zookeeper 服务注册

    环境测试 6台机器 centos6.7 x64 master ( namenode/cluster ) 10.10.100.101 namenode1 10.10.100.105 namenode2 ...

  10. QMouseEvent鼠标事件

    Qt中的QMouseEvent一般只涉及鼠标左键或右键的单击.释放等操作,而对鼠标滚轮的响应则通过QWheeEvent来处理