<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>ishabib</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/ishabib1/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/ishabib1/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 03:49:01 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>SQL Server - To AWE or not to AWE? That is the question!!</title>
      <link>https://docs.microsoft.com/archive/blogs/ishabib1/sql-server-to-awe-or-not-to-awe-that-is-the-question</link>
      <pubDate>Wed, 01 Jan 2014 05:28:00 GMT</pubDate>
      <dc:creator><![CDATA[Ismail Habib]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ishabib1/2014/01/01/sql-server-to-awe-or-not-to-awe-that-is-the-question/</guid>
      <description><![CDATA[&nbsp;
Address Windows Extension has always been a debate and I always get the question of whether...]]></description>
      <content:encoded><![CDATA[<p class="Publishwithline"><span style="font-family: Calibri; font-size: xx-small;">&nbsp;</span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Address Windows Extension has always been a debate and I always get the question of whether to enable AWE on SQL Server or not. Now to be honest this is not a straight forward answer there are multiple options here that we need to look at and we cannot discuss AWE without talking about Lock Pages in Memory option.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">To summarize you have the following options</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">1)</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: small;"><span style="font-family: Calibri;">32-bit SQL Server on 32-bit OS&nbsp;--&gt;</span><span style="font-family: Calibri;">&nbsp;not much can you do here unless you enable /PAE where the OS can access up to 64 Gigs of memory then Enable AWE and Lock pages in memory</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">2)</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: small;"><span style="font-family: Calibri;">32-bit SQL Server on 64-bit OS&nbsp;--&gt;</span><span style="font-family: Calibri;"> Enable AWE and Lock Pages in Memory</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">3)</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: small;"><span style="font-family: Calibri;">64-bit SQL Server on 64-bit OS</span><span style="font-family: Calibri;">&nbsp; --&gt;AWE Option is ignored, its best to enable Lock Pages in Memory</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">4)</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: small;"><span style="font-family: Calibri;">64-bit SQL Server on 32-bit OS&nbsp;--&gt;</span><span style="font-family: Calibri;"> :P just messing with you guys</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">So that is the short answer however to actually understand why these options are the recommended options that is the tricky part. So we will start by explaining why there is a 4 Gigs limits on 32-bit architecture. Followed by what AWE does to the OS and memory, we will also touch the Lock Pages in Memory. Then we will wrap up at this point of time not really sure of what since I wrapped up at the beginning but when we reach there we will figure something out.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">So why can&rsquo;t 32-bit architecture support more than 4 Gigs?</span></span></p>
