quinta-feira, 15 de outubro de 2015

Inside the Storage Engine: Anatomy of a page

Inside the Storage Engine: Anatomy of a page

Next up in the Inside the Storage Engine series is a discussion of page structure. Pages exist to store records. A database page is an 8192-byte (8KB) chunk of a database data file. They are aligned on 8KB boundaries within the data files, starting at byte-offset 0 in the file. Here’s a picture of the basic structure:
page.gif
Header
The page header is 96 bytes long. What I’d like to do in this section is take an example page header dump from DBCC PAGE and explain what all the fields mean. I’m using the database from the page split post and I’ve snipped off the rest of the DBCC PAGE output.
DBCC TRACEON (3604)
DBCC PAGE (‘pagesplittest’, 1, 143, 1);
GO
m_pageId = (1:143)                   m_headerVersion = 1                  m_type = 1
m_typeFlagBits = 0x4                 m_level = 0                          m_flagBits = 0x200
m_objId (AllocUnitId.idObj) = 68     m_indexId (AllocUnitId.idInd) = 256
Metadata: AllocUnitId = 72057594042384384
Metadata: PartitionId = 72057594038386688                                 Metadata: IndexId = 1
Metadata: ObjectId = 2073058421      m_prevPage = (0:0)                   m_nextPage = (1:154)
pminlen = 8                          m_slotCnt = 4                        m_freeCnt = 4420
m_freeData = 4681                    m_reservedCnt = 0                    m_lsn = (18:116:25)
m_xactReserved = 0                   m_xdesId = (0:0)                     m_ghostRecCnt = 0
m_tornBits = 1333613242

