Author Archive

Handling the Support Pager

By Paul Moen December 29th, 2006 at 11:22 am
Posted in Non-Tech ArticlesNot on Homepage

His monitor screen wavers slightly, the slight interference of a incoming mobile/cell call or SMS. And with a sharp beep, the pager goes off. He is on the clock. (There is no clock, but he knows the clock exists in the form of “How soon are we going to be back, Joe?”, estimated downtime, estimated time of arrival of a solution, “Are we there yet?”, and “How long? Users are waiting”.)

Yet he still hasn’t connected to the box to see what fragments of messages in voluminous logs indicate a trail, a scent. The pager beeps again — it is getting serious. The monitoring software, being a software tool, keeps trying and failing and paging. He swiftly silences the tool with well trained muscle memory — choose, click, choose, click. His brain then switches on the experience banks.

Has he seen this before? Is it transient page, the curse of the false positive, the “I’ve got a headache” error? How bad is it really, what destruction of data and indexes, datafiles, and disks awaits?

The prompt is back, the password is in, and bingo! Rote, memory, and experience kick in. He is like a seasoned detective, scanning for the clues. He is quietly confident, he has backups, he has standbys, he has flashback. And he has resources he can bring to bear on the problem — within reach are the minds of dozens of DBAs; and more extensive, a vast case history of problems; and finally a searchable universe called the Net.

The problem–however serious–will be solved, can be solved. Tenacity may be required, leaps of faith, moments of deep thought. Soon, functionality will be restored, and everyone will live happily ever after. But for now, the clock is ticking.

MySQL Recipes: Promoting a Slave to Master or Changing Masters

By Paul Moen December 8th, 2006 at 11:12 am
Posted in Group Blog Posts

Not a dear diary post today — I have a couple up my sleeve though.

In the corporate world, promoting a slave to a master requires many years of hard work, obtaining a suitable business degree, getting an MBA, and having a taste for promotion. The alternative is getting that break as an entrepreneur where you start as the master of your own destiny and end being the master when the money runs out or you take the money and move on.

In MySQL–land, failovers for redundancy, disaster recovery, or load balancing are performed by master databases and slave databases, the most popular method using binlog replication.

(more…)

Oracle block corruptions, DBV vs RMAN

By Paul Moen September 28th, 2006 at 3:35 pm
Posted in Group Blog Posts

Over-the-Top Tales from the Trenches.
Motto: Bringing order to the chaos of every day DBA life.

Dear Diary,

Is that a whiff of decay in the air, the pungent odour of corruption? No… not me, the database.

Oracle prides itself on the robust nature of its database. Kill it off, or have a sudden power outage, and 99.9% of the time the db will pick itself up, clean off the dust of uncommitted transactions, and get back into the game.

There is nothing more nasty or dangerous to any database than a filesystem/disk with IO issues. To paraphase the bard, “Is the data to be or not to be? that is the question”. Did the block(s) get written on disk or did something else happen? Or did you get fries with that?

As a DBA, you are paid to wear the tin-foil hat occasionally to protect yourself from the soothing signals transmitted by disk caches and controllers, informing you that everything is ok… go back to sleep… your data is ok…

Is there an easy way to check for block corruptions and also logical corruptions (e.g., dodgy indexes) after the hint of filesystem IO issues?

The first thing that comes to mind is DBV. So you have 250+ datafiles. You hunt for a script to check each one, then trawl through the mountain of data DBV produces for each datafile.

On Unix you could run a shell script like:

#!/bin/bash
BLOCKSIZE=$1
DATADIR=$2
cd $DATADIR
ls -1 *.dbf | while read FILE
do
    dbv file=$FILE blocksize=$BLOCKSIZE
done

Call the shell script like this:

./dbv.sh 8192 /oracle/oradata/$ORACLE_SID >> dbv.log 2>&1

While that dbv.sh will work on most recent and no-so-recent versions of Oracle, there is another way, one which will populate a table in the db for you if there are any corruptions, and give you a reasonable ETA on the total amount of time required. This way is The Tao of RMAN.

RMAN is able to check the database for block and logical corruptions using a nice command called
BACKUP VALIDATE CHECK LOGICAL DATABASE.

In this example command file, RMAN uses 4 channels to speed up the process and potentially thrash your disk. A good option would be to use iostat -x 5 5, as described by Alex in this article, to determine when the disks are saturated, and modify the command file accordingly.

You could also use the RATE option to limit the disk rate like this, ALLOCATE CHANNEL c1 DEVICE TYPE DISK RATE=1500K;

