Showing posts with label Error. Show all posts
Showing posts with label Error. Show all posts

2015-03-19

Report Migration - Phantom Connection String in Catalog table

As mentioned in my prior post, I did a SQL Server migration back to 2014. When I did the report migration from server A to server B, I found something worth to be recorded here.

Let's start from beginning, what I have are

The old SQL Server is at 2008R2 version, reporting service is installed by following default setting
  • Reporting Service URL: http://<SS2008R2>/reportserver
  • Report Catalog DB name: ReportServer
The new SQL Server is 2012, reporting service is installed by following default setting
  • Reporting Service URL: http://<SS2012>/reportserver
  • Report Catalog DB name: ReportServer

What I need to do is to migrate hundreds of reports from SS2008R2 to SS2012, and update all connection strings from SS2008R2 to SS2012.

There were quite a lot ways to do this task, RS utility, report migration tool published by Microsoft (http://www.microsoft.com/en-au/download/details.aspx?id=29560). But because connection string inside the reports needs to be updated as well, I finally decided to write a short C# codes to do the migration. What the code will do is
  • copy the reports from SS2008R2
  • deploy the reports to SS2012
  • update the data source to SS2012

The code is quite simple, firstly ReportingService2010 web services from both SS2008R2 and SS2012 need to be added. usually it is at http://<ReportServer>/reportserver/reportservice2010.asmx

Now I initialized both source server and target server

 RSSource2010 = new RSSource.ReportingService2010();  
 RSSource2010.Credentials = System.Net.CredentialCache.DefaultCredentials;  
 RSSource2010.Url = @"http://" + SourceServer + "/reportserver/reportservice2010.asmx";  
 RSTarget2010 = new RSTarget.ReportingService2010();  
 RSTarget2010.Credentials = System.Net.CredentialCache.DefaultCredentials;  
 RSTarget2010.Url = @"http://" + TargetServer + "/reportserver/reportservice2010.asmx";  

Now below code shows how to migrate the report and change the data source connection string. I have made it a bit simpler. In a production enviornment it could be far more complicated

 //to make it simple, assume the report will be migrated to the root folder, "/"  
 string TargetPath = "/";  
 //get source report, here the variable ReportPath is the source report  
 //we can get it from catalog table (not suggested by MS) or from the webservice  
 byte[] ReportContents = RSSource2010.GetItemDefinition(ReportPath);  
 RS2010_Target.Warning[] warnings = null;  
 try  
 {  
      //create the target item  
      RS2010_Target.CatalogItem TargetItem = RSTarget2010.CreateCatalogItem("Report", "Migrated_Report", TargetPath, true, ReportContents, null, out warnings);  
      //need to change the data source of the target item to new server  
      //to make it simple, assume the data source connection string is embeded in the report  
      //otherwise it could be an expression or reference data source  
      RS2010_Target.DataSource[] DSs = RSTarget2010.GetItemDataSources(TargetItem.Path);  
      RS2010_Target.DataSource[] NewDSs = new RSTarget.DataSource[DSs.Count()];  
      for (int i = 0; i < DSs.Count(); i++)  
      {  
           //copy new data source name  
           RS2010_Target.DataSource NewDS = new RSTarget.DataSource();  
           NewDS.Name = DSs[i].Name;  
           //read source report data source  
           var t = DSs[i].Item.GetType();  
           if (t.Name == "DataSourceDefinition")  
           {  
                RS2010_Target.DataSourceDefinition TargetDSDef = new RSTarget.DataSourceDefinition();  
                RS2010_Target.DataSourceDefinition SourceDSDef = (RS2010_Target.DataSourceDefinition)DSs[i].Item;  
                //set target report data source connection string to new server  
                //set target report data source properties by copying from source  
                TargetDSDef.ConnectString = ((RS2010_Target.DataSourceDefinition)DSs[i].Item).ConnectString.ToUpper().Replace(SourceServer.ToUpper(), TargetServer.ToUpper());  
                TargetDSDef.Enabled = true;  
                TargetDSDef.Extension = ((RS2010_Target.DataSourceDefinition)DSs[i].Item).Extension;  
                TargetDSDef.CredentialRetrieval = RSTarget.CredentialRetrievalEnum.Integrated;  
                TargetDSDef.WindowsCredentials = ((RS2010_Target.DataSourceDefinition)DSs[i].Item).WindowsCredentials;  
                NewDS.Item = (RS2010_Target.DataSourceDefinitionOrReference)TargetDSDef;  
                NewDSs[i] = NewDS;  
           }  
      }  
      //set the data source  
      RSTarget2010.SetItemDataSources(TargetItem.Path, NewDSs);  
 }  

The code works. If you open the report, you can find the report runs correctly, data is coming from SS2012, etc.

BUT

If you open the report via Report Builder, the connection string has been updated. The connection string from report builder will be

DATA SOURCE=<RS2012>;INITIAL CATALOG=REPORTSERVER

However if you query Catalog table by using below statement, You can see the data source coming from Catalog table is still pointing to RS2008R2

 ;WITH XMLNAMESPACES ( DEFAULT 'http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition', 'http://schemas.microsoft.com/SQLServer/reporting/reportdesigner' AS rd )  
 SELECT ReportName           = name  
   ,DataSourceName      = x.value('(@Name)[1]', 'VARCHAR(250)')   
       ,DataProvider      = x.value('(ConnectionProperties/DataProvider)[1]','VARCHAR(250)')  
       ,ConnectionString = x.value('(ConnectionProperties/ConnectString)[1]','VARCHAR(250)')  
  FROM ( SELECT C.Name,CONVERT(XML,CONVERT(VARBINARY(MAX),C.Content)) AS reportXML  
    FROM ReportServer.dbo.Catalog C  
    WHERE C.Content is not null and c.Name like '%the report migrated%'  
    AND C.Type = 2  
  ) a  
  CROSS APPLY reportXML.nodes('/Report/DataSources/DataSource') r ( x )  
 ORDER BY name ;  

I tried this procedure on my VM machine and got the identical result, so I am not quite sure what caused this discrepancy though the report after migration works. If you are accidently reading this thread, and know what happened, please let me know :D

2015-02-24

SSIS Binary Code is not found - You need to invetigate by youself

Recently when one of my collegues worked in a SSIS script task, she got a "binary code is not found" error. What she did is

  • Open the VSTA IDE
  • Add a web reference to the reporting service
  • Build the code, and close the IDE
  • While she tried to close the script window, an error window "binary code is not found" popped up She went back and checked her code, nothing was added yet except for the web reference
  • She set the "delay verification" to true to remove the red cross, but she executed the script task, the task failed with identical error message.

When we do a google search, basically you can find hints like:

  • The code is wrong, check your syntax
  • Set "delay verification" to true if you are using SSIS2008 and later versions
  • Set "PrecompileScriptIntoBinaryCode" to true if you are using SSIS2005

Obviously none of above is applicable in her case. So I grab the package and run on my PC, guess what? Nothing is wrong on my PC. So problem must occurs on her machine.

Now look at MSDN at https://msdn.microsoft.com/en-us/library/ms152787.aspx, it says "to develop Reporting Services applications based on the Web service...using Microsoft Visual Studio and the Microsoft .NET Framework SDK"

Now it looks much clear. I downloaded .Net Framework SDK and installed on here machine. Now she can build the script task with web service.

So considering the case I posted before DBCC Error, searching online is good, but you still need to do your own task. :D

2015-02-03

DBCC CheckDB('Master') Error - Rational Diagnostic

This is a error when I deploy was working on SQL Server migration project.

Actually I would like to log the whole migration project, start from the planning, to end of migration, with the exception handlings. Reason for that is because, if you search online, you will find tons of articles talking about best practice for "upgrade", however you couldn't find too many resources about best practice of "migration". The SQL Server migration task, is to migrate databases from our current SQL Server 2008 R2 Standard Edition database server, to SQL Server 2012 Entreprise Edition on another VM server.

But today I would like to talk about the DBCC master error after I built the 2012 instance.

Long in short, I grabbed the installation disc, followed set up wizard, inputted administration account and service account, and assigned the file location. Everything looked good, and it went smooth.

After installation, I restarted the server, opened the SSMS, and as the most common task, did a DBCC check and then did the backup. Then I got below error message

 Msg 8928, Level 16, State 6, Line 1  
 Object ID 0, index ID -1, partition ID 0, alloc unit ID 0 (type Unknown): Page (1:382) could not be processed. See other errors for details.  
 CHECKDB found 1 allocation errors and 0 consistency errors not associated with any single object.  
 Msg 8939, Level 16, State 98, Line 1  
 Table error: Object ID 44, index ID 1, partition ID 281474979594240, alloc unit ID 281474979594240 (type In-row data), page (1:382). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 133129 and -1.  
 Msg 8906, Level 16, State 1, Line 1  
 Page (1:382) in database ID 1 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags 'IAM_PG MIXED_EXT ALLOCATED 0_PCT_FULL'.  
 Msg 8906, Level 16, State 1, Line 1  
 Page (1:502) in database ID 1 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags 'MIXED_EXT ALLOCATED 0_PCT_FULL'.  
 Msg 2575, Level 16, State 1, Line 1  
 The Index Allocation Map (IAM) page (1:382) is pointed to by the next pointer of IAM page (0:0) in object ID 44, index ID 1, partition ID 281474979594240, alloc unit ID 281474979594240 (type In-row data), but it was not detected in the scan.  
 Msg 8939, Level 16, State 98, Line 1  
 Table error: Object ID 44, index ID 1, partition ID 281474979594240, alloc unit ID 281474979594240 (type In-row data), page (1:382). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 133129 and -1.  
 Msg 7965, Level 16, State 2, Line 1  
 Table error: Could not check object ID 44, index ID 1, partition ID 281474979594240, alloc unit ID 281474979594240 (type In-row data) due to invalid allocation (IAM) page(s).  
 CHECKDB found 4 allocation errors and 2 consistency errors in table 'sys.sysnsobjs' (object ID 44).  
 CHECKDB found 5 allocation errors and 2 consistency errors in database 'master'.  
 repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB (master).  


OMG, if you do a quick google search, you will get tons of troubleshooting methods and suggestions. But probably 9 out of 10 will tell you, your disk has problem.

So let's think about this problem: They are on virtual environment, if one of them has disk fragment problem, eventually all virtual machines should get similar problems, so it should be the case.

So to test my assumption, I uninstalled SQL Server 2012 and then did a reinstall. I re-ran the DBCC command and get the identical error. So think about it, in a virtual environment, install a software  twice and system allocates the same sector to your contents, it doesnt look like a very high chance, isn't it?

So I started to look at this specific object, it is sysnsobjs from the Object_Name function. But when I did a google search, I couldn't find similar errors.

When I look at the MSDN I found the error content actually is related to some schema definition. So is it because of SP/schema change? as I know the installation disc was downloaded in 2012.

SO I downloaded the new installation disc, which was released in 2014 with SP2. Now time to test:

To repeat the error, I built a VM and have two CDs on hand:
  • the old CD, 2012 released in 2012
  • the new CD, 2012 released in 2014 with SP2
I installed two instances on the VM:
  • DBCC CheckDB on the first instance returns identical error.
  • DBCC CheckDB on the 2nd instance passed successfully
  • Then I tried to apply SP2 on the first instance, error is still there
  • Then I tried to use new CD to repair the first instance, error is still there
  • Then I tried to repair master database via single user mode, the error is gone
 
So what is the conclusion? While from my experience, troubleshooting sometimes is fun, as you need to use your imagination. :D