Here’s what all the fields mean (note that the fields aren’t quite stored in this order on the page):
  • m_pageId
    • This identifies the file number the page is part of and the position within the file. In this example, (1:143) means page 143 in file 1.
  • m_headerVersion
    • This is the page header version. Since version 7.0 this value has always been 1.
  • m_type
    • This is the page type. The values you’re likely to see are:
      • 1 – data page. This holds data records in a heap or clustered index leaf-level.
      • 2 – index page. This holds index records in the upper levels of a clustered index and all levels of non-clustered indexes.
      • 3 – text mix page. A text page that holds small chunks of LOB values plus internal parts of text tree. These can be shared between LOB values in the same partition of an index or heap.
      • 4 – text tree page. A text page that holds large chunks of LOB values from a single column value.
      • 7 – sort page. A page that stores intermediate results during a sort operation.
      • 8 – GAM page. Holds global allocation information about extents in a GAM interval (every data file is split into 4GB chunks – the number of extents that can be represented in a bitmap on a single database page). Basically whether an extent is allocated or not. GAM = Global Allocation Map. The first one is page 2 in each file. More on these in a later post.
      • 9 – SGAM page. Holds global allocation information about extents in a GAM interval. Basically whether an extent is available for allocating mixed-pages. SGAM = Shared GAM. the first one is page 3 in each file. More on these in a later post.
      • 10 – IAM page. Holds allocation information about which extents within a GAM interval are allocated to an index or allocation unit, in SQL Server 2000 and 2005 respectively. IAM = Index Allocation Map. More on these in a later post.
      • 11 – PFS page. Holds allocation and free space information about pages within a PFS interval (every data file is also split into approx 64MB chunks – the number of pages that can be represented in a byte-map on a single database page. PFS = Page Free Space. The first one is page 1 in each file. More on these in a later post.
      • 13 – boot page. Holds information about the database. There’s only one of these in the database. It’s page 9 in file 1.
      • 15 – file header page. Holds information about the file. There’s one per file and it’s page 0 in the file.
      • 16 – diff map page. Holds information about which extents in a GAM interval have changed since the last full or differential backup. The first one is page 6 in each file.
      • 17 – ML map page. Holds information about which extents in a GAM interval have changed while in bulk-logged mode since the last backup. This is what allows you to switch to bulk-logged mode for bulk-loads and index rebuilds without worrying about breaking a backup chain. The first one is page 7 in each file.
      • 18 – a page that’s be deallocated by DBCC CHECKDB during a repair operation.
      • 19 – the temporary page that ALTER INDEX … REORGANIZE (or DBCC INDEXDEFRAG) uses when working on an index.
      • 20 – a page pre-allocated as part of a bulk load operation, which will eventually be formatted as a ‘real’ page.
  • m_typeFlagBits
    • This is mostly unused. For data and index pages it will always be 4. For all other pages it will always be 0 – except PFS pages. If a PFS page has m_typeFlagBits of 1, that means that at least one of the pages in the PFS interval mapped by the PFS page has at least one ghost record.
  • m_level
    • This is the level that the page is part of in the b-tree.
    • Levels are numbered from 0 at the leaf-level and increase to the single-page root level (i.e. the top of the b-tree).
    • In SQL Server 2000, the leaf level of a clustered index (with data pages) was level 0, and the next level up (with index pages) was also level 0. The level then increased to the root. So to determine whether a page was truly at the leaf level in SQL Server 2000, you need to look at the m_type as well as the m_level.
    • For all page types apart from index pages, the level is always 0.
  • m_flagBits
    • This stores a number of different flags that describe the page. For example, 0x200 means that the page has a page checksum on it (as our example page does) and 0x100 means the page has torn-page protection on it.
    • Some bits are no longer used in SQL Server 2005.
  • m_objId
  • m_indexId
    • In SQL Server 2000, these identified the actual relational object and index IDs to which the page is allocated. In SQL Server 2005 this is no longer the case. The allocation metadata totally changed so these instead identify what’s called the allocation unit that the page belongs to. This post explains how an allocation unit ID is calculated.
  • m_prevPage
  • m_nextPage
    • These are pointers to the previous and next pages at this level of the b-tree and store 6-byte page IDs.
    • The pages in each level of an index are joined in a doubly-linked list according to the logical order (as defined by the index keys) of the index. The pointers do not necessarily point to the immediately adjacent physical pages in the file (because of fragmentation).
    • The pages on the left-hand side of a b-tree level will have the m_prevPage pointer be NULL, and those on the right-hand side will have the m_nextPage be NULL.
    • In a heap, or if an index only has a single page, these pointers will both be NULL for all pages.
  • pminlen
    • This is the size of the fixed-length portion of the records on the page.
  • m_slotCnt
    • This is the count of records on the page.
  • m_freeCnt
    • This is the number of bytes of free space in the page.
  • m_freeData
    • This is the offset from the start of the page to the first byte after the end of the last record on the page. It doesn’t matter if there is free space nearer to the start of the page.
  • m_reservedCnt
    • This is the number of bytes of free space that has been reserved by active transactions that freed up space on the page. It prevents the free space from being used up and allows the transactions to roll-back correctly. There’s a very complicated algorithm for changing this value.
  • m_lsn
    • This is the Log Sequence Number of the last log record that changed the page.
  • m_xactReserved
    • This is the amount that was last added to the m_reservedCnt field.
  • m_xdesId
    • This is the internal ID of the most recent transaction that added to the m_reservedCnt field.
  • m_ghostRecCnt
    • The is the count of ghost records on the page.
  • m_tornBits
    • This holds either the page checksum or the bits that were displaced by the torn-page protection bits – depending on what form of page protection is turnde on for the database.
Note that I didn’t include the fields starting with Metadata:. That’s because they’re not part of a page header. During SQL Server 2005 development I did some major work rewriting the guts of DBCC PAGE and to save everyone using it from having to do all the system table lookups to determine what the actual object and index IDs are, I changed DBCC PAGE to do them internally and output the results.
Records
See this blog post for details.
Slot Array
It’s a very common misconception that records within a page are always stored in logical order. This is not true. There is another misconception that all the free-space in a page is always maintained in one contiguous chunk. This also is not true. (Yes, the image above shows the free space in one chunk and that very often  is the case for pages that are being filled gradually.)If a record is deleted from a page, everything remaining on the page is not suddenly compacted – inserters pay the cost of compaction when its necessary, not deleters.Consider a completely full page – this means that record deletions cause free space holes within the page. If a new record needs to be inserted onto the page, and one of the holes is big enough to squeeze the record into, why go to the bother of comapcting it? Just stick the record in and carry on. What if the record should logically have come at the end of all other records on the page, but we’ve just inserted it in the middle – doesn’t that screw things up somewhat?No, because the slot array is ordered and gets reshuffled as records are inserted and deleted from pages. As long as the first slot array entry points to the logically first record on the page, everything’s fine. Each slot entry is just a two-byte pointer into the page – so its far more efficient to manipulate the slot array than it is to manipulate a bunch of records on the page. Only when we know there’s enough free space contained within the page to fit in a record, but its spread about the page do we compact the records on the page to make the free space into a contiguous chunk.One interesting fact is that the slot array grows backwards from the end of the page, so the free space is squeezed from the top by new rows, and from the bottom by the slot array.

Unable to Deploy DPM 2012 SP1 Agent to Target Server


It’s sound weird but this is just happening to me. I got a project which just require to deploy DPM 2012 SP1 into the environment which need to protect physical hyper-v server and virtual machine running Windows Server 2003, Windows Server 2008 R2 and Windows Server 2012. The funny thing is I can successful deploy agent to Windows Server 2012 VM but failed to Windows Server 2003 and Windows Server 2008 R2. Error message that I received is “Error 347:- An error occurred when the agent operation attempted to create the DPM agent coordinator service”
SNAGHTML1673bbf
Search using Google and Tech-Net article advice to perform manual agent installation. Tried that as well but failed to load the setup launch Screen.
image
Thanks to Flemming which has posted the solution.
Here is the summary of the solution which I have taken:-
a) Install

