In this post, I will continue my experiments with Oracle policy managed databases with Grid Infrastructure, and present one of the new features introduced with Grid Infrastructure 12c last June: the cluster configuration policies and policy sets. It allows the administrator to dynamically reconfigure all server pools at a time, with a single command, according to the business workload.

To take a simple example, imagine you have two servers allocated for your production instances, and two servers allocated for you development instances. This repartition is conform to your daily workload. But you have very intensive batches running every night on your production databases. The production servers are strongly used, and you have two development servers, up and running, but not used at all. What a great resources wasting!

In this case you have several solutions:

1) Shut down development servers during the night because they are not used. It will at least allow energy saving 🙂
2) Review your needs and allocate more server(s) to the production system
3) Create a crazy script to reconfigure each server pool, one by one, to accomodate the configuration to the real needs, with srvctl commands run in serial.
4) Use policies and policy sets

As you may expect, I will develop the last solution!

A policy set is a “document” (Oracle definition) which contains one or more policies. Each policy contains the configuration of all server-pools in the cluster: MIN_SIZE and MAX_SIZE, IMPORTANCE, server list, etc.

It will make the administrator able to activate a policy or another, according to the workload or business needs, to dynamically and immediately change all the configuration of the cluster server-pools. For instance: use two servers for production and two servers for development during working days, and use three servers for production and one server for development during nights and week ends.

First of all, there is my current configuration:

[oracle@node01 ~]$ srvctl config srvpool
Server pool name: Free
Importance: 0, Min: 0, Max: -1
Category:
Candidate server names:
Server pool name: Generic
Importance: 0, Min: 0, Max: -1
Category:
Candidate server names:
Server pool name: srvprod
Importance: 0, Min: 2, Max: 2
Category: hub
Candidate server names:
Server pool name: srvtest
Importance: 0, Min: 2, Max: 2
Category: hub
Candidate server names:

I have two nodes running in my srvprod pool and two nodes running in the srvtest pool.

An instance DB1 (prod) is running on nodes 1 and 4:

[oracle@node01 ~]$ srvctl status database -d DB1
Instance DB1_1 is running on node node01
Instance DB1_2 is running on node node04

And an instance DB2 (dev) is running on nodes 2 and 3:

[oracle@node01 ~]$ srvctl status database -d DB2
Instance DB2_1 is running on node node02
Instance DB2_2 is running on node node03

The simplest way to benefit of policies and policy sets is to create a text file with the wanted configuration. Following steps explain how to proceed.

Step 1: Create a new policy set

The crsctl tool offers an option to generate a new policy set file, based on the current active configuration. We must connect as grid:

[grid@node01 ~]$ mkdir -p /u00/app/oracle/admin/policies
[grid@node01 ~]$ crsctl create policyset -file /u00/app/oracle/admin/policies/new_policy

The file has been generated:

[grid@node01 ~]$ ll /u00/app/oracle/admin/policies
total 4
-rw-r--r-- 1 grid oinstall 305 Apr 29 16:21 new_policy

 

There is the file content:

[grid@node01 ~]$ cat /u00/app/oracle/admin/policies/new_policy
SERVER_POOL_NAMES=Free ora.srvprod ora.srvtest
POLICY
  NAME=Default
  SERVERPOOL
    NAME=ora.srvprod
    IMPORTANCE=0
    MAX_SIZE=2
    MIN_SIZE=2
    SERVER_CATEGORY=ora.hub.category
  SERVERPOOL
    NAME=ora.srvtest
    IMPORTANCE=0
    MAX_SIZE=2
    MIN_SIZE=2
    SERVER_CATEGORY=ora.hub.category

The line “NAME=Default” corresponds to the name of the policy in the policy set. The policy set itself is represented by the file “new_policy” created above.

Step 2: Update the current policy set

To update the current policy set, we just have to edit our policy set file “new_policy” and to add new policies above the Default one.

As an example, imagine we want to allocate one server more for production during the nights, and to allocate all servers to the production during week ends, to disable the development instances. We append the following policies:

POLICY
NAME=Nights
SERVERPOOL
NAME=ora.srvprod
IMPORTANCE=0
  MAX_SIZE=3
    MIN_SIZE=3
