Archive for the ‘SQL Server 2008’ Category

Replication Gotcha – Including An Article In Multiple Publications

Tuesday, August 31st, 2010

When administering replication topologies it's common to group articles into publications based on roles that subscribers fulfill. Often you'll have multiple subscriber roles and therefore multiple publications, and in some cases a subset of articles are common between them. There's nothing to prevent you from adding the same article to more than one publication but I wanted to point out how this can potentially lead to major performance problems with replication.

Let's start with a sample table:

CREATE TABLE [dbo].[ReplDemo]
   
(
     
[ReplDemoID] [int] IDENTITY(1, 1) NOT FOR REPLICATION
                        
NOT NULL ,
     
[SomeValue] [varchar](20) NOT NULL ,
     
CONSTRAINT [PK_ReplDemo] PRIMARY KEY CLUSTERED ( [ReplDemoID] ASC )
       
ON [PRIMARY]
   
)
ON  [PRIMARY]
GO

Now let's pretend that we need this table replicated to two subscribers which have different roles. We'll create one publication for each role and add the table to both publications:

-- Adding the transactional publication
EXEC sp_addpublication @publication = N'ReplDemo Publication A',
   
@description = N'Publication to demonstrate behavior when same article is in multiple publications',
   
@sync_method = N'concurrent', @retention = 0, @allow_push = N'true',
   
@allow_pull = N'true', @allow_anonymous = N'false',
   
@enabled_for_internet = N'false', @snapshot_in_defaultfolder = N'true',
   
@compress_snapshot = N'false', @ftp_port = 21, @ftp_login = N'anonymous',
   
@allow_subscription_copy = N'false', @add_to_active_directory = N'false',
   
@repl_freq = N'continuous', @status = N'active',
   
@independent_agent = N'true', @immediate_sync = N'false',
   
@allow_sync_tran = N'false', @autogen_sync_procs = N'false',
   
@allow_queued_tran = N'false', @allow_dts = N'false', @replicate_ddl = 1,
   
@allow_initialize_from_backup = N'false', @enabled_for_p2p = N'false',
   
@enabled_for_het_sub = N'false'
GO
EXEC sp_addpublication_snapshot @publication = N'ReplDemo Publication A',
   
@frequency_type = 1, @frequency_interval = 0,
   
@frequency_relative_interval = 0, @frequency_recurrence_factor = 0,
   
@frequency_subday = 0, @frequency_subday_interval = 0,
   
@active_start_time_of_day = 0, @active_end_time_of_day = 235959,
   
@active_start_date = 0, @active_end_date = 0, @job_login = NULL,
   
@job_password = NULL, @publisher_security_mode = 1
GO
-- Adding the transactional articles
EXEC sp_addarticle @publication = N'ReplDemo Publication A',
   
@article = N'ReplDemo', @source_owner = N'dbo',
   
@source_object = N'ReplDemo', @type = N'logbased', @description = N'',
   
@creation_script = N'', @pre_creation_cmd = N'drop',
   
@schema_option = 0x00000000080350DF,
   
@identityrangemanagementoption = N'manual',
   
@destination_table = N'ReplDemo', @destination_owner = N'dbo', @status = 8,
   
@vertical_partition = N'false',
   
@ins_cmd = N'CALL [dbo].[sp_MSins_dboReplDemo]',
   
@del_cmd = N'CALL [dbo].[sp_MSdel_dboReplDemo]',
   
@upd_cmd = N'SCALL [dbo].[sp_MSupd_dboReplDemo]'
GO

-- Adding the transactional publication
EXEC sp_addpublication @publication = N'ReplDemo Publication B',
   
@description = N'Publication to demonstrate behavior when same article is in multiple publications',
   
@sync_method = N'concurrent', @retention = 0, @allow_push = N'true',
   
@allow_pull = N'true', @allow_anonymous = N'false',
   
@enabled_for_internet = N'false', @snapshot_in_defaultfolder = N'true',
   
@compress_snapshot = N'false', @ftp_port = 21, @ftp_login = N'anonymous',
   
@allow_subscription_copy = N'false', @add_to_active_directory = N'false',
   
@repl_freq = N'continuous', @status = N'active',
   
@independent_agent = N'true', @immediate_sync = N'false',
   
@allow_sync_tran = N'false', @autogen_sync_procs = N'false',
   
@allow_queued_tran = N'false', @allow_dts = N'false', @replicate_ddl = 1,
   
