<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SQL Server with Mr. Denny &#187; Paul Randal</title>
	<atom:link href="http://itknowledgeexchange.techtarget.com/sql-server/tag/paul-randal/feed/" rel="self" type="application/rss+xml" />
	<link>http://itknowledgeexchange.techtarget.com/sql-server</link>
	<description></description>
	<lastBuildDate>Wed, 19 Jun 2013 19:39:00 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Deleting LOB Data and Shrinking the Database</title>
		<link>http://itknowledgeexchange.techtarget.com/sql-server/deleting-lob-data-and-shrinking-the-database/</link>
		<comments>http://itknowledgeexchange.techtarget.com/sql-server/deleting-lob-data-and-shrinking-the-database/#comments</comments>
		<pubDate>Wed, 13 Mar 2013 14:00:52 +0000</pubDate>
		<dc:creator>Denny Cherry</dc:creator>
				<category><![CDATA[Andre Kamman]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[DBCC PAGE]]></category>
		<category><![CDATA[Mladen Prajdić]]></category>
		<category><![CDATA[Paul Randal]]></category>
		<category><![CDATA[SQL Saturday]]></category>
		<category><![CDATA[SQL Saturday 194]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[SQL Server 2008 R2]]></category>
		<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[System Objects]]></category>
		<category><![CDATA[Tables]]></category>

		<guid isPermaLink="false">http://itknowledgeexchange.techtarget.com/sql-server/?p=2564</guid>
		<description><![CDATA[While attending SQL Saturday 194 in Exeter over in England one of the attendees came to Mladen Prajdić, Andre Kamman and myself with an interesting problem.  She had a database table which was about 200 Gigs in size which she wanted to delete about half of the data from the table.  The catch was that the [...]]]></description>
				<content:encoded><![CDATA[<p>While attending <a href="http://www.sqlsaturday.com/194/eventhome.aspx">SQL Saturday 194</a> in Exeter over in England one of the attendees came to Mladen Prajdić, Andre Kamman and myself with an interesting problem.  She had a database table which was about 200 Gigs in size which she wanted to delete about half of the data from the table.  The catch was that the database table was full of LOB data where the rows were very large, with an average LOB data size of over a meg.  She also needed to shrink the database after the database was deleted so that she could reclaim the space from the database.  Oh and all this had to be done on SQL Server 2005 Standard Edition. (Everything here applies to SQL Server up through SQL Server 2012 as well.)</p>
<p>Deleting the data from the database is the easy part, a simple delete loop will handle that nicely.  The problem is when you delete rows from a table which contains LOB data the LOB pages aren&#8217;t cleared when they are deallocated.  We can see this by running the following code.</p>
<p><code>CREATE DATABASE Lobtest<br />
GO<br />
use Lobtest<br />
GO<br />
CREATE TABLE t1 (c1 int IDENTITY(1,1) PRIMARY KEY, c2 ntext)<br />
GO<br />
INSERT INTO T1 (c2) VALUES (replicate('a', 20000))<br />
GO<br />
DBCC IND ('LobTest', 't1', 1)<br />
GO<br />
DBCC TRACEON(5201, -1)<br />
GO<br />
DELETE FROM t1<br />
GO<br />
DBCC IND ('LobTest', 't1', 1)<br />
GO<br />
DECLARE @dbid as int = db_id('Lobtest')<br />
DBCC PAGE (@dbid, 1, 231, 3)<br />
GO</code></p>
<p>You can see that page 231 is a LOB page which is allocated to the table t1. When you look at the actual page using DBCC PAGE after the row has been deleted we can see that there is data in the page, and that the page header shows that the page is still allocated to the table t1. This can be seen by looking in the header of the page for the header value labeled &#8220;Metadata: ObjectId = 245575913&#8243;.</p>
<p>When you go to shrink the database the SQL Server engine will get to the LOB pages and it will need to figure out if the LOB row is a part of a row which still exists or not. In order to do this SQL Server will need to scan through the pages which make up the table looking for any rows which reference the page it is trying to delete.</p>
<p>When doing shrinks after deleing large amounts of LOB data SQL Server will generate large amounts of IO while figuring this out and the shrink operation will take an extremely long time. (Paul Randle talks more about <a href="http://www.sqlskills.com/blogs/paul/why-lob-data-makes-shrink-run-slooooowly-t-sql-tuesday-006/">it here</a>.)</p>
<p>So the question that this person at SQL Saturday had was, how can I reclaim the space from my database within a reasonable time.</p>
<p>The solution that we came up with was actually pretty simple.  Do the database deletion as normal.  Then backup and restore the database.  Then do the shrink, followed by rebuilding the clustered indexes in order to fix the fragmentation issue which the shrink will introduce.</p>
<p>This works for a pretty simple reason, because the PFS page shows that the LOB page isn&#8217;t allocated even though the page is full of data (you can verify this by looking at page 1 in file 1 in the sample database created by the script above).  When the database engine backups up the database the database engine looks at the PFS pages to figure out which pages to back up.  Because the PFS pages show that the pages are empty the database engine doesn&#8217;t bother to backup the pages, so when the pages are restored they are restored as blank pages.  This means that after the restore the shrink operation can run without an issue.</p>
<p>In the case of this application there was a maintenance window which could be taken advantage of which would allow the backup and the restore to happen.</p>
<p>Another option which we came up with which would require less downtime involved using database mirroring.  By configuring database mirroring (which is initialized via a backup and restore process giving us the same basic approach) and then failing over to the mirror we would end up in the same position.  We could then shrink the database without issue (probably pausing database mirroring so that we didn&#8217;t have to wait for the second server to process the shrink in real time) and then fail back the database to the original server.</p>
<p>As geeky as it was, Mladen, Andre and I had a great time figuring this out, and the attendee had a great time watching us go through all the possible options as we excluded them one by one.  And most importantly she got her problem solved.</p>
<p>So if you end up in this situation here&#8217;s a solution that will help you shrink the database so that you can reclaim the space that the LOB data pages are taking up without having to wait forever.</p>
<p>Denny</p>
<!-- wpms-network-global-inserts -->]]></content:encoded>
			<wfw:commentRss>http://itknowledgeexchange.techtarget.com/sql-server/deleting-lob-data-and-shrinking-the-database/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Lets get session state out of the database, and into memory where it belongs.</title>
		<link>http://itknowledgeexchange.techtarget.com/sql-server/lets-get-session-state-out-of-the-database-and-into-memory-where-it-belongs/</link>
		<comments>http://itknowledgeexchange.techtarget.com/sql-server/lets-get-session-state-out-of-the-database-and-into-memory-where-it-belongs/#comments</comments>
		<pubDate>Thu, 06 Jan 2011 14:00:38 +0000</pubDate>
		<dc:creator>Denny Cherry</dc:creator>
				<category><![CDATA[Paul Randal]]></category>
		<category><![CDATA[Session State]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://itknowledgeexchange.techtarget.com/sql-server/lets-get-session-state-out-of-the-database-and-into-memory-where-it-belongs/</guid>
		<description><![CDATA[One of the all to common configuration mistakes that are made is to put the session state within the SQL Server when a website begins to scale to multiple web servers. Some background For those that don&#8217;t know what session state is, let me take a step back and fill you in.  Session state allows [...]]]></description>
				<content:encoded><![CDATA[<p>One of the all to common configuration mistakes that are made is to put the session state within the SQL Server when a website begins to scale to multiple web servers.</p>
<p><strong>Some background</strong></p>
<p>For those that don&#8217;t know what session state is, let me take a step back and fill you in.  Session state allows the web developer to store values in variables up on the web server, but in a shared location so that it doesn&#8217;t matter what web server the end user connects to the values are all there and the web servers understand the session information from each other.  This is very important for shopping websites, or pretty much any site with a login prompt and a load ballancer that is configured to send the users connection to the next available web server.</p>
<p><strong>What is the problem?</strong></p>
<p>The problem becomes that most people when they need to scale out session state opt to put the session state information into SQL Server because that is a nice easy repository that is probably already up and running, not to mention that the session state code in ASP.NET easily supports it.  The issue with putting the session state information into SQL Server is that you don&#8217;t give a crap about persisting the session state information to disk.  The information doesn&#8217;t get persisted more than an hour or so, and if the information within the database is lost, the only impact is that any values in session variables is lost.</p>
<p><strong>So what are the options?</strong></p>
<p>There are a few options besides using SQL Server for session state.</p>
<ol>
<li>Keep using the in-process option.</li>
<li>Use the ASP.NET Session State Service</li>
</ol>
<p>The easiest option is to keep using the in-process option in IIS for session information.  This means that you will need to configure what are called sticky sessions on the load balancer so that the user always goes to the same web server every time.  In the event that a web server fails, all the session information for those users would be lost, and they would need to start over by logging back into the site, or they would have an empty shopping cart, or whatever the site does.</p>
<p>The ASP.NET Session State Service is a Windows service that provides a memory only session state repository so that session information isn&#8217;t ever written to disk, and it isn&#8217;t kept on the web server.  You can either stand up a dedicated machine for this, or setup a couple and cluster the service manually so that you have an HA solution for your session state service.  If you have an existing SQL Server cluster you can even use this cluster for it, if you don&#8217;t have anywhere better to put it.  Just configure the cluster to have the SQL Server run on one node as the preferred node, and have the session state run on another node as its preferred node.  This way the services won&#8217;t ever run on the same node unless the other node is offline.  The session state service doesn&#8217;t take a lot of CPU power, and the amount of RAM it needs to be completely dependent on the amount of information that you are stuffing into session variables on the web servers.</p>
<p>In either case, either solution is better than putting the session state information into a SQL Server database.  The information doesn&#8217;t need to be written to disk, ever.  The information that is written into the session state database is in a blob binary form, not any sort of relational form so you can&#8217;t really do anything with it.</p>
<p><strong>How do I know if sessions state is in SQL?</strong></p>
<p>That is an easy one.  You&#8217;ll have some funky database, probably in simple recovery mode usually name aspnetdb (maybe with a prefix and/or a suffix).</p>
<p><strong>What other problems can session state cause?</strong></p>
<p>Well first it&#8217;ll take away buffer pool resources from your other databases.  Because the session state database is hit very hard the data from the database will always be in memory.  How ever much data is in the session state database, you are missing that much buffer pool space for your other databases.  Because of the way that session state works, every single time a page is clicked on the website, at least one call is made to the session state database pretty much forcing the database server to keep the data from the database in the buffer pool.</p>
<p>Another problem that you can see if ghost records.  Paul Randal describes ghost records perfectly on his blog post <a href="http://www.sqlskills.com/BLOGS/PAUL/post/Inside-the-Storage-Engine-Ghost-cleanup-in-depth.aspx">Ghost cleanup in depth.</a></p>
<blockquote><p>When a record is deleted, apart from  it being marked as a ghost record, the page that the record is on is  also marked as having ghost records in one of the allocation maps &#8211; the  PFS page (post coming soon!) &#8211; and in its page header. Marking a page as  having ghost records in a PFS page also changes the database state to  indicate that there are some ghost records to cleanup &#8211; somewhere.  Nothing tells the ghost cleanup task to clean the specific page that the  delete happened on - yet. That only happens when the next scan  operation reads the page and notices that the page has ghost records. </p></blockquote>
<p>He also talks about how to fix the problem in the same blog post, so I&#8217;ll leave you to <a href="http://www.sqlskills.com/BLOGS/PAUL/post/Inside-the-Storage-Engine-Ghost-cleanup-in-depth.aspx">click through</a> for all that information.</p>
<p>Another problem goes back to the fact that the SQL Server will be persisting everything to disk, and with the information in this database changing all the time, as the website grows you&#8217;ll need faster and faster disks under the session state database just to keep up.  As the site grows more popular you will end up spending more and more money on faster and faster disks, just to keep the session state working, much less anything else on the SQL Server.  You may even get to the point where you actually need a dedicated SQL Server just to run the session state database.</p>
<p>Another problem is good old locking and blocking.  SQL Server likes to take page level locks when it does insert, update and delete operations.  Well, unless each page on disk only has a single row in it you are going to have processes being blocked for short periods of time as other users session state information is updated.  You can work around this to some extent by hacking the session state database&#8217;s stored procedures and forcing row locks, but now you are taking more locks (and more memory for locks), etc.</p>
<p><strong>How do I change to the session state server?</strong></p>
<p>First you need to install the service on the server that will be your session state server.  On Windows 2008 just install all the .NET components and that should do the trick.  You&#8217;ll probably want to start the service as well.  When you bring up the list of services it is the one called &#8220;ASP.NET State Service&#8221;.<br />
<a href="http://www.mrdenny.com/blog/images/Session Service in list.jpg"><img src="http://www.mrdenny.com/blog/images/Session Service in list.jpg" border="0" alt="" /></a></p>
<p>Then on each web server you&#8217;ll want to change the session state information.  You can either use IIS Manager to do this, or change the web.config.  However you configured session state the first time, that&#8217;s how you&#8217;ll want to change it this time.</p>
<p>To use the IIS Manager select the website (or application) to configure and double click on the &#8220;Session State&#8221; icon on the right (shown below).<br />
<a href="http://www.mrdenny.com/blog/images/SessionStateIcon.jpg"><img src="http://www.mrdenny.com/blog/images/SessionStateIcon.jpg" border="0" alt="" /></a></p>
<p>From there select &#8220;State Server&#8221; from the list and change &#8220;localhost&#8221; to the server you&#8217;ll be using for session state.  If you have changed the TCP port number from 42424 to something else you can adjust that here as well.<br />
<a href="http://www.mrdenny.com/blog/images/SessionStateSettings.jpg"><img src="http://www.mrdenny.com/blog/images/SessionStateSettings.jpg" border="0" alt="" width="158" height="120" /></a></p>
<p>To set the session state setting via the web.config file find the existing session state information and edit it, or add in the session state information.  Set the &#8220;mode&#8221; to &#8220;StateServer&#8221; and set the &#8220;stateConnectionString&#8221; to the same value that goes in the IIS config setting.</p>
<pre>&lt;configuration&gt;
  &lt;system.web&gt;
    &lt;sessionState mode="StateServer"
      stateConnectionString="tcpip=SampleStateServer:42424"
      cookieless="false"
      timeout="20"/&gt;
  &lt;/system.web&gt;
&lt;/configuration&gt;
</pre>
<p>Hopefully I&#8217;ve convinces you to move your session state information out of SQL Server and into a repository that it actually belongs in.</p>
<p>Denny</p>
<!-- wpms-network-global-inserts -->]]></content:encoded>
			<wfw:commentRss>http://itknowledgeexchange.techtarget.com/sql-server/lets-get-session-state-out-of-the-database-and-into-memory-where-it-belongs/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Today&#8217;s plagiarism incident&#8230;</title>
		<link>http://itknowledgeexchange.techtarget.com/sql-server/todays-plagiarism-incident/</link>
		<comments>http://itknowledgeexchange.techtarget.com/sql-server/todays-plagiarism-incident/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 02:03:54 +0000</pubDate>
		<dc:creator>Denny Cherry</dc:creator>
				<category><![CDATA[Allen Kinsel]]></category>
		<category><![CDATA[Brent Ozar]]></category>
		<category><![CDATA[DCMA]]></category>
		<category><![CDATA[Paul Randal]]></category>
		<category><![CDATA[Plagiarism]]></category>
		<category><![CDATA[SearchSQLServer.com]]></category>
		<category><![CDATA[SQLServerPedia.com]]></category>
		<category><![CDATA[Todd McDermid]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://itknowledgeexchange.techtarget.com/sql-server/todays-plagiarism-incident/</guid>
		<description><![CDATA[If you are on Twitter and you follow some of the more popular people on twitter (BrentO, PaulRandal, SQLInsaneo, myself, etc) you&#8217;ll probably have noticed a sh*t storm of tweets about a certain blog which was plagiarizing information from lots of places including places like Microsoft&#8217;s TechNet and MSDN sites, SearchSQLServer.com, and several blogs. After [...]]]></description>
				<content:encoded><![CDATA[<p>If you are on Twitter and you follow some of the more popular people on twitter (<a href="http://twitter.com/BrentO">BrentO</a>, <a href="http://twitter.com/PaulRandal">PaulRandal</a>, <a href="http://twitter.com/SQLInsaneo">SQLInsaneo</a>, <a href="http://twitter.com/mrdenny">myself</a>, etc) you&#8217;ll probably have noticed a sh*t storm of tweets about a certain blog which was plagiarizing information from lots of places including places like Microsoft&#8217;s <a href="http://technet.microsoft.com">TechNet</a> and <a href="http://msdn.microsoft.com">MSDN </a>sites, <a href="http://www.SearchSQLServer.com">SearchSQLServer.com</a>, and several blogs.</p>
<p>After the blogger in question (Peter) removed all his SQL content (no idea if it was all plagiarized or just some was and taking it all down was easier) everything settled down a bit.</p>
<p>Later that day <a href="http://toddmcdermid.blogspot.com">Todd McDermid</a> posted a <a href="http://toddmcdermid.blogspot.com/2010/01/another-instance-of-plagiarism.html">blog post</a> giving a bit of an overview of today&#8217;s events and his opinions about the plagiarism and our reaction to it.</p>
<p>Before I continue I want to say that I fully respect Todd and his opinions on the subject, even though I don&#8217;t agree with them.  Anyone willing to sit around and write for other people&#8217;s education for little or no money deserves to be respected.</p>
<p>Now as for the DMCA style take down nasty grams (and I like that way better then take down notices for some reason) there are other issues at play than just our giving information away to everyone.</p>
<p>For example, if you dig through Microsoft&#8217;s TechNet and MSDN sites there&#8217;s plenty in there which says that you can&#8217;t republish the information posted without written consent.</p>
<blockquote><p>&#8220;Unless otherwise specified, the Services are for your personal and  								non-commercial use. You may not modify, copy, distribute, transmit, display,  								perform, reproduce, publish, license, create derivative works from, transfer,  								or sell any information, software, products or services obtained from the  								Services.&#8221; *Stolen directly from the <a href="http://www.microsoft.com/info/cpyright.mspx#EEB">TechNet ToS</a> which I found by clicking the Terms of Use link at the bottom of every page on the TechNet site.</p></blockquote>
<p>As for my articles which were plagiarized, the company which paid for those articles to be written (I&#8217;m assuming that it comes as no shock to anyone that people are paid to write articles for websites and magazines) owns the copyright on those articles for as long as they choose to enforce them.  Some companies hold a lifetime exclusive on the articles, while others hold a shorter one.</p>
<p>Either the blogger in question or not was aware of the law on plagiarism or not, but he states on his website that he&#8217;s a college graduate.  Pretty much every college will toss you out for plagiarizing other peoples works, and the students are well aware of it.  He should have assumed that in the professional world that plagiarizing was still unacceptable.</p>
<p>Unfortunately for Peter there is a lot of information out there which can be freely read and referenced, but not copied.  This blog would be included in that.  For those of you reading this on <a href="http://sqlserverpedia.com/blog/">SQLServerPedia.com</a> it took a decent amount of work to get permission to post my blog posts up on the SQLServerPedia.com blog feed.  Why did it take so long?  Well because I don&#8217;t own the copyright to these blog posts.  I write on behalf of Tech-Target and they own the copyright to anything and everything which I post on my blog, unless I have posted it somewhere else first (and then they still own the rights to the version on their site).</p>
<p>Would I like to have everyone be able to read what I write?  The big reason that I spend so much time writting (especially this last month) is so that people can read it.  I have information to share, and hopefully people find the information that I have useful.  But a the copyright ownership of information has to be respected for web based articles just like it does for SQL Server Magazine, TechNet Magazine, etc.</p>
<p>These are my thoughts and opinions, on today&#8217;s events.  Take them for what they are worth, god knows I&#8217;m no copyright lawyer.  Please feel free to post your own here, on twitter, on <a href="http://toddmcdermid.blogspot.com/2010/01/another-instance-of-plagiarism.html">Todd&#8217;s post</a> (no registration required on his blog, unlike here) or your own blog if you have one.</p>
<p>Denny</p>
<!-- wpms-network-global-inserts -->]]></content:encoded>
			<wfw:commentRss>http://itknowledgeexchange.techtarget.com/sql-server/todays-plagiarism-incident/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