Here is the command file:

run {
allocate channel c1 device type disk ;
allocate channel c2 device type disk ;
allocate channel c3 device type disk ;
allocate channel c4 device type disk ;
backup validate check logical database;
}

To run the command file and have the rman output go to a logfile, call it like this:

rman target / cmdfile rman_check_corrupt.cmd log rman_check_corrupt.log 2>&1 &

While RMAN does its thing, you can jump into the database and check how long Oracle estimates the long-running process will take, using this SQL:

select sid,start_time,elapsed_seconds,time_remaining, round(time_remaining/60,2) "Min",message from v$session_longops where time_remaining > 0
/

As RMAN proceeds, you can perform some stationary exercise at your desk, increase your blood pressure and heart rate by running

select count(*) from v$database_block_corruption;

So was it six corruptions or only five, are you feeling lucky?

The best part of RMAN is that is will run on primary and standby databases equally effectively. However, as mentioned in Marc’s article, neither the mightly dbv nor even RMAN will help you with the insidous data guard corruption bug.

Have Fun!
Paul

Related posts in the series:

Creating standby databases using RMAN duplicate

The mysterious world of shmmax and shmall

Recipes for Creating a Managed Standby with RMAN

By Paul Moen September 25th, 2006 at 10:31 am
Posted in Group Blog Posts

Over-the-Top Tales from the Trenches.
Motto: Bringing order to the chaos of every-day DBA life.

Dear Diary,

Today I created safety nets — redundant databases in the form of managed standbys.

Like a lot of DBA-related work, this comes in the form of a recipe. This recipe is not set in stone. Rather, it’s an evolving work — a tinker here, a tinker there, always looking for the extra ounce of speed, like a F1 Ferrari mechanic working on the racing car that Michael Schumacher hurls round the track.

The real aim of the managed standby is redundancy. (That is where Michael sloughs off the track at 250 miles per hour and magically is back on the track racing after a short downtime.)

So, on to the recipes.

This recipe is based on Oracle 10G Release 2 and assumes:

  1. Directory structure is the same on both primary and standby machines.
  2. Backup is going locally to disk at location source_backup_directory
  3. TNSNAMES entry STANDBY points to standby db on both machines.
  4. TNSNAMES entry PROD points to prod db on both machines.
  5. RMAN catalog exists, and is resolved via TNSNAMES entry rcatdb.
  6. RMAN default channel locations.

On Source/Primary db:

su - oracle
rman target / catalog rcat_owner@rcatdb
RMAN> BACKUP CURRENT CONTROLFILE FOR STANDBY;
RMAN> BACKUP CHECK LOGICAL FULL DATABASE PLUS ARCHIVELOG;
RMAN> exit;

scp source_backup_directory oracle@standby:standby_backup_directory

On Destination or Standby db:

sqlplus "/ as sysdba"
startup nomount
exit;

On Source/Primary db:

rman target / catalog rcat_owner@rcatdb auxiliary sys@STANDBY

RMAN> DUPLICATE TARGET DATABASE FOR STANDBY NOFILENAMECHECK DORECOVER;
RMAN> exit;

On Source/primary db:

show parameter log_archive_dest;
alter system set log_archive_dest_x = 'SERVICE=STANDBY LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=PROD';
alter system set log_archive_dest_state_x = 'ENABLE';

On Destination or Auxiliary STANDBY:

alter system set FAL_SERVER = 'PROD';
alter system set FAL_CLIENT = 'STANDBY';

shutdown immediate;
startup nomount;
alter database mount standby database;
alter database recover managed standby database disconnect from session;

To check progress:

On Primary:

column destination format a30

select dest_id,destination,status,database_mode,recovery_mode,error from V$ARCHIVE_DEST_STATUS
where status != 'INACTIVE';

To check progress on Primary or Standby:

select * from v$managed_standby;

For the complete recipe and for other versions please visit the online documentation.

Everyone knows the idea. In the cookbook, the picture of the pavlova1 is a picture of delicious, crunchy but soft meringue dripping with passionfruit sauce, topped with ripe strawberries. The recipe seems simple, but you end up with something like a white flat dinner plate with the consistency of styrofoam.

So how does your Grandma use the pavlova recipe and not make the infamous styrofoam plate? Practice (of course), and insider tips.

The final steps in the ordination to the RMAN-managed standby priesthood are the insider secrets. Listen up, padawan2.