@allow_initialize_from_backup = N'false', @enabled_for_p2p = N'false',
   
@enabled_for_het_sub = N'false'
GO
EXEC sp_addpublication_snapshot @publication = N'ReplDemo Publication B',
   
@frequency_type = 1, @frequency_interval = 0,
   
@frequency_relative_interval = 0, @frequency_recurrence_factor = 0,
   
@frequency_subday = 0, @frequency_subday_interval = 0,
   
@active_start_time_of_day = 0, @active_end_time_of_day = 235959,
   
@active_start_date = 0, @active_end_date = 0, @job_login = NULL,
   
@job_password = NULL, @publisher_security_mode = 1
GO
-- Adding the transactional articles
EXEC sp_addarticle @publication = N'ReplDemo Publication B',
   
@article = N'ReplDemo', @source_owner = N'dbo',
   
@source_object = N'ReplDemo', @type = N'logbased', @description = N'',
   
@creation_script = N'', @pre_creation_cmd = N'drop',
   
@schema_option = 0x00000000080350DF,
   
@identityrangemanagementoption = N'manual',
   
@destination_table = N'ReplDemo', @destination_owner = N'dbo', @status = 8,
   
@vertical_partition = N'false',
   
@ins_cmd = N'CALL [dbo].[sp_MSins_dboReplDemo]',
   
@del_cmd = N'CALL [dbo].[sp_MSdel_dboReplDemo]',
   
@upd_cmd = N'SCALL [dbo].[sp_MSupd_dboReplDemo]'
GO

After creating the publications we create our subscriptions, take & apply the snapshot, and we're ready to start making changes so we execute this simple insert statement:

INSERT  INTO dbo.ReplDemo
       
( SomeValue )
VALUES  ( 'Test' )

