SlideShare a Scribd company logo
Oracle High Availability
in application development
Aleksandr Tokarev
Plan
• Basic terms
• Aspects of HA
• Oracle approach to HA
• HA for application development
• Q&A session
• Load balancing (optional)
Availability
The ability to obtain a service to submit
new work, update or alter existing work or
collect the results of previous work.
If a customer cannot access the system
even all components are available, the
system unavailable.
High Availability
The characteristic of a system, which aims
to ensure an agreed level of operational
availability for a higher than normal period.
Principles
1. Elimination of single points of failure
2. Reliable crossover
3. Early failures detection
Real world challenges
• Growing user number
• Users are located in different time zones
• Stretching maintenance window
• Failures become more complicated
Oracle HA stack
1. RAC
2. At least
• DataGuard/Active Data Guard
• Golden Gate or similar replication tool
3. Editioned objects
4. Web Logic Application server +
Universal Connection Pool
(JDBC/ODP)
HA terms
ONS (Oracle Notification Service):
• Publish/subscribe service for clusterware events
• Could be localy or remotely consumed
• Automatically installed and configured during Oracle
clusterware installation
FAN (Fast Application Notification):
• Subset of ONS
• Notifies client about service changes (what, when, where)
• Could be issued by RAC (RAC one node), DG (fast start
failover)
• 2 types: HA events and Load balancing events
• 3 events could be used by applications: UP, DOWN, LBA
• Integrated into: OCI, UCP, JDBC, ODP.NET
HA terms
FCF (Fast Connection Failover):
Client-side feature to receive/process FAN.
It works on UCP level.
TAF (Transparent Application Failover):
Client-side feature to restore
connections/resume select statements. It
works on OCI level.
HA terms
TG (Transaction Guard):
A way to provides at-most-once execution of
transactions. Preserves commit outcome.
AC (Application Continuity):
An approach to replay fallen transaction i.e.
mimic node fail as a delay to client with
minimal intervention to application code.
TAF
• OCI feature (JDBC OCI, ODP.NET)
• Could be done on client (tns) or server (dbms_service)
side
• Autoconnects to preconfigured instance
• Needn’t FAN
• Works with RAC/RAC one node, DG physical standby,
Fast Restart Single instance
• Based on callbacks (OracleOCIFailover interface)
• Could continue SELECT statement from failure point
• Session states, packages variable should be initialized in
callbacks
TAF Client side
RACDB_TAF =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = linux1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = linux2-vip)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = racdb_taf.idevelopment.info)
(FAILOVER_MODE =
(TYPE = SELECT) – we could use SESSION here
(METHOD = BASIC) – we could use PRECONNECTED here
(RETRIES = 180)
(DELAY = 5)
)
)
)
TAF server side
srvctl add service -d orcl -s TAF_TEST -r "orcl1,orcl2,orcl3,orcl4"
srvctl start service -s TAF_TEST -d orcl
begin
dbms_service.modify_service(service_name => 'TAF_TEST',
aq_ha_notifications => false,
failover_method =>
dbms_service.failover_method_basic,
failover_type =>
dbms_service.failover_type_session,
failover_retries => 60,
failover_delay => 3);
end;
void Main(string[] args)
{
// register callback function OnFailOver
ConObj.Failover += new OracleFailoverEventHandler(OnFailOver);
//here let's establish connections and do whatever we want
}
//Failover Callback Function
public FailoverReturnCode OnFailOver(object sender, OracleFailoverEventArgs
eventArgs)
{
switch (eventArgs.FailoverEvent)
{
case FailoverEvent.Begin:
{
Console.WriteLine(" nFailover Begin - Failing Over ... Please standby n");
Console.WriteLine(" Failover type was found to be " + eventArgs.FailoverType);
break;
}
case FailoverEvent.Abort:
{
Console.WriteLine(" Failover aborteded.n");
break;
}
case FailoverEvent.End:
{
Console.WriteLine(" Failover ended ...resuming servicesn");
break;
}
case FailoverEvent.Error:
{
Console.WriteLine(" Failover error gotten. Sleeping...n");
Thread.Sleep(3000);
return FailoverReturnCode.Retry;
}
}
return FailoverReturnCode.Success;
}
TAF ODP.NET example
TAF Java
public interface OracleOCIFailover{
// Possible Failover Types
public static final int FO_SESSION = 1;
public static final int FO_SELECT = 2;
public static final int FO_NONE = 3;
public static final int;
// Possible Failover events registered with callback
public static final int FO_BEGIN = 1;
public static final int FO_END = 2;
public static final int FO_ABORT = 3;
public static final int FO_REAUTH = 4;
public static final int FO_ERROR = 5;
public static final int FO_RETRY = 6;
public static final int FO_EVENT_UNKNOWN = 7;
public int callbackFn (Connection conn,
Object ctxt, // ANy thing the user wants to save
int type, // One of the possible Failover Types
int event ); // One of the possible Failover Events
FCF
• Asynchronously process UP/DOWN HA
FAN events
• Removes affected connections
• Works under Universal Connection Pool
(RAC/RAC one node, DG, Fast Restart)
• ONS should be enabled
srvctl add ons
srvctl enable ons
srvctl start ons
FCF Java example
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
pds.setConnectionPoolName("FCFSamplePool");
pds.setFastConnectionFailoverEnabled(true);
pds.setONSConfiguration("nodes=racnode1:4200,racnode2:4200nwallet
file= /oracle11/onswalletfile");
pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSour
ce");
pds.setURL("jdbc:oracle:thin@(DESCRIPTION= "+
"(LOAD_BALANCE=on)"+
"(ADDRESS=(PROTOCOL=TCP)(HOST=racnode1) (PORT=1521))"+
"(ADDRESS=(PROTOCOL=TCP)(HOST=racnode2) (PORT=1521))"+
"(CONNECT_DATA=(SERVICE_NAME=service_name)))");
Ensure ons.jar is on application CLASSPATH.
FCF Java example
boolean retry = true;
while(retry)
{
try
{
//Getting a RAC connection from the pool
conn = pds.getConnection();
// Executing a query on the connection.
rs = stmt.executeQuery("select user from dual");
rs.next();
System.out.println("nConnected as : " + rs.getString(1));
//Setting retry to false to exit the loop
retry = false;
}
catch (SQLException eSQL)
{
System.out.println("nSQLException: " + eSQL);
// Checking connection usability after a RAC-down event triggers UCP FCF actions
if (conn == null || !((ValidConnection) conn).isValid())
{
try//Closing the connection
{
conn.close();
}
catch (SQLException eClose)
{
System.out.println("nException arose when closing connection: " + eClose);
}
//Setting retry to true to try again
retry = true;
}
}
Thread.sleep(1000);
}
FCF ODP.NET example
using System;
using Oracle.DataAccess.Client;
class HAEventEnablingSample
{
static void Main()
{
OracleConnection con = new OracleConnection();
// Open a connection using ConnectionString attributes
// Also, enable "load balancing"
con.ConnectionString =
"User Id=user_name;Password=password;Data Source=oracle;" +
"Min Pool Size=10;Connection Lifetime=120;Connection Timeout=60;" +
"HA Events=true;Incr Pool Size=5;Decr Pool Size=2";
con.Open();
// Create more connections and perform work against the database here.
con.Dispose();
}
Before Oracle 12 .config file should be changed:
<onsConfig mode="remote">
<ons database="db1">
<add name="nodeList" value="racnode1:4100, racnode2:4200" />
</ons>
<ons database="db2">
<add name="nodeList" value=" racnode3:4100, racnode4:4200" />
</ons>
</onsConfig>
FCF ODP.NET example
If you need enhanced error treatment use OracleHAEventArgs
class:
public delegate void OracleHAEventHandler(object sender, OracleHAEventArgs
eventArgs);
public static void OnFANEventHandler(OracleHAEventArgs eventArgs)
{
lock(typeof(FANCallBackSample))
{
if (eventArgs.Status == OracleHAEventStatus.Down){
// Your event treatment
}
... ... ...
}
}
TG
API under JDBC, OCI, ODP.NET
to resolve possible ‘double-execution’
problem.
Creates globally unique LTXID
Stores it on DB + client driver
TG use-case after outage
• Requests from DB LTXID by session handle
(DBMS_APP_CONT.GET_LTXID_OUTCOME )
• Gets the commit state before failure
• If committed return control to app
• If uncommited asks about next actions
TG could be enabled by DBMS_SERVICE.CREATE_SERVICE
or srvctl modify service -db DBNAME -s MYSERVICENAME
-commit_outcome TRUE
TG Supported COMMITs
• Local transactions
• Data definition language (DDL)
transactions
• Distributed transactions
• Commit on success (auto-commit)
• PL/SQL with embedded commit
TG ODP.NET example
txn = con.BeginTransaction();
<your processing>
try
{
txn.Commit();
}
catch (Exception ex)
{
if (ex is OracleException)
{
if (ex.IsRecoverable
&& ex.OracleLogicalTransaction != null
&& !ex.OracleLogicalTransaction.Committed)
{
// safe to re-submit work
}
else
{
// do not re-submit work
if (ex.OracleLogicalTransaction.UserCallCompleted)
{
// return commit success to application to continue
}
else
{
// transaction committed, states such as row count or
// out parameters may be lost
// if the application needs these states.
// return commit success and warn
}
}
}
}
Don’t forget to grant GRANT EXECUTE ON DBMS_APP_CONT TO <Ora user under .NET>.
due ODP.Net invokes it implicitly in case of exception.
TG Java example
private static final String GET_LTXID_OUTCOME_WRAPPER =
"DECLARE PROCEDURE GET_LTXID_OUTCOME_WRAPPER("+ " ltxid IN RAW,"+ " is_committed OUT
NUMBER ) "+ "IS " + " call_completed BOOLEAN; "+ " committed BOOLEAN; "+ "BEGIN "+ "
DBMS_APP_CONT.GET_LTXID_OUTCOME(ltxid, committed, call_completed); "+ " if committed
then is_committed := 1; else is_committed := 0; end if; "+ "END; "+ "BEGIN
GET_LTXID_OUTCOME_WRAPPER(?,?); END;";
boolean getTransactionOutcome(Connection conn, LogicalTransactionId ltxid)
throws SQLException {
boolean committed = false;
CallableStatement cstmt = null;
try {
cstmt = conn.prepareCall(GET_LTXID_OUTCOME_WRAPPER);
cstmt.setObject(1, ltxid); // use this starting in 12.1.0.2
cstmt.registerOutParameter(2, OracleTypes.BIT);
cstmt.execute();
committed = cstmt.getBoolean(2);
}
catch (SQLException sqlexc) {
throw sqlexc;
}
finally {
if(cstmt != null)
cstmt.close();
}
return committed;
}
TG Java example
Connection jdbcConnection = getConnection();
boolean isJobDone = false;
while(!isJobDone) {
try {
// apply the raise (DML + commit):
RaiseToAllEmployees(jdbcConnection,5);
// no exception, the procedure completed:
isJobDone = true;
} catch (SQLRecoverableException recoverableException) {
// Retry only if the error was recoverable.
try {
jdbcConnection.close(); // close old connection:
} catch (Exception ex) {} // pass through other exception s
Connection newJDBCConnection = getConnection(); // reconnect to allow
retry
// Use Transacton Guard to force last request: committed or uncommitted
LogicalTransactionId ltxid
= ((OracleConnection)jdbcConnection).getLogicalTransactionId();
isJobDone = getTransactionOutcome(newJDBCConnection, ltxid);
jdbcConnection = newJDBCConnection;
}
}
AC
• JDBC OCI and JDBC thin Oracle 12
technology. It works with UCP, JDBC,
Weblogic + RAC/RAC one node or DG
• Intended to hide failures from client by
replaying workload using TG data
• Rebuilds transaction and non-transaction
states
• Requires small intervention to code
AC workflow
• Client issues a request to UCP
• AC retains each call
• Failure occurs and FAN is sent to UCP
• AC reconnects when it is possible
• TG checks transaction states and identifies last
success statement using LTXID
• AC restores non-transaction state (package
variables, temporary tables etc) in accordance
with settings
• AC replays saved calls in accordance with given
boundaries and commits
AC configuration
• Ask you DBA to configure AC service either by srvctl or
dbms_service.
declare
params dbms_service.svc_parameter_array;
begin
params('FAILOVER_TYPE'):='TRANSACTION';
params('REPLAY_INITIATION_TIMEOUT'):=300;
params('FAILOVER_DELAY'):=3;
params('FAILOVER_RETRIES'):=30;
params('commit_outcome'):='true';
dbms_service.modify_service('[your service]',params);
end;
• Don’t forget to grant execute on dbms_app_cont
• Set for your sequences, guid and timestamp KEEP
properties
GRANT [KEEP DATE TIME | KEEP SYSGUID].. [to USER]
GRANT KEEP SEQUENCE.. [to USER] on [sequence object];
ALTER SEQUENCE.. [sequence object] [KEEP];
AC Java example
private void DBAction(Connection c, int numValue) throws SQLException {
String updsql = "UPDATE hr.employes " +
"SET job_id=job_id " +
"WHERE employee_id=?";
PreparedStatement pstmt = null;
/*some non-transactional actions for instance sending email about employes
processing start using utl_mail*/
/* let’s set boundaries
*/
((oracle.jdbc.replay.ReplayableConnection)c).beginRequest();
pstmt=c.prepareStatement(updsql);
c.setAutoCommit(false);
for (int i=0;i<numValue;i++) {
pstmt.setInt(1,i);
pstmt.executeUpdate();
}
c.commit();
// End of the Callback.
((oracle.jdbc.replay.ReplayableConnection)c).endRequest();
pstmt.close();
}
AC Java Example
import java.sql.*;
import oracle.jdbc.pool.*;
import oracle.jdbc.*;
import oracle.jdbc.replay.*;
public static void main(String args[]) throws SQLException {
Connection conn = null;
OracleDataSourceImpl ocpds = new OracleDataSourceImpl();
ocpds.setURL("jdbc:oracle:thin:@rac-scan:1521/app");
ocpds.setUser("user");
ocpds.setPassword("passw");
conn = ocpds.getConnection();
self.dbAction(conn,100000);
conn.close();
}
AC cons
• Doesn’t work with GoldenGate, Active
DataGuard
• No .NET support
• AC works ‘automagicaly’ so should to be
tested thoroughly
• Memory consumption on JDBC side
• Application should be AC-aware if a logic
uses non-transactional features
Summary client failover
Technology Connection cleanup
Automatic
reconnection Replay
TAF not intendend + long-running queries only
FCF + + hand-coded
TG not intendend - sometimes hand-coded
AC not intendend + sometimes need to specify boundaries
Conclusions
If you wish to achieve true HA it is possible, but
you should consider:
1. Infrastructure costs
2. Licensing burden
3. Expenses for software development to support
various types of replay
We are happy to help our customers!
Are they ready?
Q&A
Contacts
Feel free to ask:
shtock@mail.ru
Reasons for smart load balancing
Capacity of HA architecture is changing
overtime:
• Not all opened connections are best
connections – could be connected to
either slow or currently maintained nodes
• New connections shouldn’t even try to use
dead, slow or currently maintained nodes
Oracle load balancing types
• Client-side
– Uses TNS names for connections to different
nodes (load_balance = on)
– Random connection distributions
– Works on connection attempt
• Server-side
– Relies on server metrics
– Connects based on policies and configuration
– Works continuously
What’s inside
What for
1. Adjust work distribution based on defined
goals on working nodes:
– throughput
– service time
– CPU utilization (NONE)
2. Reacts as fast as possible on cluster
reconfiguration:
– New nodes
– Defunct nodes
How to enable LB
Ask your DBA to:
– Install Oracle RAC
– Setup ONS/FAN daemons properly
– Configure LBA by OEM or DBMS_SERVICE
Example:
EXECUTE DBMS_SERVICE.MODIFY_SERVICE (
service_name => 'sjob' ,
goal => DBMS_SERVICE.GOAL_SERVICE_TIME ,
clb_goal => DBMS_SERVICE.CLB_GOAL_SHORT);
How to enable LB Java
Properties prop = new Properties ();
prop.put(oracle.net.ns.SQLnetDef.TCP_CONNTIMEOUT_STR,
"" + (1 * 1000)
); // 1 second
PoolDataSource pds =
PoolDataSourceFactory.getPoolDataSource();
pds.setConnectionPoolName("FCFSamplePool");
pds. setConnectionProperties ( prop );
pds.setFastConnectionFailoverEnabled(true);
pds.setONSConfiguration("nodes=racnode1:4200,racnode2:4200nwallet
file= /oracle11/onswalletfile");
pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSour
ce");
pds.setURL("jdbc:oracle:thin@(DESCRIPTION= (LOAD_BALANCE=on)
(ADDRESS=(PROTOCOL=TCP)(HOST=racnode1) (PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=racnode2) (PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=service_name)))");
How to enable LB ODP.NET
using System;
using Oracle.DataAccess.Client;
class ConnectionPoolingSample
{
static void Main()
{
OracleConnection con = new OracleConnection();
//Open a connection using ConnectionString attributes
//related to connection pooling.
con.ConnectionString =
"User Id=scott;Password=tiger;Data Source=oracle;" +
"Min Pool Size=10;Connection Lifetime=120;Connection Timeout=60;" +
"Incr Pool Size=5; Decr Pool Size=2" +
"HA events=true;load balancing=true;pooling=true";
con.Open();
Console.WriteLine("Connection pool successfully created");
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
Console.WriteLine("Connection is placed back into the pool.");
}
}
Conclusion
If you don’t want/have time to implement
your own load balancing you definitely
should consider Oracle real time load
balancing.
It works “from the box” in case of FCF is
configured properly and easily managed using
services.
Q&A
Contacts
Feel free to ask:
shtock@mail.ru

More Related Content

PPT
Oracle Database Vault
PPT
MODULE 4 -Normalization_1.ppt
PDF
Mongo db dhruba
PDF
OCI Database Management 설정 방법
PPT
SQL Server Transaction Management
PPTX
Bases de Datos No Relacionales
PPT
Introduction of Oracle
PDF
Minutes to hundredths conversion
Oracle Database Vault
MODULE 4 -Normalization_1.ppt
Mongo db dhruba
OCI Database Management 설정 방법
SQL Server Transaction Management
Bases de Datos No Relacionales
Introduction of Oracle
Minutes to hundredths conversion

Similar to Oracle High Availabiltity for application developers (20)

PDF
Oracle Drivers configuration for High Availability, is it a developer's job?
PDF
Oracle Drivers configuration for High Availability
PDF
Load balancing and failover options
PPT
Accelerated data access
PDF
Oracle Fleet Patching and Provisioning Deep Dive Webcast Slides
PPTX
Sharding and Load Balancing in Scala - Twitter's Finagle
ODP
Finagle and Java Service Framework at Pinterest
PDF
FBTFTP: an opensource framework to build dynamic tftp servers
PPTX
Ob1k presentation at Java.IL
PDF
Java one2013
PPT
Extreme Availability using Oracle 12c Features: Your very last system shutdown?
PPTX
Apache Flink Overview at SF Spark and Friends
PDF
Building Scalable Stateless Applications with RxJava
PPTX
Extreme replication at IOUG Collaborate 15
PPTX
Advance java session 5
ODP
Application Continuity with Oracle DB 12c
PPT
Mobicents JSLEE progress and roadmap - Mobicents Summit 2011
PPT
Distributed & Highly Available server applications in Java and Scala
PPTX
Copper: A high performance workflow engine
PDF
0396 oracle-goldengate-12c-tutorial
Oracle Drivers configuration for High Availability, is it a developer's job?
Oracle Drivers configuration for High Availability
Load balancing and failover options
Accelerated data access
Oracle Fleet Patching and Provisioning Deep Dive Webcast Slides
Sharding and Load Balancing in Scala - Twitter's Finagle
Finagle and Java Service Framework at Pinterest
FBTFTP: an opensource framework to build dynamic tftp servers
Ob1k presentation at Java.IL
Java one2013
Extreme Availability using Oracle 12c Features: Your very last system shutdown?
Apache Flink Overview at SF Spark and Friends
Building Scalable Stateless Applications with RxJava
Extreme replication at IOUG Collaborate 15
Advance java session 5
Application Continuity with Oracle DB 12c
Mobicents JSLEE progress and roadmap - Mobicents Summit 2011
Distributed & Highly Available server applications in Java and Scala
Copper: A high performance workflow engine
0396 oracle-goldengate-12c-tutorial
Ad

More from Alexander Tokarev (20)

PPTX
Rate limits and all about
PPTX
rnd teams.pptx
PPTX
FinOps for private cloud
PPTX
Graph ql and enterprise
PPTX
FinOps introduction
PPTX
Open Policy Agent for governance as a code
PPTX
Relational databases for BigData
PPTX
Cloud DWH deep dive
PPTX
PPTX
P9 speed of-light faceted search via oracle in-memory option by alexander tok...
PPTX
Row Level Security in databases advanced edition
PPTX
Row level security in enterprise applications
PPTX
Inmemory BI based on opensource stack
PPTX
Oracle InMemory hardcore edition
PPTX
Tagging search solution design Advanced edition
PPTX
Faceted search with Oracle InMemory option
PPTX
Oracle JSON treatment evolution - from 12.1 to 18 AOUG-2018
PPTX
Tagging search solution design
PPTX
Oracle JSON internals advanced edition
PPTX
Oracle Result Cache deep dive
Rate limits and all about
rnd teams.pptx
FinOps for private cloud
Graph ql and enterprise
FinOps introduction
Open Policy Agent for governance as a code
Relational databases for BigData
Cloud DWH deep dive
P9 speed of-light faceted search via oracle in-memory option by alexander tok...
Row Level Security in databases advanced edition
Row level security in enterprise applications
Inmemory BI based on opensource stack
Oracle InMemory hardcore edition
Tagging search solution design Advanced edition
Faceted search with Oracle InMemory option
Oracle JSON treatment evolution - from 12.1 to 18 AOUG-2018
Tagging search solution design
Oracle JSON internals advanced edition
Oracle Result Cache deep dive
Ad

Recently uploaded (20)

PPTX
bas. eng. economics group 4 presentation 1.pptx
PPTX
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
PDF
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
PPTX
UNIT-1 - COAL BASED THERMAL POWER PLANTS
DOCX
573137875-Attendance-Management-System-original
PPTX
KTU 2019 -S7-MCN 401 MODULE 2-VINAY.pptx
DOCX
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx
PPTX
Internet of Things (IOT) - A guide to understanding
PPTX
web development for engineering and engineering
PPTX
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
PPTX
MCN 401 KTU-2019-PPE KITS-MODULE 2.pptx
PPTX
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
PDF
Enhancing Cyber Defense Against Zero-Day Attacks using Ensemble Neural Networks
PDF
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
PDF
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
PDF
composite construction of structures.pdf
PDF
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
PPTX
FINAL REVIEW FOR COPD DIANOSIS FOR PULMONARY DISEASE.pptx
PDF
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
PPTX
Lecture Notes Electrical Wiring System Components
bas. eng. economics group 4 presentation 1.pptx
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
UNIT-1 - COAL BASED THERMAL POWER PLANTS
573137875-Attendance-Management-System-original
KTU 2019 -S7-MCN 401 MODULE 2-VINAY.pptx
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx
Internet of Things (IOT) - A guide to understanding
web development for engineering and engineering
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
MCN 401 KTU-2019-PPE KITS-MODULE 2.pptx
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
Enhancing Cyber Defense Against Zero-Day Attacks using Ensemble Neural Networks
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
composite construction of structures.pdf
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
FINAL REVIEW FOR COPD DIANOSIS FOR PULMONARY DISEASE.pptx
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
Lecture Notes Electrical Wiring System Components

Oracle High Availabiltity for application developers

  • 1. Oracle High Availability in application development Aleksandr Tokarev
  • 2. Plan • Basic terms • Aspects of HA • Oracle approach to HA • HA for application development • Q&A session • Load balancing (optional)
  • 3. Availability The ability to obtain a service to submit new work, update or alter existing work or collect the results of previous work. If a customer cannot access the system even all components are available, the system unavailable.
  • 4. High Availability The characteristic of a system, which aims to ensure an agreed level of operational availability for a higher than normal period.
  • 5. Principles 1. Elimination of single points of failure 2. Reliable crossover 3. Early failures detection
  • 6. Real world challenges • Growing user number • Users are located in different time zones • Stretching maintenance window • Failures become more complicated
  • 7. Oracle HA stack 1. RAC 2. At least • DataGuard/Active Data Guard • Golden Gate or similar replication tool 3. Editioned objects 4. Web Logic Application server + Universal Connection Pool (JDBC/ODP)
  • 8. HA terms ONS (Oracle Notification Service): • Publish/subscribe service for clusterware events • Could be localy or remotely consumed • Automatically installed and configured during Oracle clusterware installation FAN (Fast Application Notification): • Subset of ONS • Notifies client about service changes (what, when, where) • Could be issued by RAC (RAC one node), DG (fast start failover) • 2 types: HA events and Load balancing events • 3 events could be used by applications: UP, DOWN, LBA • Integrated into: OCI, UCP, JDBC, ODP.NET
  • 9. HA terms FCF (Fast Connection Failover): Client-side feature to receive/process FAN. It works on UCP level. TAF (Transparent Application Failover): Client-side feature to restore connections/resume select statements. It works on OCI level.
  • 10. HA terms TG (Transaction Guard): A way to provides at-most-once execution of transactions. Preserves commit outcome. AC (Application Continuity): An approach to replay fallen transaction i.e. mimic node fail as a delay to client with minimal intervention to application code.
  • 11. TAF • OCI feature (JDBC OCI, ODP.NET) • Could be done on client (tns) or server (dbms_service) side • Autoconnects to preconfigured instance • Needn’t FAN • Works with RAC/RAC one node, DG physical standby, Fast Restart Single instance • Based on callbacks (OracleOCIFailover interface) • Could continue SELECT statement from failure point • Session states, packages variable should be initialized in callbacks
  • 12. TAF Client side RACDB_TAF = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = linux1-vip)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = linux2-vip)(PORT = 1521)) (LOAD_BALANCE = yes) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = racdb_taf.idevelopment.info) (FAILOVER_MODE = (TYPE = SELECT) – we could use SESSION here (METHOD = BASIC) – we could use PRECONNECTED here (RETRIES = 180) (DELAY = 5) ) ) )
  • 13. TAF server side srvctl add service -d orcl -s TAF_TEST -r "orcl1,orcl2,orcl3,orcl4" srvctl start service -s TAF_TEST -d orcl begin dbms_service.modify_service(service_name => 'TAF_TEST', aq_ha_notifications => false, failover_method => dbms_service.failover_method_basic, failover_type => dbms_service.failover_type_session, failover_retries => 60, failover_delay => 3); end;
  • 14. void Main(string[] args) { // register callback function OnFailOver ConObj.Failover += new OracleFailoverEventHandler(OnFailOver); //here let's establish connections and do whatever we want } //Failover Callback Function public FailoverReturnCode OnFailOver(object sender, OracleFailoverEventArgs eventArgs) { switch (eventArgs.FailoverEvent) { case FailoverEvent.Begin: { Console.WriteLine(" nFailover Begin - Failing Over ... Please standby n"); Console.WriteLine(" Failover type was found to be " + eventArgs.FailoverType); break; } case FailoverEvent.Abort: { Console.WriteLine(" Failover aborteded.n"); break; } case FailoverEvent.End: { Console.WriteLine(" Failover ended ...resuming servicesn"); break; } case FailoverEvent.Error: { Console.WriteLine(" Failover error gotten. Sleeping...n"); Thread.Sleep(3000); return FailoverReturnCode.Retry; } } return FailoverReturnCode.Success; } TAF ODP.NET example
  • 15. TAF Java public interface OracleOCIFailover{ // Possible Failover Types public static final int FO_SESSION = 1; public static final int FO_SELECT = 2; public static final int FO_NONE = 3; public static final int; // Possible Failover events registered with callback public static final int FO_BEGIN = 1; public static final int FO_END = 2; public static final int FO_ABORT = 3; public static final int FO_REAUTH = 4; public static final int FO_ERROR = 5; public static final int FO_RETRY = 6; public static final int FO_EVENT_UNKNOWN = 7; public int callbackFn (Connection conn, Object ctxt, // ANy thing the user wants to save int type, // One of the possible Failover Types int event ); // One of the possible Failover Events
  • 16. FCF • Asynchronously process UP/DOWN HA FAN events • Removes affected connections • Works under Universal Connection Pool (RAC/RAC one node, DG, Fast Restart) • ONS should be enabled srvctl add ons srvctl enable ons srvctl start ons
  • 17. FCF Java example PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionPoolName("FCFSamplePool"); pds.setFastConnectionFailoverEnabled(true); pds.setONSConfiguration("nodes=racnode1:4200,racnode2:4200nwallet file= /oracle11/onswalletfile"); pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSour ce"); pds.setURL("jdbc:oracle:thin@(DESCRIPTION= "+ "(LOAD_BALANCE=on)"+ "(ADDRESS=(PROTOCOL=TCP)(HOST=racnode1) (PORT=1521))"+ "(ADDRESS=(PROTOCOL=TCP)(HOST=racnode2) (PORT=1521))"+ "(CONNECT_DATA=(SERVICE_NAME=service_name)))"); Ensure ons.jar is on application CLASSPATH.
  • 18. FCF Java example boolean retry = true; while(retry) { try { //Getting a RAC connection from the pool conn = pds.getConnection(); // Executing a query on the connection. rs = stmt.executeQuery("select user from dual"); rs.next(); System.out.println("nConnected as : " + rs.getString(1)); //Setting retry to false to exit the loop retry = false; } catch (SQLException eSQL) { System.out.println("nSQLException: " + eSQL); // Checking connection usability after a RAC-down event triggers UCP FCF actions if (conn == null || !((ValidConnection) conn).isValid()) { try//Closing the connection { conn.close(); } catch (SQLException eClose) { System.out.println("nException arose when closing connection: " + eClose); } //Setting retry to true to try again retry = true; } } Thread.sleep(1000); }
  • 19. FCF ODP.NET example using System; using Oracle.DataAccess.Client; class HAEventEnablingSample { static void Main() { OracleConnection con = new OracleConnection(); // Open a connection using ConnectionString attributes // Also, enable "load balancing" con.ConnectionString = "User Id=user_name;Password=password;Data Source=oracle;" + "Min Pool Size=10;Connection Lifetime=120;Connection Timeout=60;" + "HA Events=true;Incr Pool Size=5;Decr Pool Size=2"; con.Open(); // Create more connections and perform work against the database here. con.Dispose(); } Before Oracle 12 .config file should be changed: <onsConfig mode="remote"> <ons database="db1"> <add name="nodeList" value="racnode1:4100, racnode2:4200" /> </ons> <ons database="db2"> <add name="nodeList" value=" racnode3:4100, racnode4:4200" /> </ons> </onsConfig>
  • 20. FCF ODP.NET example If you need enhanced error treatment use OracleHAEventArgs class: public delegate void OracleHAEventHandler(object sender, OracleHAEventArgs eventArgs); public static void OnFANEventHandler(OracleHAEventArgs eventArgs) { lock(typeof(FANCallBackSample)) { if (eventArgs.Status == OracleHAEventStatus.Down){ // Your event treatment } ... ... ... } }
  • 21. TG API under JDBC, OCI, ODP.NET to resolve possible ‘double-execution’ problem. Creates globally unique LTXID Stores it on DB + client driver
  • 22. TG use-case after outage • Requests from DB LTXID by session handle (DBMS_APP_CONT.GET_LTXID_OUTCOME ) • Gets the commit state before failure • If committed return control to app • If uncommited asks about next actions TG could be enabled by DBMS_SERVICE.CREATE_SERVICE or srvctl modify service -db DBNAME -s MYSERVICENAME -commit_outcome TRUE
  • 23. TG Supported COMMITs • Local transactions • Data definition language (DDL) transactions • Distributed transactions • Commit on success (auto-commit) • PL/SQL with embedded commit
  • 24. TG ODP.NET example txn = con.BeginTransaction(); <your processing> try { txn.Commit(); } catch (Exception ex) { if (ex is OracleException) { if (ex.IsRecoverable && ex.OracleLogicalTransaction != null && !ex.OracleLogicalTransaction.Committed) { // safe to re-submit work } else { // do not re-submit work if (ex.OracleLogicalTransaction.UserCallCompleted) { // return commit success to application to continue } else { // transaction committed, states such as row count or // out parameters may be lost // if the application needs these states. // return commit success and warn } } } } Don’t forget to grant GRANT EXECUTE ON DBMS_APP_CONT TO <Ora user under .NET>. due ODP.Net invokes it implicitly in case of exception.
  • 25. TG Java example private static final String GET_LTXID_OUTCOME_WRAPPER = "DECLARE PROCEDURE GET_LTXID_OUTCOME_WRAPPER("+ " ltxid IN RAW,"+ " is_committed OUT NUMBER ) "+ "IS " + " call_completed BOOLEAN; "+ " committed BOOLEAN; "+ "BEGIN "+ " DBMS_APP_CONT.GET_LTXID_OUTCOME(ltxid, committed, call_completed); "+ " if committed then is_committed := 1; else is_committed := 0; end if; "+ "END; "+ "BEGIN GET_LTXID_OUTCOME_WRAPPER(?,?); END;"; boolean getTransactionOutcome(Connection conn, LogicalTransactionId ltxid) throws SQLException { boolean committed = false; CallableStatement cstmt = null; try { cstmt = conn.prepareCall(GET_LTXID_OUTCOME_WRAPPER); cstmt.setObject(1, ltxid); // use this starting in 12.1.0.2 cstmt.registerOutParameter(2, OracleTypes.BIT); cstmt.execute(); committed = cstmt.getBoolean(2); } catch (SQLException sqlexc) { throw sqlexc; } finally { if(cstmt != null) cstmt.close(); } return committed; }
  • 26. TG Java example Connection jdbcConnection = getConnection(); boolean isJobDone = false; while(!isJobDone) { try { // apply the raise (DML + commit): RaiseToAllEmployees(jdbcConnection,5); // no exception, the procedure completed: isJobDone = true; } catch (SQLRecoverableException recoverableException) { // Retry only if the error was recoverable. try { jdbcConnection.close(); // close old connection: } catch (Exception ex) {} // pass through other exception s Connection newJDBCConnection = getConnection(); // reconnect to allow retry // Use Transacton Guard to force last request: committed or uncommitted LogicalTransactionId ltxid = ((OracleConnection)jdbcConnection).getLogicalTransactionId(); isJobDone = getTransactionOutcome(newJDBCConnection, ltxid); jdbcConnection = newJDBCConnection; } }
  • 27. AC • JDBC OCI and JDBC thin Oracle 12 technology. It works with UCP, JDBC, Weblogic + RAC/RAC one node or DG • Intended to hide failures from client by replaying workload using TG data • Rebuilds transaction and non-transaction states • Requires small intervention to code
  • 28. AC workflow • Client issues a request to UCP • AC retains each call • Failure occurs and FAN is sent to UCP • AC reconnects when it is possible • TG checks transaction states and identifies last success statement using LTXID • AC restores non-transaction state (package variables, temporary tables etc) in accordance with settings • AC replays saved calls in accordance with given boundaries and commits
  • 29. AC configuration • Ask you DBA to configure AC service either by srvctl or dbms_service. declare params dbms_service.svc_parameter_array; begin params('FAILOVER_TYPE'):='TRANSACTION'; params('REPLAY_INITIATION_TIMEOUT'):=300; params('FAILOVER_DELAY'):=3; params('FAILOVER_RETRIES'):=30; params('commit_outcome'):='true'; dbms_service.modify_service('[your service]',params); end; • Don’t forget to grant execute on dbms_app_cont • Set for your sequences, guid and timestamp KEEP properties GRANT [KEEP DATE TIME | KEEP SYSGUID].. [to USER] GRANT KEEP SEQUENCE.. [to USER] on [sequence object]; ALTER SEQUENCE.. [sequence object] [KEEP];
  • 30. AC Java example private void DBAction(Connection c, int numValue) throws SQLException { String updsql = "UPDATE hr.employes " + "SET job_id=job_id " + "WHERE employee_id=?"; PreparedStatement pstmt = null; /*some non-transactional actions for instance sending email about employes processing start using utl_mail*/ /* let’s set boundaries */ ((oracle.jdbc.replay.ReplayableConnection)c).beginRequest(); pstmt=c.prepareStatement(updsql); c.setAutoCommit(false); for (int i=0;i<numValue;i++) { pstmt.setInt(1,i); pstmt.executeUpdate(); } c.commit(); // End of the Callback. ((oracle.jdbc.replay.ReplayableConnection)c).endRequest(); pstmt.close(); }
  • 31. AC Java Example import java.sql.*; import oracle.jdbc.pool.*; import oracle.jdbc.*; import oracle.jdbc.replay.*; public static void main(String args[]) throws SQLException { Connection conn = null; OracleDataSourceImpl ocpds = new OracleDataSourceImpl(); ocpds.setURL("jdbc:oracle:thin:@rac-scan:1521/app"); ocpds.setUser("user"); ocpds.setPassword("passw"); conn = ocpds.getConnection(); self.dbAction(conn,100000); conn.close(); }
  • 32. AC cons • Doesn’t work with GoldenGate, Active DataGuard • No .NET support • AC works ‘automagicaly’ so should to be tested thoroughly • Memory consumption on JDBC side • Application should be AC-aware if a logic uses non-transactional features
  • 33. Summary client failover Technology Connection cleanup Automatic reconnection Replay TAF not intendend + long-running queries only FCF + + hand-coded TG not intendend - sometimes hand-coded AC not intendend + sometimes need to specify boundaries
  • 34. Conclusions If you wish to achieve true HA it is possible, but you should consider: 1. Infrastructure costs 2. Licensing burden 3. Expenses for software development to support various types of replay We are happy to help our customers! Are they ready?
  • 35. Q&A
  • 36. Contacts Feel free to ask: shtock@mail.ru
  • 37. Reasons for smart load balancing Capacity of HA architecture is changing overtime: • Not all opened connections are best connections – could be connected to either slow or currently maintained nodes • New connections shouldn’t even try to use dead, slow or currently maintained nodes
  • 38. Oracle load balancing types • Client-side – Uses TNS names for connections to different nodes (load_balance = on) – Random connection distributions – Works on connection attempt • Server-side – Relies on server metrics – Connects based on policies and configuration – Works continuously
  • 40. What for 1. Adjust work distribution based on defined goals on working nodes: – throughput – service time – CPU utilization (NONE) 2. Reacts as fast as possible on cluster reconfiguration: – New nodes – Defunct nodes
  • 41. How to enable LB Ask your DBA to: – Install Oracle RAC – Setup ONS/FAN daemons properly – Configure LBA by OEM or DBMS_SERVICE Example: EXECUTE DBMS_SERVICE.MODIFY_SERVICE ( service_name => 'sjob' , goal => DBMS_SERVICE.GOAL_SERVICE_TIME , clb_goal => DBMS_SERVICE.CLB_GOAL_SHORT);
  • 42. How to enable LB Java Properties prop = new Properties (); prop.put(oracle.net.ns.SQLnetDef.TCP_CONNTIMEOUT_STR, "" + (1 * 1000) ); // 1 second PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionPoolName("FCFSamplePool"); pds. setConnectionProperties ( prop ); pds.setFastConnectionFailoverEnabled(true); pds.setONSConfiguration("nodes=racnode1:4200,racnode2:4200nwallet file= /oracle11/onswalletfile"); pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSour ce"); pds.setURL("jdbc:oracle:thin@(DESCRIPTION= (LOAD_BALANCE=on) (ADDRESS=(PROTOCOL=TCP)(HOST=racnode1) (PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=racnode2) (PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=service_name)))");
  • 43. How to enable LB ODP.NET using System; using Oracle.DataAccess.Client; class ConnectionPoolingSample { static void Main() { OracleConnection con = new OracleConnection(); //Open a connection using ConnectionString attributes //related to connection pooling. con.ConnectionString = "User Id=scott;Password=tiger;Data Source=oracle;" + "Min Pool Size=10;Connection Lifetime=120;Connection Timeout=60;" + "Incr Pool Size=5; Decr Pool Size=2" + "HA events=true;load balancing=true;pooling=true"; con.Open(); Console.WriteLine("Connection pool successfully created"); // Close and Dispose OracleConnection object con.Close(); con.Dispose(); Console.WriteLine("Connection is placed back into the pool."); } }
  • 44. Conclusion If you don’t want/have time to implement your own load balancing you definitely should consider Oracle real time load balancing. It works “from the box” in case of FCF is configured properly and easily managed using services.
  • 45. Q&A
  • 46. Contacts Feel free to ask: shtock@mail.ru

Editor's Notes

  • #9: Now it’s time to move from general principles to details. In order to understand how Oracle deals with HA for app dev we need to introduce some terms. The core of Oracle HA is FAN by ONS. Probably we will speak about load balancing events today.
  • #12: srvctl add service -d orcl -s TAF_TEST -r &amp;quot;orcl1,orcl2,orcl3,orcl4&amp;quot;srvctl start service -s TAF_TEST -d orcl begin dbms_service.modify_service(service_name =&amp;gt; &amp;apos;TAF_TEST&amp;apos;, aq_ha_notifications =&amp;gt; false, failover_method =&amp;gt; dbms_service.failover_method_basic, failover_type =&amp;gt; dbms_service.failover_type_session, failover_retries =&amp;gt; 60, failover_delay =&amp;gt; 3); end;
  • #13: In order to enable TAF tnsnames.ora should be modified on client side or use dbms_service on server side (preconnected will not work) SESSION – any uncommited transactions will be rolled back, rollback should be issued from client side, session connects to other instance SELECT – the same but query will start from same SCN and from a row where it failed during FETCH without errors if there is no transactions in process Basic – connect will be done only in case of failure Preconnected means that connection is already established for second instance
  • #14: Create service, run it and set taf
  • #15: FailoverType will contain SELECT or SESSION or NONE as were mentioned before. In case of error the failover continue to retry until it is succesfull.
  • #16: Java callbacks are nearly the same. Just implement the interface.
  • #18: FCF is enabled by rather clear piece of JAVA
  • #19: In order to replay workload appropriate exception handling should be provided. All dead connections will be cleaned and if there are good connection the application will continue to work. New isValid function permits to check is the connection whether good or not. The most probable exception will be ORA-17008: FCF Closed Connection
  • #20: What we actually should do in .NET just enable HA events in connection string.
  • #22: Let’s imagine the case – client initiated transaction, committed it but just after commit we got network failure. Transaction is commited actualy but we have Error in communication channel exception. Before Ora 12 application developer can’t be sure whether commit was really successful except requery DB. TG resolves that issue. Logical Transaction ID - From the application perspective, the logical transaction ID uniquely identifies the last database transaction submitted on the session that failed. TG is automatically enabled by Application Continuity.
  • #23: The procedure has 2 out parameters. The procedure returns TRUE in committed parameter if the transaction with the named logical LTXID hasCOMMITTED. Returns FALSE if the logical LTXID has notCOMMITTED. Parameter user_call_complet indicates whether all information has been returned to the client. Examples of such messages are the number of rows processed when using autocommit or commit on success, parameter and function results when calling PL/SQL, or PL/SQL with more work to do after theCOMMIT.  Or by dbms_service
  • #25: Typical TG scenario looks like OracleLogicalTracsaction is LTXID we talked at the begining It&amp;apos;s safe to re-submit the work if the error is recoverable and the transaction has not been committed If transaction isn’t recoverable application developer should consider other way to restore states.
  • #26: In JAVA we have to invoke dbms_app_cont explicitly so the code will be slightly longer. Initially we should prepare a method to get transaction state. First output parameter (second actually – the first one is input) contains boolean – was the commit whether actually fine or not.
  • #27: Let’s assume the RaiseToAllEmployes method has commit statement inside. So in case of exception we get logical transaction id and request real commit state. If the job is done we exit from the loop otherwise retry.
  • #28: Rebuilds package variables, autonomous transactions, contexts, utl_smtp, scheduler/jobs and etc Small intervention in case of you don’t use extensively server-side logic.
  • #29: We have to set boundaries for replay for non-transactional stuff i.e. if we use utl_smtp, utl_http, utl_file,dbms_pipe from db-tier. Otherwise AC is transparent.
  • #30: Without KEEP these parameters will get new values but for the sake of integrity they should be replayed with initial values.
  • #31: Let’s prepare our function to execute db command. It uses begin/end requests intentionally in order to show what we should do in case of non-transactional stuff Please pay attention it is replayable connection rather than jdbcconnection In case of Autocommit should be disabled
  • #32: Here we have to use OracleDataSourceImpl in remplacement of OracleDataSource. So nothing special. If we have an issue during our 100000 updates they will be automaticaly replayed either on the same instance once it will be restored or on proper DG switchover or RAC node.
  • #38: What for do we need load balancing? It seems that connection pools already solved all problems with many sessions. Unfortunately not all. Even if we have a bunch of opened connections it isn’t good sometimes to use some of them. Challenges, mentioned at the beginning, encourage LB to become more and more smart.
  • #39: There are 2 load balancing types. We will not dive into client-side LB due it works obviously. Let’s spend time on server-side Server-side load balancing provides load balancing at the transaction level instead of load balancing at the time of initial connection.
  • #40: UCP consists from the mechanism which receive messages about nodes metrics from Load Balancing Advisory. LBA monitors activity for all instances in the cluster, analyze service level for each instance (for a given goal) and publishes FAN events. When doesn’t get metrics – uses random. New connections or old but nonactive for bad instances disappear from the pool.
  • #41: What for the previous picture was so complicated? Th – measures how fast db task could be completed i.e. how fast the instance serves 1 transaction, usually used with fixed response time systems (trading, billing) St – measures CPU time, i.e. which node could do maximum amount of work in least time usually with non-fixed response time (reporting) None – oracle names it as NONE. Probably it is very easy. Please pay attention that goas are set on cluster level – not in UCP.
  • #43: As you could see nothing were changed from our first example. We just need to have FCF enabled. It could be JDBC OCI or JDBC thin driver. So once it is done getConnection return the most appropriate connection from the pool.
  • #44: Nothing special as well. HA event is used to automatic bad connection cleanup, load balancing – self explanatory.