Database Administrators running databases on Linux spend a vast majority of their time in the command line interface. Changing environment settings, moving through directories, typing out and executing lengthy commands, and manipulating files requires valuable keystrokes and time. The rule of thumb for an efficient DBA should be that any command executed more than once per day should be reduced to four characters or less. This presentation reviews techniques to dramatically reduce the amount of time Database Administrators spend typing commands by using shell features and scripting to do the work for them.
4. How Much Time?
• Do you back up your important files?
• How long does it take to log into a server?
• How many times do you log into a server each day?
• How long and complicated is your password?
• Do you use the same password for each server?
• Do you need to put in a password when you switch users on a
server?
• How do you change environment settings for different databases?
• How do you change environment settings for different oracle
homes?
• Does your shell prompt offer enough information?
• Does your sqlplus prompt offer enough information?
• How often do you check for running instances on the server?
• How often do you check Clusterware resources?
• How efficient are you?
5. Workstation Backup
xcopy source [destination] [/Y] [/W] [/D:date] [/C] [/S] [/E] [/V] ...
source Specifies the file to copy.
destination Specifies the location and the name of new files.
/C Continues copying even if errors occur.
/H Copies hidden and system files also.
/D:date Copies files changed on or after the specified date.
Copies directories and subdirectories except empty
/S
ones.
Suppresses prompting to confirm you want to overwrite
/Y
an existing destination file.
/E Copies any subfolder, even if it is empty.
/V Verifies each new file.
/W Prompts you to press a key before copying.
10. Shared Key Authentication
• Makes password authentication not necessary
• Usually precedes password authentication
• Used by RAC for communication between nodes
[oracle@server1 ~]$ ssh -v server2
OpenSSH_4.3p2, OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008
...
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Trying private key: /home/oracle/.ssh/identity
debug1: Offering public key: /home/oracle/.ssh/id_rsa
debug1: Authentication succeeded (publickey).
...
[oracle@server2 ~]$
• Enabled in SSHD by default
[root@server1 ~]# cat /etc/ssh/sshd_config | grep Pubkey
#PubkeyAuthentication yes
11. Shared Key Authentication
• Create keys on Windows with Putty Key Generator
• Can optionally use a passphrase
• The use of a passphrase is for additional security
• Counterproductive to eliminating keystrokes
• Can use different algorithms
• Public key is displayed for copy/paste
• Private key needs to be secure
12. Shared Key Authentication
• Host keys on Windows with Pageant
• Run in the background
• Start with Windows startup
• Load private key into Pageant
13. Shared Key Authentication
• Authorized_keys file on server
[root@server1 ~]# cat /etc/ssh/sshd_config | grep #AuthorizedKeysFile
#AuthorizedKeysFile .ssh/authorized_keys
• Permissions need to be set properly
[smiller@server1 ~]$ chmod 700 ~/.ssh
[smiller@server1 ~]$ ls -ld ~/.ssh
drwx------ smiller smiller /home/smiller/.ssh
[smiller@server1 ~]$ chmod 600 ~/.ssh/authorized_keys
[smiller@server1 ~]$ ls -ld ~/.ssh/authorized_keys
-rw------- smiller smiller /home/smiller/.ssh/authorized_keys
• Append the public key to the authorized_keys file
[smiller@server1 ~]$ cat /home/smiller/.ssh/authorized_keys
ssh-rsa
AAAAB3NzaC1yc2EAAAABJQAAAIG2QRU8oQ0Rp7LuMre9Vaxjt7mL50xsADMUAXuBPOlXxjeJVPbjYO+0EjUo116gXWMc74Qa
9iA1O8+3EoQOgjttsYjVMgYmposqltdBz3LG7EDqKfiV+73CABgrayZxo2WaBIZF3c5448gtQp6JC6HElEZFnX9xCuL43y9t
ovUicw==
14. Shared Key Authentication
• Generate a public/private key pair
[smiller@server1 ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/smiller/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in (/home/smiller/.ssh/id_rsa.
Your public key has been saved in (/home/smiller/.ssh/id_rsa.pub.
The key fingerprint is:
f5:2e:c1:bf:ed:75:27:6f:50:a2:6a:17:a7:94:e5:e7 smiller@server1
[smiller@server1 ~]$ cp /home/smiller/.ssh/id_rsa.pub /tmp
[smiller@server1 ~]$ su - oracle
Password:
[oracle@server1 ~]$ cat /tmp/id_rsa.pub >> ~/.ssh/authorized_keys
[oracle@server1 ~]$ exit
[smiller@server1 ~]$ alias suo='ssh oracle@localhost'
[smiller@server1 ~]$ suo
[oracle@server1 ~]$
16. My User's Profile Script
function ora (From oracle's .bash_profile script)
{ if [ $( cat /home/smiller/fromsmiller ) -eq 1 ];
echo 1 > ~/fromsmiller then
chmod go+rw ~/fromsmiller . /home/smiller/oracleprofile
sudo /bin/su - oracle echo 0 > /home/smiller/fromsmiller
} fi
if [ $(hostname -s) = "usa-server1" -o $(hostname -s) = "usa-server2" ]; then
ora
fi
ENVFILE=~/$(hostname -s).env
[ ! -f $ENVFILE ] && touch $ENVFILE && chmod 764 $ENVFILE
17. Shared Oracle User
• sudo su - oracle
• Environment settings are not transferred with sudo by default
• Source a file as the Oracle user
source <file>
OR
. <file>
• Automate the sourcing of the file by modifying Oracle's .bash_profile
if [ $( cat /home/smiller/fromsmiller ) -eq 1 ]; then
source /home/smiller/oracleprofile
echo 0 > /home/smiller/fromsmiller
fi
19. Server Environment File (RAC)
You have not set a default ORACLE_HOME. Would you like to do so now?
y
1) /u01/app/crs
2) /u01/app/oracle/product/asm/11.1
3) /u01/app/oracle/product/db/11.1
4) /u01/app/oracle/product/agent12c
5) /u01/app/oracle/product/agent12c/core/12.1.0.1.0
6) /u01/app/oracle/product/agent12c/sbin
7) /u01/app/oracle/product/db/10.2
8) NA
9) Manual Input
Please select the ORACLE_HOME you would like to use as your default
ORACLE_HOME: 3
20. Server Environment File (RAC)
You have not set a default CRS/GRID_HOME. Would you like to do so now?
y
1) /u01/app/crs
2) /u01/app/oracle/product/asm/11.1
3) /u01/app/oracle/product/db/11.1
4) /u01/app/oracle/product/agent12c
5) /u01/app/oracle/product/agent12c/core/12.1.0.1.0
6) /u01/app/oracle/product/agent12c/sbin
7) /u01/app/oracle/product/db/10.2
8) NA
9) Manual Input
Please select the CRS/GRID_HOME: 1
21. Server Environment File (RAC)
You have not set a default ASM_HOME. Would you like to do so now?
y
1) /u01/app/crs
2) /u01/app/oracle/product/asm/11.1
3) /u01/app/oracle/product/db/11.1
4) /u01/app/oracle/product/agent12c
5) /u01/app/oracle/product/agent12c/core/12.1.0.1.0
6) /u01/app/oracle/product/agent12c/sbin
7) /u01/app/oracle/product/db/10.2
8) NA
9) Manual Input
Please select the ASM_HOME: 2
22. Server Environment File (RAC)
You have not set a default AGENT_HOME. Would you like to do so now?
y
1) /u01/app/crs
2) /u01/app/oracle/product/asm/11.1
3) /u01/app/oracle/product/db/11.1
4) /u01/app/oracle/product/agent12c
5) /u01/app/oracle/product/agent12c/core/12.1.0.1.0
6) /u01/app/oracle/product/agent12c/sbin
7) /u01/app/oracle/product/db/10.2
8) NA
9) Manual Input
Please select the AGENT_HOME: 4
23. Server Environment File (RAC)
You have not set a default RAC_NODE. Would you like to do so now?
y
Please enter the RAC_NODE (NA for none):
1
You have not set a default ORACLE_BASE. Would you like to do so now?
y
Please enter the ORACLE_BASE (NA for none):
/u01/app/oracle
25. Server Environment File (Non-RAC)
You have not set a default ORACLE_HOME. Would you like to do so now?
y
1) /opt/app/oracle/product/10.2.0.4/db_1
2) /opt/app/oracle/product/agent10g
3) /opt/app/oracle/product/10.2.0/db_1
4) NA
5) Manual Input
Please select the ORACLE_HOME you would like to use as your default ORACLE_HOME: 3
26. Server Environment File (Non-RAC)
You have not set a default CRS/GRID_HOME. Would you like to do so now?
y
1) /opt/app/oracle/product/10.2.0.4/db_1
2) /opt/app/oracle/product/agent10g
3) /opt/app/oracle/product/10.2.0/db_1
4) NA
5) Manual Input
Please select the CRS/GRID_HOME: NA
27. Server Environment File (Non-RAC)
You have not set a default ASM_HOME. Would you like to do so now?
y
1) /opt/app/oracle/product/10.2.0.4/db_1
2) /opt/app/oracle/product/agent10g
3) /opt/app/oracle/product/10.2.0/db_1
4) NA
5) Manual Input
Please select the ASM_HOME: NA
28. Server Environment File (Non-RAC)
You have not set a default AGENT_HOME. Would you like to do so now?
y
1) /opt/app/oracle/product/10.2.0.4/db_1
2) /opt/app/oracle/product/agent10g
3) /opt/app/oracle/product/10.2.0/db_1
4) NA
5) Manual Input
Please select the AGENT_HOME: 2
29. Server Environment File (Non-RAC)
You have not set a default RAC_NODE. Would you like to do so now?
y
Please enter the RAC_NODE (NA for none):
NA
You have not set a default ORACLE_BASE. Would you like to do so now?
y
Please enter the ORACLE_BASE (NA for none):
/opt/app/oracle
41. Crsstat
ora.ORCL.ORCL1.inst OFFLINE OFFLINE
ora.ORCL.ORCL2.inst OFFLINE OFFLINE
ora.ORCL.db OFFLINE OFFLINE
ora.usa-server1.ASM1.asm ONLINE ONLINE on usa-server1
ora.usa-server1.LISTENER_USA-SERVER1.lsnr ONLINE ONLINE on usa-server1
ora.usa-server1.gsd ONLINE ONLINE on usa-server1
ora.usa-server1.ons ONLINE ONLINE on usa-server1
ora.usa-server1.vip ONLINE ONLINE on usa-server1
ora.usa-server2.ASM2.asm ONLINE ONLINE on usa-server2
ora.usa-server2.LISTENER_USA-SERVER2.lsnr ONLINE ONLINE on usa-server2
ora.usa-server2.gsd ONLINE ONLINE on usa-server2
ora.usa-server2.ons ONLINE ONLINE on usa-server2
ora.usa-server2.vip ONLINE ONLINE on usa-server2
42. Watch
watch crsstat
Every 2.0s: crsstat ORCL Sun Sep 9 02:37:00 2012
HA Resource Target State
----------- ------ -----
ora.ORCL.ORCL1.inst OFFLINE OFFLINE
ora.ORCL.ORCL2.inst OFFLINE OFFLINE
ora.ORCL.db OFFLINE OFFLINE
43. Multi-line crs_stat (crsm)
Target Target Target
HA Resource |State/Location HA Resource |State/Location HA Resource |State/Location
----------- ||-------------- ----------- ||-------------- ----------- ||--------------
ORCLA.ORCLA1.inst XX usa-server1 ORCLG.db -- ORCLV.ORCLV1.inst --
ORCLA.ORCLA1.inst -- ORCLH.ORCLH1.inst -- ORCLV.db XX usa-server1
ORCLA.orclaha.sjm.com.ORCLA1.s XX usa-server1 ORCLH.ORCLH1.inst -- ORCLW.ORCLW1.inst XX usa-server1
ORCLA.orclaha.sjm.com.cs XX usa-server1 ORCLH.db -- ORCLW.ORCLW1.inst --
ORCLA.db XX usa-server1 ORCLI.ORCLI1.inst -- ORCLW.db XX usa-server1
ORCLB.ORCLB1.inst XX usa-server1 ORCLI.ORCLI1.inst -- ORCLW.orclwha.sjm.com.ORCLW1.s XX usa-server1
ORCLB.ORCLB1.inst -- ORCLI.db -- ORCLW.orclwha.sjm.com.cs XX usa-server1
ORCLB.orclbha.sjm.com.ORCLB1.s XX usa-server1 ORCLJ.ORCLJ1.inst -- ORCLX.ORCLX1.inst XX usa-server1
ORCLB.orclbha.sjm.com.cs XX usa-server1 ORCLJ.ORCLJ1.inst -- ORCLX.ORCLX1.inst --
ORCLB.db XX usa-server1 ORCLJ.db -- ORCLX.db XX usa-server1
ORCLC.ORCLC1.inst XX usa-server1 ORCLK.ORCLK1.inst -- ORCLY.ORCLY1.inst XX usa-server1
ORCLC.ORCLC1.inst -- ORCLK.ORCLK1.inst -- ORCLY.ORCLY1.inst --
ORCLC.orclcha.sjm.com.ORCLC1.s XX usa-server1 ORCLK.db -- ORCLY.db XX usa-server1
ORCLC.orclcha.sjm.com.cs XX usa-server1 ORCLL.ORCLL1.inst -- ORCLY.orclyha.sjm.com.ORCLY1.s XX usa-server1
ORCLC.db XX usa-server1 ORCLL.ORCLL1.inst -- ORCLY.orclyha.sjm.com.cs XX usa-server1
ORCLD.ORCLD1.inst -- ORCLL.db -- ORCLZ.ORCLZ1.inst XX usa-server1
ORCLD.ORCLD1.inst -- ORCLM.ORCLM1.inst -- ORCLZ.ORCLZ1.inst --
ORCLD.orcldha.sjm.com.ORCLD1.s -- ORCLM.ORCLM1.inst -- ORCLZ.db XX usa-server1
ORCLD.orcldha.sjm.com.cs -- ORCLM.db -- ORCLZZ.ORCLZZ1.inst --
ORCLD.db -- ORCLN.ORCLN1.inst -- ORCLZZ.ORCLZZ1.inst --
ORCLE.ORCLE1.inst XX usa-server1 ORCLN.ORCLN1.inst -- ORCLZZ.db --
ORCLE.ORCLE1.inst -- ORCLN.db -- usa-server1.ASM1.asm XX usa-server1
ORCLE.orcleha.sjm.com.ORCLE1.s XX usa-server1 ORCLO.ORCLO1.inst -- usa-server1.LISTENER_USA-SERVER XX usa-server1
ORCLE.orcleha.sjm.com.cs XX usa-server1 ORCLO.ORCLO1.inst -- usa-server1.gsd XX usa-server1
ORCLE.db XX usa-server1 ORCLO.db -- usa-server1.ons XX usa-server1
ORCLF.ORCLF1.inst XX usa-server1 ORCLP.ORCLP1.inst -- usa-server1.vip XX usa-server1
ORCLF.ORCLF1.inst -- ORCLP.ORCLP1.inst -- usa-server2.ASM2.asm --
ORCLF.orclfha.sjm.com.ORCLF1.s XX usa-server1 ORCLP.db -- usa-server2.LISTENER_USA-SERVER X-
ORCLF.orclfha.sjm.com.cs XX usa-server1 ORCLQ.ORCLQ1.inst XX usa-server1 usa-server2.gsd X-
ORCLF.db XX usa-server1 ORCLQ.ORCLQ1.inst -- usa-server2.ons X-
ORCLG.ORCLG1.inst -- ORCLQ.db XX usa-server1 usa-server2.vip XX usa-server1
ORCLG.ORCLG1.inst -- ORCLV.ORCLV1.inst XX usa-server1
44. Rlwrap
• Gives capability to re-execute commands in sqlplus,
asmcmd and rman
• Command history program similar to bash’s history package
• Installable as RPM or compile from source
• Gives similar behavior to sqlplus in Windows
• Will run in Cygwin
• Very robust, but simple arrow up gives last command
executed
• http://sysdba.wordpress.com/2006/10/08/how-to-use-rlwrap-to-get-a-command-history-in-sqlplus/
• http://goo.gl/EfGOl
• http://utopia.knoware.nl/~hlub/rlwrap/#rlwrap
• http://goo.gl/YdJN5
45. Login.sql
SET SQLPROMPT "_USER'@'_CONNECT_IDENTIFIER > "
set linesize 140
set pagesize 100
DEFINE _EDITOR=vi
SQLPATH=/home/smiller/scripts
SYS@ORCL1 >
46. Upload Script
cpk.bat "usa-server1 usa-server2"
@echo off OR
cpk.bat
set FILESPATH=C:UserssmillerPutty
set TRANSFERSCRIPTS=%FILESPATH%transferscripts
set TRANSFERPATH=%FILESPATH%transfer
set PSCP_USER=smiller
set TARGET=%1
IF (%1)==() set usa-server1 usa-server2 usa-server3 usa-server4
for %%I in ( %TARGET% ) do (
echo.
echo Transferring files to %%I
echo.
%FILESPATH%plink.exe %PSCP_USER%@%%I "mkdir -p ~/scripts"
%FILESPATH%pscp.exe %TRANSFERPATH%* %PSCP_USER%@%%I:
%FILESPATH%pscp.exe %TRANSFERSCRIPTS%* %PSCP_USER%@%%I:scripts/
%FILESPATH%plink.exe %PSCP_USER%@%%I "dos2unix ~/oracleprofile; dos2unix ~/sharedcode; dos2unix
~/setoraclebash; dos2unix ~/scripts/*; chmod 755 ~/scripts/*; chmod 775 ~/setenvs.sh;"
echo. )
Time is the great equalizer.There is always a faster way of doing things.I created this presentation because I am always struggling for time.Try to make repeatable tasks take less keystrokes or none at all.
Backup is one of the most basic things and it continues to surprise me how many professionals don't bother to do it or do it in a way that doesn't help them when their laptop or desktop becomes unavailable.A simple file backup will give you 95% of your functionality back on your rebuilt machine or a brand new one. Windows' xcopy command is relatively robust and works very well for a file backup. Some of the switches available for the xcopy command are listed here.
This is the backup batch file I use to backup all of the files I need from my laptop. Other than the programs I use, there is nothing else on my laptop that I would need if it died today. If I do come across another file or directory that needs to be backed up, I simply add it to script.I first mount a network share to a blank drive letter to use as a destination.I try to use as many environment variables as possible to make the script highly portable.Finally, I unmount the network share.This script runs from a task everyday while I am at lunch. Since it is only copying new or modified files and most of the files I am copying are text files, it generally takes less than 30 seconds to run. Well worth it when (not if) your hard drive dies.
I have a couple of different command window profile scripts for different purposes. This is one I use for my sqlplus sessions that connect to the Oracle RDBMS running on my laptop.First I set my environment variables that I will be using.Secondly I set shortcut commands, similar to what I would use alias or function for on Linux.
Most DBA's use Putty or a similar SSH client on their Windows PC or MAC. Putty is highly customizable but a little Windows setup can make pulling up a Putty session extremely quick and efficient.Create a directory specifically for shortcuts on your machine and include it in your path. All of the shortcuts you will create should live in this directory so they will all be backed up, in the default path and in one place.Instead of bringing up the Putty window and loading a saved session with your mouse, create batch files for each frequently accessed server and place them in the shortcuts folder. The batch file for each server should be four letters or less not including the .bat extension. Each batch file will utilize wscript with a parameter file and an embedded batch file.The openputty.bat with the Putty saved session name as an argument creates the putty session with all of the settings saved with that session.Invis.vbs runs the openputty.bat batch file completely hidden from the screen. Without the vbs script, a separate command line window would be present behind the putty session for the duration of the session.Each subsequent putty session batch file would have the same information except for the name and the session variable.Use Windows R to open a Run window and type the batch file name without the .bat extension to open the putty session.Change server1 to s1
Use the auto-login feature of Putty if you usually login with the same username.
Considering how complex passwords need to be by most companies standards and how many times a day you need to type them, shared key authentication can be a huge time saver.Shared key authentications makes typing a complex password unnecessary.Shared key authentication usually comes before password authentication in the list of default methods of authentication, therefore eliminating the need to put in a password without making complex changes to the server SSH configuration.This is the method that Oracle RAC uses to move files and execute commands between RAC nodes.Public key authentication as it is also known is enabled by default for all users in Linux and needs to be explicitly disabled by the administrator if they choose not to use it.
In order to avoid putting in a password every time you log into a server from your local workstation, shared key authentication can be used..The key pair that will be used will need to be generated in some way. The creators of Putty have tools that can be used in Windows. Putty Key Generator can be used to generate a private/public key pair.A passphrase can be used but is primarily for additional security and doesn't make sense when trying to reduce keystrokes.The parameters in the program indicate how strong the encryption of the key will be.Once the key is generated, the public half of the pair is displayed so it can be directly copied to the servers.Save the private key to a secure folder on your workstation by pressing the "Save private key" button. This will be used later.
The creators of Putty also created a program called Pageant that runs on Windows to host private keys for shared key authentication.Pageant will run as a background process and can be loaded automatically at Windows startup by adding it to the startup folder.Once it is running, right click on the hat wearing computer in the system icons and choose "Add Key". Find the private key that was saved from the Putty Key Generator.Once it is chosen, they key will show up in the Pageant Key List and will stay there across reboots until it is removed.I haven't used my password to login into a server in almost six months using this method.
There are a couple of things to check on the server as well for shared key authentication.The authorized keys file on the server will by default be .ssh/authorized_keys but can be changed in the config file. Check this first because this is often changed for security.The permissions on the .ssh directory in your user's home directory and the authorized_keys file itself have to be set to a maximum permissions level or shared key authentication will not work.Set the .ssh directory to read, write, execute for the owner only and set the authorized_keys file to read and write only for the owner.Append the public key generated from Putty Keygen to the authorized_keys files of any server on which you want to use the shared key authentication.
In the case that traditional passwords are used between your user and the oracle user on the server, shared key authentication can also be used.Generate a public/private key pair using the ssh-keygen command.Add the generated public key to oracle's authorized_keys file.Create an alias for the command to ssh to the same server as the oracle user.
The three most common Linux login shells are the Bourne Again Shell, C Shell and Korn Shell, of which the Bourne Again Shell, or Bash, is the default and most common.The scripts executed on login are determined by the shell being used. Check these files when troubleshooting why something is happening or not happening when you log into a server.When logging into a Linux server, the shell that will be used is determined normally by the /etc/passwd file, but it can also come from an ldap query. Both examples here show that my login shell will be bash.
These are the additions I have made to my user's default .bash_profile. I generally put as little functionality in here as possible since the permissions on the file should only allow my user to see it.The oracle function is what makes my oracle session when I su to it unique from any other user that su's to oracle. The function echos a 1 into the fromsmiller file, changes the permissions so the oracle user can read and write to it and does an su to oracle.As part of the oracle user's profile script, it will read the fromsmiller file, find the 1, source my main profile script and reset the fromsmiller file so I don't affect other users' oracle sessions by echoing a 0 into the file. When someone else su's to oracle, the oracle shell will again check the fromsmiller file, but because it is set to 0, their environment will not be affected.The if statement is qualified with the test that says if the server I am on is usa-server1 or usa-server2, execute the oracle function, which means when I log into those two servers, I will be at the command prompt as the oracle user. I use this for most servers since 95% of the time, I su to the oracle user right away when I login anyhow.The "ENVFILE" is an environment file that is unique to each server. Hostname -s will expand to the server name without the domain with a .env extension. It will live in my home directory on that server. The test says that if the environment file does not exist, create it and give it read/write/execute for me, read/write for the group and read for others. The permissions are necessary because the oracle user will be modifying this file.
You will either have access to the Oracle binaries with your login user or you will use something like sudo to switch to a shared oracle user.If it is necessary to use sudo to su to oracle, it is important to remember that most environment settings including variables are not transferred to the new session by default. The scripting was written so it doesn't matter whether using sudo is necessary or not. With difficulty some environment settings can be transferred with sudoers.The better option is to source a file once you have already switched to the new user. This way you are not limited to just carrying over environment variables, you can also create functions, aliases and other functionality.The code here is what was referenced in the previous slide to automatically source a file and should be added to oracle's .bash_profile. It will not affect other users' oracle shell.
The server environment file can have any variables you will want set when you log in but should be limited to those that need to be unique to the server.All environment variables in this file will be set and exported but more importantly, some of them are critical for the functionality of other scripts.
There is a check in the main script that is sourced when su'ing to the oracle users that checks if any of the variables in the environment file for the server you are logged into are blank. If they are a script will run prompting you to populate them. Keep in mind that that script will need to be modified if any customizations are made to the variables script.The first question shown here is for the DEFAULT_ORACLE_HOME variable. Since it was blank when I logged in, I am being asked if I want to set it.The list for the various oracle paths in the slides to follow comes from an xlm parsing command running against the oracle inventory xml file on the server. The list shows all of the oracle homes listed in that inventory file and will set the DEFAULT_ORACLE_HOME variable to the one chosen.Once these variables are populated, you will not be asked again unless something changes with the environment file.
If you don't want to set a variable, for example, if this server is single node and does not run Clusterware, then you would choose number 8. Any variables in the variable file with the value of NA will be set to null.
The same would apply here if ASM was not being used.
Here, you would choose the agent home if you are running Grid Control in your environment and this server is running a Grid agent.
The final two questions are manual input since a list of values doesn't make sense.If the previous questions did not have an appropriate choice listed in the "List of Values", there is also an option for manual input.
Once populated, the environment variable file would look something like this for a RAC server.
This is an example of a single node server without ASM. There are only three oracle homes listed in the inventory file.
Since there is no Clusterware installed, option 4 is chosen for NA.
ASM does not exist so NA is chosen again.
An agent happens to be installed on this server.
RAC_NODE is set to NA.
This is an example of a single node server environment file. Many of the variables are set to NA.
The oracleprofile script is the main script that is sourced when su'ing to the oracle user.It starts out checking and populating if necessary the environment variables script that we just reviewed. The setenvs.sh script is the script used to perform the tasks we just went through with the previous dozen or so slides. It is always executed and will only prompt for the previous questions when a variable in the environment variable file is blank.The for loop either exports the variable as blank if it is populated with NA or exports the variable as it is in the file.The some basic exports are made for the session. Not all of the variables are exported as some of them are used for the rest of the script.
The next few slides are pieces of the oracleprofile script broken down according to their functionality.The prompt can serve any number of purposes and can be as simple or complicated as you choose.PS1 is a reserved environment variable and will determine prompt of your shell. This function is executed a number of times, including every time the "Instance Chooser" is used as we'll see coming up in another slide. It can also be invoked manually.PS1 accepts two arguments; the ORACLE_HOME and the ORACLE_SID. The prompt will be updated with these values every time the function is called.
The most common way most people check a Linux server to see what instances are running on it is with the command "ps -ef | greppmon or smon". That command is way too many characters and doesn't give enough information. The only thing you know from this output is that ASM and a number of other instances are running on this server.
What if you modified that basic command a bit to parse the output so you only see the column with the necessary information.
You know that +ASM1 is an asm instance and the others are database instances so strip that prefix away. Get rid of the grep process in the output and sort the instances alphabetically.
Taking the parsed output of the ps command and some further scripting, this output is displayed to tell me not only the instances that are running, but out of what oracle home each one is running. Since many of my servers have multiple listeners, all of the listeners are also listed with their oracle homes as well.
Plis another function like ps1 and is not as complicated as it looks.The first four lines are a local variable declaration and the header for the instances.The "for" loop runs the ps command leaving an alphabetically sorted list of the running instances.The running instance is stripped of its RAC_NODE suffix and then attempts to match an entry in /etc/oratab to the left of the first colon. If a match is found, the value found to the right of the first colon is assigned to VAR.Because the asm entry in /etc/oratab usually includes the node suffix, this line of code was added. If the first four characters of the running instance is +ASM, then find the entry in /etc/oratab for the running instance without stripping the RAC_NODE suffix and assign the value found to the right of the first colon to VAR.If VAR is blank because an /etc/oratab entry could not be found for the running instance, set VAR to NA.Print the running instance and its oracle home.Print the header for the listeners.Print the running listeners and their oracle home.
The db function is the primary reason I started creating these function because using oraenv or setting environment variables on each server was tedious and typing oraenv and the oracle sid goes way beyond my four character limit.The functionality of db is quite simple. Typing "db" gives you a menu like the one above, hopefully with less options.The list is taken from /etc/oratab. Note option 25 gives the option to manually enter an oracle sid and an oracle home in case the oracle sid you are looking for is not in the /etc/oratab.The db function will utilize the ps1 function from earlier to reset the prompt with the options that you chose.The code for this function is similar to that of the pl function and is included in the notes to this slide deck.function db {PS3=$'\\n''What would you like to set your ORACLE_SID parameter to? 'echoselect VAR in $( egrep '^[^#*]*:' /etc/oratab | cut -d ':' -f 1 | grep -v '+ASM' | sort ) "Manual Input"; do case $VAR in "Manual Input") echo echo "Type in your SID" read VAR2 export ORACLE_SID=$VAR2 break ;; *) export ORACLE_SID=$VAR$RAC_NODE break ;;esacdoneSIDTAB=$( egrep "^$( echo ${ORACLE_SID%$RAC_NODE} ):" /etc/oratab | cut -d ':' -f 2 )export ORACLE_HOME=$SIDTABexport ORACLE_BASEexport PATH=$CRSHOME/bin:$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$SCRIPTS:$DEFPATHps1 $ORACLE_HOME $ORACLE_SID}
Besides setting environment variables for instances on the server, there are three other functions that set specific environment variables.asm will set the oracle home, sid and path for asm as well as reset the prompt.crs will set the oracle home and path for crs or grid depending on your version. It executes ps1 to show the oracle home and a custom value for the oracle sid.agt will also set the oracle home and path with a custom value for the oracle sid for the grid agent.Again, the code for these is simple and self-explanatory and is included in the notes of this slide.function asm{ export ORACLE_HOME=$ASM_HOME export PATH=$CRSHOME/bin:$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$SCRIPTS:$DEFPATH export ORACLE_SID=$( grep "^+ASM" /etc/oratab | cut -d ":" -f 1 ) ps1 $ORACLE_HOME $ORACLE_SID}function crs{ export ORACLE_HOME=$CRSHOME export PATH=$CRSHOME/bin:$CRSHOME/OPatch:$SCRIPTS:$DEFPATH ps1 $ORACLE_HOME 'crs/grid'}function agt{ export ORACLE_HOME=$AGENT_HOME export PATH=$CRSHOME/bin:$ORACLE_HOME/agent_inst/bin:$ORACLE_HOME/OPatch:$SCRIPTS:$DEFPATHps1 $ORACLE_HOME agent}
You should be familiar with this command and its output if you manage a RAC cluster. It is important to understand where to find the right information when managing RAC and crs_stat is a very valuable tool for that.Crs_stat is obsolete in 11.2 and I will develop a similar script for the similar output of crsctl.
If you are familiar with crs_stat, you probably know about crsstat. crsstat is an Awk script written to parse and simplify the output of crs_stat.I personally like using crsstat with a built-in Linux command called watch.
If you are familiar with crs_stat, you probably know about crsstat. crsstat is an Awk script written to parse and simplify the output of crs_stat.I personally like using crsstat with a built-in Linux command called watch. Watch allows you to run a command in a loop while showing the output in a constant state. It would be the same as if I ran crsstat OPDEV every two seconds to monitor the status of the database and its instances.However, with my DEV cluster that contains over 40 databases, it is impossible to keep all of the output from crsstat on one page and watch just truncates what can't fit on your screen.
It is for this reason that I created the multiline crsstat, or crsm.I stuck with Awk as the parsing language for the crs_stat output and used some shortcuts like boolean values for State and Location to save characters on the page.The script is written to display all of the resources or a subset of the resources from crs_stat in a three column fixed width format.Even with 42 databases and over 100 resources, I can fit everything onto one screen so I can run it in watch and monitor every resource on the cluster.#!/bin/sh# Crsstatm (multi-line)# Created by Seth Miller 2012/06/15# Version 1.1# This is a modification of the "crsstat" script widely used to interpret Oracle Clusterware# "crs_stat" output. This version is written specifically for Oracle Database 11.1 and has# not yet been tested on any other versions. It displays the crs_stat output in a three column format.# Summary of output# The "ora." is truncated from the resource name # The target of the resource will be "X" if it is "ONLINE" and "-" if it is "OFFLINE"# The state of the resource will be "X <node name>" if it is "ONLINE on <node name>"# and "-" if it is "OFFLINE"# An example of the output would be: # ORCL.ORCL1.inst XX server1# This should be interpreted as:# Instance ORCL1 of database ORCL is targeted to be ONLINE and is in an online state on node server1# Clusterware home directoryORA_CRS_HOME=/u01/app/crsCRSSTATBIN=$ORA_CRS_HOME/bin/crs_statAWK=/usr/bin/awkLD_LIBRARY_PATH=$ORA_CRS_HOME/lib# Command line argument to limit outputRSC_KEY=$1QSTAT=-u$CRSSTATBIN $QSTAT | $AWK \\'# Table header# Start of the BEGIN block BEGIN { # Print the headerprintf "%1$36s%1$53s%1$53s\\n", "Target"printf "%1$11s%2$22s%3$-20s%1$11s%2$22s%3$-20s%1$11s%2$22s%3$-20s\\n", "HA Resource", "|", "State/Location"printf "%1$11s%2$22s%3$-20s%1$11s%2$22s%3$-20s%1$11s%2$22s%3$-20s\\n", "-----------", "|", "|--------------"# Table body FS="="; PROCSTATE = 0; NUMLINES = 0 }# End of BEGIN block# Line Processing block # If the first word of the line contains NAME and the second word contains the value of $RSC_KEY then $1~/NAME/ && $2~/'$RSC_KEY'/ { # truncate "ora." from the front of the resource name sub(/ora./,"",$2) # assign resource name to the "APPNAME" variable APPNAME = $2 # set PROCSTATE equal to 1 signifying a block has begun and the next line should be the resource target PROCSTATE=1 # increment the NUMLINES variable by 1 NUMLINES++ } # If the previous line processed was the name of the resource then PROCSTATE == 0 { # restart the Line Processing Block next } # If the first word of the line contains TARGET and the previous line processed was the name of the resource then $1~/TARGET/ && PROCSTATE == 1 { # change the word "ONLINE" to "X" anywhere in the value of the resource targetgsub(/ONLINE/,"X",$2) # change the word "OFFLINE" to "-" anywhere in the value of the resource targetgsub(/OFFLINE/,"-",$2) # assign resource target to the "APPTARGET" variable APPTARGET = $2 # set PROCSTATE equal to 2 signifying the next line should be the resource state PROCSTATE=2 } # If first word of the line contains STATE and the previous line processed was the target of the resource then $1~/STATE/ && PROCSTATE == 2 { # change the phrase "ONLINE on *" to "X" in the value of the resource state and assign it to the variable "FUN" FUN = gensub(/ONLINE on (.*)/,"X \\\\1","g",$2) # change the word "OFFLINE" to "-" anywhere in the "FUN" variablegsub(/OFFLINE/,"-",FUN) # assign resource state to the "APPSTATE" variable APPSTATE = FUN # set PROCSTATE equal to 3 signifying the block has ended PROCSTATE=3 } # If the block has ended, populate the array with the values captured in the block PROCSTATE == 3 { # Populate the first subfield of the current array field with the resource name NUMFIELDS=1; ARR1[NUMLINES,NUMFIELDS] = APPNAME # Populate the second subfield of the current array field with the resource target NUMFIELDS++; ARR1[NUMLINES,NUMFIELDS] = APPTARGET # Populate the third subfield of the current array field with the resource state NUMFIELDS++; ARR1[NUMLINES,NUMFIELDS] = APPSTATE }# Start of the END blockEND { # Column variables have the format COLXe and COLXb # meaning column X end and column X begin # The end of the first column is the total number of resources to be printed # divided by 3 for 3 columns # plus 1 to make the first two columns longer than the last in case of an off number of resources # truncated to the whole number COL1e=int(NUMLINES/3+1) # The beginning of the second column is the number of lines in column 1 plus 1 COL2b=COL1e+1 # The end of the second column is the total of the first two columns minus 1 COL2e=COL2b+COL1e-1 # The beginning of the third column is the number of lines in columns 1 and 2 plus 1 COL3b=COL2e+1 # These lines can be uncommented for debug printing of the column variable assignments # print "Column 1 End:", COL1e, "Column 2 Begin:", COL2b, "Column 2 End:", COL2e, # "Column 3 Begin:", COL3b, "Total:", NUMLINES # Start of the print loop # Start with 1 and increment by one until the value of end of column 1 is reached for (x=1; x<=COL1e; x++) # Print the three column output of the array printf "%-32.30s%1.1s%-20.18s%-32.30s%1.1s%-20.18s%-32.30s%1.1s%s\\n", ARR1[x,1], ARR1[x,2], ARR1[x,3], ARR1[x+COL1e,1], ARR1[x+COL1e,2], ARR1[x+COL1e,3], ARR1[x+COL2e,1], ARR1[x+COL2e,2], ARR1[x+COL2e,3]}# End of the END block'
Rlwrap is an open-source tool for Linux to allow editing of input from the keyboard on any command line tool running in Linux.It works very similar in functionality to the bash command line.For example, up arrow will input the last command edited, control-r will give you the ability to search and recall previous commands and the EMACS movement key combinations will work to edit the command.It works incredibly well for sqlplus, asmcmd and rman command line interfaces.Create aliases or functions with four characters or less with "rlwrap" before the command line tool executable for a much more efficient interface.Has a lot of useful options that for the most part go unused. Learn the EMACS shortcuts for a much more efficient interface.The goo.gl links are shortened URLs for the preceding links.
It is important to customize your local or remote sqlplus sessions if for no other reason than to set the sqlprompt. One of the environment variables that was set at the beginning of the login session was the SQLPATH variable. Sqlplus looks to this variable after the local directory to execute scripts in sqlplus that are not qualified with a path.Always know where you are in sqlplus. As a DBA you probably have a pretty powerful login if not sysdba and there's no rollback with DML. A customized sql prompt is the easiest way to make sure the command you are executing is being executed in the right place.
I build my scripts to be fully portable across all of my servers. I keep them on my local machine so I can make changes globally and back them up on a regular basis. Any changes to my script are made to my local copy and uploaded to my servers using a custom upload script.This script is a batch file that I run manually when I want to update a script and update the server copies.This script can either take a command line variable or not. I can execute it with a space delimited, quoted command line variable to only upload to a subset of servers or execute it without a variable to upload to all of the servers in the list.plink.exe executes commands remotely and pscp.exe uploads files through SSH.First the script makes sure the scripts directory exists, then it uploads the base files followed by the scripts. Finally, the files are converted to get rid of the extra Windows carriage return and modify some permissions.
Talk about licensing and limitations in the enterprise.