6 Managing and Monitoring Your Active Standby Pairs

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

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:

CatchingUp

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.

Down

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.

Healthy

The Pod and the TimesTen components within the Pod are in a healthy state, given this Pod's role in the active standby pair.

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 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.

HealthyStandby

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.

OtherDown

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).

Terminal

TimesTen in the Pod cannot be repaired by the Operator.

Unknown

The state of this Pod is unknown. Either the Pod is unreachable or the TimesTen agent contained within the Pod has failed.

UpgradeFailed

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.

Monitoring the health of the active standby pair of databases

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:

ActiveDown

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.

ActiveTakeover

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.

BothDown

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.

ConfiguringActive

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.

Failed

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.

Initializing

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.

ManualInterventionRequired

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.

Normal

Both databases are up and running, and operating as they should.

Reexamine

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.

StandbyCatchup

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.

StandbyDown

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.

StandbyStarting

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.

WaitingForActive

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.

Understanding the BothDown state

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.

Understanding the ManualInterventionRequired state

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.

Bringing up one database

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:

Verify the conditions are met for the database

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.

  1. 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
    
  2. 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
    
  3. 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
    
  4. 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;
    
  5. 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.
    
  6. 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.

Set the reexamine value

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.

  1. 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
    
  2. 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
    
  3. 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
    
  4. 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.
    
  5. 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.

Suspending the management of a TimesTenClassic object

These sections discuss why you may want to suspend the management of your TimesTenClassic object by the Operator and then how to do it:

Overview

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.

Suspend management of the TimesTenClassic object

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:

  1. 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
    
  2. 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
    
  3. 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
    
  4. 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.

Locating the Operator

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

Managing the TimesTen databases

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:

Manually invoke TimesTen utilities

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>

Modify TimesTen connection attributes

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:

Then, take these steps:

Manually edit the db.ini file

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:

  1. 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>
    
  2. 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
    
  3. 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.

Modifying first connection attributes

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.

  1. 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
    
  2. 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
    
  3. 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
    
  4. 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)
    
  5. 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
    
  6. 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
    
  7. 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)
    
  8. 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.

Modifying general 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.ini files.

  1. 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
    
  2. Verify the current directory (/tt/home/oracle).

    % pwd
    /tt/home/oracle
    
  3. 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
    
  4. 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 the sys.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
    ...
    
  5. 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:

  1. 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
    
  2. Verify the current directory (/tt/home/oracle).

    % pwd
    /tt/home/oracle
    
  3. 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
    
  4. 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
    ...
    
  5. 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.

Revert to manual control

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.

  1. 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
    
  2. Navigate to the /deploy directory where the operator.yaml resides. (kube_files/deploy, in this example.)

    % cd kube_files/deploy
    
  3. 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
    
  4. 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
    
  5. 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
    
  6. 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
    
  7. 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.
    

Delete an active standby pair of TimesTen databases

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