Caveats:

  1. Make sure you take a backup of the controlfile for standby before any level 0 backup…
    RMAN> BACKUP CURRENT CONTROLFILE FOR STANDBY;

    This will allow RMAN to recover the standby and roll forward using all available archive logs.

  2. Either have the backup go to a tape library, a NFS/SAN volume which is accessible by both boxes, or get all the backup files to the proposed standby.
  3. Having a weird or complex or substantially different directory on the proposed standby makes baby Jesus cry3. Try to get them the same. The return on investment over time will be substantial, not only for this project, but for ongoing maintenance, ease of administration, and so on.
  4. Make sure that the standby and primary can see each other via tnsnames first.

So why go to the trouble of learning how to implement a managed standby using RMAN? If your primary db is in archivelog mode the whole operation is online. Online as in, no downtime on the primary.

If you are proactive and take a backup of the controlfile for standby every night as part of an RMAN backup, you can create a new standby from last night’s RMAN backup whereever and whenever you like.

The take-home message:
Implementing standbys has never been easier or more straight-forward than using
RMAN DUPLICATE TARGET DATABASE FOR STANDBY NOFILENAMECHECK DORECOVER;

Have Fun.
Paul

Update: 2006/11/04: Adding the startup nomount to standby database. This is makes sure the pfile is readable and the memory can be sourced.

See prior articles in this series.

References:
1. Pavlova
1. Pavlova, again
2. Padawan
3. make baby Jesus cry

The mysterious world of shmmax and shmall

By Paul Moen September 13th, 2006 at 6:46 pm
Posted in Group Blog Posts

Over the Top Tales from the trenches.
Motto: Bringing order to the chaos of every day DBA life.

Dear Diary,

Today I delved into the internal workings of Linux kernel memory settings.
A recalcitrant machine would not allow me to open a second newly created instance due to ORA-27102 “out of memory”.
I determined using free that there was in fact 16 Gigabytes of fresh free RAM available, and this was linux x86_64 from uname -a.
So no jumping through hugepage hoops to get a 32 bit OS to allow a 32 bit db address more than 1.7 Gig.
So what was the story, I wondered…
Do I ring the bat phone on the desk and ask a SA (System Admin) or Unix admin as we call them here, and get the answer in a jiffy, handed on a plate?

No, you can only learn by pushing the envelope, lifting that little extra weight, growing that bit taller to reach the sun using whatever fertiliser required, google and metalink are good starts.

I walked my well worn path to the sage of metalink, payed homage and received enough info (Note:301830.1) to begin the journey to discovering how linux kernel shared memory settings affect Oracle.

Like Soviet central planners there are two important settings. Like most people I knew about shmmax, but it is sly, it is not the maximum amount of memory which can be allocated, it is the maximum size of any shared memory chunk.
Shmmax is how big a bite you want per bite from free memory.
The real godfather, the wizard behind the curtain is shmall. Its value determines the maximum amount of memory that ALL shared memory can take.
Just to make it fun, the actual setting is derived…
the maximum amount of memory = shmall * pagesize
where pagesize = getconf PAGE_SIZE and shmall = cat /proc/sys/kernel/shmall

Making shmall larger than free RAM is a recipe for paging hell and much gnashing of teeth. Oracle recommends half the RAM, we pushed the envelope and chose 75% as 8 gigabytes of free for OS and cache is just wasteful.
Especially given Oracle is already caching hot blocks in its memory.

Happy days and the 2nd and 3rd instance had plenty of room to startup and become managed standbys… a story for another day.

Boiled down to one sentence summary:
shmall determines the total amount of shared memory to be allocated using its value multipled by the OS pagesize.

Have Fun

Paul

SQLserver 2005 Query Efficiency

By Paul Moen June 30th, 2006 at 7:18 am
Posted in Group Blog Posts

Until recently if you wanted to determine what queries or stored procedures were the least efficient you would have to capture all SQL either via SQL Profiler or have a scheduled job which dumped the sql running from sysprocesses.

Now with the new dynamic performance views available in SQLserver 2005 you can run queries which allow you to determine these poor performers without much extra work. It is not statspack or Automatic Workload Repository (AWR) or V$ACTIVE_SESSION_HISTORY (more importantly) but it is a good start to determining what sql and what sessions are consuming the most resources in SQLserver 2005 instance.

As I noted in my last entry, the SQLserver 2005 team have a series of blogs and this inspired me to read and port my existing Oracle scripts which determine query efficiency to SQLserver 2005.
One of my favourite Oracle scripts uses the number of logical reads per execution as a good sign of poorly performing sql. Logical reads per execution is also a reasonable estimation of CPU per execution. Sometimes you have to add an extra condition i.e WHERE executions > 1, or order by executions as well to get the most called, most inefficient sql.