Microsoft Visual C++ 2008 Redistributable Package (x64) or

Microsoft Visual C++ 2008 Redistributable Package (x86) depend on your target guest operating system version.

b) Install .Net Framework 3.5 SP1
c) Re-deploy DPM Agent to the target VMs.
d) If still having the issue, you may want to deploy .Net Framework 3.5 with SP1
Additional resources:-

Eight steps to restore an individual Exchange 2010 mailbox with System Center Data Protection Manager

Exchange admins often have to restore an individual mailbox rather than an entire database. John Joyner shows you eight steps to do this using PowerShell commands and Microsoft System Center DPM.
 
There are few viable organizations that don't back up their Exchange databases. The total loss of an email system and all the corporate knowledge it contains is at best a catastrophe for any organization. Everyone will agree that if you are using on-premise or private cloud Exchange servers for your business, the databases must be backed up. Most IT pros know there are dozens if not hundreds of Exchange backup tools and solutions, and the cost and complexity factors can run quite high.
While the main purpose of Exchange backup is to enable server, storage, and datacenter disaster recovery (DR) scenarios, a common and routine request of Exchange admins is to restore an individual mailbox. Microsoft does not provide a native and fully automated way to granularly restore a single mailbox from an Exchange database backup. This feature can be a make-or-break decision for Exchange admins when selecting a backup solution. Some good news is that a combination of native Exchange 2010 PowerShell commands and Microsoft System Center Data Protection Manager 2010 (DPM) can achieve mailbox-level recovery with surprising ease.
Without the ability to restore an individual mailbox, it is necessary to first restore an entire Exchange database, and then extract the desired mailbox from the recovered database. Having your Exchange 2010 recovery database folders pre-staged, and customizing the following steps for your environment can reduce the time needed to perform individual mailbox restores to a manageable level. Mailbox recovery using native Exchange 2010 and DPM 2010 features is a fairly straightforward process. Here are some proven steps to deliver a recovered mailbox to a user in the form of a PST file.

Scenario

User John Smith reports he accidentally force-deleted some emails out of his mailbox, and he needs the data back. After confirming that deleted item recovery is not available to the user with Outlook, complete these steps and afterwards instruct the user to add the PST as a Data File to his Outlook profile. The entire contents of the recovered mailbox will be in a folder named "Recovery" inside that PST, and the user can browse to the PST and copy and paste the missing emails back into their normal mailbox.
1. Using Exchange Management Console, find out which mailbox server the database of the current mailbox is on, for example, "John Smith" mailbox is in database DB01 on mailbox server MAILBOX01. 2. Create a new temporary user with "(Recovered)" in the user name, with the mailbox located in the same database. "John Smith (Recovered)" in DB01 in this example. 3. Activate a recovery database on that mailbox server, MAILBOX01 in this example, by running this Exchange PowerShell cmdlet:
New-MailboxDatabase -Recovery -Name RDB1 -Server MAILBOX01 -EdbFilePath "C:\mountpoints\rdb1-db\RDB1-DB.ebd" -LogFolderPath "C:\mountpoints\rdb1-log"
Tip: Prepare two pairs of recovery database storage folders for each mailbox server. A recovery database named RDB1 might have storage folders pre-staged, such as C:\mountpoints\rdb1-db and C:\mountpoints\rdb1-log. MAILBOX01 would have an RDB1 and an RDB2 prepared, each with a database and a log folder pre-created and ready to restore into. 4. Perform the mailbox restore operation in the DPM console.
  • Navigate to the Recovery space, then browse in the left pane to select the Exchange server name where the database replica resides (DB01 in this example). If you are using Exchange 2010 high-availability Database Availability Groups (DAGs), the replica will be listed in DPM under a mailbox server running a standby database copy, not the primary server where you created the recovery mailbox.

