Monday, June 22, 2009

First real IFR This last weekend - Great flight!!

So, in all my IFR training I managed to actually fly IMC (Instrument Meteorological Conditions - or in the clouds) about 30 minutes. The rest of the time was under a "hood", which restricts your vision to just the instruments. This is not an unusual thing but I think every newly minted instrument pilot (got my certificate in November) waits excitedly for his first real "in the clouds" experience. In Utah it's even harder because lots of times the clouds have ice in them, which one wants to avoid. So, after getting my IFR ticket, I was very much looking forward to an opportunity to fly some real IFR.

This weekend, I got mine!!

I decided to take myself to Wendover, UT. (that's where the airport is, the city is in Nevada) on Saturday. If you have been watching the weather you might have noticed that Utah has gotten a lot of rain of late. Saturday's weather was cloudy and rainy. Perfect!

I filed my IFR flight plan on my computer and took off for Wendover. My intention was to catch my clearance in the air which is what I did. Now, the MEA (minimum en route altitude) between South Valley regional (U42) in Salt Lake City and Wendover (ENV) is 9,000, which means I have to fly at or above 9,000 feet to go IFR. A Cessna-150 isn't a fast climber, particularity when you are full fuel. I was pretty much at the edge of the Salt Lake City (SLC) class B airspace when I finally hit 9k. At 9k I got my clearance from Center and I was on my way.

About 30 miles or so from SLC, I hit clouds for the first time. it was a line of very light precipitation .... the clouds enveloped me, light rain falling on my windshield and briefly looking outside (you want to be constantly scanning your instruments of course) it looked like I was enveloped in marshmallow or something.

At some points you could look down and see the roads below. This is really a pretty good route for single engine instrument flying... there are a few mountains, but you are pretty much following I-80 the whole way... and for the most part are flying along a valley (with one good ridge to pass). You can see the map of my route here (this is known as a sectional chart).

Also, click on this link and you will see the low altitude en-route chart that I used for my flight.



The ceilings were at about 8-10k MSL for the most part (but at some points seemed much lower), so if I had a problem I'd have lots of visibility to land on the highway. I also have a nice GPS which shows me the highway, terrain and the like, so coming down in an emergency would be a reasonable experience.

It took me a while to really get my scan going well, and I was hitting some light chop too. Also there was some lateral sheer trying to move me too and fro. After a while I got things settled down and pretty much did a good job of staying on the airway. The airplane was filled with Fuel. Originally I filed for 10k, but could only get it to climb to 9.5k. Center was nice enough to let me go down to 9k and fly the rest of the route. When it's heavy, that 150 does not want to climb fast at all!

The Outside air temperature (OAT) was about 40 degrees, so there was no risk of icing of course. However while in the clouds I did experience a brief and slight loss of power. I applied some carb heat and that took care of the problem. That was my second experience with carb ice... it can be a bit scary, but if you know what to do, it's not a big deal avoiding it. The only problem is that in applying carb heat, you loose some engine power. This can make holding altitude difficult if you are already barely holding it. I didn't have too much of a problem at 9k, but I suspect that I'd have not been able to maintain 10k with carb heat applied.

I exited the clouds about 25 miles east of ENV or so.... Excited for my first IMC experience. I proceeded to do a visual approach into ENV which went smoothly. I ate some lunch at ENV and then started the return trip.

On the way back, it became clear that I'd have to file IFR again. I dialed up Cedar City Radio and opened the IFR flight plan with them. I then called Center, got my clearance and was again on my way. On the trip back, I hit clouds again for about 20 minutes or so. it was a thrilling and exciting experience! Entering the Class B airspace, I canceled IFT and returned to SLC and my home airport South Valley Regional (U42) via a normal visual approach.

It is this kind of flying that I got my instrument ticket for! Had I been VFR only, I'd have not been able to go because of mountain obscuration and some low ceilings that, with mountains present, probably would have caused me to scrub the trip. I'm not into scud running with mountains around that you can't see the tops of. As it was, with my little C150, my VOR and a GPS as a backup I safely made my trip and enjoyed a great high that few pilots really get to experience.

I can't wait to do it again!

If I didn't already like the Black Eyed Peas, now I *really* do.

While I can't quite say I've been a ravid fan of the Black Eyed Peas, I've enjoyed their music in the past and I very much like their new album (The E.N.D.), especially the songs BOOM BOOM POW and I Gotta Feeling. Now, having read this news post, I'm even more of a fan.

Anyone who will stand up to Perez Hilton is just A-OK in my book. In my mind Perez is one of many things wrong with America. While violence is not a good thing, and I sure don't support assault and do support self-control, I'm sure that there are those that feel Perez probably more than deserved what he got.

Monday, June 15, 2009

RSS Feed is back...

I re-added the RSS feed button at the bottom of the Blog page. It was lost when I changed to the new Blog template.... lemme know if something is still broken!

Sunday, June 14, 2009

MERGE ME BABY!! A Contest for a new book!!

At the end of this post I'm starting a contest. So read the post and maybe you will win a book!!

So, I've had occasion to work with the MERGE command of late. In my travels I've found the MERGE command to be a way under utilized command. It's been a while since I used it, to be honest, and I had to re-learn a few things. I think in the process I have a few interesting tid-bits to share.

Let's take a case where we have a table that we want to store all objects with a status of INVALID in. For the sake of keeping things clear later, we will call the table MERGE_TARGET. Here is the DDL for this table:

Drop table merge_target;
create table merge_target
as select object_id, object_name, object_type, status
from user_objects
where status = 'INVALID';
Alter table merge_target
Add constraint pk_merge_target primary key (object_id);

Now, let's create an object and invalidate it. We will create a table, then create a view dependent on that table. Finally we drop the table making the view invalid.

Drop table dodo;
Create table dodo (id number);
Create view view_dodo as select * from dodo;
Drop table dodo;

Excellent, now we have an invalid object called view_dodo. We can see this by querying the user_objects view as seen here:

select object_name, status
from user_objects
where status='INVALID';

OBJECT_NAME STATUS
-------------------- -------
VIEW_DODO INVALID

The problem is that our merge_target table is not up to date:

select * from merge_target;
no rows selected

How do we update it. Clearly we can use the insert command but what happens as time goes on and records change ... we will have to do inserts, updates and deletes. This is where the merge command comes in. With one simple command we can get the table updated. Here is our first crack at a merge command. Don't stop here though, becuase this does not take care of every possible situation that might occur:

merge into merge_target mt
using user_objects uo
on (uo.object_id=mt.object_id)
when matched then
update set mt.object_name=uo.object_name,
mt.object_type=uo.object_type,
mt.status=uo.status
where uo.status='INVALID'
when not matched then
insert (mt.object_id, mt.object_name, mt.object_type, mt.status)
values(uo.object_id, uo.object_name, uo.object_type, uo.status)
where uo.status='INVALID';

Now look at merge_target:
SQL> select * from merge_target;

OBJECT_ID OBJECT_NAME OBJECT_TYPE STATUS
---------- -------------------- ------------------- -------
70803 VIEW_DODO VIEW INVALID

So what if the view is renamed, but still invalid?

rename view_dodo to dodo_view;
select object_name, status
from user_objects
where status='INVALID';

OBJECT_NAME STATUS
-------------------- -------
DODO_VIEW INVALID

select * from merge_target;


OBJECT_ID OBJECT_NAME OBJECT_TYPE STATUS
---------- -------------------- ------------------- -------
70803 VIEW_DODO VIEW INVALID

Let's issue the MERGE command again and see what happens!

merge into merge_target mt
using user_objects uo
on (uo.object_id=mt.object_id)
when matched then
update set mt.object_name=uo.object_name,
mt.object_type=uo.object_type,
mt.status=uo.status
where uo.status='INVALID'
when not matched then
insert (mt.object_id, mt.object_name, mt.object_type, mt.status)
values(uo.object_id, uo.object_name, uo.object_type, uo.status)
where uo.status='INVALID';
commit;

select * from merge_target;

OBJECT_ID OBJECT_NAME OBJECT_TYPE STATUS
---------- -------------------- ------------------- -------
70803 DODO_VIEW VIEW INVALID

Wow! Cool. It seems that Merge does an insert, and then also does updates!
So what happens if the view becomes valid again? Let's see:

Create table dodo (id number);
alter view dodo_view compile;
select object_name, status
from user_objects
where status='INVALID';
no rows selected

Sweet, now there is nothing in USER_OBJECTS that is invalid. What about the merge_target view though, it still has VIEW_DODO in it. What do we do? We issue the MERGE command again!

merge into merge_target mt
using user_objects uo
on (uo.object_id=mt.object_id)
when matched then
update set mt.object_name=uo.object_name,
mt.object_type=uo.object_type,
mt.status=uo.status
where uo.status='INVALID'
when not matched then
insert (mt.object_id, mt.object_name, mt.object_type, mt.status)
values(uo.object_id, uo.object_name, uo.object_type, uo.status)
where uo.status='INVALID';

SQL> select * from merge_target;

OBJECT_ID OBJECT_NAME OBJECT_TYPE STATUS
---------- -------------------- ------------------- -------
70803 DODO_VIEW VIEW INVALID

Woops, that didn't work so well. If you are not running Oracle Database 10g and later, this is a problem you will need to deal with manually. However, there is a solution in Oracle Database 10g. To use it, we have to update the Merge command just slightly to that seen here:

merge into merge_target mt
using user_objects uo
on (uo.object_id=mt.object_id)
when matched then
update set mt.object_name=uo.object_name,
mt.object_type=uo.object_type,
mt.status=uo.status
where uo.status='VALID' or uo.status= 'INVALID'
delete where (uo.status='VALID')
when not matched then
insert (mt.object_id, mt.object_name, mt.object_type, mt.status)
values(uo.object_id, uo.object_name, uo.object_type, uo.status)
where uo.status='INVALID';

Now, let's see what happens!

select * from merge_target;
no rows selected

Great!! Note that we added a delete clause under the update clause. Also note that the where clause in the update clause is now changed to include updates of both VALID and INVALID records. That's the rub with the delete clause, it ONLY works on records that have actually passed through the update clause. So we have to process all of the VALID records as an update, before we can actually process them for a delete. That was something that tripped me up for a while before I got it figured out, so learn from my mistake. :-)

Finally, there is still a problem. What happens if we do this?

-- we drop the table, invalidating the view
drop table dodo;

-- Re-populate merge_target with the invalid view again
merge into merge_target mt
using user_objects uo
on (uo.object_id=mt.object_id)
when matched then
update set mt.object_name=uo.object_name,
mt.object_type=uo.object_type,
mt.status=uo.status
where uo.status='VALID' or uo.status= 'INVALID'
delete where (uo.status='VALID')
when not matched then
insert (mt.object_id, mt.object_name, mt.object_type, mt.status)
values(uo.object_id, uo.object_name, uo.object_type, uo.status)
where uo.status='INVALID';

select * from merge_target;

OBJECT_ID OBJECT_NAME OBJECT_TYPE STATUS
---------- -------------------- ------------------- -------
70803 DODO_VIEW VIEW INVALID

Now, what happens if we drop the view completely?

drop view dodo_view;

select object_name, status
from user_objects
where status='INVALID';

no rows selected

Let's update merge_target now. Once this is done, it should be empty, right?

merge into merge_target mt
using user_objects uo
on (uo.object_id=mt.object_id)
when matched then
update set mt.object_name=uo.object_name,
mt.object_type=uo.object_type,
mt.status=uo.status
where uo.status='VALID' or uo.status= 'INVALID'
delete where (uo.status='VALID')
when not matched then
insert (mt.object_id, mt.object_name, mt.object_type, mt.status)
values(uo.object_id, uo.object_name, uo.object_type, uo.status)
where uo.status='INVALID';

select * from merge_target;

OBJECT_ID OBJECT_NAME OBJECT_TYPE STATUS
---------- -------------------- ------------------- -------
70803 DODO_VIEW VIEW INVALID

Oh BLAST! We have found another hole in our logic somewhere. Can you find the answer? The answer results in a somewhat more sophisticated version of the merge command.

So, here is what I'm going to do.

For the next 90 days, I'm not going to post the answer to this question. For the first person who posts a comment to this blog with the correct answer to this question will go one free copy of our 11g RMAN Backup and Recovery book when it comes out!! I will not post comments that have the correct answer until the contest is over. Once the contest is over, I'll post the winners name and you will need to send me your mailing address so I can ship you your book.

All shipping costs on me unless you live outside the current solar system! ON September 15th in a separate BLOG post I will post the answer to this query. If you have an urgent need for the answer you can write me at robertgfreeman@yahoo.com, but you will not be eligible for the book. Of course this offer does not apply anywhere that it is illegal to make such an offer, you are responsible for the tax ramifications, etc...etc.... This is a personal contest and has no association with Oracle, Oracle Press, Santa Clause, the North Pole, any of my employers past or present or anyone else in the world living, dead, half-dead, in Zombie format, who may live in the future or who might be a fantasy in someones head. My family is not eligible (like they know anything about Oracle) nor is anyone at any of my employers within the last 5 years. Any employee of Oracle Corp. is also not eligible or anyone with Oracle Press.

Can you make something too simple?

I'm working on the new revised edition of our Oracle Database Backup and Recovery book for Oracle Database 11g ... I've been looking at some comments here and there that have been made about the book, and also comments about the competition. What I find interesting is that the approach that the competition has taken, the recipe approach if you will, seems to be popular with some. I suppose that makes sense. Everyone wants something to be easy. But that's the rub, can you take something as complex as backup and recovery and make it too simple?

In the recipe book, in the first two chapters they have you do a backup recipe and a restore recipe. Now the Junior DBA (or perhaps the overworked senior DBA) might say, FANTASTIC, I backed up my database and I restored my database, I'm set. They might just setup a script, start backups and off they go, not fully realizing what they have just done.

For in the book, they fail to mention some salient points.

1. That the recipe will have you backing up into ORACLE_HOME by default. Since there is no previous recipe to configure the Flash Recovery Area, that is where your backups will go by default.

2. They do have a recipe for putting the database in ARCHIVELOG mode... However if you do that first and then follow the recipe for backing up your database, you might find yourself in a world of hurt. The backup recipe does not backup archived redo logs.

3. Since you are not backing them the archived redo logs, or removing them, guess what happens to the archive log destination directory?

So in an effort for simplicity the chapter falls short of the mark a bit. I know we all want simple solutions. Something we can craft out of the box without having to understand, without having to think, and that's all well and good. I'm not sure it's practical when dealing with backups of your database.

I'd love your feedback on how we can make our RMAN book better. I'd love to hear any suggestions you might have out there on how we can make it better, what we can add, modify or even delete.
 
Subscribe in a reader