Normally on a poorly performing system I tend to follow these steps, in this case rewritten to use SQLserver 2005 new dynamic views.

  1. Quickly check taskmanager or perfmon to verify that the CPU or IO hog is in fact SQLserver and not IIS or SQL fulltext indexing services (or something else).
  2. Check for contention, is there one process blocking all others.
  3. Run the script to find sql with the highest elapsed time per execution.
  4. Run the script to find sql with the highest physical reads (PIO) per execution.
  5. Run the script to find sql with the highest logical reads (LIO) per execution.

So here are the efficiency scripts:

Note: All these scripts will return the actual text as the last column. You could replace that with the plan_handle or sql_handle to allow you to return the XML plan as described in that Top N sql article.

Have Fun

Paul

rem SQL Efficiency by Elapsed Time. Paul Moen (Pythian) 2006

select qs.creation_time
, qs.execution_count "Exec"
, qs.total_elapsed_time "Elapsed"
, total_physical_reads "PIO"
, total_logical_reads "LIO"
, round(qs.total_elapsed_time/qs.execution_count,1) "Time/Exec"
,  round(qs.total_physical_reads/qs.execution_count,1) "PIO/Exec"
,  round(qs.total_logical_reads/qs.execution_count,1) "LIO/Exec"
,  st.text
from sys.dm_exec_query_stats as qs
cross apply sys.dm_exec_sql_text(qs.sql_handle) as st
where qs.execution_count > 0
order by "Time/Exec" desc

rem SQL Efficiency by Physical Reads per execution. Paul Moen (Pythian) 2006

select qs.creation_time
, qs.execution_count "Exec"
, qs.total_elapsed_time "Elapsed"
, total_physical_reads "PIO"
, total_logical_reads "LIO"
, round(qs.total_elapsed_time/qs.execution_count,1) "Time/Exec"
,  round(qs.total_physical_reads/qs.execution_count,1) "PIO/Exec"
,  round(qs.total_logical_reads/qs.execution_count,1) "LIO/Exec"
,  st.text
from sys.dm_exec_query_stats as qs
cross apply sys.dm_exec_sql_text(qs.sql_handle) as st
where qs.execution_count > 0
order by "PIO/Exec" desc

rem SQL Efficiency by Logical Reads per execution
rem which is good estimate for CPU/execution. Paul Moen (Pythian) 2006

select qs.creation_time
, qs.execution_count "Exec"
, qs.total_elapsed_time "Elapsed"
, total_physical_reads "PIO"
, total_logical_reads "LIO"
, round(qs.total_elapsed_time/qs.execution_count,1) "Time/Exec"
,  round(qs.total_physical_reads/qs.execution_count,1) "PIO/Exec"
,  round(qs.total_logical_reads/qs.execution_count,1) "LIO/Exec"
,  st.text
from sys.dm_exec_query_stats as qs
cross apply sys.dm_exec_sql_text(qs.sql_handle) as st
where qs.execution_count > 0
order by "LIO/Exec" desc

Useful SQLserver 2005 blogs

By Paul Moen June 26th, 2006 at 6:31 pm
Posted in Group Blog Posts

I have been scanning some blogs by different teams involved with SQLserver 2005.
Here is a short list:

  1. SQLserver 2005 Database engine tips
  2. SQLserver 2005 Query Optimizer
  3. SQLserver Query optimization - talking about SQL/TSQL optimization
  4. SQLserver storage Engine

There is a bit of cross linking happening so some articles are repeated on one or more blogs.

The database engine blog has an article about finding the top N worse SQL brought a (bemused) smile to my face. Finally SQLserver has views like Oracle, no more do you need to run SQL profiler 24×7 or some script which captures the SQL running every n secs to have an historical record of what has been running.

Guess this means I can start porting my Oracle scripts from using v$sql, v$sqlarea and in Oracle 10G R2 v$active_session_history to using sys.dm_exec_query_stats, sys.dm_exec_sql_text and sys.dm_exec_query_plan.

The trouble with plenty of relational databases has been that lack of exposure of the metadata/catalog of the database and the data within that catalog. Until recently plenty of the internal stuff in SQLserver had to be queried using various DBCC calls. Similarly, this is the same stuff that MySQL versions prior to 5 have with SHOW TABLE STATUS and SHOW FULL PROCESSLIST etc.

There is no nice way to see what the spread of data within a column is. It is good that these vendors are exposing this to the outside world via SQL rather than a tool with requires the output to be further parsed.

Have Fun

Paul