Here's the million dollar question: How many times does this insert statement get added to the distribution database? To find out we'll run the following statement on the distributor (after the log reader agent has done it's work, of course):

SELECT  MSrepl_commands.xact_seqno ,
       
MSrepl_commands.article_id ,
       
MSrepl_commands.command_id ,
       
MSsubscriptions.subscriber_id
FROM    distribution.dbo.MSrepl_commands AS [MSrepl_commands]
       
INNER JOIN distribution.dbo.MSsubscriptions AS [MSsubscriptions] ON MSrepl_commands.publisher_database_id = MSsubscriptions.publisher_database_id
                                                             
AND MSrepl_commands.article_id = MSsubscriptions.article_id
       
INNER JOIN distribution.dbo.MSarticles AS [MSarticles] ON MSsubscriptions.publisher_id = MSarticles.publisher_id
                                                             
AND MSsubscriptions.publication_id = MSarticles.publication_id
                                                             
AND MSsubscriptions.article_id = MSarticles.article_id
WHERE   MSarticles.article = 'ReplDemo'
ORDER BY MSrepl_commands.xact_seqno ,
       
MSrepl_commands.article_id ,
       
MSrepl_commands.command_id

Here's the output of the statement:

Query Results

That's one row for each publication the table article is included in. Now imagine that an update statement affects 100,000 rows in the table. In this example that would turn into 200,000 rows that will be inserted into the distribution database and need to be cleaned up at a later date. It's not hard to see how this could lead to performance problems for tables that see a high volume of insert\update\delete activity.

Workarounds
Two workarounds for this behavior come to mind:

  1. Modify data using stored procedures, then replicate both their schema and execution. This won't help for insert statements and is useless if you're only updating\deleting a single row each time the procedure executes. This also assumes that all dependencies necessary for the stored procedure(s) to execute exist at the subscriber
  2. Limit table articles to one publication per article. If you're creating publications from scratch then place table articles that would otherwise be included in multiple publications into their own distinct publication. If you're working with existing publications that already include the table article then subscribe only to the article(s) that you need rather than adding the article to another publication. (Subscribing to individual articles within a publication can get tricky - I'll demonstrate how to do this in a future post)

Find Tables and Columns by Data Type

Tuesday, August 24th, 2010

old yellow eyesA couple weeks back someone asked me some questions about data types.  Apparently, while implementing some financial data, each developer on the project had chosen their own data type.  This was a bit of a problem that can lead to serious problems.  When financial data is rounded unexpectedly – bad things can sometimes happen and it usually doesn’t involve plots for half pennies.

Anyways, I advised that it might be a good idea to get all of the data types on these columns aligned. To do this I provided them with a couple scripts that are below that they used to find the occurrences of this information.  These scripts both use the sys.columns and sys.types catalog views.

This first script, pulls out all of the columns that are in the database using decimal, numeric, or money data type.  It includes a filter where scale is not equal to zero – which should have included all of the financial data.

SELECT OBJECT_NAME(c.object_id) as table_name
    , c.name
    , t.name
    , c.precision
    , c.scale
FROM sys.columns c
    INNER JOIN sys.types t ON c.user_type_id = t.user_type_id
WHERE t.name IN ('decimal','numeric','money')
AND c.scale <> 0
ORDER BY 1, 2

The second script lists all of the columns of a specific name with their table and data type information.

SELECT OBJECT_NAME(c.object_id) as table_name
    , c.name
    , t.name
    , c.precision
    , c.scale
FROM sys.columns c
    INNER JOIN sys.types t ON c.user_type_id = t.user_type_id
WHERE c.name = 'ListPrice'
ORDER BY 1, 2

Through the use of these and similar scripts, columns and the tables that they are in can be easily determined.  And this information can be found using either the data type or the name of the column.

Related posts:

  1. Index Those Foreign Keys
  2. Find Tables with Forwarded Records
  3. Webcast Next Week – Performance Impacts Related to Different Function Types

Replication Gotcha: Blank XML

Tuesday, August 24th, 2010

Transactional replication in SQL Server 2005\2008 can handle the XML datatype just fine with few exceptions - one in particular being when the XML value is blank. I'll save the argument about whether or not a blank (or empty string if you prefer) value is well formed XML for another day because the point is that SQL Server allows it. Consider the following table:

CREATE TABLE [dbo].[XMLReplTest]
   
(
     
[XMLReplTestID] [int] IDENTITY(1, 1) NOT FOR REPLICATION
                           
NOT NULL ,
     
[SomeXML] [xml] NOT NULL ,
     
CONSTRAINT [PK_XMLReplTest] PRIMARY KEY CLUSTERED
       
( [XMLReplTestID] ASC ) ON [PRIMARY]
   
)
ON  [PRIMARY]
GO

Execute the following statement and you'll see that SQL Server handles it just fine:

INSERT  INTO dbo.XMLReplTest
       
( SomeXML )
VALUES  ( '' )

Now let's add this table to a transactional replication publication:

-- Adding the transactional publication
EXEC sp_addpublication @publication = N'XML Replication Test',
   
@description = N'Sample publication to demonstrate blank XML gotcha',
   
@sync_method = N'concurrent', @retention = 0, @allow_push = N'true',
   
@allow_pull = N'true', @allow_anonymous = N'false',
   
@enabled_for_internet = N'false', @snapshot_in_defaultfolder = N'true',
   
@compress_snapshot = N'false', @ftp_port = 21, @ftp_login = N'anonymous',
   
@allow_subscription_copy = N'false', @add_to_active_directory = N'false',
   
@repl_freq = N'continuous', @status = N'active',
   
@independent_agent = N'true', @immediate_sync = N'false',
   
@allow_sync_tran = N'false', @autogen_sync_procs = N'false',
   
@allow_queued_tran = N'false', @allow_dts = N'false', @replicate_ddl = 1,
   
@allow_initialize_from_backup = N'false', @enabled_for_p2p = N'false',
   
@enabled_for_het_sub = N'false'
GO
EXEC sp_addpublication_snapshot @publication = N'XML Replication Test',
   
@frequency_type = 1, @frequency_interval = 0,
   
@frequency_relative_interval = 0, @frequency_recurrence_factor = 0,
   
@frequency_subday = 0, @frequency_subday_interval = 0,
   
@active_start_time_of_day = 0, @active_end_time_of_day = 235959,
   
@active_start_date = 0, @active_end_date = 0, @job_login = NULL,
   
@job_password = NULL, @publisher_security_mode = 1
GO

-- Adding the transactional articles
EXEC sp_addarticle @publication = N'XML Replication Test',
   
@article = N'XMLReplTest', @source_owner = N'dbo',
   
@source_object = N'XMLReplTest', @type = N'logbased', @description = N'',
   
@creation_script = N'', @pre_creation_cmd = N'drop',
   
@schema_option = 0x00000000080350DF,
   
@identityrangemanagementoption = N'manual',
   
@destination_table = N'XMLReplTest', @destination_owner = N'dbo',
   
@status = 8, @vertical_partition = N'false',
   
@ins_cmd = N'CALL [dbo].[sp_MSins_dboXMLReplTest]',
   
@del_cmd = N'CALL [dbo].[sp_MSdel_dboXMLReplTest]',
   
@upd_cmd = N'SCALL [dbo].[sp_MSupd_dboXMLReplTest]'
GO

Assume we've created the publication, added a subscriber, taken & applied the snapshot, and we're ready to start changing data. Let's throw a monkey wrench into the works by executing the insert statement with the blank XML again and watch what happens to the log reader agent:

Log Reader Agent Error

That's not a very nice error (or resolution)! I've been able to reproduce this behavior in SQL 2005 & 2008 but I have not tried it in 2008 R2. I've entered a Connect bug report so hopefully this is fixed in a forthcoming cumulative update. In the meantime there is a simple workaround - add a check constraint. Since we're working with the XML datatype the only option for checking length with a scalar function is DATALENGTH. The DATALENGTH for a blank xml value is 5 so we want to check that any inserted or updated value is greater than 5:

ALTER TABLE dbo.XMLReplTest ADD CONSTRAINT
  
CK_XMLReplTest_SomeXML CHECK (DATALENGTH(SomeXML) > 5)
GO

If you are affected by this behavior please consider taking a moment to go vote for it on Connect.

Recap: PGH.NET August 2010 Meeting

Thursday, August 12th, 2010

On August 10th 2010 I attended and presented at the PGH.NET User Group meeting named “5 Guys with Code.”  According to one of the PGH.NET leaders tweet it looks like the headcount was 60+

Twitter  David Hoerster @brittrking Awesome mtg la ..

The following are some thoughts and highlights from the presentations.

Presentations

  •  
    • John Sterrett (Blog | Twitter) – Table Value Parameters with SQL Server 2008 and Microsoft .NET  
  • I presented a feature that is included in SQL Server 2008 and underused by many developers.  This presentation shows developers how to pass a  DataTable, DataReaders and Lists to SQL Server database objects with only two extra lines of C# or VB.NET code. 

    As promised below are some reference links

  • David Hoerster (Blog | Twitter) – jQuery Code Snippets in Visual Studio 2010

Time is money and David’s fifteen minute tip might just save you a lot of time and money.    He covered several tools that will help you generate some awesome JavaScript. 

I  really liked the jsFiddle.NET tool.  It looks like a great tool to mockup some a user interface (more on user interfaces later).

  • Rich Dudley (Blog  | Twitter ) – A Quick Look at the New SQL CE Engine

Being addicted to databases I very happy to see that I wasn’t the only one presenting a topic based on databases.  Rich did a great job explaining what SQL CE can do and what it cannot do. 

Rich blogged about his experience (post includes photos, slides and more)

  • John Hidey (Blog | Twitter) – Layout Controls for XAML

I have to admit that XAML and I don’t get along well.  We had a fling a few years ago.  XAML cheated on me and I haven’t been the same since.

Ok seriously, I tried XAML a few times and found it very hard to understand.  John did a great job going over the common things that are hard to understand when you get started with XAML.   John started with some very basic controls and then built a final example that included all the basic controls.

At this summers PGH.NET Code Camp we had a speakers session where one of the presenters said, “Code is considered legacy code when TDD is not applied.”  Eric bowling for TDD example showed how anyone can start developing TDD.

24 Hours of PASS: Summit Preview

Wednesday, August 11th, 2010

Registration is open for the second 24 Hours of PASS this year. This one is going to be a preview of the Summit itself. So all the sessions are tied, in some manner, to sessions being given at the summit.Here’s a link to go and register.

I’m very excited to be able to say that I’ll be presenting in this 24HOP. One of my presentations at the Summit this year is Identifying and Fixing Performance Problems Using Execution Plans. It covers pretty much what it says, methods for fixing performance problems by exploring the information available within execution plans. But, how do you know you have a performance problem? That’s where my preview session comes in. Identifying Costly Queries will show you several ways to gather metrics on your system so that you can understand which queries are causing you the most pain. Once you know which queries need tuning, you can use execution plans to tune them. Whether you’ll be attending the PASS Summit or not, and whether or not you’ll go to my session once you’re there, I think this 24HOP session will be useful to help you understand where the pain points are within your own systems. I hope you’ll attend.

More importantly though, check out all the other great sessions. This is an excellent collection of presenters and presentations. For anyone who has ever said “PASS doesn’t do anything for me,” I want you especially to take a look at the amazing training opportunities being offered by PASS, for free. The volunteers that run PASS do amazing things and this is just one of them. Take advantage of this opportunity and, hopefully, recognize that PASS is doing things for you. This just barely scratches the surface of all that PASS offers.


DBTA:What to Expect at the PASS 2008 Summit

Monday, August 9th, 2010

With SQL Server 2008 now RTM, what’s your best opportunity to learn about the new features and capabilities of Microsoft’s premier data management platform? The PASS 2008 Community Summit! The Professional Association for SQL Server (www.sqlpass.org) is holding its ninth annual event this November in Microsoft’s own backyard in Seattle at the Washington State Convention Center. [READ MORE]

Posted 15 Sep 2008

Moving SharePoint to the data center

Tuesday, August 3rd, 2010

I cannot speak for the whole legal industry but where I work a lot of people love some SharePoint.  It’s like 50 Cent says, “We love SharePoint like a fat kid loves cake.”  And trust me we love some cake.  With this mad love of SharePoint comes great collaboration and with this great collaboration comes tons of binary files stored in a database.  What does this mean to the DBA? SharePoint now consists of VLDB’s

Hmm… How do we move the VLDB’s across the USA and keep them in sync?

With the built in features of Log Shipping, database Mirroring, Transactional Replication with SQL Server I knew it was possible to migrate the databases and keep them in-sync.   At the time I wasn’t exactly sure of the best way to do this so I used the bat phone.

While some people love SharePoint I love Twitter. Twitter allows me to communicate with several great DBA’s.  For example, I used #sqlhelp which is the equivalent of getting Batman on the bat phone.  This time it was Brent Ozar ( Twitter | Blog) who confirmed my gut feeling that Log Shipping was the way to go.

So…. How do you do it?

The complete process I used is documented at mssqltips #2073.  This tip walks you though the process of 22 steps to get the job done.  I hope this tip helps out other DBA’s that need to migrate VLDB’s from one location to another location without using third party tools.

If you have any comments or suggestions please forward them along.

Running a query against multiple servers at one

Thursday, July 29th, 2010

So you’ve got a bunch of machines that you want to run a quick query against.  SQL Server 2008’s Management Studio gives you a quick and easy.  Open up the Registered Servers in Management Studio and select a group of servers.  Then right click on the group and click on the “New Query” option.

This will open a new query window where you can run a query against all the servers that are online in that group. In my sample query shown below you’ll see that I ran SELECT @@VERSION against all the servers.  When I ran this 3 of the 6 servers in the group were online so three servers were able to return data.

Now if you look at the messages tab (look down) you’ll see which servers the query ran against, and which servers it failed against.  It also tells you what accounts the query was run using (based on the connection info for each server).

Now you can’t merge data together in a temp table as everything in the query window will be run against each server.  It simply displays the information together.  You can pull a single value like I showed above, or you can query a table.

Now when querying from a tables on multiple servers you’ll need to make sure that the schema for those tables are identical otherwise it will only return the data for the first table that it queries.  An error will be shown on the messages tab telling that you that the schemas don’t match if this is the problem.

Denny

Powershell Remoting with SQL Server

Tuesday, July 27th, 2010

One of the best things to come out with Powershell V2 is remoting and asynchronous calls. Between the two of these, you can basically send commands simultaneously to a number of SQL Server instances. BUT… and there always seems to be one of those, there is a lot of work required to get this running right. I’m going to outline what I did recently to test the ability of PowerShell to begin administering my servers remotely. Hopefully this provide the basis for a checklist and a how-to. I’ll update this post over time so that I get things right.

Enable remoting on the machines you wish to call

This requires admin privileges, but it’s pretty simple unless you need to modify which ports are available, etc. But to get it going the easiest way:

Enable-PSRemoting

You’ll get a warning outlining what this will do to the system and asking if you want to continue:

Running command “Set-WSManQuickConfig” to enable this machine for remote management through WinRM service.
 This includes:
    1. Starting or restarting (if already started) the WinRM service
    2. Setting the WinRM service type to auto start
    3. Creating a listener to accept requests on any IP address
    4. Enabling firewall exception for WS-Management traffic (for http only).

Do you want to continue?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is “Y”):

There may be other prompts about the operations that are listed above (in fact, “will be” is a better way to phrase it). In general, work through the help files to understand what all that means.

Configure Sessions

We’re talking about working with SQL Server here, so you know that you need to load the snapin. Easy right. In fact, you probably already have it loading by default through your configuration. Ah, but here’s the issue. When you’re running remotely, the session on that other machine is not running under your context. So it’s not going to use your configuration at all. Instead you need to define a session. There are several ways you could do this. Steven Muraski (blog|twitter) has a mechanism for forcing configurations to the remote machines. I haven’t tried this yet. I did the brute force approach.

First you create a script that holds the session information you want on each of the machines, in this case:

add-pssnapin SqlServerCmdletSnapin100

add-pssnapin SqlServerProviderSnapin100

That loads the necessary snapins for SQL Server. Once that’s done, you have to register this as a named configuration on the system:

[sourcode language="powershell"]Register-PSSessionConfiguration -Name SQLShell -StartupScript C:\scripts\sql.ps1[/sourcecode]

Again, this is run on each machine that you wish to remote to. You can do this through remote sessions, funny enough. Once you’ve enabled remoting and set up the sessions, they’ll stay in place, as is, even after rebooting the system. This means you only have to do this once.

Remoting to SQL Server

You can create multiple sessions and then call them asynchronously, but instead, I tried a different tack. This is my full script:


$instances = @{"Server1"="Server1\InstanceA"; "Server2"="Server2\InstanceB"}

$job = Invoke-Command -ComputerName (Get-Content "c:\scripts\serverlist.txt") -ScriptBlock {param($rinstances) Invoke-Sqlcmd -ServerInstance $rinstances.$env:computername -Query "SELECT * FROM sys.dm_exec_requests WHERE session_id > 50"} -JobName tsql -ConfigurationName SqlShell -ArgumentList $instances

Wait-Job tsql

$results = Receive-Job -Name tsql
$results

Stop-Job -Name tsql
Remove-Job -Name tsql

I created a list of servers and put it in a file, serverlist.txt. Because I’m dealing with instances, I need a way to match the list of servers to the instances. I did this with the associative array (aka hash table), $instances. I’m calling Invoke-Command and passing it a list of computer names through the serverlist.txt file. I pass that a script block, more about that in a minute, and I set a JobName as tsql. This makes the Invoke-Command into a remote job, but in my case, a set of remote jobs. I pass it the the configuration we created earlier with -ConfigurationName.

The ScriptBlock is pretty straight forward from there. The one extra wrinkle that I had to get right, and thanks to Steven Muraski, who got me through this little roadblock as well as several others (all through Twitter by the way), is that you have to get your local parameter into the script block through the use of param and -ArgumentList. Then I just called it based on the server name I was running on (yes, what if I had more than one instance, I didn’t, OK?).

Then, because I wanted to see it and didn’t want to go through a process of collecting information as it finished, I just told it to wait on the job, by name. Then I collected the results, displayed them through the default and shut down the job and removed it.

So this is one, admittedly less than perfect, approach to getting remoting working with SQL Server in PowerShell. I’m going to spend more time on this to refine the process.

For a completely different view of the exact same problem, go check out what Aaron Nelson (blog|twitter) did. We were working on this at roughly the same time and exchanging notes. He helped me, I hope I helped him a bit.


Free one day training on Storage and Virtualization with Mr.Denny

Sunday, July 25th, 2010

Free training is good, if it is on a special topic important for every DBA then better, if it is coming from an industry expert on the subject then much better, if it is an all day event then excellent, if it is from Mr.Denny then excellent * 2, if you can get all of the above and get cool swag (xbox 360) then excellent * 3.

Why wait? Register for this session on Storage and Virtualization for the DBA session by Mr.Denny at Microsoft Office in Irvine, CA on Aug 9th 2010.

Yes, the event is on a monday but you will get good training without pluff on the topic. And its about time to burn that vacation day and use it wisely to learn something about the topic if you are around the area. Talk to your manager/supervisor to register for this event as the seats are limited and will fill up as first come first served basis.

Note that this event is priced at $395 at PASS conference and you are getting this for FREE! It’s a win, win!

Going into 2011, I want to focus on Storage and High availability side in SQL Server and its a good opportunity for me to attend this session and its worth taking a 7 hour drive. :-)

Digg This  Reddit This  Stumble Now!  Buzz This  Vote on DZone  Share on Facebook  Bookmark this on Delicious  Kick It on DotNetKicks.com  Shout it  Share on LinkedIn  Bookmark this on Technorati  Post on Twitter  Google Buzz (aka. Google Reader)