Need help in scripting

Hello,

In a loop I am using below command for every database

crsctl status res | grep -E "ora\.$DATABASE\.(.+)\.svc"

and below is one of the sample output

NAME=ora.sgraphut.sgraphutxdb.svc

Now I want to extract just service name out of this string (that is sgraphutxdb) please help me how do I proceed?
Additionally,if I need to pass the node name as one of the parameters while calling this script
Let's suppose the script name is test_relocate.sh and I need to execute this like below:

test_relocate.sh -n node1

Now how do I recognize this inside the script in a loop

Best regards,
Vishal

Let us consider the node name always occur at the point.

You can add this to the end

awk -F"." '{print $(NF-1)}'

so it would look like,

looop.....
NODE=$(crsctl status res | grep -E "ora\.$DATABASE\.(.+)\.svc" | awk -F"." '{print $(NF-1)}')
echo $NODE
test_relocate.sh $NODE
......loop

Thank you.
Can you please help me understand what is NF here in $(NF-1)

crsctl status res | grep -E "ora\.$DATABASE\.(.+)\.svc" | awk -F"." '{print $(NF-1)}

Adding to this, let's suppose I also want to use $nodename in this command and its value would be fetched from the arugments when this script would be called

Assuming this script name would be status_res.sh and the user needs to use arguments nodename which would give results specific to one server

status_res.sh -n node1

Now how should I read this argument internally in the script since I would be using below command in script

crsctl status res -n nodenamw| grep -E "ora\.$DATABASE\.(.+)\.svc" | awk -F"." '{print $(NF-1)}

Best regards,
Vishal

Try using

crsctl status res -n $2| ...

, as node1 is the second parameter to the script.

status_res.sh -n node1

[LEFT][/LEFT]
Now I want to check in the code if something is next to -n, only that should be considered as nodename irrespective of the position of argument

Suggestions please.

Best regards,
Vishal

And what exactly are you trying to achieve? What's the reason for the manual service relocation?

In awk, NF is the number of fields in the current record. $(NF-1) is the last-but-one field.

Look at man getopts (posix).

When I use below code

 crsctl status res -n dev-oragrid-ux01| grep -E "ora.*.db"

below is the output

NAME=ora.cmdbut.boms10.world.svc
NAME=ora.cmdbut.boms_cmdbut_01.world.svc
NAME=ora.cmdbut.cmdbut_01.svc
NAME=ora.cmdbut.db
NAME=ora.lms_dry.db
NAME=ora.mckdwut.db
NAME=ora.miutl1ut.db
NAME=ora.p3fi_dev.db
NAME=ora.personut.db
NAME=ora.sgraphut.db
NAME=ora.sgraphut.sgraphutxdb.svc

I only need the strings ending with .db and starting with ora. but here the strings ending with .svc is also coming since I think in that cmdbut is there having db pattern

Below is the desired output

NAME=ora.cmdbut.db
NAME=ora.lms_dry.db
NAME=ora.mckdwut.db
NAME=ora.miutl1ut.db
NAME=ora.p3fi_dev.db
NAME=ora.personut.db
NAME=ora.sgraphut.db

Please help me with this.

Best regards,
Vishal

Try

grep -E "ora.*\.db$"

Not sure if you really need the -E.

for service in `crsctl status res -n $host| grep -E "ora\.$database\.(.+)\.svc" | 

In the above code I want to further extract the output skipping database name and .svc
For example,below is the output for code :

 crsctl status res -n dev-oragrid-ux01| grep -E "ora.cmdbut.(.+)\.svc"

NAME=ora.cmdbut.boms10.world.svc
NAME=ora.cmdbut.boms_cmdbut_01.world.svc
NAME=ora.cmdbut.cmdbut_01.svc

In the code $host=dev-oragrid-ux01 and $database=cmdbut
Now out of each 3 outputs I want only boms10.world , boms_cmdbut_01.world and cmdbut_01 which means that I want to extract string whihc is after $database and before .svc

Please advise me how can I do this?

Best regards,
Vishal

Try

grep -E "ora\.$database\.(boms10.world|boms_cmdbut_01.world|cmdbut_01)\.svc" |

Hi,

This was just one sample example boms10.world|boms_cmdbut_01.world|cmdbut_01 and I can't use hardcoded values
but I want to use this generically in a for loop like below:

for database in `crsctl status res -n $host| grep -E "ora.*\.db" | awk -F"." '{print $(NF-1)}'`
do
{
for service in `crsctl status res -n $host| grep -E "ora\.$database\.(.+)\.svc" | awk -F"." '{print $(NF-1)}'`
do
{
echo "Checking service $service on Database $database"
}
done
}
done

I am not getting accurate results from nested(second) for loop.

.svc" | awk -F"." '{print $(NF-1)}'

Instead of awk -F"." '{print $(NF-1)}' ,I want to use a code which extracts the string after the database name till .svc and skipping .svc which would give me just the service name which is desired.

Best regards,
Vishal

Instead of

grep -E "ora\.$database\.(.+)\.svc" | awk -F"." '{print $(NF-1)}'`

