Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
oracle_rac_application_continuity [2020/10/22 11:55] – [Service Creation] andonovj | oracle_rac_application_continuity [2020/10/22 12:13] (current) – andonovj | ||
---|---|---|---|
Line 10: | Line 10: | ||
- | ====Service Creation==== | + | ======Service Creation====== |
- | <Code: bash |Create service actest> | + | < |
[oracle@enode01 labs]$ srvctl add service -db eastdb \ | [oracle@enode01 labs]$ srvctl add service -db eastdb \ | ||
-service actest \ | -service actest \ | ||
Line 24: | Line 24: | ||
-retention 86400 \ | -retention 86400 \ | ||
-replay_init_time 1800 \ | -replay_init_time 1800 \ | ||
- | <code> | + | -notification TRUE |
- | ====Startup==== | + | </Code> |
+ | =====Status & Startup===== | ||
+ | We can check the configuration of the service as follows. Remember to put the database name. | ||
- | <sxh> | + | <Code: |
- | [oracle@lparaca ~]$ srvctl | + | [oracle@enode01 labs]$ srvctl |
- | Service actest | + | Service |
- | [oracle@lparaca ~]$ srvctl start service -db orcl -service actest | + | Server pool: |
- | </sxh> | + | Cardinality: |
+ | Disconnect: false | ||
+ | Service role: PRIMARY | ||
+ | Management policy: AUTOMATIC | ||
+ | DTP transaction: | ||
+ | AQ HA notifications: | ||
+ | Global: false | ||
+ | Commit Outcome: true | ||
+ | Failover type: TRANSACTION | ||
+ | Failover method: | ||
+ | TAF failover retries: 30 | ||
+ | TAF failover delay: 5 | ||
+ | Connection Load Balancing Goal: SHORT | ||
+ | Runtime Load Balancing Goal: SERVICE_TIME | ||
+ | TAF policy specification: | ||
+ | Edition: | ||
+ | Pluggable | ||
+ | Maximum lag time: ANY | ||
+ | SQL Translation Profile: | ||
+ | Retention: 86400 seconds | ||
+ | Replay Initiation Time: 1800 seconds | ||
+ | Session State Consistency: | ||
+ | GSM Flags: 0 | ||
+ | Service | ||
+ | Preferred instances: eastdb1 | ||
+ | Available instances: eastdb2 | ||
+ | [oracle@enode01 labs]$ | ||
+ | [oracle@enode01 labs]$ srvctl start service -db eastdb | ||
+ | [oracle@enode01 labs]$ | ||
+ | [oracle@enode01 labs]$ srvctl status service -db eastdb | ||
+ | Service actest is running on instance(s) eastdb1 | ||
+ | [oracle@enode01 labs]$ | ||
+ | </Code> | ||
+ | Now that we have the service, let's run the simple application. The application itself is one, but we will run it with different connection settings: | ||
- | ====Check & Test==== | + | =====Application |
- | + | ||
- | < | + | |
- | [oracle@lparaca ~]$ srvctl status service -serverpool orclsp | + | |
- | Service actest of database orcl is running on nodes: lparaca. | + | |
- | [oracle@lparaca ~]$ lsnrctl status | + | |
- | + | ||
- | LSNRCTL for Linux: Version 12.1.0.2.0 - Production on 19-JAN-2018 05:16:01 | + | |
- | + | ||
- | Copyright (c) 1991, 2014, Oracle. | + | |
- | + | ||
- | Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521)) | + | |
- | STATUS of the LISTENER | + | |
- | ------------------------ | + | |
- | Alias | + | |
- | Version | + | |
- | Start Date 19-JAN-2018 04:02:17 | + | |
- | Uptime | + | |
- | Trace Level off | + | |
- | Security | + | |
- | SNMP OFF | + | |
- | Listener Parameter File / | + | |
- | Listener Log File / | + | |
- | Listening Endpoints Summary... | + | |
- | (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER))) | + | |
- | (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.50)(PORT=1521))) | + | |
- | (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.51)(PORT=1521))) | + | |
- | Services Summary... | + | |
- | Service " | + | |
- | Instance " | + | |
- | Service " | + | |
- | Instance " | + | |
- | Service " | + | |
- | Instance " | + | |
- | Service " | + | |
- | Instance " | + | |
- | The command completed successfully | + | |
- | + | ||
- | </ | + | |
- | Now your service will failover to the other instance and the uncommited changes will be replayed. Therefore, any node failure will be transparent to the end user. | + | |
- | + | ||
- | + | ||
- | ====Application | + | |
- | The application should be changed also be using the UPC = Universal Connection Pooling | + | |
Below you can see the source which I have used: | Below you can see the source which I have used: | ||
- | <sxh> | + | <Code: |
package act; | package act; | ||
- | |||
import java.sql.Connection; | import java.sql.Connection; | ||
import java.sql.SQLException; | import java.sql.SQLException; | ||
Line 181: | Line 170: | ||
} | } | ||
+ | </ | ||
+ | | ||
+ | Now that we have the code, we can run it one in a two ways: | ||
+ | =====Noreplay Mode===== | ||
+ | We can run that application standard without any application continuity as follows: | ||
- | </sxh> | + | < |
- | + | [oracle@enode01 labs]$ cat runnoreplay.sh | |
- | + | java -classpath | |
- | Once the code is compiled | + | ./ |
+ | ojdbc6.jar actest.ACTest actest_noreplay.properties | ||
+ | </Code> | ||
+ | |||
+ | Where the connection properties are as follows: | ||
+ | |||
+ | < | ||
+ | [oracle@enode01 labs]$ cat actest_noreplay.properties | ||
+ | username=scott | ||
+ | password=tiger | ||
+ | autoCommit=false | ||
+ | # Use standard 12.1 datasource no replay | ||
+ | datasource=oracle.jdbc.pool.OracleDataSource | ||
+ | url=jdbc: | ||
+ | cluster01- | ||
+ | scan)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=actest. | ||
+ | example.com))) | ||
+ | # UCP setting: | ||
+ | ucp_pool_size=2 | ||
+ | ucp_validate_connection_on_borrow=true | ||
+ | ucp_connection_wait_timeout=60 | ||
+ | # Think Time taken to process | ||
+ | Time in milliseconds. | ||
+ | # -1 means no sleep. | ||
+ | thread_think_time=20 | ||
+ | # Number of concurrent threads running in the application | ||
+ | # UCP is tuned to have MAX and MIN limit set to this | ||
+ | number_of_threads=6 | ||
+ | verbose=true | ||
+ | </ | ||
+ | |||
+ | That way, the application WILL NOT take advantage of the Application Continuity and it will fail if the connection gets interrupted: | ||
+ | |||
+ | < | ||
+ | [oracle@enode01 labs]$ ./ | ||
+ | ###################################################### | ||
+ | Connecting to | ||
+ | jdbc: | ||
+ | ter01- | ||
+ | scan)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=actest. | ||
+ | example.com))) | ||
+ | # of Threads : 6 | ||
+ | UCP pool size : 2 | ||
+ | Thread think time : 20 ms | ||
+ | ###################################################### | ||
+ | 2 active connections, | ||
+ | 2 active connections, | ||
+ | ... (killed process from 2nd session) | ||
+ | .Exception occurred while getting connection: | ||
+ | oracle.ucp.UniversalConnectionPoolException: | ||
+ | Connection from Datasource: java.sql.SQLRecoverableException: | ||
+ | Listener refused the connection with the following error: | ||
+ | ORA-12514, TNS: | ||
+ | requested in connect descriptor | ||
+ | ... | ||
+ | [oracle@enode01 labs]$ | ||
+ | </ | ||
+ | |||
+ | =====Replay Mode===== | ||
+ | In order to make the application aware of the feature, we have to start it with the Universal Connection pooling using the replay option. To do that, we can use THE SAME application but with different connection properties: | ||
+ | |||
+ | < | ||
+ | [oracle@enode01 labs]$ cat actest_replay.properties | ||
+ | username=scott | ||
+ | password=tiger | ||
+ | autoCommit=false | ||
+ | # Use new 12.1 replay datasource | ||
+ | datasource=oracle.jdbc.replay.OracleDataSourceImpl | ||
+ | url=jdbc: | ||
+ | cluster01- | ||
+ | scan)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=actest. | ||
+ | example.com))) | ||
+ | # UCP setting: | ||
+ | ucp_pool_size=2 | ||
+ | ucp_validate_connection_on_borrow=true | ||
+ | ucp_connection_wait_timeout=60 | ||
+ | # Think Time taken to process the results from the database. | ||
+ | Time in milliseconds. | ||
+ | # -1 means no sleep. | ||
+ | thread_think_time=20 | ||
+ | # Number of concurrent threads running in the application | ||
+ | # UCP is tuned to have MAX and MIN limit set to this | ||
+ | number_of_threads=6 | ||
+ | verbose=true | ||
+ | </ | ||
+ | |||
+ | The properties are 99.9% the same, with the only difference of the: " | ||
+ | |||
+ | < | ||
+ | [oracle@enode01 labs]$ diff actest_noreplay.properties | ||
+ | actest_replay.properties | ||
+ | 5,6c5,6 | ||
+ | < # Use standard 12.1 datasource no replay | ||
+ | < datasource=oracle.jdbc.pool.OracleDataSource | ||
+ | --- | ||
+ | > # Use new 12.1 replay datasource | ||
+ | > datasource=oracle.jdbc.replay.OracleDataSourceImpl | ||
+ | </ | ||
+ | That way, the application will be able to reconnect after interrupted connection: | ||
- | <sxh> | + | <Code: |
- | C: | + | [oracle@enode01 labs]$ |
- | C: | + | ###################################################### |
- | ng2 | + | Connecting to |
- | connection factory set | + | jdbc: |
- | Using URL | + | ter01- |
- | jdbc: | + | scan)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=actest. |
- | FAILOVER=ON) | + | example.com))) |
- | 21)) (CONNECT_DATA = (SERVER = DEDICATED) | + | # of Threads : 6 |
- | pool configured, trying to get a connection | + | UCP pool size : 2 |
+ | Thread think time : 20 ms | ||
+ | ###################################################### | ||
+ | 2 active connections, avg response time from db 304 ms | ||
+ | 2 active connections, | ||
+ | 2 active connections, | ||
+ | 2 active connections, | ||
+ | 2 active connections, | ||
+ | 2 active connections, | ||
+ | 2 active connections, | ||
+ | 2 active connections, | ||
+ | 2 active connections, | ||
+ | ... (Interupted | ||
+ | 2 active connections, | ||
+ | 2 active connections, | ||
+ | 2 active connections, | ||
+ | 2 active connections, | ||
+ | [oracle@enode01 labs]$ | ||
- | C: | + | </Code> |
- | </sxh> | + |