Figure A - Selecting to recover an Exchange 2010 mailbox with DPM 2010
  • See in the screenshot of the DPM console (Figure A) that DPM will recover the mailbox from the standby copy backed up from mailbox server MAILBOX02.
  • Select the recovery date and time from the calendar portion of the display. Locate the user mailbox in the Recoverable Item area, right click, and select Recover.
  • Choose to recover to an Exchange Server database, and type the name of the server and recovery database that are prepared for the restore, such as MAILBOX01 and RDB1.
  • Click through to complete the wizard and start the restore job.
5. When the DPM job is complete, run the following Exchange Powershell cmdlet to migrate the recovered mailbox content to the recovery user mailbox in a folder named "Recovery":
Restore-Mailbox -Identity 'John Smith (Recovered)' -RecoveryDatabase RDB1 -RecoveryMailbox 'John Smith' -TargetFolder Recovery
6. Next, extract the contents of the recovery mailbox to a PST folder to deliver to the user by running the following Exchange Powershell cmdlet:
New-MailboxExportRequest -Mailbox JohnSmithRecovered -FilePath \\MAILBOX01\RECOVERED.PST$\JohnSmith.Recovered.pst
Tip: Pre-create the shared folder that will contain the PST file, RECOVERED.PST$ in this example. The folder needs to grant full access to the Exchange Trusted Subsystem group. 7. Deliver the PST file to the user, and delete the Active Directory account and mailbox of the temporary user "John Smith (Recovered)" in this example. 8. Finally, remove the recovery database created for this restore job by running the following Exchange Powershell cmdlet:
Remove-MailboxDatabase -Identity RDB1
There will still be files in the recovery database and log folders (C:\mountpoints\rdb1-db, etc. in this example). The contents of these folders must be manually deleted before you can use those folders in the next recovery job.

Fonte: John Joyner


 

Survey results around purchase and use of SSDs

Back at the start of July I kicked off a survey around your plans for SSDs (see here) and now I present the results to you. There's not much to editorialize here, but the numbers are interesting to see.
 
The "other" answers were (verbatim):
  • 3 x 'have bought and am trying them out'
  • 3 x 'not sure if we need them or not'
  • 2 x 'all production servers are hosted'
  • 1 x 'bought them, tried them..not good enough yet for tempdb'
  • 1 x 'Have some, want more, could you really every have enough?'
  • 1 x 'We get every penny from or spinning media, and have no need for SSD'
The results reflect what I've been hearing when teaching classes and talking to customers/conference attendees over the last six months. People are becoming more interested in SSDs but there's still a lot of wariness about them and of course the whole money issue of being able to buy them. I'm also not surprised (given the general readership demographics of this blog) by the number of people who've analyzed their IOPS requirements and concluded that they don't need SSDs to accomplish that.
 
The "other" answers were (verbatim):
  • 3 x 'not in the budget'
  • 1 x 'I plan to buy expensive drives and throw them at you, paul! love, conor'
  • 1 x 'I'm going to do the same thing Conor will do. Denny'
  • 1 x 'OLAP Scale Out'
  • 1 x 'Use them as cache'
  • 1 x 'Using in an EMC V-MAX SAN to dynamically move high workloads to SSD temporarily'
Ahem – thanks Conor and Denny :-)
Another unsurprising set of results that reflects what I've been hearing. One number I'd be interested in drilling deeper into is answer #3 – are people putting/planning to put tempdb on SSDs because that's what they've heard is the best thing to do, or because tempdb truly is the largest I/O bottleneck that can benefit the most from SSDs? That's a set of experiments I'd like to try out with my Fusion-io drives.
The final "other" answer is also interesting – I was talking to a couple of folks from EMC in Ireland about the V-MAX when we were there earlier this month. Very cool idea to migrate data up and down a set of devices with varying latencies (at the block level, not the file level) – I'd like to see more on how the technology copes with one-off operations like consistency checks or backups – do those IOs affect which layer a block resides in?
Anyway, hope you find these results interesting.
Thanks to all those who responded!


FONTE: By: Paul Randal

terça-feira, 22 de setembro de 2015

Situação engraçada que aconteceu comigo quando estava dormindo dentro do carro na hora do almoço.


quarta-feira, 9 de setembro de 2015

Boa tarde,

Esse blog é para divulgar vídeos interessante e dicas relacionados a música, trabalhos em casa entre outros.

Segue um vídeo da época que eu tinha banda...  The Doors Cover