use

awk -F"." -vDB=$database 'match ($0, "ora\."DB"\..*\.svc) {sub ("^.*\."DB"\.",""); sub (/\.svc$/,"");print}'

You may try something like this:

srvctl config database | 
  while read _db; do
    srvctl status service  -d "$_db"
  done

I'm not sure what's the format of the output of srvctl config database when multiple databases are configured
(if the list is newline or comma separated), I don't have an access to such a RAC right now.
If the above doesn't work, please post the output of: srvctl config database .

You could of course configure Database/Grid Control to automate this type of monitoring.

Hello,

srvctl config database -d db_name

The above command gives the configuration information for a specific database.
My goal is:

  1. Retrieve database name on the $host from the list one by one for which I am using below code
for database in `crsctl status res -n $host| grep -E "ora.*\.db" | awk -F"." '{print $(NF-1)}'`

2.Check if service is running on preferred or available instance of the database.
Below example:

srvctl status service -d ksr

Service knuggets_ksr.world is running on instance(s) ksr_01
Service ksadmin_ksr.world is running on instance(s) ksr_01

srvctl config service -d ksr -s knuggets_ksr.world

Service name: knuggets_ksr.world
Service is enabled
Server pool: ksr_knuggets_ksr.world
Preferred instances: ksr_01
Available instances: ksr_02

From first command I get to know both the services are running on ksr_01 instance of the database.

From second command I get to know ksr_01 is the preffered instance of this service.

  1. Check if the preferred instance is running on the $host or not.($host is the argument passed in the script)
srvctl status database -d ksr

ksr_01 is running on node1
ksr_02 is running on node 2

5.Depending on another argument which would be passed while running the script whether the service to be relocated to available or preferred instance I will use flag

./relocate.sh -n node1 -t preferred

This would mean that all the services which are running on available instances for those databases hosted on node 1 should be relocated to preferred instance if the preferred instance is on node 1 for that service.

This is a cluster envrionment and multiple instances run on different nodes for the same database.

  1. Relocate the service
srvctl relocate service -d $database -i <current node> -t <target node $node1> -s <$service>

Best regards,
Vishal

Please post the output of srvctl config database , don't add -d database ! What's the Oracle version?

Check this script from Ilmar Kerm.
You're aware that the service relocation will cause a possibly short outage, aren't you?

Please refer to the below output

srvctl config database
alfresut
clientut
cmdbut
cpaut
engut
ksrut
lms_dry
mckstgut
miutl2ut
orsut
orsut9fm
personut
sgraphut
timextut
miutl1ut
p3fi_dev
mhidwut
mckdwut
mckdwst

This has both 10g and 11g databases.

Best regards,
Vishal

Thanks! As I said, you don't need to use crsctl ... | grep ... to get the names of the databases resources, srvctl config database is sufficient.
You could use a callout script like the one, I mentioned above. Or you still want to write your own script?

But I want to relocate services fro a specific node maintenance activity.During maintenance of one node I want to write a script that whatever services are running on preferred instances on node 1 they be relocated to their available instances.

Appreciate your help.

Best regards,
Vishal

Why do you think you need a script for that? It happens automatically when you bring the resources or the node down ...
If I understand correctly, all you need is a simple crsctl stop cluster on the node that needs maintenance.