Tuesday, March 29, 2011
Review: Minecraft
Since I like to write about Indie game design, it is inevitable that, at some point, I must discuss Minecraft. Written by this Swedish guy commonly known as Notch, it emerged overnight to take over the world and sell meeelions of copies. It has had a level of success my games can never ever hope to match, and it's kind of earned it.
Of course, I could go on, as many others have, about the soul-crushing lack of anything in the game to help anyone actually understand it. Of course, officially, it's still a beta, but it's still super harsh in the early going. Don't try to play it without reading this Newbie FAQ and bookmarking the recipe list, unless you enjoy suffering.
For the few people who haven't played it yet, Minecraft is usually described as a Lego video game. You start out a guy on a deserted island. You can gather cubes of dirt and wood and stone and use them to build, well, whatever you want. Houses. Castles. Roller coasters. There's no plot, per se. It's a creativity tool and an incredibly addictive one. The game system is very simple, allowing for hilarious mishaps, outlandish creations, and manifestations of mental illness.
I made a nice two bedroom house for a family of four. There's a wall around it. It's nice.
But for a no-budget Indie game to sell north of 1.5 million copies? In beta? There is something crazy insane going on here, some sort of true genius. This guy captured lightning in a bottle, with a fairly crude-looking game with no tutorial and a punishingly difficult first ten minutes. I honestly wouldn't have thought it possible. Anyone who cares about game design should look closer and see what this guy did right...
You Have To Earn What You Get
If you want to make a house out of 500 blocks of stone, you first have to dig them up. But then you just have an empty house. If you want something nice, like a clock or a golden pillar or a roller coaster, you have to search more and dig deeper. One of the key elements of Minecraft is the personal satisfaction you get from looking at what you built, which comes in part from knowing that you had to spend your time to earn it. And people do spend the time, because ...
You Get Stuff Fairly Quickly
The guiding principle behind Minecraft seems to be that you have to earn everything you get (by spending time), but practically everything comes cheaply. The stone to make a fortress can be dug up fairly quickly. The key insight here is that, to give a player self-satisfaction, you do need to charge a price (again, paid in your time), but that price can be very small. As long as there is any price at all, even a low one, the player can feel pride in his or her creation.
There Is Danger
On normal difficulty or higher, monsters can spawn anywhere where it is dark. And these aren't candyass, meaningless trash monsters, either. They are skeleton archers that can kill you dead before you even figure out where they are and exploding ambulatory suicide cacti that spend one second hissing in warning before they pop, killing you and destroying everything nearby.
Minecraft was never meant to be a shooter. You can make weapons and armor, but they're tough to make and wear out quickly. The vast majority of foes should simply be avoided. The point of the game is not kicking ass but achieving safety.
Now, to be clear, the danger element is not necessary. Plenty of players switch the game to Peaceful difficulty and never face a worse threat than falling into lava. But for players like me, who need some sort of story element or immediate goal to get into a game, the pressing need to make a Safe Place is a perfect way to feel involved. And, once the game gets you actually playing, it becomes much easier to answer the most difficulty question any creativity toy poses: "I can make anything I want, but what do I want to make?"
But Not Too Much
Minecraft is dangerous, but not too dangerous. Torches are easy to make, they never go out (for now, see below), and monsters never spawn in lit areas. It is easy to make an enclosed place where monsters will never jump you. And yet, if you ever walk outside or if you accidentally leave a dark spot in your house, the danger comes pouring back in.
And, much in the same way that only a tiny amount of effort gives a player pride of ownership, the mere awareness of danger is enough to keep things interesting. Once, when I was modifying my house, I forgot to place a torch in one of the rooms. It gets dark, I go to bed, a zombie spawns in that room, and, when I wake up, it's eating my face.
No matter how safe you make things, a moment of complacency can always kill you. The constant presence of danger can make anything more interesting, even stacking little cubes.
The Game Model Is Incredibly Forgiving
Game designers frequently want to make things too hard for players. There is a constant fear that someone, somewhere, is getting away with something. For example, it must have been very tempting to have Minecraft have a real physics model. Make your wood building too big or unbalanced, and watch as it crumbles before your eyes. Hah! Take that, you dumb gamer!
Minecraft isn't like that. It's a creativity tool. It strongly resists the desire to be hardass about what you can build and gets out of the way as much as possible. Want your giant stone castle to hang in midair? Sure! The game's job is simply to let you create.
With one limitation. Fire is merciless. Try to burn up the patches of brush in front of hour house and I promise, within five minutes, your happy green island will look like Mordor.
And the Developer Is Very Generous
For the amount of entertainment the game can provide, it's amazingly cheap. Around twenty bucks for the beta, and that comes with all future patches. No DRM. No recurring fees. One account serves as many machines as you want to use it on. And once, when their ordering servers were down, Notch simply made the game free.
This is just one example of someone becoming very successful by making something really cheap. See also: Humble Indie Bundle.
But We're Just At the Beginning
One of my favorite things about Minecraft is that it's a work in progress. We can watch the developer's tightrope act in real time, and they might still screw everything up!
For example, they have been flirting for a while with making torches go out. You would have to spend time running around with flint and steel relighting torches, or areas will go dark and "Oh God! Zombies! My face! Aaaahhhh!" This would be a huge change in the nature of the game, introducing a new activity that would pull lots of time away from the core activity: gathering materials and doing stuff with them. This change has been put off for a while, though, so they may have had the wisdom to rethink it.
(In fact, watch for any change that will heavily alter the proportion of time the player spends on various activities - digging, building, etc. These are the changes that will muck up the game.)
They are also considering adding Hardcore mode, where if you die your world is gone for good. I suppose this is a good change, since it is optional and some people love pain.
But I suspect that their design instincts are pretty good. Instead of making torches go out, they are adding cute wolf pets. Genius. My daughters will die of happiness.
So Try It
If you love Indie games, try this one. It takes some work to get into it, but it is a worthwhile exercise just too see how much innovation small developers are capable of. I am on the record as saying that small Indies aren't as innovative as people give them credit for. This is one case when I've been very happy to be proved wrong.
Tuesday, March 22, 2011
Minecraft Makes Little Girls Cry.
I've been playing Minecraft a lot lately (when I'm not porting our newest game to Windows and iPad), and I will have several things to write about this truly fascinating game. For example, my nine year old daughter is addicted to it, and I thought her first experience with it was telling.
Here is a brief summary of my daughter's initial Minecraft session:
Starts game at spawn point.
Walks a long way from spawn point.
Builds most of a house.
Tries to make the roof of the house by placing a block of sand directly above her.
The block of sand falls onto her.
She suffocates.
She respawns at the start point.
She can't figure out where her house is.
She cries.
Walks a long way from spawn point.
Builds most of a house.
Tries to make the roof of the house by placing a block of sand directly above her.
The block of sand falls onto her.
She suffocates.
She respawns at the start point.
She can't figure out where her house is.
She cries.
So what have we learned? First, that Minecraft is truly an educational game, punishing lack of foresight with an almost Eve-like intensity. It has much to teach about planning and forethought, and it delivers its lessons in the most painful way possible. Nothing educational can have value without the possibility of crushing failure.
Second, this would be a great bit of ad copy:
Minecraft - It makes little girls cry.
Third, after she went to bed, I logged in and spent a minute finding her house again. This made me a hero with a ludicrously small amount of effort. That justifies the twenty bucks spent on the game right there.
More to follow, once I figure out how to make a cake.
Friday, March 11, 2011
My Very Brief Review of Halo: Reach.
Every game should have jetpacks.
(Actually, maybe a little explanation. My wife and I play every Halo and Gears of War game together in co-op. It's happy-close-couple-relationship-time.)
(Sadly, the single-player components of Halo games have gotten painfully phoned in. The kick-ass set pieces of Halo 3 have degenerated into long, tedious sequences of interchangeable roads and warehouses.)
(But Halo: Reach has JETPACKS. And that is AWESOME. For the three minutes it lets you play with them.)
(Every mission in Halo: Reach should give you jetpacks. You should be able to boing-boing-boing all over the dang place.)
(Actually, what's more, every game should have jetpacks. Dragon Age. Minecraft. Farmville. Rock Band. EVERY game.)
(Tetris should have jetpacks.)
(Jetpacks.)
Thursday, March 10, 2011
The Whittling Part Of the Brain
(One of the reasons I started this blog, besides pimping my games, was to resurrect some of my old writing that has disappeared from the face of the Earth. For example, about a decade ago, I wrote a column for the late, lamented Computer Games Magazine called The Grumpy Gamer. Here it is, only slightly updated.)
(This was the first column in that series, and, while its basic idea is simple, I still think this piece or writing is True. What still fascinates me is the way some people feel that their way of resting their brain makes them oh so superior to people who rest their brains in a different way.)
The Whittling Part Of the Brain
I have spent the last several years of my life designing computer role-playing games for a living. Thus it came to be that after a friend of mine, who designs board games for a living, couldn’t figure out why anyone found Everquest to be the slightest bit fun, he came to me for an explanation.
For those of you who haven’t experienced this particular brand of delight, most of the Everquest experience tends to involve waiting next to a place where wimpy monsters appear, waiting for them to appear, butchering them once they do appear, collecting their loot, and repeating this process until it’s five in the morning. For the uninitiated, this looks, let us be frank here, like a big waste of time.
But, when he asked me why anyone would want to do this, I had an explanation ready. It’s the same explanation I give whenever anyone asks me what the point of playing computer games is. I simply say that computer games satisfy the Whittling Part of the Brain.
Some of you, in this advanced, techmological age, may not be familiar with the concept of whittling. To whittle, you sit down with a knife in one hand and a stick (or other piece of wood) in the other. Then you take the knife and systematically proceed to carve thin slivers of wood off the stick until there’s nothing left but a pile of wood shavings and your own sense of deep self-satisfaction.
(This sounds, of course, like a pretty dubious source of entertainment, but people do some pretty bizarre things to kill time. Like watch Jersey Shore, for example.)
Of course, this sort of thing is what people did before computers were invented. Or televisions. Or fun. Nowadays, people can do all sorts of low-thought things to pass the time. Knitting and needlepoint. Crossword puzzles. TV. Reading mystery novels. Playing Minesweeper. And playing computer role-playing games.
The human brain just seems to have a need for resting, for passing some time in a low-energy state. Computer role-playing games are perfect for that. When I fight fifty basically identical combats against darkspawn in Dragon Age or spend five hours finally getting my level 13 druid in World of Warcraft to level 14 or piled a hundred bricks on top of other bricks in Minecraft, I’ve done more than waste my time. I’ve given by brain rest that, for reasons I can’t begin to understand, it craved.
And, of course, some of my friends think that I’m wasting my time, both designing the games and playing them. The same friends who don’t think twice about doing their five thousandth crossword puzzle, or reading basically the same damn mystery novel for the billionth time. Or read The Onion, like that’s such an enriching activity. People just like to fritter time away, and computers give us an unusually satisfying way to do it.
The most important thing about these low-brain activities is that they have to be rewarding in some way. They have to give us occasional positive feedback, little flashes of satisfaction. Sometimes, when whittling, you might carve away a particularly long and attractive spiral of wood. (Yeah. I know. Just bear with me on that one.) When knitting, you have the satisfaction of finishing your sweater. With a crossword puzzle, you feel smart when you finish.
And when playing a role-playing game, you get a constant, pleasing form of feedback in the form of gold and experience points. Or upgrading from a +1 to a +2 sword. Or getting a new spell, or completing a quest. Everquest is particularly cunning in the way it rewards the player. It has the character’s skills constantly creep upward, a tiny bit at a time, providing a constant stream of tiny rewards.
Now sure, when described this way, the whole activity sounds a little sad and lame. But really, when you think about it, if it’s such a pointless activity, why do we want to do it? I have found that, in general, our brains our smarter than we are. They want what they want, and if my brain wants to spend a while in front of a computer screen stabbing orcs, who am I to tell it it shouldn’t?
So there you go. In just the first column in this series, I’ve come up with a complete, comprehensive explanation for why it’s good and healthy and productive for us to like to play computer games. And I will recite it to myself, again and again, at two in the morning, when I’m lying awake trying to convince myself that I’m not wasting my life.
(This was the first column in that series, and, while its basic idea is simple, I still think this piece or writing is True. What still fascinates me is the way some people feel that their way of resting their brain makes them oh so superior to people who rest their brains in a different way.)
The Whittling Part Of the Brain
I have spent the last several years of my life designing computer role-playing games for a living. Thus it came to be that after a friend of mine, who designs board games for a living, couldn’t figure out why anyone found Everquest to be the slightest bit fun, he came to me for an explanation.
For those of you who haven’t experienced this particular brand of delight, most of the Everquest experience tends to involve waiting next to a place where wimpy monsters appear, waiting for them to appear, butchering them once they do appear, collecting their loot, and repeating this process until it’s five in the morning. For the uninitiated, this looks, let us be frank here, like a big waste of time.
But, when he asked me why anyone would want to do this, I had an explanation ready. It’s the same explanation I give whenever anyone asks me what the point of playing computer games is. I simply say that computer games satisfy the Whittling Part of the Brain.
Some of you, in this advanced, techmological age, may not be familiar with the concept of whittling. To whittle, you sit down with a knife in one hand and a stick (or other piece of wood) in the other. Then you take the knife and systematically proceed to carve thin slivers of wood off the stick until there’s nothing left but a pile of wood shavings and your own sense of deep self-satisfaction.
(This sounds, of course, like a pretty dubious source of entertainment, but people do some pretty bizarre things to kill time. Like watch Jersey Shore, for example.)
Of course, this sort of thing is what people did before computers were invented. Or televisions. Or fun. Nowadays, people can do all sorts of low-thought things to pass the time. Knitting and needlepoint. Crossword puzzles. TV. Reading mystery novels. Playing Minesweeper. And playing computer role-playing games.
The human brain just seems to have a need for resting, for passing some time in a low-energy state. Computer role-playing games are perfect for that. When I fight fifty basically identical combats against darkspawn in Dragon Age or spend five hours finally getting my level 13 druid in World of Warcraft to level 14 or piled a hundred bricks on top of other bricks in Minecraft, I’ve done more than waste my time. I’ve given by brain rest that, for reasons I can’t begin to understand, it craved.
And, of course, some of my friends think that I’m wasting my time, both designing the games and playing them. The same friends who don’t think twice about doing their five thousandth crossword puzzle, or reading basically the same damn mystery novel for the billionth time. Or read The Onion, like that’s such an enriching activity. People just like to fritter time away, and computers give us an unusually satisfying way to do it.
The most important thing about these low-brain activities is that they have to be rewarding in some way. They have to give us occasional positive feedback, little flashes of satisfaction. Sometimes, when whittling, you might carve away a particularly long and attractive spiral of wood. (Yeah. I know. Just bear with me on that one.) When knitting, you have the satisfaction of finishing your sweater. With a crossword puzzle, you feel smart when you finish.
And when playing a role-playing game, you get a constant, pleasing form of feedback in the form of gold and experience points. Or upgrading from a +1 to a +2 sword. Or getting a new spell, or completing a quest. Everquest is particularly cunning in the way it rewards the player. It has the character’s skills constantly creep upward, a tiny bit at a time, providing a constant stream of tiny rewards.
Now sure, when described this way, the whole activity sounds a little sad and lame. But really, when you think about it, if it’s such a pointless activity, why do we want to do it? I have found that, in general, our brains our smarter than we are. They want what they want, and if my brain wants to spend a while in front of a computer screen stabbing orcs, who am I to tell it it shouldn’t?
So there you go. In just the first column in this series, I’ve come up with a complete, comprehensive explanation for why it’s good and healthy and productive for us to like to play computer games. And I will recite it to myself, again and again, at two in the morning, when I’m lying awake trying to convince myself that I’m not wasting my life.
Thursday, March 3, 2011
Audit vault Server & Agent Installation
Installing the Audit Vault Server
1. Open a terminal window and “unset” the ORACLE_SID and ORACLE_HOME environment variables. (Note: The environment variables are set for your source database by default.)
[oracle@EDRSR2P1 ~]$ echo $ORACLE_SID
orcl
[oracle@EDRSR2P1 ~]$ export ORACLE_SID=
[oracle@EDRSR2P1 ~]$ echo $ORACLE_SID
[oracle@EDRSR2P1 ~]$ echo $ORACLE_HOME
/u01/app/oracle/product/10.2.0/db_1
[oracle@EDRSR2P1 ~]$ export ORACLE_HOME=
[oracle@EDRSR2P1 ~]$ echo $ORACLE_HOME
2. Install the Audit Vault Server. Invoke Oracle Universal Installer to begin the installation of the Audit Vault server.
a. The Audit Vault Server installation files have been staged in the $HOME/av_installmedia directory. Change to the directory containing the Audit Vault Server installation files.
[oracle@EDRSR2P1 ~]$ cd av_installmedia/server
b. Invoke the Oracle installer as follows:
[oracle@EDRSR2P1 server]$ ./runInstaller
3. Perform an Advanced installation of the Audit Vault Server.
a. On the Select Installation Type page, select Advanced Installation. Click Next.
b. On the Advanced Installation Details page, provide the following information and click Next:
Audit Vault Name: av
Audit Vault Home: /u01/app/oracle/product/10.2.0/av_1
Audit Vault Administrator: avadmin1
Administrator Password: oracle_1
Audit Vault Auditor Username: avaudit1
Auditor Password: oracle_1
c. The Database Vault User Credentials Page appears. Enter the following information:
Database Vault Owner: dbvowner1
Owner Password: dbvoracle_1
Database Vault Account Manager: dbvacct1
Account Manager Password: dbvoracle_1
Click Next.
d. The Product-Specific Prerequisite Checks page appears. After the checks complete, click Next.
e. The Specify Database Storage Option page appears. Select File System and specify /u01/app/oracle/oradata/av in the Specify Database file location field. Click Next.
f. The Specify Backup and Recovery Options page appears. Select Enable Automated Backups. Specify /u01/app/oracle/flash_recovery_area/av in the Recovery Area Location field. Specify oracle in the Username and Password fields. Click Next.
g. The Specify Schema Database Passwords page appears. Select “Use the same passwords for all accounts” and enter oracle_2 in the Password field. Click Next.
h. Review the information on the Summary page. Click Install.
i. The Install page appears.
j. The Configuration Assistants page appears. The Database Configuration Assistant Page appears.
k. Click OK on the password management page.
l. Execute the root.sh script as directed. Do not overwrite the existing files.
m. When the End of Installation page appears, make note of the Enterprise Manager Database Control URL and the Audit Vault Console URL. Click Exit.
Enterprise Manager Database Control URL: _____________________________
Audit Vault Console URL: ___________________________________________
n. Click Yes to confirm.
4. Create a user in the Audit Vault Server database for the Audit Vault Agent.
a. Open a terminal window and set the Audit Vault environment variables (ORACLE_SID, ORACLE_HOME and PATH) for the Audit Vault Server.
You can also use the $HOME/labs/setavserver.sh script to accomplish this as follows:
[oracle@EDRSR2P1 labs]$ . ./setavserver.sh
OR set the environment variables manually:
[oracle@EDRSR2P1 ~]$ export ORACLE_SID=av
[oracle@EDRSR2P1 ~]$ echo $ORACLE_SID
av
[oracle@EDRSR2P1 ~]$ export ORACLE_HOME=/u01/app/oracle/product/10.2.0/av_1
[oracle@EDRSR2P1 ~]$ echo $ORACLE_HOME
/u01/app/oracle/product/10.2.0/av_1
[oracle@EDRSR2P1 ~]$ export PATH=/u01/app/oracle/product/10.2.0/av_1/bin:$PATH
b. Log in to SQL*Plus using the Database Vault Account Manager username and password.
[oracle@EDRSR2P1 av_1]$ sqlplus dbvacct1/dbvoracle_1
c. Create the Audit Vault Agent user. Exit from SQL*Plus.
SQL> create user avagentuser identified by avagentpass;
User created.
SQL> exit
5. In the terminal window, use AVCA to add the Audit Vault Agent user to Audit Vault. Supply the following values:
Agentname: avagent1
Agenthost: <server name> Note: Include the domain name as in this example: edrsr2p1.us.oracle.com
Agentusr: avagentuser
[oracle@EDRSR2P1 av_1]$ avca add_agent -agentname avagent1 -agenthost <Audit Vault Agent hostname> -agentusr avagentuser
AVCA started
Adding agent...
Agent added successfully.
Install the Audit Vault agent on Source Database Server
6. Invoke Oracle Universal Installer to begin the installation of the Audit Vault agent.
a. Change directories to the directory containing the Audit Vault agent installation files
[oracle@EDRSR2P1 ]$ cd av_installmedia/avagent/linux_x32
b. Invoke Oracle Universal Installer as follows:
[oracle@EDRSR2P1 linux_x32]$ ./runInstaller
7. Proceed with the installation of the Audit Vault Agent.
a. On the Audit Vault Agent Installation Details page, provide the following information and click Next:
Audit Vault Agent Name: avagent1
Audit Vault Agent Home: /u01/app/oracle/product/10.2.0/av_agent_1
Agent Username: avagentuser
Agent Password: avagentpass
Audit Vault Server Connection Information: host name:listener port:service name
(auditvault-server-host:1522:av.us.oracle.com as an example)
b. The Product-Specific Prerequisite Checks page appears. After the checks complete, click Next.
c. Review the information on the Summary page. Click Install.
d. The Install page appears.
e. The Configuration Assistants page appears.
f. Execute the root.sh script as directed. Click OK.
g. On the End of Installation page, note the Audit Vault agent port number. Click Exit.
Starting Audit Vault Server & Agent (For Information only)
f. Execute the AVCA redeploy command as follows:
[oracle@EDRSR2P1 av_installmedia]$ avca redeploy
AVCA started
Starting OC4J...
OC4J started successfully.
Deploying to standalone OC4J...
done.
Restarting agent OC4J...
OC4J restarted successfully.
[oracle@EDRSR2P1 av_installmedia]$
g. In your Audit Vault Agent terminal window, restart the Audit Vault Agent OC4J as follows:
[oracle@EDRSR2P1 av_installmedia]$ avctl start_oc4j
AVCTL started
Starting OC4J...
OC4J started successfully.
[oracle@EDRSR2P1 av_installmedia]$
h. In your Audit Vault Server terminal window, restart the Audit Vault agent as follows:
[oracle@EDRSR2P1 av_1]$ avctl start_agent -agentname avagent1
AVCTL started
Starting agent...
Agent started successfully.
11. Log in to Audit Vault Console as the Audit Vault Administrator user.
Open a browser window and enter the following URL:
http://<host name>:<Audit Vault Console port>/av
Note: The Audit Vault Console port is displayed at the end of the Audit Vault Server installation. Refer to page A-5 if you have forgotten the port number. Supply the following:
User Name: avadmin1
Password: oracle_1
Connect as: AV_ADMIN
The Oracle Database 10g Licensing Information page appears. Click “I Agree.” Click the Agent tab and verify that the avagent1 agent is started.
Dataguard RMAN
Information in this document applies to any platform.
Oracle ServerEnterprise Edition - Version: 10.2.0.1 to 10.2.0.4
Oracle Server
The following note describes step-by-step procedure to create physical standby by using RMAN duplicate without shutting down the primary (Production) database. Database Name :- prim
Primary db_unique_name :- prim
standby db_unique_name :- stdby
Primary Hostname :- raca.idc.oracle.com
standby Hostname :- core1.idc.oracle.com
Primary db_unique_name :- prim
standby db_unique_name :- stdby
Primary Hostname :- raca.idc.oracle.com
standby Hostname :- core1.idc.oracle.com
STEP: 1
Enable Force Logging on primary,
Enable Force Logging on primary,
SQL> ALTER DATABASE FORCE LOGGING;
Database altered.
NOTE: Create password file if not present, also check if archiving enabled. STEP: 2
Configure a Standby Redo Log on primary,
Configure a Standby Redo Log on primary,
SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 3 '/u01/app/oracle/databases/prim/redo/log3a.log' size 50m; Database altered. SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 4 '/u01/app/oracle/databases/prim/redo/log4a.log' size 50m; Database altered. SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 5 '/u01/app/oracle/databases/prim/redo/log5a.log' size 50m; Database altered. SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 6 '/u01/app/oracle/databases/prim/redo/log6a.log' size 50m; Database altered. NOTE: To check the number of SRL,
(maximum number of logfiles for each thread + 1) * maximum number of threads
For example, if the primary database has 3 log files for each thread and 2 threads, then 8 standbys redo log file groups are needed on the standby database.
Verify the standby redo log file groups were created.
SQL> SELECT GROUP#,ThREAD#,SEQUENCE#,ARCHIVED,STATUS FROM V$STANDBY_LOG;
(maximum number of logfiles for each thread + 1) * maximum number of threads
For example, if the primary database has 3 log files for each thread and 2 threads, then 8 standbys redo log file groups are needed on the standby database.
Verify the standby redo log file groups were created.
SQL> SELECT GROUP#,ThREAD#,SEQUENCE#,ARCHIVED,STATUS FROM V$STANDBY_LOG;
STEP :3
Modify the primary initialization parameter for dataguard on primary,
SQL>alter system set LOG_ARCHIVE_CONFIG='DG_CONFIG=(prim,stdby)';
System altered.
SQL> alter system set LOG_ARCHIVE_DEST_1='LOCATION=/u01/app/oracle/databases/prim/redo/ VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=prim';
System altered.
SQL>alter system set LOG_ARCHIVE_DEST_2='SERVICE=stdby LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=stdby';
System altered.
SQL> alter system set LOG_ARCHIVE_DEST_STATE_1=ENABLE;
System altered.
SQL>alter system set FAL_SERVER=stdby;
System altered.
SQL>alter system set FAL_CLIENT=prim;
System altered.
SQL>alter system set DB_FILE_NAME_CONVERT='/u01/app/oracle/databases/stdby/data/','/u01/app/oracle/databases/prim/data' scope=spfile;
System altered.
SQL>alter system set LOG_FILE_NAME_CONVERT='/u01/app/oracle/databases/stdby/redo/','/u01/app/oracle/databases/prim/redo' scope=spfile;
System altered.
STEP:4
Run the backup job at the primary by connecting to target and catalog DB(if any)
Run the backup job at the primary by connecting to target and catalog DB(if any)
RMAN> backup as compress backupset database include current controlfile for standby;
On Sql Prompt
SQL> alter system archive log current;
run { allocate channel c1 type disk; allocate channel c2 type disk; backup as compressed backupset database format '/u01/app/oracle/databases/stage/%U'; backup current controlfile for standby format '/u01/app/oracle/databases/stage/%U';sql ‘alter system archive log current’ backup archivelog all format '/u01/app/oracle/databases/stage/%U'; } using target database control file instead of recovery catalog allocated channel: c1 channel c1: sid=22 devtype=DISK allocated channel: c2 channel c2: sid=32 devtype=DISK Starting backup at 05-MAR-09 channel c1: starting full datafile backupset channel c1: specifying datafile(s) in backupset input datafile fno=00001 name=/u01/app/oracle/databases/prim/data/system01.dbf input datafile fno=00002 name=/u01/app/oracle/databases/prim/data/undotbs01.dbf channel c1: starting piece 1 at 05-MAR-09 channel c2: starting full datafile backupset channel c2: specifying datafile(s) in backupset input datafile fno=00003 name=/u01/app/oracle/databases/prim/data/sysaux01.dbf channel c2: starting piece 1 at 05-MAR-09 channel c1: finished piece 1 at 05-MAR-09 piece handle=/u01/app/oracle/databases/stage/0tk95ldn_1_1 tag=TAG20090305T143325 comment=NONE channel c1: backup set complete, elapsed time: 00:01:56 channel c1: starting full datafile backupset channel c1: specifying datafile(s) in backupset including current control file in backupset channel c1: starting piece 1 at 05-MAR-09 channel c2: finished piece 1 at 05-MAR-09 piece handle=/u01/app/oracle/databases/stage/0uk95ldn_1_1 tag=TAG20090305T143325 comment=NONE channel c2: backup set complete, elapsed time: 00:01:58 channel c2: starting full datafile backupset channel c2: specifying datafile(s) in backupset channel c1: finished piece 1 at 05-MAR-09 piece handle=/u01/app/oracle/databases/stage/0vk95lhb_1_1 tag=TAG20090305T143325 comment=NONE channel c1: backup set complete, elapsed time: 00:00:03 including current SPFILE in backupset channel c2: starting piece 1 at 05-MAR-09 channel c2: finished piece 1 at 05-MAR-09 piece handle=/u01/app/oracle/databases/stage/10k95lhd_1_1 tag=TAG20090305T143325 comment=NONE channel c2: backup set complete, elapsed time: 00:00:02 Finished backup at 05-MAR-09 Starting backup at 05-MAR-09 current log archived channel c1: starting archive log backupset channel c1: specifying archive log(s) in backup set input archive log thread=1 sequence=5 recid=1 stamp=679686819 input archive log thread=1 sequence=6 recid=2 stamp=679686958 input archive log thread=1 sequence=7 recid=3 stamp=679687040 input archive log thread=1 sequence=8 recid=4 stamp=679743155 input archive log thread=1 sequence=9 recid=5 stamp=680047441 input archive log thread=1 sequence=10 recid=6 stamp=680621993 channel c1: starting piece 1 at 05-MAR-09 channel c2: starting archive log backupset channel c2: specifying archive log(s) in backup set input archive log thread=1 sequence=11 recid=7 stamp=680636808 input archive log thread=1 sequence=12 recid=22 stamp=680703332 input archive log thread=1 sequence=13 recid=32 stamp=680704306 input archive log thread=1 sequence=14 recid=34 stamp=680704331 input archive log thread=1 sequence=15 recid=36 stamp=680704336 input archive log thread=1 sequence=16 recid=38 stamp=680705571 input archive log thread=1 sequence=17 recid=51 stamp=680711731 channel c2: starting piece 1 at 05-MAR-09 channel c2: finished piece 1 at 05-MAR-09 piece handle=/u01/app/oracle/databases/stage/12k95lhl_1_1 tag=TAG20090305T143531 comment=NONE channel c2: backup set complete, elapsed time: 00:00:26 channel c1: finished piece 1 at 05-MAR-09 piece handle=/u01/app/oracle/databases/stage/11k95lhl_1_1 tag=TAG20090305T143531 comment=NONE channel c1: backup set complete, elapsed time: 00:01:01 Finished backup at 05-MAR-09 Starting backup at 05-MAR-09 channel c1: starting full datafile backupset channel c1: specifying datafile(s) in backupset including standby control file in backupset channel c1: starting piece 1 at 05-MAR-09 channel c1: finished piece 1 at 05-MAR-09 piece handle=/u01/app/oracle/databases/stage/13k95lji_1_1 tag=TAG20090305T143634 comment=NONE channel c1: backup set complete, elapsed time: 00:00:02 Finished backup at 05-MAR-09 released channel: c1 released channel: c2 Create parameter file on primary copy this & password file it to standby and make the necessary changes,
SQL>create pfile='/u01/app/oracle/databases/prim/stage/initstdby.ora' from spfile; File created.oracle@raca prim]$ scp –p /u01/app/oracle/dbs/initstdby.ora standbyhost:/u01/app/oracle/dbs/ oracle@raca prim]$ scp –p /u01/app/oracle/dbs/Pwdorcl standbyhost:/u01/app/oracle/dbs/ STEP :6
Copy the listener.ora,tnsname.ora and sqlnet.ora files into staging directory.
Copy the listener.ora,tnsname.ora and sqlnet.ora files into staging directory.
[oracle@raca prim]$ scp –p /u01/app/oracle/network/admin/*.ora standbyhost:/u01/app/oracle/network/admin Copy the redo logs also to standby to avoid size mismatch,
[oracle@raca prim]$ scp –p /u01/app/oracle/databases/prim/redo/*.log standbyhost:/u01/app/oracle/databases/prim/redo/ Move the files to standby server,
a. Create the same directory on standby server and copy the backups. os standby,
$mkdir -p /u01/app/oracle/databases/stage/
[oracle@raca prim]$ scp /u01/app/oracle/databases/stage/* core1.idc.oracle.com:/u01/app/oracle/databases/stage/ b. Alternatively we can copy the backups to standby different directory. On standby server connect to RMAN target as primary and auxiliary instance or if your primary is having catalog database then connect to target as primary, catalog database and auxiliary instance. Catalog those backup pieces to let the controlfile of primary or catalog database to know the backup information.
For details on how to catalog backup piece refer,
NOTE 470463.1 - How To Catalog Backups / Archivelogs / Datafile Copies / Controlfile Copies
STEP: 8
Make the necessary changes on the copied initstdby.ora file on standby.
Make the necessary changes on the copied initstdby.ora file on standby.
db_name=prim db_unique_name=stdby log_archive_config='DG_CONFIG=(prim,stdby)' log_archive_dest_1='LOCATION=/u01/app/oracle/databases/stdby/redo/ VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=stdby' log_archive_dest_2='SERVICE=prim LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=prim' log_archive_dest_state_1=ENABLE db_file_name_convert='/u01/app/oracle/databases/prim/data/','/u01/app/oracle/databases/stdby/data/' log_file_name_convert='/u01/app/oracle/databases/prim/redo/','/u01/app/oracle/databases/stdby/redo/' REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE standby_archive_dest='/u01/app/oracle/databases/stdby/arch/'standby_file_management=AUTO fal_client=stdby fal_server=prim Create standby instance,
create the same password as that of primary. Alternatively we can copy the password file from primary and rename it on standby.
For example from primary copry the password file,
scp /u01/app/oracle/dbs/opapwprim core1.idc.oracle.com:/u01/app/oracle/dbs/
on standby,
$mv orapwprim orapwstdby
or create new password same as primary as mentioned below,
a. in UNIX,
$export ORACLE_SID $orapwd file='$ORACLE_HOME/dbs/orapwstdby' password=sys entries=10; d:>set ORACLE_SID=stdby d:>oradim -new -sid stdby -intpwd sys b Create necessary directories and start the auxiliary instance on standby
[oracle@core1 stdby]$ pwd
/u01/app/oracle/databases/stdby
[oracle@core1 stdby]$mkdir data redo oradata stage udump bdump cdump
SQL>create spfile from pfile='/u01/app/oracle/databases/stage/initstdby.ora';
/u01/app/oracle/databases/stdby
[oracle@core1 stdby]$mkdir data redo oradata stage udump bdump cdump
SQL>create spfile from pfile='/u01/app/oracle/databases/stage/initstdby.ora';
File created.
SQL>start nomount;
ORACLE instance started.
Total System Global Area 612368384 bytes
Fixed Size 1220844 bytes
Variable Size 167776020 bytes
Database Buffers 436207616 bytes
Redo Buffers 7163904 bytes
SQL>exit
SQL>start nomount;
ORACLE instance started.
Total System Global Area 612368384 bytes
Fixed Size 1220844 bytes
Variable Size 167776020 bytes
Database Buffers 436207616 bytes
Redo Buffers 7163904 bytes
SQL>exit
STEP :10
Create net services on both primary and standby,
At prim server,
prim =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST =raca.idc.oracle.com )(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = prim)
)
)
stdby =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST =core1.idc.oracle.com )(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = stdby)
)
)
At standby server,
prim =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST =raca.idc.oracle.com )(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = prim)
)
)
stdby =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST =core1.idc.oracle.com )(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = stdby)
)
)
STEP : 11 Use RMAN duplicate for standby on standby,
When 'dorecover' is specified in the duplicate for stanby command then do a archivelog switch on the target database and run the duplicate.
Example : on primary,
sql> alter system archive log current;
on standby,
Connect to target(i.e. prim via connect string) and catalog database(if any) and this auxiliary database by, $RMAN target sys/oracle@prim catalog RMAN/RMAN@catdb auxiliary / if no catalog database, $RMAN target sys/<password>@prim auxiliary / Recovery Manager: Release 10.2.0.1.0 - Production on Thu Mar 5 12:30:56 2009 Copyright (c) 1982, 2005, Oracle. All rights reserved. connected to target database: PRIM (DBID=3971986030) connected to auxiliary database: PRIM (DBID=3971986030, not open) RMAN> duplicate target database for standby dorecover; Starting Duplicate Db at 05-MAR-09 using target database control file instead of recovery catalog allocated channel: ORA_AUX_DISK_1 channel ORA_AUX_DISK_1: sid=36 devtype=DISK contents of Memory Script: { set until scn 503194; restore clone standby controlfile; sql clone 'alter database mount standby database'; } executing Memory Script executing command: SET until clause Starting restore at 05-MAR-09 using channel ORA_AUX_DISK_1 channel ORA_AUX_DISK_1: starting datafile backupset restore channel ORA_AUX_DISK_1: restoring control file channel ORA_AUX_DISK_1: reading from backup piece /u01/app/oracle/databases/prim/stage/0pk86cs2_1_1 channel ORA_AUX_DISK_1: restored backup piece 1 piece handle=/u01/app/oracle/databases/prim/stage/0pk86cs2_1_1 tag=TAG20090224T175722 channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:01 output filename=/u01/app/oracle/databases/stdby/oradata/control01.ctl Finished restore at 05-MAR-09 sql statement: alter database mount standby database released channel: ORA_AUX_DISK_1 contents of Memory Script: { set until scn 503194; set newname for datafile 1 to "/u01/app/oracle/databases/stdby/data/system01.dbf"; set newname for datafile 2 to "/u01/app/oracle/databases/stdby/data/undotbs01.dbf"; set newname for datafile 3 to "/u01/app/oracle/databases/stdby/data/sysaux01.dbf"; restore check readonly clone database ; } executing Memory Script executing command: SET until clause executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME Starting restore at 05-MAR-09 allocated channel: ORA_AUX_DISK_1 channel ORA_AUX_DISK_1: sid=36 devtype=DISK channel ORA_AUX_DISK_1: starting datafile backupset restore channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set restoring datafile 00003 to /u01/app/oracle/databases/stdby/data/sysaux01.dbf channel ORA_AUX_DISK_1: reading from backup piece /u01/app/oracle/databases/stage/0uk95ldn_1_1 channel ORA_AUX_DISK_1: restored backup piece 1 piece handle=/u01/app/oracle/databases/stage/0uk95ldn_1_1 tag=TAG20090305T143325 channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:07 channel ORA_AUX_DISK_1: starting datafile backupset restore channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set restoring datafile 00001 to /u01/app/oracle/databases/stdby/data/system01.dbf restoring datafile 00002 to /u01/app/oracle/databases/stdby/data/undotbs01.dbf channel ORA_AUX_DISK_1: reading from backup piece /u01/app/oracle/databases/stage/0tk95ldn_1_1 channel ORA_AUX_DISK_1: restored backup piece 1 piece handle=/u01/app/oracle/databases/stage/0tk95ldn_1_1 tag=TAG20090305T143325 channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:15 Finished restore at 05-MAR-09 contents of Memory Script: { switch clone datafile all; } executing Memory Script datafile 1 switched to datafile copy input datafile copy recid=4 stamp=680711065 filename=/u01/app/oracle/databases/stdby/data/system01.dbf datafile 2 switched to datafile copy input datafile copy recid=5 stamp=680711065 filename=/u01/app/oracle/databases/stdby/data/undotbs01.dbf datafile 3 switched to datafile copy input datafile copy recid=6 stamp=680711065 filename=/u01/app/oracle/databases/stdby/data/sysaux01.dbf contents of Memory Script: { set until scn 503194; recover standby clone database delete archivelog ; } executing Memory Script executing command: SET until clause Starting recover at 05-MAR-09 using channel ORA_AUX_DISK_1 starting media recovery channel ORA_AUX_DISK_1: starting archive log restore to default destination channel ORA_AUX_DISK_1: restoring archive log archive log thread=1 sequence=11 channel ORA_AUX_DISK_1: restoring archive log archive log thread=1 sequence=12 channel ORA_AUX_DISK_1: restoring archive log archive log thread=1 sequence=13 channel ORA_AUX_DISK_1: restoring archive log archive log thread=1 sequence=14 channel ORA_AUX_DISK_1: restoring archive log archive log thread=1 sequence=15 channel ORA_AUX_DISK_1: restoring archive log archive log thread=1 sequence=16 channel ORA_AUX_DISK_1: restoring archive log archive log thread=1 sequence=17 channel ORA_AUX_DISK_1: reading from backup piece /u01/app/oracle/databases/stage/12k95lhl_1_1 channel ORA_AUX_DISK_1: restored backup piece 1 piece handle=/u01/app/oracle/databases/stage/12k95lhl_1_1 tag=TAG20090305T143531 channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:03 channel ORA_AUX_DISK_1: starting archive log restore to default destination channel ORA_AUX_DISK_1: restoring archive log archive log thread=1 sequence=8 channel ORA_AUX_DISK_1: restoring archive log archive log thread=1 sequence=9 channel ORA_AUX_DISK_1: restoring archive log archive log thread=1 sequence=10 channel ORA_AUX_DISK_1: reading from backup piece /u01/app/oracle/databases/stage/11k95lhl_1_1 channel ORA_AUX_DISK_1: restored backup piece 1 piece handle=/u01/app/oracle/databases/stage/11k95lhl_1_1 tag=TAG20090305T143531 channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:15 archive log filename=/u01/app/oracle/databases/stdby/redo/1_8_679684398.dbf thread=1 sequence=8 channel clone_default: deleting archive log(s) archive log filename=/u01/app/oracle/databases/stdby/redo/1_8_679684398.dbf recid=8 stamp=680711072 archive log filename=/u01/app/oracle/databases/stdby/redo/1_9_679684398.dbf thread=1 sequence=9 channel clone_default: deleting archive log(s) archive log filename=/u01/app/oracle/databases/stdby/redo/1_9_679684398.dbf recid=10 stamp=680711078 archive log filename=/u01/app/oracle/databases/stdby/redo/1_10_679684398.dbf thread=1 sequence=10 channel clone_default: deleting archive log(s) archive log filename=/u01/app/oracle/databases/stdby/redo/1_10_679684398.dbf recid=9 stamp=680711078 archive log filename=/u01/app/oracle/databases/stdby/redo/1_11_679684398.dbf thread=1 sequence=11 channel clone_default: deleting archive log(s) archive log filename=/u01/app/oracle/databases/stdby/redo/1_11_679684398.dbf recid=6 stamp=680711066 archive log filename=/u01/app/oracle/databases/stdby/redo/1_12_679684398.dbf thread=1 sequence=12 channel clone_default: deleting archive log(s) archive log filename=/u01/app/oracle/databases/stdby/redo/1_12_679684398.dbf recid=7 stamp=680711067 archive log filename=/u01/app/oracle/databases/stdby/redo/1_13_679684398.dbf thread=1 sequence=13 channel clone_default: deleting archive log(s) archive log filename=/u01/app/oracle/databases/stdby/redo/1_13_679684398.dbf recid=4 stamp=680711066 archive log filename=/u01/app/oracle/databases/stdby/redo/1_14_679684398.dbf thread=1 sequence=14 channel clone_default: deleting archive log(s) archive log filename=/u01/app/oracle/databases/stdby/redo/1_14_679684398.dbf recid=1 stamp=680711066 archive log filename=/u01/app/oracle/databases/stdby/redo/1_15_679684398.dbf thread=1 sequence=15 channel clone_default: deleting archive log(s) archive log filename=/u01/app/oracle/databases/stdby/redo/1_15_679684398.dbf recid=3 stamp=680711066 archive log filename=/u01/app/oracle/databases/stdby/redo/1_16_679684398.dbf thread=1 sequence=16 channel clone_default: deleting archive log(s) archive log filename=/u01/app/oracle/databases/stdby/redo/1_16_679684398.dbf recid=2 stamp=680711066 archive log filename=/u01/app/oracle/databases/stdby/redo/1_17_679684398.dbf thread=1 sequence=17 channel clone_default: deleting archive log(s) archive log filename=/u01/app/oracle/databases/stdby/redo/1_17_679684398.dbf recid=5 stamp=680711066 media recovery complete, elapsed time: 00:00:01 Finished recover at 05-MAR-09 Finished Duplicate Db at 05-MAR-09 RMAN>exit NOTE: We can use without dorecover clause also,
Example,
RMAN>duplicate target database for standby;
OR, this is for when standby database have same directory structure
RMAN>duplicate target database for standby nofilenamecheck dorecover;
STEP : 12 Start the MRP(managed recovery process) on standby,
SQL> select name,db_unique_name,database_role, from v$database; NAME DB_UNIQUE_NAME DATABASE_ROLE --------- ---------------- -------------- PRIM STDBY PHYSICAL STANDBY SQL> alter database recover managed standby database disconnect; Database altered.Enable the log_archive_dest_2 on primary, which is to send the logs to standby server.
SQL>alter system set log_archive_dest_state_2=enable; System altered. STEP :14
Check the standby whether it is in SYNC with primary,
A. Check the v$archived view on standby,
SQL> SELECT SEQUENCE#, FIRST_TIME, NEXT_TIME FROM V$ARCHIVED_LOG ORDER BY SEQUENCE#; SEQUENCE# FIRST_TIM NEXT_TIME ---------- --------- --------- 29 06-MAR-09 06-MAR-09 30 06-MAR-09 06-MAR-09 31 06-MAR-09 06-MAR-09 32 06-MAR-09 06-MAR-09 33 06-MAR-09 06-MAR-09 34 06-MAR-09 06-MAR-09 35 06-MAR-09 06-MAR-09 36 06-MAR-09 06-MAR-09 37 06-MAR-09 06-MAR-09 38 06-MAR-09 06-MAR-09 39 06-MAR-09 06-MAR-09 B. Do the log switch on primary,
SQL> ALTER SYSTEM SWITCH LOGFILE; System altered. SQL> SELECT SEQUENCE#, FIRST_TIME, NEXT_TIME FROM V$ARCHIVED_LOG ORDER BY SEQUENCE#; SEQUENCE# FIRST_TIM NEXT_TIME ---------- --------- --------- 29 06-MAR-09 06-MAR-09 30 06-MAR-09 06-MAR-09 31 06-MAR-09 06-MAR-09 32 06-MAR-09 06-MAR-09 33 06-MAR-09 06-MAR-09 34 06-MAR-09 06-MAR-09 35 06-MAR-09 06-MAR-09 36 06-MAR-09 06-MAR-09 37 06-MAR-09 06-MAR-09 38 06-MAR-09 06-MAR-09 39 06-MAR-09 06-MAR-09 SEQUENCE# FIRST_TIM NEXT_TIME ---------- --------- --------- 40 06-MAR-09 07-MAR-09 SQL> select sequence#,applied from v$archived_log order by sequence#; SEQUENCE# APP ---------- --- 29 YES 30 YES 31 YES 32 YES 33 YES 34 YES 35 YES 36 YES 37 YES 38 YES 39 YES SEQUENCE# APP ---------- --- 40 YES
Subscribe to:
Posts (Atom)