<p><span style="font-family: Calibri;"><span style="font-size: small;">It&rsquo;s simple a 32-bit processors means that it has 32 bit address lines &ndash; address lines are the lines connecting the processors to the Memory since it all boils down to 0 and 1 (wires can either have electricity or not) each address lines specifies a single byte in the address putting 32 address combinations of 0&rsquo;s and 1&rsquo;s you get only 2</span><sup><span style="font-size: x-small;">32</span></sup><span style="font-size: small;">-1 different options and that is about 4 gigs of memory (minus 1 byte). That basically means that each pointers used by your application are of 32 bit.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">So how are these 4 gigs mapped after all any application needs to use the OS (Kernel) and should be managed by the OS, well for simplicity, the 4 gigs are divided as follows Address (0x80000000 to 0xFFFFFFFF) are used by the OS, that is about 2 gigs of memory and the remaining 2 gigs (from address 0x00000000 to 0x7FFFFFFF) are used by your application this is shown in the figure below.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/3884.32bitProcessaddressspace.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/3884.32bitProcessaddressspace.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/3884.32bitProcessaddressspace.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/3884.32bitProcessaddressspace.PNG" alt="" width="269" height="267" border="0" /></a></span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Okay so that answers the 32 bit 4 gig byte address issue we won&rsquo;t get into PAE and /3gb its sort of outside the scope of this article however you can check the links below for details on this.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">/3GB: </span><a href="https://msdn.microsoft.com/en-us/library/windows/hardware/ff556232(v=vs.85).aspx"><span style="color: #0563c1; font-family: Calibri; font-size: small;">https://msdn.microsoft.com/en-us/library/windows/hardware/ff556232(v=vs.85).aspx</span></a></p>
<p><span style="font-family: Calibri; font-size: small;">PAE: </span><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa366796(v=vs.85).aspx"><span style="color: #0563c1; font-family: Calibri; font-size: small;">https://msdn.microsoft.com/en-us/library/windows/desktop/aa366796(v=vs.85).aspx</span></a></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Okay so this is all 32-bit on 32-bit but what happens to the address space of 32-bit process on a 64 bit OS. Does it use 2 Gigs for the process? Does it use 4 gigs for the process? How much memory is used for the OS?</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">The answers are as follows </span></span></p>
<p><span style="font-size: small;">&agrave;<span style="font-family: Calibri;">The 32- bit is allocated the 4 gigs of memory</span></span></p>
<p><span style="font-size: small;">&agrave;<span style="font-family: Calibri;">The OS still uses 2 gigs it turns out it only needs 2 gigs.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Not only that the Process still uses the top 4 gigs and 0x0000000 - 0x80000000 and the OS uses the bottom space. All the memory in between is left free to ensure that the Process Address space does not override the OS an additional security mechanism &ndash; Cool!</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Okay so what is AWE?</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Address Windowing Extensions (AWE) allow 32-bit&nbsp;process to access large amounts of memory, i.e over 4 Gigs as explained earlier</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Now the trick is all in how AWE works.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Now a 32-bit application can only see a maximum of 4 gigs on a 64-bit OS however the OS can see more than 4 gigs, but what if we need more than 4 gigs of memory what if we are loading more than 4 gigs we have 2 options here</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">1)</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: small;"><span style="font-family: Calibri;">Paging data from and to the hard disk (really slow because of the mechanical movement required to allocate the required data.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">2)</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: small;"><span style="font-family: Calibri;">If it&rsquo;s a 64-bit OS load all the required data for example SQL Server data file into the memory and instead of paging to the hard disk we can page to the memory (not fully accurate but will do for explanation purposes.)</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">And this is what AWE is all about it creates an address window in the 4 gigs address space and allows you to move data to and from the 4 gigs address space but this data is not loaded from hard disk it is loaded from the memory.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">So how does windows do that well its simple uses a set of API&rsquo;s that are used to load memory to and from the 4 gigs of memory.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">AWE actually needs to place a few restrictions on the memory that is being used. I have copied these restrictions from the following link (</span><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa366527(v=vs.85).aspx)"><span style="color: #0563c1; font-family: Calibri; font-size: small;">https://msdn.microsoft.com/en-us/library/windows/desktop/aa366527(v=vs.85).aspx)</span></a></p>
<ul>
<li><span style="font-size: small;"><span style="font-family: Calibri;">Virtual address ranges allocated for the AWE are not sharable with other processes (and therefore not inheritable). In fact, two different AWE virtual addresses within the same process are not allowed to map the same physical page. These restrictions provide fast remapping and cleanup when memory is freed.</span></span></li>
<li><span style="font-size: small;"><span style="font-family: Calibri;">The physical pages that can be allocated for an AWE region are limited by the number of physical pages present in the machine, since this memory is never paged &ndash; it is locked down until the application explicitly frees it or exits. The physical pages allocated for a given process can be mapped into any AWE virtual region within the same process. Applications that use AWE must be careful not to take so much physical memory that they cause other applications to page excessively or prevent creation of new processes or threads due to lack of resources. Use the</span> <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx"><strong><span style="font-family: Calibri;">GlobalMemoryStatusEx</span></strong></a> <span style="font-family: Calibri;">function to monitor physical memory use.</span></span></li>
<li><span style="font-size: small;"><span style="font-family: Calibri;">AWE virtual addresses are always read/write and cannot be protected via calls to <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa366898(v=vs.85).aspx"><strong>VirtualProtect</strong></a></span> <span style="font-family: Calibri;">(that is, no read-only memory, noaccess memory, guard pages, and the like can be specified).</span></span></li>
<li><span style="font-size: small;"><span style="font-family: Calibri;">AWE address ranges cannot be used to buffer data for graphics or video calls.</span></span></li>
<li><span style="font-size: small;"><span style="font-family: Calibri;">An AWE memory range cannot be split, nor can pieces of it be deleted. Instead, the entire virtual address range must be deleted as a unit when deletion is required. This means you must specify MEM_RELEASE when calling</span> <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa366892(v=vs.85).aspx"><strong><span style="font-family: Calibri;">VirtualFree</span></strong></a><span style="font-family: Calibri;">.</span></span></li>
<li><span style="font-size: small;"><span style="font-family: Calibri;">Applications can map multiple regions simultaneously, provided they do not overlap.</span></span></li>
<li><span style="font-size: small;"><span style="font-family: Calibri;">Applications that use AWE are not supported in emulation mode. That is, an x86 application that uses AWE functions must be recompiled to run on another processor, whereas most applications can run without recompiling under an emulator on other platforms.</span></span></li>
</ul>
<p><span style="font-size: small;"><span style="font-family: Calibri;">In order to use AWE your SQL Service account has to be able to lock the pages in memory. That is to prevent the paging out of the extended memory space as to not cause two processes to access the same address space and corrupt each other&rsquo;s address space.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">Now how does SQL Server do AWE. Well on 32 bit systems and I stole this algorithm from CSS SQL Server Engineers blog in the following link. (</span><a href="https://blogs.msdn.com/b/psssql/archive/2007/10/18/do-i-have-to-assign-the-lock-privilege-for-local-system.aspx"><span style="color: #0563c1; font-family: Calibri; font-size: small;">https://blogs.msdn.com/b/psssql/archive/2007/10/18/do-i-have-to-assign-the-lock-privilege-for-local-system.aspx</span></a><span style="font-size: small;"><span style="font-family: Calibri;">)</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">1)</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: small;"><span style="font-family: Calibri;">If AWE is not enabled and there is enough memory </span>&agrave;<span style="font-family: Calibri;"> print a message in the errorlog guiding the user to use AWE</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">2)</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: Calibri; font-size: small;">If the lock pages in memory is not set correctly that is insufficient privileges or not set at all nothing is printed in the errorlog nothing is printed at all it uses the AdjustTokenPrivileges() API (</span><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa375202(v=vs.85).aspx)"><span style="color: #0563c1; font-family: Calibri; font-size: small;">https://msdn.microsoft.com/en-us/library/windows/desktop/aa375202(v=vs.85).aspx)</span></a></p>
<p><span style="font-family: Calibri; font-size: small;">3)</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: small;"><span style="font-family: Calibri;">If both are good it prints a message informing to the user is printed indicating AWE is Enabled,</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">So what happens in a 64-bit SQL Server well the option of AWE is ignored since the address space does not have the 4 gigs limit however lock paging in memory does enhance the performance of SQL Server cause it allows SQL Server to prevent the OS from paging information back to the hard disk and hence enhances the performance of SQL Server.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">But how is that done.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">Well take a look at the code sample below of an example of using AWE. You can find this sample in (</span><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa366531(v=vs.85).aspx)"><span style="color: #0563c1; font-family: Calibri; font-size: small;">https://msdn.microsoft.com/en-us/library/windows/desktop/aa366531(v=vs.85).aspx)</span></a></p>
<p><span style="font-family: Calibri; font-size: small;">&nbsp;</span></p>
<p>&nbsp;</p>
<pre class="scroll"><code class="cplusplus">#include &lt;windows.h&gt;<br /> <br /> #include &lt;stdio.h&gt;<br /> <br /> #include &lt;tchar.h&gt;<br /> <br /> <br /> <br /> #define MEMORY_REQUESTED 1024*1024 // request a megabyte<br /> <br /> <br /> <br /> BOOL<br /> <br /> LoggedSetLockPagesPrivilege ( HANDLE hProcess,<br /> <br /> BOOL bEnable);<br /> <br /> <br /> <br /> void _cdecl main()<br /> <br /> {<br /> <br /> BOOL bResult; // generic Boolean value<br /> <br /> ULONG_PTR NumberOfPages; // number of pages to request<br /> <br /> ULONG_PTR NumberOfPagesInitial; // initial number of pages requested<br /> <br /> ULONG_PTR *aPFNs; // page info; holds opaque data<br /> <br /> PVOID lpMemReserved; // AWE window<br /> <br /> SYSTEM_INFO sSysInfo; // useful system information<br /> <br /> int PFNArraySize; // memory to request for PFN array<br /> <br /> <br /> <br /> GetSystemInfo(&amp;sSysInfo); // fill the system information structure<br /> <br /> <br /> <br /> _tprintf(_T("This computer has page size %d.\n"), sSysInfo.dwPageSize);<br /> <br /> <br /> <br /> // Calculate the number of pages of memory to request.<br /> <br /> <br /> <br /> NumberOfPages = MEMORY_REQUESTED/sSysInfo.dwPageSize;<br /> <br /> _tprintf (_T("Requesting %d pages of memory.\n"), NumberOfPages);<br /> <br /> <br /> <br /> // Calculate the size of the user PFN array.<br /> <br /> <br /> <br /> PFNArraySize = NumberOfPages * sizeof (ULONG_PTR);<br /> <br /> <br /> <br /> _tprintf (_T("Requesting a PFN array of %d bytes.\n"), PFNArraySize);<br /> <br /> <br /> <br /><span style="background-color: #ffff00;"> aPFNs = (ULONG_PTR *) HeapAlloc(GetProcessHeap(), 0, PFNArraySize);</span><br /> <br /> <br /> <br /> if (aPFNs == NULL) <br /> <br /> {<br /> <br /> _tprintf (_T("Failed to allocate on heap.\n"));<br /> <br /> return;<br /> <br /> }<br /> <br /> <br /> <br /> // Enable the privilege.<br /> <br /> <br /> <br /> if( ! LoggedSetLockPagesPrivilege( GetCurrentProcess(), TRUE ) ) <br /> <br /> {<br /> <br /> return;<br /> <br /> }<br /> <br /> <br /> <br /> // Allocate the physical memory.<br /> <br /> <br /> <br /> NumberOfPagesInitial = NumberOfPages;<br /> <br /> bResult = AllocateUserPhysicalPages( GetCurrentProcess(),<br /> <br /> &amp;NumberOfPages,<br /> <br /> aPFNs );<br /> <br /> <br /> <br /> if( bResult != TRUE ) <br /> <br /> {<br /> <br /> _tprintf(_T("Cannot allocate physical pages (%u)\n"), GetLastError() );<br /> <br /> return;<br /> <br /> }<br /> <br /> <br /> <br /> if( NumberOfPagesInitial != NumberOfPages ) <br /> <br /> {<br /> <br /> _tprintf(_T("Allocated only %p pages.\n"), NumberOfPages );<br /> <br /> return;<br /> <br /> }<br /> <br /> <br /> <br /> // Reserve the virtual memory.<br /> <br /> <br /> <br /><span style="background-color: #ffff00;"> lpMemReserved = VirtualAlloc( NULL,</span><br /> <br /><span style="background-color: #ffff00;"> MEMORY_REQUESTED,</span><br /> <br /><span style="background-color: #ffff00;"> MEM_RESERVE | MEM_PHYSICAL,</span><br /> <br /><span style="background-color: #ffff00;"> PAGE_READWRITE );</span><br /> <br /> <br /> <br /> if( lpMemReserved == NULL ) <br /> <br /> {<br /> <br /> _tprintf(_T("Cannot reserve memory.\n"));<br /> <br /> return;<br /> <br /> }<br /> <br /> <br /> <br /> // Map the physical memory into the window.<br /> <br /> <br /> <br /><span style="background-color: #ffff00;"> bResult = MapUserPhysicalPages( lpMemReserved,</span><br /> <br /><span style="background-color: #ffff00;"> NumberOfPages,</span><br /> <br /><span style="background-color: #ffff00;"> aPFNs );</span><br /> <br /> <br /> <br /> if( bResult != TRUE ) <br /> <br /> {<br /> <br /> _tprintf(_T("MapUserPhysicalPages failed (%u)\n"), GetLastError() );<br /> <br /> return;<br /> <br /> }<br /> <br /> <br /> <br /> // unmap<br /> <br /> <br /> <br /> bResult = MapUserPhysicalPages( lpMemReserved,<br /> <br /> NumberOfPages,<br /> <br /> NULL );<br /> <br /> <br /> <br /> if( bResult != TRUE ) <br /> <br /> {<br /> <br /> _tprintf(_T("MapUserPhysicalPages failed (%u)\n"), GetLastError() );<br /> <br /> return;<br /> <br /> }<br /> <br /> <br /> <br /> // Free the physical pages.<br /> <br /> <br /> <br /> bResult = FreeUserPhysicalPages( GetCurrentProcess(),<br /> <br /> &amp;NumberOfPages,<br /> <br /> aPFNs );<br /> <br /> <br /> <br /> if( bResult != TRUE ) <br /> <br /> {<br /> <br /> _tprintf(_T("Cannot free physical pages, error %u.\n"), GetLastError());<br /> <br /> return;<br /> <br /> }<br /> <br /> <br /> <br /> // Free virtual memory.<br /> <br /> <br /> <br /> bResult = VirtualFree( lpMemReserved,<br /> <br /> 0,<br /> <br /> MEM_RELEASE );<br /> <br /> <br /> <br /> // Release the aPFNs array.<br /> <br /> <br /> <br /> bResult = HeapFree(GetProcessHeap(), 0, aPFNs);<br /> <br /> <br /> <br /> if( bResult != TRUE )<br /> <br /> {<br /> <br /> _tprintf(_T("Call to HeapFree has failed (%u)\n"), GetLastError() );<br /> <br /> }<br /> <br /> <br /> <br /> }<br /> <br /> <br /> <br /> /*****************************************************************<br /> <br /> LoggedSetLockPagesPrivilege: a function to obtain or<br /> <br /> release the privilege of locking physical pages.<br /> <br /> <br /> <br /> Inputs:<br /> <br /> <br /> <br /> HANDLE hProcess: Handle for the process for which the<br /> <br /> privilege is needed<br /> <br /> <br /> <br /> BOOL bEnable: Enable (TRUE) or disable?<br /> <br /> <br /> <br /> Return value: TRUE indicates success, FALSE failure.<br /> <br /> <br /> <br /> *****************************************************************/<br /> <br /> BOOL<br /> <br /> LoggedSetLockPagesPrivilege ( HANDLE hProcess,<br /> <br /> BOOL bEnable)<br /> <br /> {<br /> <br /> struct {<br /> <br /> DWORD Count;<br /> <br /> LUID_AND_ATTRIBUTES Privilege [1];<br /> <br /> } Info;<br /> <br /> <br /> <br /> HANDLE Token;<br /> <br /> BOOL Result;<br /> <br /> <br /> <br /> // Open the token.<br /> <br /> <br /> <br /> Result = OpenProcessToken ( hProcess,<br /> <br /> TOKEN_ADJUST_PRIVILEGES,<br /> <br /> &amp; Token);<br /> <br /> <br /> <br /> if( Result != TRUE ) <br /> <br /> {<br /> <br /> _tprintf( _T("Cannot open process token.\n") );<br /> <br /> return FALSE;<br /> <br /> }<br /> <br /> <br /> <br /> // Enable or disable?<br /> <br /> <br /> <br /> Info.Count = 1;<br /> <br /> if( bEnable ) <br /> <br /> {<br /> <br /> Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;<br /> <br /> } <br /> <br /> else <br /> <br /> {<br /> <br /> Info.Privilege[0].Attributes = 0;<br /> <br /> }<br /> <br /> <br /> <br /> // Get the LUID.<br /> <br /> <br /> <br /> Result = LookupPrivilegeValue ( NULL,<br /> <br /> SE_LOCK_MEMORY_NAME,<br /> <br /> &amp;(Info.Privilege[0].Luid));<br /> <br /> <br /> <br /> if( Result != TRUE ) <br /> <br /> {<br /> <br /> _tprintf( _T("Cannot get privilege for %s.\n"), SE_LOCK_MEMORY_NAME );<br /> <br /> return FALSE;<br /> <br /> }<br /> <br /> <br /> <br /> // Adjust the privilege.<br /> <br /> <br /> <br /> Result = AdjustTokenPrivileges ( Token, FALSE,<br /> <br /> (PTOKEN_PRIVILEGES) &amp;Info,<br /> <br /> 0, NULL, NULL);<br /> <br /> <br /> <br /> // Check the result.<br /> <br /> <br /> <br /> if( Result != TRUE ) <br /> <br /> {<br /> <br /> _tprintf (_T("Cannot adjust token privileges (%u)\n"), GetLastError() );<br /> <br /> return FALSE;<br /> <br /> } <br /> <br /> else <br /> <br /> {<br /> <br /> if( GetLastError() != ERROR_SUCCESS ) <br /> <br /> {<br /> <br /> _tprintf (_T("Cannot enable the SE_LOCK_MEMORY_NAME privilege; "));<br /> <br /> _tprintf (_T("please check the local policy.\n"));<br /> <br /> return FALSE;<br /> <br /> }<br /> <br /> }<br /> <br /> <br /> <br /> CloseHandle( Token );<br /> <br /> <br /> <br /> return TRUE;<br /> <br /> }<br /> </code></pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">The Three functions highlighted in yellow show that we first allocate the memory in the HEAP with the size of the data that needs to be loaded. Memory in the HEAP is not movable. (HeapAlloc)</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Then we reserve in the VirtualAddressSpace to load the data from the heap into that address space being reserved. (VirtualAlloc)</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Then we map this memory from the Heap to the VirtualAddressSpace specified.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">That pretty much explains how the AWE is used in 32-bit SQL Server.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">As for 64 it was mentioned earlier that lock pages in memory is the best option and AWE is ignored.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Hope this explains the options you have with AWE.</span></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Sources:</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;"><a href="https://social.msdn.microsoft.com/Forums/sqlserver/en-US/446fddf9-72aa-4d58-8382-a3ef931d2be9/awe-using-sql-server-2005-32bit-on-a-64-bit-operating-system?forum=sqldatabaseengine">https://social.msdn.microsoft.com/Forums/sqlserver/en-US/446fddf9-72aa-4d58-8382-a3ef931d2be9/awe-using-sql-server-2005-32bit-on-a-64-bit-operating-system?forum=sqldatabaseengine</a><br /><a href="https://sqlblog.com/blogs/argenis_fernandez/archive/2012/12/30/the-myth-around-32-bit-sql-server-instances-on-64-bit-operating-systems-and-awe.aspx">https://sqlblog.com/blogs/argenis_fernandez/archive/2012/12/30/the-myth-around-32-bit-sql-server-instances-on-64-bit-operating-systems-and-awe.aspx</a><br /><a href="https://msdn.microsoft.com/en-us/library/aa366796(VS.85).aspx">https://msdn.microsoft.com/en-us/library/aa366796(VS.85).aspx</a><br /><a href="https://msdn.microsoft.com/en-us/library/ms191481.aspx">https://msdn.microsoft.com/en-us/library/ms191481.aspx</a></span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;"><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa366892(v=vs.85).aspx">https://msdn.microsoft.com/en-us/library/windows/desktop/aa366892(v=vs.85).aspx</a></span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;"><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa375202(v=vs.85).aspx">https://msdn.microsoft.com/en-us/library/windows/desktop/aa375202(v=vs.85).aspx</a></span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">and most of the blogs mentioned in the case</span></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-family: Calibri; font-size: small;">&nbsp;</span></p>]]></content:encoded>
    </item>
    <item>
      <title>Shrink a Transaction log file</title>
      <link>https://docs.microsoft.com/archive/blogs/ishabib1/shrink-a-transaction-log-file</link>
      <pubDate>Wed, 15 Aug 2012 03:15:00 GMT</pubDate>
      <dc:creator><![CDATA[Ismail Habib]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ishabib1/2012/08/15/shrink-a-transaction-log-file/</guid>
      <description><![CDATA[I came across a very important issue with one of my customers they had a SharePoint site with a...]]></description>
      <content:encoded><![CDATA[<p class="Publishwithline">I came across a very important issue with one of my customers they had a SharePoint site with a transaction log file that grew aggressively and filled up the partition that it was stored on. So they contacted me to assist them in shrinking the transaction log database after researching I didn&rsquo;t find anyone that actually explains how this can be accomplished in a comprehensive manner without breaking the chain. So I decided to provide the steps myself and after that I provide an internal look in part to of this series.</p>
<p>Please Run the Following Script under the<br />SharePoint Configuration database in management studio</p>
<p>&nbsp;</p>
<p><span style="color: blue;">DECLARE <br />&nbsp;&nbsp; </span><span style="color: #434343;">@DBName </span><span style="color: blue;">VARCHAR</span><span style="color: gray;">(</span><span style="color: black;">255</span><span style="color: gray;">)<br /></span><span style="color: blue;">SET <br />&nbsp;&nbsp; </span><span style="color: #434343;">@DBName </span><span style="color: blue;">=&nbsp; </span><span style="color: red;">'AdventureWorks2008R2'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green;">---Replace with Database Name<br /></span><span style="color: blue;">DECLARE <br />&nbsp;&nbsp; </span><span style="color: #434343;">@TransactionLogName </span><span style="color: blue;">VARCHAR</span><span style="color: gray;">(</span><span style="color: black;">255</span><span style="color: gray;">)<br /></span><span style="color: blue;">SET <br />&nbsp;&nbsp; </span><span style="color: #434343;">@TransactionLogName </span><span style="color: blue;">=&nbsp; </span><span style="color: red;">'AdventureWorks2008R2_Log'&nbsp; </span><span style="color: green;">---Replace with Transaction log file Name<br />-------------------STEPS TO GET TRANSACTION LOG FILE NAME-----------------------------<br />--RIGHT CLICK ON YOUR DATABASE--&gt;Properties--&gt; From the left panel choose files--&gt;Under File Type search for log--&gt;select Logical Name from that row<br />--------------------------------------------------------------------------------------<br />---------------------------------------------------------------<br />--My good friend/Mentor Rafid suggested another way to get the Log File Name (Rafid&rsquo;s Blog: https://blogs.msdn.com/b/rafidl/)<br />-- select name from sys.database_files <br />--&nbsp; where type_desc='log'<br />-- should also work <br />---------------------------------------------------------------------<br /><br /></span><span style="color: blue;">DECLARE </span><span style="color: #434343;">@SetMode </span><span style="color: blue;">NVARCHAR</span><span style="color: gray;">(</span><span style="color: magenta;">MAX</span><span style="color: gray;">)<br /></span><span style="color: blue;">SET </span><span style="color: #434343;">@SetMode&nbsp; </span><span style="color: blue;">= </span><span style="color: red;">'ALTER DATABASE {DataBaseName} set recovery {RecoveryMode}'<br /><br /></span><span style="color: blue;">DECLARE </span><span style="color: #434343;">@ShrinkLog </span><span style="color: blue;">NVARCHAR</span><span style="color: gray;">(</span><span style="color: magenta;">MAX</span><span style="color: gray;">)<br /></span><span style="color: blue;">SET </span><span style="color: #434343;">@ShrinkLog </span><span style="color: blue;">= </span><span style="color: red;">'DBCC SHRINKFILE ({TransactionLogName},1)'<br /><br /><br /></span><span style="color: blue;">DECLARE </span><span style="color: #434343;">@SCRIPT </span><span style="color: blue;">NVARCHAR</span><span style="color: gray;">(</span><span style="color: magenta;">MAX</span><span style="color: gray;">)<br /></span><span style="color: blue;">SET </span><span style="color: #434343;">@SCRIPT </span><span style="color: blue;">= </span><span style="color: magenta;">REPLACE</span><span style="color: gray;">(</span><span style="color: #434343;">@SetMode</span><span style="color: gray;">, </span><span style="color: red;">'{DataBaseName}'</span><span style="color: gray;">, </span><span style="color: #434343;">@DBName</span><span style="color: gray;">) <br /></span><span style="color: blue;">SET </span><span style="color: #434343;">@SCRIPT </span><span style="color: blue;">= </span><span style="color: magenta;">REPLACE </span><span style="color: gray;">(</span><span style="color: #434343;">@SCRIPT</span><span style="color: gray;">, </span><span style="color: red;">'{RecoveryMode}'</span><span style="color: gray;">,</span><span style="color: red;">'Simple'</span><span style="color: gray;">)&nbsp; <br /></span><span style="color: blue;">EXECUTE </span><span style="color: gray;">(</span><span style="color: #434343;">@SCRIPT</span><span style="color: gray;">) <br /> <br /></span><span style="color: blue;">SET </span><span style="color: #434343;">@SCRIPT </span><span style="color: blue;">= </span><span style="color: magenta;">REPLACE</span><span style="color: gray;">(</span><span style="color: #434343;">@ShrinkLog</span><span style="color: gray;">, </span><span style="color: red;">'{TransactionLogName}'</span><span style="color: gray;">, </span><span style="color: #434343;">@TransactionLogName</span><span style="color: gray;">) <br /></span><span style="color: blue;">EXECUTE </span><span style="color: gray;">(</span><span style="color: #434343;">@SCRIPT</span><span style="color: gray;">) <br /> <br /></span><span style="color: blue;">SET </span><span style="color: #434343;">@SCRIPT </span><span style="color: blue;">= </span><span style="color: magenta;">REPLACE</span><span style="color: gray;">(</span><span style="color: #434343;">@SetMode</span><span style="color: gray;">, </span><span style="color: red;">'{DataBaseName}'</span><span style="color: gray;">, </span><span style="color: #434343;">@DBName</span><span style="color: gray;">) <br /></span><span style="color: blue;">SET </span><span style="color: #434343;">@SCRIPT </span><span style="color: blue;">= </span><span style="color: magenta;">REPLACE </span><span style="color: gray;">(</span><span style="color: #434343;">@SCRIPT</span><span style="color: gray;">, </span><span style="color: red;">'{RecoveryMode}'</span><span style="color: gray;">,</span><span style="color: red;">'Full'</span><span style="color: gray;">)<br /></span><span style="color: blue;">EXECUTE </span><span style="color: gray;">(</span><span style="color: #434343;">@SCRIPT</span><span style="color: gray;">) <br /></span></p>
<p>Choose Management from management studio and then right click on Maintenance Plans</p>
<p><br /> <br /> <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/1031.1.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/1031.1.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/1031.1.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/1031.1.png" /></a><br />&nbsp;&nbsp;</p>
<p>Select Maintenance plan wizard</p>
<p>&nbsp;</p>
<p>In the SQL Server Maintenance Plan Wizard click&nbsp;on Next</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/5417.2.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/5417.2.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/5417.2.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/5417.2.png" /></a></p>
<p>&nbsp;</p>
<p>After adding a name and a description click on&nbsp; Change</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/5518.3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/5518.3.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/5518.3.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/5518.3.png" /></a></p>
<p>In the Job Schedule properties Make sure that the frequency is set to daily</p>
<p>Daily Frequency is set to 1 hour</p>
<p>And Duration is set to no end date</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/6763.4.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/6763.4.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/6763.4.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/6763.4.png" /></a></p>
<p>In the Select Maintenance Task select Back up Database (Transaction Log)</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/7608.5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/7608.5.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/7608.5.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/7608.5.png" /></a></p>
<p>In the Select Maintenance Task Order Click on Next</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/2703.6.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/2703.6.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/2703.6.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/2703.6.png" /></a>&nbsp;</p>
<p>In the Define Database Backup (Transaction Log) Tasks</p>
<p>Select the Database you want to shrink</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/7142.7.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/7142.7.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/7142.7.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/7142.7.png" /></a>&nbsp;</p>
<p>In Select Reporting Action Click on Next</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/3618.8.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/3618.8.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/3618.8.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/3618.8.png" /></a>&nbsp;</p>
<p>In Complete Wizard Click on Finish</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/6661.9.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/6661.9.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/6661.9.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/6661.9.png" /></a></p>
<p>The way this works is a set of prerequisites that are required to run the SHRINK Command</p>
<p>The problem is the structure of the Log file as illustrated in the link below</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/8712.IC93848.gif" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/8712.IC93848.gif"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/8712.IC93848.gif" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/8712.IC93848.gif" /></a></p>
<p><br /> <br /> <br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/0216.IC167852.gif" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/0216.IC167852.gif"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/37/0216.IC167852.gif" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-37/0216.IC167852.gif" /></a>&nbsp;&nbsp;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;</p>
<p>Source: https://msdn.microsoft.com/en-us/library/ms179355(SQL.105).aspx</p>
<p>Log files store a step by step on each transaction that occurs on your MDF or NDF files since the last time you have taken a full backup of the database</p>
<p>So every time you have taken a backup the transactions are deleted from the log file (they are not actually deleted they are just marked as dirty) this process is called truncating the log file</p>
<p>Transaction log file are divided into Virtual Log File if a virtual Log File does contain transactions marked as active then this VLF cannot be truncated and hence to overcome this issue we change the<br />recovery mode from Full to Simple this cases a checkpoint to run every min and hence continuously marks VLF as in active. The last part of the script is to make sure that the Transaction logs will be continuously marked as inactive through backing up and this is the schedule wizard that we followed</p>]]></content:encoded>
    </item>
    <item>
      <title>3 Steps for Developing Against Windows Azure Tables</title>
      <link>https://docs.microsoft.com/archive/blogs/ishabib1/3-steps-for-developing-against-windows-azure-tables</link>
      <pubDate>Wed, 29 Jun 2011 01:28:03 GMT</pubDate>
      <dc:creator><![CDATA[Ismail Habib]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ishabib1/2011/06/29/3-steps-for-developing-against-windows-azure-tables/</guid>
      <description><![CDATA[This blog post is not intended to explain how to designWindows Azure Tables. This will be discussed...]]></description>
      <content:encoded><![CDATA[<p>This blog post is not intended to explain how to design<br />Windows Azure Tables. This will be discussed in a later topic.</p>
<p>The whole purpose of this blog is to explain to developers an easy way to build and interact with Windows Azure Tables.</p>
<p>Thinking about this it is very easy to implement it in a few<br />easy Steps</p>
<p>&nbsp;</p>
<p>1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />Create the Service Entity<br />Class</p>
<p>2)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />Create the Table Context<br />Class</p>
<p>3)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />Start Manipulation</p>
<p>&nbsp;</p>
<p>We will discuss these Classes in Details with Examples</p>
<p><b>The Service Entity Class:</b></p>
<p>For the sake of this blog I will use the famous blog sample the<br />blog Entity is meant to define the data that is required to be stored within<br />the sample</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="1072">
<p><b>&nbsp;&nbsp;&nbsp; public class BlogEntity :<br />&nbsp; Microsoft.WindowsAzure.StorageClient.TableServiceEntity</b></p>
<p><b>&nbsp;&nbsp;&nbsp; {</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public BlogEntity()</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp; RowKey = String.Format("{0:10}_{1}", (DateTime.MaxValue.Ticks - DateTime.Now.Ticks),<br />&nbsp; Guid.NewGuid());</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp; PartitionKey = DateTime.Now.ToString("ddmmyyy");</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String<br />&nbsp; Title { get; set;<br />&nbsp; }</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String Id<br />&nbsp; { get; set; }</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String<br />&nbsp; Body { get; set;<br />&nbsp; }</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String<br />&nbsp; ImagePath { get; set;<br />&nbsp; }</b></p>
<p><b>&nbsp;&nbsp;&nbsp; }</b></p>
<p><b>&nbsp;</b></p>
<p><b>&nbsp;</b></p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>The above class inherits from TableServiceEntity which is<br />part of the Microsoft.WindowsAzure.StorageClient;</p>
<p>All the data that is required is stored in as properties in<br />this class</p>
<p>Notice the PartitionKey and the RowKey defined in the class<br />you can think of them as the Table Name and the Row Number in a Relational<br />Database</p>
<p>The PartitionKey is the Table Name that contains all the<br />data that we would like to group together. In the Scinario above each day we<br />get a new Partition</p>
<p>The RowKey is a unique identifier within the Partition.</p>
<p>This class is used as a representation of each Row within<br />the partition</p>
<p><b>Table Context Class:</b></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="1072">
<p><b>&nbsp;&nbsp;&nbsp; public class BlogContext : TableServiceContext</b></p>
<p><b>&nbsp;&nbsp;&nbsp; {</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public BlogContext(string<br />&nbsp; baseAddress, StorageCredentials<br />&nbsp; credentials)</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : base(baseAddress, credentials)</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public IQueryable&lt;BlogEntity&gt; BlogEntities</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.CreateQuery&lt;BlogEntity&gt;("BlogEntities");</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void<br />&nbsp; InsertEntry(BlogEntity entity)</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</b></p>
<p><b>&nbsp;</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.AddObject("BlogEntities",<br />&nbsp; new BlogEntity<br />&nbsp; { Title = entity.Title, Body = entity.Body, Id = entity.Id, ImagePath =<br />&nbsp; entity.ImagePath });</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.SaveChanges();</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</b></p>
<p><b>&nbsp;</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void<br />&nbsp; RemoveEntry(string id)</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BlogEntity res = (from<br />&nbsp; r in BlogEntities where<br />&nbsp; r.Id == id select r).First();</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.DeleteObject(res);</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.SaveChanges();</b></p>
<p><b>&nbsp;</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void<br />&nbsp; ModifyEntry(BlogEntity entity)</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BlogEntity res = (from<br />&nbsp; r in BlogEntities where<br />&nbsp; r.Id == entity.Id select r).First();</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp; res.Title = entity.Title;</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp; res.Body = entity.Body;</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp; res.ImagePath = entity.ImagePath;</b></p>
<p><b>&nbsp;</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.UpdateObject(res);</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.SaveChanges();</b></p>
<p><b>&nbsp;</b></p>
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</b></p>
<p><b>&nbsp;&nbsp;&nbsp; }</b></p>
<p><b>&nbsp;</b></p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>The Table Context Class the is the class required to<br />Manipulate the data within the table it inherits from TableServiceContext</p>
<p>This enables any client application to interact with the<br />table it includes. This interaction is the same style you would use when<br />interacting with</p>
<p>Relational tables.</p>
<p>This is all you need as a developer to use tables as storage<br />entities.</p>]]></content:encoded>
    </item>
  </channel>
</rss>