SERVER_CATEGORY=ora.hub.category
SERVERPOOL
NAME=ora.srvtest
IMPORTANCE=0
MAX_SIZE=1
    MIN_SIZE=1
SERVER_CATEGORY=ora.hub.category
POLICY
  NAME=WeekEnds
SERVERPOOL
NAME=ora.srvprod
IMPORTANCE=0
  MAX_SIZE=4
    MIN_SIZE=4
SERVER_CATEGORY=ora.hub.category
SERVERPOOL
NAME=ora.srvtest
IMPORTANCE=0
MAX_SIZE=0
    MIN_SIZE=0
SERVER_CATEGORY=ora.hub.category

Once the file is edited, it must be loaded into the policy set configuration using crsctl:

[grid@node01 ~]$ crsctl modify policyset -file /u00/app/oracle/admin/policies/new_policy

 

Step 3: Enable a new policy

Our policy set now contains three policies (Default, Nights and WeekEnds). The currently enabled policy is “Default”:

[grid@node01 ~]$ crsctl status policyset | grep -i last
LAST_ACTIVATED_POLICY=Default

We are going to enable the “Nights” policy and wee what happens. To enable a policy, use the following crsctl command as grid:

[grid@node01 ~]$ crsctl modify policyset -attr "LAST_ACTIVATED_POLICY=Nights"
CRS-2673: Attempting to stop 'ora.db2.db' on 'node02'
CRS-2677: Stop of 'ora.db2.db' on 'node02' succeeded
CRS-2672: Attempting to start 'ora.db1.db' on 'node02'
CRS-2676: Start of 'ora.db1.db' on 'node02' succeeded

In the previous output, we can see on node02 that Oracle has stopped DB2 and started DB1 instead. We can confirm with srvctl:

[grid@node01 ~]$ srvctl status srvpool
Server pool name: Free
Active servers count: 0
Server pool name: Generic
Active servers count: 0
Server pool name: srvprod
Active servers count: 3
Server pool name: srvtest
Active servers count: 1
[grid@node01 ~]$ srvctl status database -d DB1
Instance DB1_1 is running on node node01
Instance DB1_2 is running on node node04
Instance DB1_3 is running on node node02
[grid@node01 ~]$ srvctl status database -d DB2
Instance DB2_2 is running on node node03

Now I enable the “WeekEnds” policy. The remaing development server will be allocated to the production server pool, and 4 production instances will be running:

[grid@node01 ~]$ crsctl modify policyset -attr "LAST_ACTIVATED_POLICY=WeekEnds"
CRS-2673: Attempting to stop 'ora.db2.db' on 'node03'
CRS-2677: Stop of 'ora.db2.db' on 'node03' succeeded
CRS-2672: Attempting to start 'ora.DB1.db' on 'node03'
CRS-2676: Start of 'ora.DB1.db' on 'node03' succeeded

All nodes are now part of the production pool:

[grid@node01 ~]$ srvctl status srvpool
Server pool name: Free
Active servers count: 0
Server pool name: Generic
Active servers count: 0
Server pool name: srvprod
Active servers count: 4
Server pool name: srvtest
Active servers count: 0

Four production instances are opened:

[grid@node01 ~]$ srvctl status database -d DB1
Instance DB1_1 is running on node node01
Instance DB1_2 is running on node node04
Instance DB1_3 is running on node node02
Instance DB1_4 is running on node node03

And the service for development is completely down:

[grid@node01 ~]$ srvctl status database -d DB2
Database is not running.

To reset to the initial policy, just use the same command with the “Default” policy attribute:

[grid@node01 ~]$ crsctl modify policyset -attr “LAST_ACTIVATED_POLICY=Default”

Conclusion

This feature represents an easy way to configure a whole policy managed cluster at will. I have demonstrated how to edit a policy set using a text file generated using crsctl, but Oracle also documented how to manually definea policy set with command line. In my opinion, this is most fastidious and the text file is a better choice.

I only regret that Oracle has not created a way to enable policies according to the database workload, or to schedule policies over the time. Here, we must manually enable the policy or use the crontab…