This chapter discusses how to monitor the health of each Pod in your active standby pair as well as the health of the active standby pairs themselves. It details the BothDown
and the ManualInterventionRequired
states with an emphasis of how the Operator behaves in each of these states. The chapter discusses how to suspend the management of your TimesTenClassic object by the Operator. It concludes with various manual operations you can perform on your TimesTen databases.
Topics:
Monitoring the health of each pod in the active standby pair
Monitoring the health of the active standby pair of databases
The Operator keeps track of the individual health and state of each Pod in the active standby pair. How often the Operator checks the health is defined by the value of the pollingInterval
. See Table 11-3, "TimesTenClassicSpecSpec" for information on pollingInterval
.
Each Pod is assigned a high level state based on the state of various components of Kubernetes and the state of TimesTen. These states are:
The standby has completed the process of duplicating the database from the active. The newly created standby is catching up to any transactions that ran on the active while the duplicate operation was running.
Either the Pod or the TimesTen components within the Pod (or both) are not functioning properly, given this Pod's role in the active standby pair.
The Pod and the TimesTen components within the Pod are in a healthy state, given this Pod's role in the active standby pair.
When a TimesTenClassic object is in the Reexamine
state, the Operator examines the state of both TimesTen instances. The Operator does not know which instance (if any) contains a properly configured active database (or a properly configured standby database). The Operator must examine both instances to see. If a healthy instance is found and that instance contains a properly configured active database, the state of the Pod is reported as HealthyActive
.
When a TimesTenClassic object is in the Reexamine
state, the Operator examines the state of both TimesTen instances. The Operator does not know which instance (if any) contains a properly configured standby database (or a properly configured active database). The Operator must examine both instances to see. If a healthy instance is found and that instance contains a properly configured standby database, the state of the Pod is reported as HealthyStandby
.
The Pod and the TimesTen components within the Pod are in a healthy state, but TimesTen in this Pod believes that TimesTen in the other Pod has failed. In particular, the OtherDown
state indicates that this Pod contains an active database, and the database's peer has reached the failThreshold
. The database in this Pod is no longer keeping transaction logs for its peer, as the peer is too far behind. Recovering the peer requires re-duplicating the active database (which the Operator will perform automatically).
The state of this Pod is unknown. Either the Pod is unreachable or the TimesTen agent contained within the Pod has failed.
An automated upgrade was attempted on TimesTen in this Pod and the upgrade failed. See "Overview of the upgrade process" for information on the upgrade process.
The Operator monitors and manages the health of each of your active standby pairs. The Operator assigns high level states to the TimesTenClassic object, which you can monitor and review. For example, you can use the kubectl
get
command to return the high level state of your TimesTenClassic object. Specifically, in this example, the value returned for the STATE
field is Normal
, indicating that the active and the standby databases are up and running, and working as they should.
% kubectl get ttc sample NAME STATE ACTIVE AGE sample Normal sample-0 15h
The states:
If the Operator detects that TimesTen in the Pod containing the active database has failed, then the TimesTenClassic object immediately enters the ActiveDown
state.
The unreachableTimeout
timeout value controls how long the state of the Pod containing the active database can be Unknown
before the TimesTenClassic object's state becomes ActiveDown
.
When the TimesTenClassic object's state becomes ActiveDown
, the standby database immediately becomes the active, and the state of the TimesTenClassic object becomes StandbyDown
.
When the TimesTenClassic object is in the Normal
state, and the standby database goes down, the state briefly changes to ActiveTakeover
.
When AWT cache groups are used, the standby is normally responsible for pushing updates from TimesTen to Oracle Database. However, if the standby fails, the active database takes over this responsibility. This occurs during the ActiveTakeover
state.
Neither the active nor the standby database is functioning properly. The Operator attempts to bring up the pair of databases.
If both Pods in the active standby pair fail, the Operator uses the information in TimesTenClassicStatus to minimize data loss. See "Understanding the BothDown state" for details.
When the TimesTenClassic object is in the WaitingForActive
state, and when the database that should be the active database comes up, the TimesTenClassic object enters the ConfiguringActive
state. The Operator then configures this database to be the active. Once the database is configured as the active, the TimesTenClassic object enters the StandbyDown
state. See "Understanding the BothDown state" for details.
If a problem occurs while Initializing
a TimesTenClassic object, the object transitions to the Failed
state. Once in this state, the Operator does not attempt to repair the object. You must delete it. Use the kubectl
describe
command to examine the Operator logs to determine the cause of the problem and then recreate the object.
This state is reported while the two Pods are starting up for the first time. In your active standby pair configuration, the Pod whose name ends with -0
is initially configured as the active database, and the Pod whose name ends with -1
is initially configured as the standby database. Specifically, if you specified the name for TimesTenClassic as sample
, the sample-0
Pod is configured as the active database, and the sample-1
Pod is configured as the standby database. Once the active/standby pair is completely deployed, the TimesTenClassic object transitions to the Normal
state.
When a TimesTenClassic object enters the ManualInterventionRequired
state, the Operator takes no further action for the object. It does not query the TimesTen agents associated with the object to determine the state of TimesTen and it does not command TimesTen to do anything. See "Understanding the ManualInterventionRequired state" and "Bringing up one database" for details.
When the TimesTenClassic object is in the ManualInterventionRequired
state, you can specify the reexamine
CRD syntax element to cause the Operator to take over the management of the object again. The Operator moves the object to the Reexamine
state. The Operator then examines the state of TimesTen. If you correctly repaired TimesTen, the TimesTenClassic object may then enter the Normal
or the StandbyDown
state, depending on the nature of your repair. If you did not correctly repair TimesTen, the TimesTenClassic object re-enters the ManualInterventionRequired
state. See "Understanding the ManualInterventionRequired state" for details.
This state is entered after the StandbyStarting
state. During the StandbyStarting
state, the standby copies the active database to the standby Pod. When the duplicate process is complete, the state changes from StandbyStarting
to StandbyCatchup
. See "StandbyStarting" for more information on the StandbyStarting
state. In the StandbyCatchup
state, the duplicate process has completed. Transactions that ran during this duplicate process must now be copied over to the standby. Thus the StandbyCatchup
state is the state when the newly created standby catches up to any transactions that ran on the active while the duplicate operation was running. Applications can continue to use the active without restriction.
The active database is functioning properly, but the standby database is not. The Operator automatically attempts to restart and reconfigure the standby database. Applications can continue to use the active database without restriction.
The standby is duplicating the database from the active. The StandbyStarting
state is complete when the duplicate operation completes. The StandbyCatchup
state is then entered. See "StandbyCatchup" for more information on the StandbyCatchup
state. Applications can continue to use the active without restriction.
When the TimesTenClassic object is in the BothDown
state, if the Operator can determine which database contains the most up-to-date data, the TimesTenClassic object enters the WaitingForActive
state. The object remains in this state until the Pod that contains the database is running, and the TimesTen agent within the tt
container (within that Pod) is responding to the Operator. See "Understanding the BothDown state" for details.
The Operator provisions, monitors, and manages active standby pairs of TimesTen databases. It detects and reacts to the failure of the active or the standby database. For example, when one database in the active standby pair is down, the Operator does the following:
If the active database fails, the Operator promotes the standby to be the active.
If the standby database fails, the Operator keeps the active running and repairs the standby.
However, if both databases fail at the same time, it is essential that the databases are brought back up appropriately. TimesTen replication does not atomically commit transactions in both database simultaneously. Transactions are committed in one database and then later are committed in the other database. (The database on which transactions are committed first is considered the database that is ahead.) Depending on how replication is configured, transactions on the active database may be ahead of the standby or the standby may be ahead of the active. To avoid data loss, the database that is ahead must become the active database after the failure is corrected.
In most cases, the Operator can determine which database was ahead at the time of the failure. However, there are cases where the Operator cannot determine which database was ahead. In particular, the Operator cannot determine which database is ahead if all of the following conditions occur:
Both databases failed during the polling interval. Specifically, the Operator examined both databases and the TimesTen Pods were in the Healthy
state. The Operator waited pollingInterval
seconds, and when the Operator examined the databases again (after this pollingInterval
), both databases were down and
RETURN
TWOSAFE
replication was configured and
DISABLE
RETURN
or LOCAL
COMMIT
ACTION
COMMIT
(or both) were configured.
See "TimesTenClassicSpecSpec" for more information on the pollingInterval
CRD syntax element and on the RETURN
TWOSAFE
and DISABLE
RETURN
replication configurations options. Also, see "CREATE ACTIVE STANDBY PAIR" in the Oracle TimesTen In-Memory Database SQL Reference and "Defining an active standby pair replication scheme" in the Oracle TimesTen In-Memory Database Replication Guide for information on defining an active standby pair replication scheme.
This combination of events indicates that some transactions may have committed on the standby and not on the active and/or some transactions may have committed on the active and not on the standby. The Operator takes no action in this case.
When both databases fail, the TimesTenClassic object enters the BothDown
state. See "BothDown" for more information on the BothDown
state. The Operator must then determine the appropriate action to take. The Operator first examines the value of the bothDownBehavior
CRD syntax element to determine what to do. See "TimesTenClassicSpecSpec" for information.
If bothDownBehavior
is set to Manual
, the TimesTenClassic object immediately enters the ManualInterventionRequired
state. The Operator takes no further action even if either TimesTen container subsequently becomes available. See "Understanding the ManualInterventionRequired state" for information on the ManualInterventionRequired
state.
If bothDownBehavior
is set to Best
(the default setting), the Operator attempts to determine which database was ahead at the time of failure.
If the Operator cannot determine which database is ahead, the TimesTenClassic object immediately enters the ManualInterventionRequired
state. See "Understanding the ManualInterventionRequired state" for details.
If the Operator can determine which database is ahead:
The TimesTenClassic object enters the WaitingForActive
state. The object remains in this state until the Pod containing that database is running and the TimesTen agent located in the tt
container within that Pod is responding to the Operator. At this point, the TimesTenClassic object enters the ConfiguringActive
state.
While the TimesTenClassic object is in the ConfiguringActive
state, TimesTen in this Pod is started, the database is loaded and is configured for use as the new active database. If there are any problems with these steps, the TimesTenClassic object enters the ManualInterventionRequired
state. If the database is successfully loaded and successfully configured as the new active, the TimesTenClassic object enters the StandbyDown
state. See "Monitoring the health of the active standby pair of databases" for information on the states of your TimesTenClassic object.
You can specify the maximum amount of time (expressed in seconds) that the TimesTenClassic object remains in the WaitingForActive
state by specifying a value for the waitingForActiveTimeout
CRD syntax element. After this period of time, if the object is still in the WaitingForActive
state, the object automatically transitions to the ManualInterventionRequired
state. The default is 0
, which indicates that there is no timeout, and the object will remain in this state indefinitely. See "TimesTenClassicSpecSpec" for more information on the waitingForActiveTimeout
CRD syntax element.
The time to recover the database varies by the size of the database. You should consider the size of your database when deciding the value for waitingForActiveTimeout
.
If the database that is ahead cannot be loaded, the TimesTenClassic object enters the ManualInterventionRequired
state. See "Understanding the ManualInterventionRequired state" for details.
When a TimesTenClassic object enters the ManualInterventionRequired
state, the Operator takes no further action for this object. It does not query the TimesTen agents associated with the object to determine the state of TimesTen and does not command TimesTen to do anything. It is important for you to address why the TimesTenClassic object is in this state.
If your TimesTenClassic object is in the ManualInterventionRequired
state and it is not the result of it first being in the BothDown
state, perform the operations necessary to manually repair one of the databases. Then, perform the steps to bring up this database. These steps are covered in "Bringing up one database" later in this chapter.
If, however, the TimesTenClassic object is in the ManualInterventionRequired
state as a result of it first being in the BothDown
state:
It may be unclear which database, if either, is suitable to be the new active. There may be transactions that have committed on the active database and not on the standby database, and simultaneously there may be transactions that have committed on the standby database and not on the active database.
You need to manually examine both databases and may need to reconcile the data before you can choose which database should be the new active.
If you can reconcile the data, and can manually fix one of the databases, then you can perform the steps to bring up one database. These steps are covered in "Bringing up one database" later in this chapter. If you cannot reconcile the data, contact Oracle Support for further assistance.
In order for you to direct the Operator to move the TimesTenClassic object out of the ManualInterventionRequired
state, you must either:
Bring up exactly one database: The Operator treats this database as the active database. All of these conditions must be met:
The TimesTen agent in the container is running.
The TimesTen the instance in the container is running.
The TimesTen database is loaded.
There is no replication scheme in the database.
The replication agent is not running.
The replication state is IDLE
.
If these conditions are met, the Operator moves the TimesTenClassic object to the StandbyDown
state. If any of these conditions are not met, the TimesTenClassic object remains in the ManualInterventionRequired
state. Note that when no replication scheme exists in the database, the Operator will still create the appropriate replication scheme based on how it is defined in the TimesTenClassic object definition. See "Bringing up one database" for an example of how you can direct the Operator to take action once one database is up and running.
Bring up both databases: In this case, you must configure the active standby pair. Specifically, each database must meet all of the following conditions:
The TimesTen agent in the container is running.
The TimesTen instance in the container is running.
The database is loaded.
The replication scheme is defined in both databases.
The replication agents are started and are running.
One database must be in the ACTIVE
state and the other database must be in the STANDBY
state.
If these conditions are met, the Operator moves the TimesTenClassic object to the Normal
state. If any of these conditions are not met, the TimesTenClassic object remains in the ManualInterventionRequired
state.
If you cannot bring up either database, the TimesTenClassic object remains in the ManualInterventionRequired
state.
You direct the Operator to examine the databases by specifying the reexamine
CRD syntax element. Every pollingInterval
, the Operator examines the value of reexamine
. If the reexamine
value has changed since the last iteration for this TimesTenClassic object, the Operator examines the state of the TimesTen containers for this object. See "TimesTenClassicSpecSpec" for more information on the pollingInterval
and the reexamine
CRD syntax elements.
The examination of the databases is performed exactly one time after you change the reexamine
value. If the required conditions were not met, you may again attempt to meet them. You must then modify the reexamine
value again to cause the Operator to reexamine the databases.
Note that whenever a TimesTenClassic object changes state, a Kubernetes Event is created. You can monitor these events with the kubectl
describe
command to be informed of such state transitions.
This section assumes you have manually repaired or have manually performed maintenance on one of the databases associated with the TimesTenClassic object. The TimesTenClassic object is currently in the ManualInterventionRequired
state. You now want to direct the Operator to treat the repaired database as the active, to perform the necessary steps to duplicate this database to the standby, and to bring up both databases, such that both are running and operating successfully.
Recall that all of these conditions must be met for the database:
TimesTen agent in the container is running.
TimesTen daemon (the instance) in the container is running.
TimesTen database is loaded.
There is no replication scheme in the database.
The replication agent is not running.
The replication state is IDLE
.
These sections show you how to verify the conditions are met for the database and how to set the reexamine
value:
Perform these steps to ensure the conditions are met for the database (the database to be the active). In this example, sample-1
will be the new active.
Note: These steps require you to use TimesTen utilities and TimesTen built-in procedures. See "Utilities" and "Built-In Procedures" in the Oracle TimesTen In-Memory Database Reference for details.
Confirm the TimesTenClassic object (sample
, in this example) is in the ManualInterventionRequired
state (represented in bold).
% kubectl get ttc sample
NAME STATE ACTIVE AGE
sample ManualInterventionRequired sample-0 12h
Use the kubectl
exec
-it
command to invoke the shell within the sample-1
Pod that contains the TimesTen database. (This database will be the new active.)
The remaining procedures take place within this shell.
% kubectl exec -it sample-1 -c tt -- /usr/bin/su - oracle
Use the ttDaemonAdmin
utility to start TimesTen daemon (if not already started). Then use the ttAdmin
utility to load the TimesTen database into memory (if not already loaded).
% ttDaemonAdmin -start TimesTen Daemon (PID: 5948, port: 6624) startup OK. % ttAdmin -ramLoad sample RAM Residence Policy : manual Manually Loaded In RAM : True Replication Agent Policy : manual Replication Manually Started : False Cache Agent Policy : manual Cache Agent Manually Started : False Database State : Open
Use the ttIsql
utility to connect to the sample
database. Then, call the ttRepStop
built-in procedure to stop the replication agent.
% ttIsql sample Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. Type ? or "help" for help, type "exit" to quit ttIsql. connect "DSN=sample"; Connection successful: DSN=sample;UID=oracle;DataStore=/tt/home/oracle/datastore/sample; DatabaseCharacterSet=AL32UTF8;ConnectionCharacterSet=US7ASCII;AutoCreate=0; PermSize=200;DDLReplicationLevel=3;ForceDisconnectEnabled=1; (Default setting AutoCommit=1) Command> call ttRepStop;
From within ttIsql
, use the SQL DROP
ACTIVE
STANDBY
PAIR
statement to drop the active standby pair replication scheme. Then use the ttIsql
repschemes
command to verify there are no replication schemes in the database. Exit from ttIsql
.
Command> DROP ACTIVE STANDBY PAIR; Command> repschemes; 0 replication schemes found.
Use the ttStatus
utility to verify the TimesTen daemon is running and the replication agent is not running.
% ttStatus TimesTen status report as of Sat Apr 24 02:14:15 2021 Daemon pid 5948 port 6624 instance instance1 TimesTen server pid 5955 started on port 6625 ------------------------------------------------------------------------ ------------------------------------------------------------------------ Data store /tt/home/oracle/datastore/sample Daemon pid 5948 port 6624 instance instance1 TimesTen server pid 5955 started on port 6625 There are 15 connections to the data store Shared Memory KEY 0x0a100c60 ID 196609 PL/SQL Memory Key 0x0b100c60 ID 229378 Address 0x5000000000 Type PID Context Connection Name ConnID Process 10418 0x000000000218a6e0 sample 2 Process 8338 0x0000000001cbb6e0 sample 1 Subdaemon 5953 0x00000000015075f0 Manager 2047 Subdaemon 5953 0x0000000001588540 Rollback 2046 Subdaemon 5953 0x0000000001607210 Checkpoint 2041 Subdaemon 5953 0x00007f132c0008c0 Flusher 2045 Subdaemon 5953 0x00007f132c080370 Log Marker 2040 Subdaemon 5953 0x00007f13340008c0 Monitor 2044 Subdaemon 5953 0x00007f133407f330 HistGC 2037 Subdaemon 5953 0x00007f13380008c0 Aging 2042 Subdaemon 5953 0x00007f133807f330 AsyncMV 2039 Subdaemon 5953 0x00007f133c0008c0 Deadlock Detector 2043 Subdaemon 5953 0x00007f133c07f330 IndexGC 2038 Subdaemon 5953 0x00007f135c0008c0 Garbage Collector 2035 Subdaemon 5953 0x00007f13600e8e20 XactId Rollback 2036 Open for user connections RAM residence policy: Manual Data store is manually loaded into RAM Replication policy : Manual Cache Agent policy : Manual PL/SQL enabled. ------------------------------------------------------------------------ Accessible by group oracle End of report
You have successfully verified the conditions for the database. The database is up and running. The Operator will treat this database as the active. You are now ready to set the value for the reexamine
CRD syntax element.
This example shows you how to set the reexamine
value in the TimesTenClassic object definition (sample
, in this example). The example also illustrates the action the Operator takes after the reexamine
value has been changed.
Set the reexamine
value. The value must be different than the current value for the TimesTenClassic object. When the Operator examines this value and notices it has changed since the last iteration, it will take appropriate action.
Use the kubectl
edit
command to edit the TimesTenClassic object.
If there is a line for reexamine
in the file, then modify its value. It must be different than the current value.
If there is no line for reexamine
in the file, then add a line and specify a value.
In this example, there is no reexamine
line. This example adds the reexamine
line and sets the value for reexamine
to April22reexamine1
(represented in bold).
Note: Not all output is shown.
% kubectl edit timestenclassic sample # Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this # file will be reopened with the relevant failures. # apiVersion: timesten.oracle.com/v1 kind: TimesTenClassic metadata: ... name: sample namespace: mynamespace ... repCreateStatement: | create active standby pair "{{tt-name}}" on "{{tt-node-0}}", "{{tt-name}}" on "{{tt-node-1}}" RETURN TWOSAFE store "{{tt-name}}" on "{{tt-node-0}}" PORT {{tt-rep-port}} FAILTHRESHOLD 0 TIMEOUT 999 store "{{tt-name}}" on "{{tt-node-1}}" PORT {{tt-rep-port}} FAILTHRESHOLD 0 TIMEOUT 999 spec: ttspec: bothDownBehavior: Best dbConfigMap: - sample image: phx.ocir.io/youraccount/tt1814110:3 imagePullPolicy: Always imagePullSecret: sekret storageClassName: oci storageSize: 250G reexamine: April22reexamine1 ... timestenclassic.timesten.oracle.com/sample edited
Use the kubectl
get
command to assess the state of the sample
TimesTenClassic object. Observe how the state changes as you issue multiple kubectl
get
commands. Also note that the Operator has successfully configured sample
-1
to be the active.
% kubectl get ttc sample NAME STATE ACTIVE AGE sample Reexamine None 68m % kubectl get ttc sample NAME STATE ACTIVE AGE sample ConfiguringActive None 68m % kubectl get ttc sample NAME STATE ACTIVE AGE sample StandbyDown sample-1 68m % kubectl get ttc sample NAME STATE ACTIVE AGE sample Normal sample-1 71m
Use the kubectl
describe
command to further review the actions of the Operator (represented in bold).
Not all output is shown:
% kubectl describe ttc sample Name: sample Namespace: mynamespace ... Kind: TimesTenClassic ... Rep Create Statement: create active standby pair "{{tt-name}}" on "{{tt-node-0}}", "{{tt-name}}" on "{{tt-node-1}}" RETURN TWOSAFE store "{{tt-name}}" on "{{tt-node-0}}" PORT {{tt-rep-port}} FAILTHRESHOLD 0 TIMEOUT 999 store "{{tt-name}}" on "{{tt-node-1}}" PORT {{tt-rep-port}} FAILTHRESHOLD 0 TIMEOUT 999 Spec: Ttspec: Both Down Behavior: Best Db Config Map: sample Image: phx.ocir.io/youraccount/tt1814110:3 Image Pull Policy: Always Image Pull Secret: sekret Reexamine: April22reexamine1 Stop Managing: April21Stop1 Storage Class Name: oci Storage Size: 250G Status: Classic Upgrade Status: Active Start Time: 0 Active Status: Image Update Pending: false Last Upgrade State Switch: 0 Prev Reset Upgrade State: Prev Upgrade State: Standby Start Time: 0 Standby Status: Upgrade Start Time: 0 Upgrade State: Active Pods: sample-1 High Level State: Normal Last Event: 54 Last High Level State Switch: 1619230912 Pod Status: Cache Status: Cache Agent: Not Running Cache UID Pwd Set: true N Cache Groups: 0 Db Status: Db: Loaded Db Id: 475 Db Updatable: No Initialized: true Last High Level State Switch: ? Pod Status: Agent: Up Last Time Reachable: 1619231126 Pod IP: 10.244.7.89 Pod Phase: Running Prev High Level State: Healthy Prev Image: Replication Status: Last Time Rep State Changed: 0 Rep Agent: Running Rep Peer P State: start Rep Scheme: Exists Rep State: STANDBY Times Ten Status: Daemon: Up Instance: Exists Release: 18.1.4.11.0 Admin User File: false Cache User File: false Cg File: false Disable Return: false High Level State: Healthy Intended State: Standby Local Commit: false Name: sample-0 Schema File: false Using Twosafe: false Cache Status: Cache Agent: Not Running Cache UID Pwd Set: true N Cache Groups: 0 Db Status: Db: Loaded Db Id: 476 Db Updatable: Yes Initialized: true Last High Level State Switch: ? Pod Status: Agent: Up Last Time Reachable: 1619231126 Pod IP: 10.244.6.149 Pod Phase: Running Prev High Level State: Healthy Prev Image: Replication Status: Last Time Rep State Changed: 1619228670 Rep Agent: Running Rep Peer P State: start Rep Scheme: Exists Rep State: ACTIVE Times Ten Status: Daemon: Up Instance: Exists Release: 18.1.4.11.0 Admin User File: false Cache User File: false Cg File: false Disable Return: false High Level State: Healthy Intended State: Active Local Commit: false Name: sample-1 Schema File: false Using Twosafe: false Prev High Level State: StandbyDown Prev Reexamine: April22reexamine1 Prev Stop Managing: April21Stop1 Rep Create Statement: create active standby pair "sample" on "sample-0.sample.mynamespace.svc.cluster.local", "sample" on "sample-1.sample.mynamespace.svc.cluster.local" NO RETURN store "sample" on "sample-0.sample.mynamespace.svc.cluster.local" PORT 4444 FAILTHRESHOLD 0 store "sample" on "sample-1.sample.mynamespace.svc.cluster.local" PORT 4444 FAILTHRESHOLD 0 Rep Port: 4444 Status Version: 1.0 Events: Type Reason Age From Message ---- ------ ---- ---- ------- - StateChange 58m ttclassic TimesTenClassic was Normal, now ManualInterventionRequired - StateChange 46m ttclassic Pod sample-0 Daemon Down - StateChange 41m ttclassic Pod sample-1 Daemon Down - StateChange 41m ttclassic Pod sample-1 Daemon Up - StateChange 41m ttclassic Pod sample-1 Database Unloaded - StateChange 40m ttclassic Pod sample-1 Database Loaded - StateChange 40m ttclassic Pod sample-1 RepState IDLE - StateChange 40m ttclassic Pod sample-1 RepAgent Not Running - StateChange 17m ttclassic Pod sample-1 Database Updatable - StateChange 17m ttclassic Pod sample-1 RepScheme None - StateChange 4m21s ttclassic TimesTenClassic was ManualInterventionRequired, now Reexamine - Error 4m16s ttclassic Active error: Daemon Down - StateChange 4m16s ttclassic TimesTenClassic was Reexamine, now ConfiguringActive - StateChange 4m10s ttclassic Pod sample-1 RepState ACTIVE - StateChange 4m10s ttclassic Pod sample-1 RepScheme Exists - StateChange 4m10s ttclassic Pod sample-1 RepAgent Running - StateChange 4m8s ttclassic TimesTenClassic was ConfiguringActive, now StandbyDown - StateChange 4m3s ttclassic Pod sample-0 Daemon Up - StateChange 4m3s ttclassic Pod sample-0 Database Unloaded - StateChange 3m56s ttclassic Pod sample-0 Database None - StateChange 3m42s ttclassic Pod sample-0 Database Loaded - StateChange 3m42s ttclassic Pod sample-0 Database Not Updatable - StateChange 3m42s ttclassic Pod sample-0 RepAgent Not Running - StateChange 3m42s ttclassic Pod sample-0 RepState IDLE - StateChange 3m36s ttclassic Pod sample-0 RepAgent Running - StateChange 3m36s ttclassic Pod sample-0 RepState STANDBY - StateChange 3m36s ttclassic TimesTenClassic was StandbyDown, now Normal
Use the kubectl
exec
-it
command to invoke the shell within the sample-1
Pod that contains the TimesTen database. Then, verify you can connect to the active database.
% kubectl exec -it sample-1 -c tt -- /usr/bin/su - oracle
$ ttIsql sample
Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.
connect "DSN=sample";
Connection successful: DSN=sample;UID=oracle;DataStore=/tt/home/oracle/datastore/sample;
DatabaseCharacterSet=AL32UTF8;ConnectionCharacterSet=US7ASCII;
AutoCreate=0;PermSize=200;DDLReplicationLevel=3;ForceDisconnectEnabled=1;
(Default setting AutoCommit=1)
Command> call ttRepStateGet;
< ACTIVE >
1 row found.
Use the kubectl
exec
-it
command to invoke the shell within the sample-0
Pod that contains the TimesTen database. Then, verify you can connect to the standby database.
% kubectl exec -it sample-0 -c tt -- /usr/bin/su - oracle
% ttIsql sample
Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.
connect "DSN=sample";
Connection successful: DSN=sample;UID=oracle;DataStore=/tt/home/oracle/datastore/sample;
DatabaseCharacterSet=AL32UTF8;ConnectionCharacterSet=US7ASCII;AutoCreate=0;
PermSize=200;DDLReplicationLevel=3;ForceDisconnectEnabled=1;
(Default setting AutoCommit=1)
Command> call ttRepStateGet;
< STANDBY >
1 row found.
The Operator is now managing and monitoring your TimesTenClassic object. The TimesTenClassic object is in the Normal
state. Both databases are up and running and ready for use.
These sections discuss why you may want to suspend the management of your TimesTenClassic object by the Operator and then how to do it:
The Operator periodically examines the state of the TimesTen instances and the databases associated with each TimesTenClassic object. It takes actions to repair anything that is broken. You may have a situation in which you want to manually perform maintenance operations. In such a situation, you do not want the Operator to interfere and attempt to perform repair operations.
You could stop the Operator (by deleting the Deployment of the timestenclassic-operator
). This action prevents the Operator from interfering. See "Revert to manual control" for more information. However, if you have more than one TimesTenClassic object and you delete the Operator, this interferes with the management of all the TimesTenClassic objects, when perhaps only one of them needs manual intervention.
Alternatively, you can direct the Operator to take no action for one TimesTenClassic object by specifying the stopManaging
CRD syntax element for this TimesTenClassic object. See "TimesTenClassicSpecSpec" for more information on this element. The Operator examines the value of stopManaging
and if it has changed since the last time the Operator examined it, the Operator changes the state of the TimesTenClassic object to ManualInterventionRequired
. This causes the Operator to no longer examine the status of the TimesTen Pods, the containers, the instances, and the databases associated with the TimesTenClassic object. The Operator takes no action on the object or its Pods.
When you want the Operator to manage the TimesTenClassic object again, you change the value of the reexamine
CRD syntax element. See "Understanding the ManualInterventionRequired state" for more information on the ManualInterventionRequired
state and the reexamine
CRD syntax element.
In this way, you can perform manual operations on TimesTen without deleting the Deployment of the timestenclassic-operator
.
This example illustrates how to use the stopManaging
CRD syntax element to direct the Operator to stop managing one of the TimesTenClassic objects running in your Kubernetes cluster. In this example, there are two TimesTenClassic objects (sample
and sample2
) that are running. There is a requirement for you to perform manual maintenance operations on the TimesTen databases associated with one of the objects (sample
, in this example). You want the Operator to stop managing this sample
TimesTenClassic object. However, you want the Operator to continue managing the other TimesTenClassic object (sample2
, in this example).
Perform these steps:
Review the Pods that are running.
% kubectl get pods NAME READY STATUS RESTARTS AGE sample-0 2/2 Running 0 6m33s sample-1 2/2 Running 0 6m32s sample2-0 2/2 Running 0 6m32s sample2-1 2/2 Running 0 6m32s timestenclassic-operator-846cb5c97c-cxbl2 1/1 Running 0 4d20h
Confirm the sample
TimesTenClassic object is in the Normal
state. Recall that you want to perform maintenance on the TimesTen databases associated with this object.
% kubectl get ttc sample
NAME STATE ACTIVE AGE
sample Normal sample-0 13m
Set the stopManaging
value. The value must be different than the current value for the TimesTenClassic object. When the Operator examines this value and notices it has changed since the last iteration, it will take appropriate action.
Use the kubectl
edit
command to edit the TimesTenClassic object.
If there is a line for stopManaging
in the file, then modify its value. It must be different than the current value.
If there is no line for stopManaging
in the file, then add a line and specify a value.
In this example, there is no stopManaging
line. This example adds the stopManaging
line and sets the value for stopManaging
to April21Stop1
(represented in bold).
Note: Not all output is shown:
% kubectl edit timestenclassic sample # Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this # file will be reopened with the relevant failures. # apiVersion: timesten.oracle.com/v1 kind: TimesTenClassic metadata: ... name: sample namespace: mynamespace ... repCreateStatement: | create active standby pair "{{tt-name}}" on "{{tt-node-0}}", "{{tt-name}}" on "{{tt-node-1}}" RETURN TWOSAFE store "{{tt-name}}" on "{{tt-node-0}}" PORT {{tt-rep-port}} FAILTHRESHOLD 0 TIMEOUT 999 store "{{tt-name}}" on "{{tt-node-1}}" PORT {{tt-rep-port}} FAILTHRESHOLD 0 TIMEOUT 999 spec: ttspec: bothDownBehavior: Best dbConfigMap: - sample image: phx.ocir.io/youraccount/tt1814110:3 imagePullPolicy: Always imagePullSecret: sekret storageClassName: oci storageSize: 250G stopManaging: April21Stop1 ... timestenclassic.timesten.oracle.com/sample edited
Use the kubectl
get
command to check the state of the sample
TimesTenClassic object. Note that the sample
TimesTenClassic object has transitioned to the ManualInterventionRequired
state. This is the expected behavior after changing the stopManaging
value to a new value.
% kubectl get ttc sample
NAME STATE ACTIVE AGE
sample ManualInterventionRequired sample-0 15m
The sample
TimesTenClassic object is in the ManualInterventionRequired
state. The Operator has suspended the monitoring and the management of the sample
TimesTenClassic object. It will take no further action on this TimesTenClassic object or its Pods. You can now perform manual operations on your TimesTen databases. When you have completed such operations and are ready for the Operator to resume management, proceed to "Bringing up one database" to complete the process.
The Operator is configured in your Kubernetes cluster using a Deployment. Kubernetes automatically monitors the Operator and restarts it if it fails. The Operator runs in a Pod and the name of the Operator begins with timestenclassic-operator
, followed by arbitrary characters to make the name unique. If you specify multiple replicas when you deploy the Operator, there are multiple Pods. Only one Pod is active at a time. The remainder of the Pods wait for the active to fail, and if it does, then one of the Pods becomes active. Active standby pairs of TimesTen databases, provisioned by the Operator, continue to function if the Operator fails. When a new Operator is started by Kubernetes, it automatically monitors and manages all existing active standby pairs of databases.
Use the kubectl
get
pods
command to display the Pods that are running the Operator. In this example, there is one Pod for the Operator. When you deployed the Operator, you specified the value of 1
for the replicas
field. Therefore, Kubernetes created one Pod. See "Deploying the Operator" for information on the deployment of the Operator.
% kubectl get pods NAME READY STATUS RESTARTS AGE timestenclassic-operator-5d7dcc7948-8mnz4 1/1 Running 0 3m21s
The Operator strives to keep your active standby pair of databases running once they are deployed. Kubernetes manages the lifecycle of the Pods. It recreates the Pods if they fail. It also recreates the Pods on available Kubernetes cluster nodes, if the nodes on which the Pods are running fail. The Operator monitors TimesTen running in the Pods, and initiates the appropriate operations to keep the pair of databases operational. These operations are done automatically by the Operator, and should require minimal human intervention.
These sections discuss the manual operations you can perform:
You can use the kubectl
exec
-it
command to manually invoke TimesTen utilities on your TimesTen instances. This command invokes shells in the Pods and enables you to control the running of TimesTen in the Pods.
TimesTen runs in the tt
container, as the oracle
user. Once you have established a shell in a Pod, use the su - oracle
command to switch to the oracle
user. This automatically configures your environment so you can run the TimesTen utilities.
Note:
The Operator is still querying the status of the Pod, and the status of TimesTen within the Pod. If you invoke a command that disrupts the functioning of either the Pod or TimesTen, the Operator may act to try to fix what you did.This example shows how to use the kubectl
exec
-it
command to invoke the shell within the sample-0
Pod that contains the TimesTen database. Then, you can run the ttIsql
utility.
% kubectl exec -it sample-0 -c tt -- /usr/bin/su - oracle % ttIsql sample Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. Type ? or "help" for help, type "exit" to quit ttIsql. connect "DSN=sample"; Connection successful: DSN=sample;UID=oracle;DataStore=/tt/home/oracle/datastore/sample; DatabaseCharacterSet=AL32UTF8;ConnectionCharacterSet=US7ASCII;PermSize=200; DDLReplicationLevel=3; (Default setting AutoCommit=1) Command>
TimesTen uses connection attributes to define the attributes of a database. There are three types of connection attributes:
Data store attributes: Define the characteristics of a database that can only be changed by destroying and recreating the database.
First connection attributes: Define the characteristics of a database that can be changed by unloading and reloading the database into memory.
General connection attributes: Control how applications access the database. These attributes persist for the duration of the connection.
For more information on TimesTen connection attributes, see "List of attributes" in the Oracle TimesTen In-Memory Database Reference and "Connection attributes for Data Manager DSNs or Server DSNs" in the Oracle TimesTen In-Memory Database Operations Guide.
In a Kubernetes environment:
You can only modify data store attributes by deleting the TimesTenClassic object and the PersistentVolumeClaims associated with the TimesTenClassic object. Doing so results in the deletion of the TimesTen databases. See "Delete an active standby pair of TimesTen databases" and "Cleanup" for information on the deletion process.
You can modify first connection and general connection attributes without deleting the TimesTenClassic object (which deletes the databases) and the PersistentVolumeClaims associated with the TimesTenClassic object. Note that there are TimesTen restrictions when modifying some of the first connection attributes. See "List of attributes" in the Oracle TimesTen In-Memory Database Reference.
To modify first or general connection attributes:
You must first edit the db.ini
file. Complete the procedure in the "Manually edit the db.ini file" section. This section must be completed first.
Then, take these steps:
If you are modifying first connection attributes, follow the procedure in the "Modifying first connection attributes" section.
If you are modifying general connection attributes, follow the procedure in the "Modifying general connection attributes" section.
Complete this section if you are modifying first or general connection attributes or both. This section must be completed before proceeding to the "Modifying first connection attributes" or the "Modifying general connection attributes" sections.
To modify first or general connection attribute requires a change in the sys.odbc.ini
file.
If you have already created your active standby pair of TimesTen databases by creating a TimesTenClassic object, and you now want to change one or more first or general connection attributes in your sys.odbc.ini
file, you must change the db.ini
file.
The details as to how you should modify your db.ini
file depends on the facility originally used to contain the db.ini
file. (Possible facilities include ConfigMaps, Secrets, or init containers. See "Populating the /ttconfig directory" for details.)
In this example, the ConfigMap facility was originally used to contain the db.ini
file and to populate the /ttconfig
directory of the TimesTen containers. The example modifies the sample
ConfigMap.
The steps are:
Use the kubectl
describe
command to review the contents of the db.ini
file (represented in bold) located in the original sample
ConfigMap.
5 kubectl describe configmap sample Name: sample Namespace: mynamespace Labels: <none> Annotations: <none> Data ==== adminUser: ---- scott/tiger db.ini: ---- PermSize=200 DatabaseCharacterSet=AL32UTF8 schema.sql: ---- create sequence scott.s; create table scott.emp (id number not null primary key, name char (32)); Events: <none>
Use the kubectl
edit
command to modify the db.ini
file in the original sample
ConfigMap. Change the PermSize
first connection attribute to 600
(represented in bold). Add the TempSize
first connection attribute and set its value to 300
(represented in bold). Add the ConnectionCharacterSet
general connection attribute and set its value to AL32UTF8
(represented in bold).
% kubectl edit configmap sample # Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this # file will be reopened with the relevant failures. # apiVersion: v1 data: adminUser: | scott/tiger db.ini: | PermSize=600 TempSize=300 ConnectionCharacterSet=AL32UTF8 DatabaseCharacterSet=AL32UTF8 schema.sql: | create sequence scott.s; create table scott.emp (id number not null primary key, name char (32)); kind: ConfigMap metadata: creationTimestamp: "2020-09-15T19:23:59Z" name: sample namespace: mynamespace resourceVersion: "71907255" selfLink: /api/v1/namespaces/mynamespace/configmaps/sample uid: 0171ff7f-f789-11ea-82ad-0a580aed0453 ... configmap/sample edited
Use the kubectl
describe
command to verify the changes to the sample
ConfigMap. (The changes are represented in bold.)
% kubectl describe configmap sample Name: sample Namespace: mynamespace Labels: <none> Annotations: <none> Data ==== schema.sql: ---- create sequence scott.s; create table scott.emp (id number not null primary key, name char (32)); adminUser: ---- scott/tiger db.ini: ---- PermSize=600 TempSize=300 ConnectionCharacterSet=AL32UTF8 DatabaseCharacterSet=AL32UTF8 Events: <none>
You have successfully changed the sample
ConfigMap. If you are modifying first connection attributes, proceed to the "Modifying first connection attributes" section. If you are modifying only general connection attributes, proceed to the "Modifying general connection attributes" section.
If you have not modified the db.ini
file, proceed to the "Manually edit the db.ini file" section. You must now delete the standby Pod and then delete the active Pod. When you delete a Pod that contains a container running TimesTen, the Operator creates a new Pod to replace the deleted Pod. This new Pod contains a new sys.odbc.ini
file which is created from the contents of the db.ini
file located in the /ttconfig
directory.
Perform these steps to delete the standby Pod.
Use the kubectl
get
command to determine which Pod is the standby Pod for the sample
TimesTenClassic object. The active Pod is the Pod represented in the ACTIVE
column. The standby Pod is the other Pod (not represented in the ACTIVE
column). Therefore, for the sample
TimesTenClassic object, the active Pod is sample-0
, (represented in bold) and the standby Pod is sample-1
.
% kubectl get ttc sample NAME STATE ACTIVE AGE sample Normal sample-0 47h
Delete the standby Pod (sample-1
, in this example). This results in the Operator creating a new standby Pod to replace the deleted Pod. When the new standby Pod is created, it will use the newly modified sample
ConfigMap. (You modified this ConfigMap in the "Manually edit the db.ini file" section.)
% kubectl delete pod sample-1 pod "sample-1" deleted
Use the kubectl
get
command to verify the standby Pod is up and running and the state is Normal
.
Note that the state is StandbyDown
(represented in bold).
% kubectl get ttc sample
NAME STATE ACTIVE AGE
sample StandbyDown sample-0 47h
Wait a few minutes, then run the command again. Note that the state has changed to Normal
(represented in bold).
% kubectl get ttc sample
NAME STATE ACTIVE AGE
sample Normal sample-0 47h
Use the kubectl
exec
-it
command to invoke the shell in the standby Pod (sample-1
, in this example). Then, run the ttIsql
utility to connect to the sample
database. Note the new PermSize
value of 600
and the new TempSize
value of 300
in the connection output (represented in bold).
% kubectl exec -it sample-1 -c tt -- /usr/bin/su - oracle % ttIsql sample Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. Type ? or "help" for help, type "exit" to quit ttIsql. connect "DSN=sample"; Connection successful: DSN=sample;UID=oracle;DataStore=/tt/home/oracle/datastore/sample; DatabaseCharacterSet=AL32UTF8;ConnectionCharacterSet=AL32UTF8; AutoCreate=0;PermSize=600;TempSize=300;DDLReplicationLevel=3; ForceDisconnectEnabled=1; (Default setting AutoCommit=1)
Fail over from the active Pod to the standby Pod. See "Failover" for details of the fail over process. Before you begin this step, ensure you quiesce your applications and you use the ttRepAdmin
-wait
command to wait until replication is caught up, such that all transactions that were executed on the active database have been replicated to the standby database. Once the standby is caught up, fail over from the active database to the standby by deleting the active Pod. When you delete the active Pod, the Operator automatically detects the failure and promotes the standby database to be the active.
Delete the active Pod (sample-0
, in this example).
% kubectl delete pod sample-0 pod "sample-0" deleted
Wait a few minutes, then use the kubectl
get
command to verify the active Pod is now sample-1
for the sample
TimesTenClassic object and the state is Normal
(represented in bold).
% kubectl get ttc sample NAME STATE ACTIVE AGE sample Normal sample-1 47h
Use the kubectl
exec
-it
command to invoke the shell in the active Pod (sample-1
, in this example). Then, run the ttIsql
utility to connect to the sample
database. Note the new PermSize
value of 600
and the new TempSize
value of 300
in the connection output (represented in bold).
% kubectl exec -it sample-1 -c tt -- /usr/bin/su - oracle Last login: Sun Oct 11 15:50:29 UTC 2020 on pts/0 [oracle@sample-1 ~]$ ttIsql sample Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. Type ? or "help" for help, type "exit" to quit ttIsql. connect "DSN=sample"; Connection successful: DSN=sample;UID=oracle;DataStore=/tt/home/oracle/datastore/sample; DatabaseCharacterSet=AL32UTF8;ConnectionCharacterSet=AL32UTF8; AutoCreate=0;PermSize=600;TempSize=300;DDLReplicationLevel=3; ForceDisconnectEnabled=1; (Default setting AutoCommit=1)
Use the kubectl
exec
-it
command to invoke the shell in the standby Pod (sample-0
, in this example). Then, run the ttIsql
utility to connect to the sample
database. Note the new PermSize
value of 600
and the new TempSize
value of 300
in the connection output (represented in bold).
% kubectl exec -it sample-0 -c tt -- /usr/bin/su - oracle % ttIsql sample Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. Type ? or "help" for help, type "exit" to quit ttIsql. connect "DSN=sample"; Connection successful: DSN=sample;UID=oracle;DataStore=/tt/home/oracle/datastore/sample; DatabaseCharacterSet=AL32UTF8;ConnectionCharacterSet=AL32UTF8; AutoCreate=0;PermSize=600;TempSize=300;DDLReplicationLevel=3; ForceDisconnectEnabled=1; (Default setting AutoCommit=1)
You have successfully modified the PermSize
and the TempSize
first connection attributes.
If you have not modified the db.ini
file, proceed to the "Manually edit the db.ini file" section. You can either directly modify the sys.odbc.ini
file for the active TimesTen database and the sys.odbc.ini
file for the standby TimesTen database or you can follow the steps in the "Modifying first connection attributes" section. The first approach (modifying the sys.odbc.ini
file directly) is less disruptive.
This section discusses the procedure for directly modifying the sys.odbc.ini
files.
The sys.odbc.ini
file is located in the TimesTen container of the Pod containing the active TimesTen database and in the TimesTen container of the Pod containing the standby TimesTen database. After you complete the modifications to the sys.odbc.ini
files, subsequent applications can connect to the database using these general connection attributes.
This example illustrates how to edit the sys.odbc.in
i files.
Use the kubectl
exec
-it
command to invoke a shell in the active Pod. (In this example, sample-0
is the active Pod.)
% kubectl exec -it sample-0 -c tt -- /usr/bin/su - oracle Last login: Sat Oct 10 22:43:26 UTC 2020 on pts/8
Verify the current directory (/tt/home/oracle
).
% pwd /tt/home/oracle
Navigate to the directory where the sys.odbc.ini
file is located. The sys.odbc.ini
file is located in the /tt/home/oracle/instances/instance1/conf
directory. Therefore, navigate to the instances/instance1/conf
directory.
% cd instances/instance1/conf
Edit the sys.odbc.ini
file, adding, modifying, or deleting the general connection attributes for your DSN. (sample
, in this example.) For a list of the general connection attributes, see "List of attributes" in the Oracle TimesTen In-Memory Database Reference.
Note:
Ensure that you only make modifications to the TimesTen general connection attributes. Data store attributes and first connection attributes cannot be modified by directly editing thesys
.
odbc
.
ini
file.This example modifies the sample
DSN, adding the ConnectionCharacterSet
general connection attribute and setting its value equal to AL32UTF8
(represented in bold).
vi sys.odbc.ini
[ODBC Data Sources]
sample=TimesTen 18.1 Driver
tt=TimesTen 18.1 Driver
[sample]
Datastore=/tt/home/oracle/datastore/sample
PermSize=200
DatabaseCharacterSet=AL32UTF8
ConnectionCharacterSet=AL32UTF8
DDLReplicationLevel=3
AutoCreate=0
ForceDisconnectEnabled=1
...
Use the ttIsql
utility to connect to the sample
database and verify the value of the ConnectionCharacterSet
attribute is AL32UTF8
(represented in bold).
% ttIsql sample
Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.
connect "DSN=sample";
Connection successful:
DSN=sample;UID=oracle;DataStore=/tt/home/oracle/datastore/sample;
DatabaseCharacterSet=AL32UTF8;ConnectionCharacterSet=AL32UTF8;
AutoCreate=0;PermSize=200;DDLReplicationLevel=3;ForceDisconnectEnabled=1;
(Default setting AutoCommit=1)
You have successfully modified the sys.odbc.ini
file located in the TimesTen container of the active Pod (in this example, sample-0
). Use the same procedure to modify the sys.odbc.ini
file located in the TimesTen container of the standby Pod (in this example, sample-1
).
For example:
Use the kubectl
exec
-it
command to invoke a shell in the standby Pod (sample-1
, in this example).
% kubectl exec -it sample-1 -c tt -- /usr/bin/su - oracle Last login: Sat Oct 10 23:08:08 UTC 2020 on pts/0
Verify the current directory (/tt/home/oracle
).
% pwd /tt/home/oracle
Navigate to the directory where the sys.odbc.ini
file is located. The sys.odbc.ini
file is located in the /tt/home/oracle/instances/instance1/conf
directory. Therefore, navigate to the instances/instance1/conf
directory.
% cd instances/instance1/conf
Edit the sys.odbc.ini
file, adding, modifying, or deleting the same general connection attributes that you modified for the active database. Therefore, this example modifies the sample
DSN, adding the ConnectionCharacterSet
general connection attribute and setting its value equal to AL32UTF8
(represented in bold).
vi sys.odbc.ini
[ODBC Data Sources]
sample=TimesTen 18.1 Driver
tt=TimesTen 18.1 Driver
[sample]
Datastore=/tt/home/oracle/datastore/sample
PermSize=200
DatabaseCharacterSet=AL32UTF8
ConnectionCharacterSet=AL32UTF8
DDLReplicationLevel=3
AutoCreate=0
ForceDisconnectEnabled=1
...
Use the ttIsql
utility to connect to the sample
database and verify the value of the ConnectionCharacterSet
attribute is AL32UTF8
(represented in bold).
% ttIsql sample
Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.
connect "DSN=sample";
Connection successful:
DSN=sample;UID=oracle;DataStore=/tt/home/oracle/datastore/sample;
DatabaseCharacterSet=AL32UTF8;ConnectionCharacterSet=AL32UTF8;
AutoCreate=0;PermSize=200;DDLReplicationLevel=3;ForceDisconnectEnabled=1;
(Default setting AutoCommit=1)
You have successfully modified the sys.odbc.ini
file located in the TimesTen container of the active Pod (sample-0
) and the sys.odbc.ini
file located in the TimesTen container of the standby Pod (sample-1
). The ConnectionCharacterSet
general connection attribute has also been modified.
If you want to manually operate your active standby pair, you can delete the timestenclassic-operator
Deployment. The Operator stops, and does not restart. This affects all of the TimesTenClassic objects that are running in your Kubernetes cluster. If you do not want the Operator to stop managing all of the TimesTenClassic objects, you can suspend the management of individual TimesTenClassic objects. See "Suspending the management of a TimesTenClassic object" for information.
The TimesTenClassic object, representing the active standby pair of TimesTen databases, remains in Kubernetes, as do the other Kubernetes objects associated with them. You can use the kubectl
exec
-it
command to invoke shells in the Pods, and then you can control Timesten that is running in those Pods.
If one or both Pods in your active standby pair fails, Kubernetes creates new ones to replace them. This is due to the StatefulSet object that the Operator had previously created in Kubernetes. However, since the Operator is not running the new Pods, it cannot automatically start TimesTen. In this case, your active standby pair cannot be configured or started. You are responsible for the operation of TimesTen in the Pods.
If you want the Operator to take control again, you must redeploy the Operator. Once the Operator is redeployed, the Operator automatically identifies the TimesTenClassic objects in your Kubernetes cluster, and will attempt to manage them again.
This example shows you how to manually control TimesTen.
Verify the Operator and the TimesTen databases are running.
% kubectl get pods NAME READY STATUS RESTARTS AGE sample-0 2/2 Running 0 18h sample-1 2/2 Running 0 18h timestenclassic-operator-5d7dcc7948-pzj58 1/1 Running 0 18h
Navigate to the /deploy
directory where the operator.yaml
resides. (kube_files
/deploy
, in this example.)
% cd kube_files/deploy
Use the kubectl
delete
command to delete the Operator. The Operator is stopped and no longer deployed.
% kubectl delete -f operator.yaml deployment.apps "timestenclassic-operator" deleted
Verify the Operator is no longer running, but the TimesTen databases are.
% kubectl get pods NAME READY STATUS RESTARTS AGE sample-0 2/2 Running 0 19h sample-1 2/2 Running 0 19h
Use the kubectl
exec
-it
command to invoke the shell in the Pod that runs TimesTen.
% kubectl exec -it sample-0 -c tt -- /usr/bin/su - oracle Last login: Wed Apr 8 14:30:45 UTC 2020 on pts/0
Run the ttStatus
utility.
% ttStatus TimesTen status report as of Wed Apr 8 14:36:31 2020 Daemon pid 183 port 6624 instance instance1 TimesTen server pid 190 started on port 6625 ------------------------------------------------------------------------ ------------------------------------------------------------------------ Data store /tt/home/oracle/datastore/sample Daemon pid 183 port 6624 instance instance1 TimesTen server pid 190 started on port 6625 There are 20 connections to the data store Shared Memory KEY 0x02200bbc ID 32769 PL/SQL Memory Key 0x03200bbc ID 65538 Address 0x5000000000 Type PID Context Connection Name ConnID Replication 263 0x00007f99fc0008c0 LOGFORCE:140299698493184 2029 Replication 263 0x00007f9a040008c0 XLA_PARENT:140300350273280 2031 Replication 263 0x00007f9a080008c0 REPLISTENER:140300347123456 2030 Replication 263 0x00007f9a080acd60 RECEIVER:140299429472000 2028 Replication 263 0x00007f9a0c0008c0 FAILOVER:140300353423104 2032 Replication 263 0x00007f9a2c0009b0 TRANSMITTER(M):140299695343360 2034 Replication 263 0x00007f9a300008c0 REPHOLD:140300356572928 2033 Subdaemon 187 0x00000000023365b0 Manager 2047 Subdaemon 187 0x00000000023b57f0 Rollback 2046 Subdaemon 187 0x0000000002432cf0 Log Marker 2041 Subdaemon 187 0x000000000244fc00 Garbage Collector 2035 Subdaemon 187 0x00007f90c80008c0 Aging 2038 Subdaemon 187 0x00007f90d00008c0 Deadlock Detector 2044 Subdaemon 187 0x00007f90d001d7d0 HistGC 2039 Subdaemon 187 0x00007f90d40008c0 Checkpoint 2042 Subdaemon 187 0x00007f90d401d7d0 AsyncMV 2036 Subdaemon 187 0x00007f90d80008c0 Monitor 2043 Subdaemon 187 0x00007f90f808b360 IndexGC 2037 Subdaemon 187 0x00007f90fc0008c0 Flusher 2045 Subdaemon 187 0x00007f910004efd0 XactId Rollback 2040 Open for user connections RAM residence policy: Always Replication policy : Manual Replication agent is running. Cache Agent policy : Manual PL/SQL enabled. ------------------------------------------------------------------------ Accessible by group oracle End of report
Run the ttIsql
utility to connect to the sample
database and perform various operations.
% ttIsql sample Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. Type ? or "help" for help, type "exit" to quit ttIsql. connect "DSN=sample"; Connection successful: DSN=sample;UID=oracle;DataStore=/tt/home/oracle/datastore/sample; DatabaseCharacterSet=AL32UTF8;ConnectionCharacterSet=US7ASCII;PermSize=200; DDLReplicationLevel=3; (Default setting AutoCommit=1) Command> describe scott.emp; Table SCOTT.EMP: Columns: *ID NUMBER NOT NULL NAME CHAR (32) 1 table found. (primary key columns are indicated with *) Command> INSERT INTO scott.emp VALUES (1,'This is a test.'); 1 row inserted. Command> SELECT * FROM scott.emp; < 1, This is a test. > 1 row found.
If you delete the TimesTenClassic object that represents the active standby pair of TimesTen databases, Kubernetes automatically deletes all the Kubernetes objects and the resources it is using. The StatefulSet, the Service, and the Pods, that are associated with the pair are all deleted from Kubernetes. However, the PersistentVolumeClaims (that contain the TimesTen databases) are not deleted. You must manually delete the PersistentVolumeClaims (PVCs) after you delete the TimesTenClassic object. After you manually delete the PVCs, the PersistentVolumes, holding the databases, are recycled by Kubernetes. (You may be able to control this using the Kubernetes volume retention policy, but this is not controlled by the Operator.)
As an example, use the kubectl
delete
command to delete the PVCs for the sample
databases.
% kubectl delete pvc tt-persistent-sample-0 persistentvolumeclaim "tt-persistent-sample-0" deleted % kubectl delete pvc tt-persistent-sample-1 persistentvolumeclaim "tt-persistent-sample-1" deleted