Thursday, April 14, 2016

SSIS – Running single SSIS packages in Parallel to get faster performance for multiple data loads

Brief description of the project

I had to move the data from a central database to different databases (all databases with the same schema)  and I wanted to achieve this trough parallel processing instead of sequential through  a FOR loop

I created a parent package and added a sequence container in it .
I added a for loop inside the sequence container and added a call ( any number that I want to ruin in parallel ) to the child packages.

Created a parent package .


I created a package level variable varLoopQuitParent = 0 and this will be used to exit the for loop after getting updated to 1 in the EXIT FOR  script in the child package later.




 
 
The Execute SQL Task: Update Processing List comes is used to reset the different databases active processing status once the data is moved.
 
Now I created a child package
 
 
( The child package is called the following way from the parent package using the Execute package Task)


 
Child package is the  real place where everything happens.
I have a table where I have a list of clients ( databases) and the connection string that I read and put into a variable ( child package level) and use that to create the dynamic connection string to the multiple databases.
 
The Execute SQL task : Get Connection string into variables on the child package calls a stored procedure (proc_ResultProcessing_List) that returns the client code and the connection string to the databases and assigns to the variable varChildConnString and varClientCode.
 
Here is the code in the sp

 
 
 

-Section 1

Declare @ConnString varchar(100)

DEclare @clientCode int



 
 
--Section 2
 
 

BEGIN TRAN TRAN1




--Section 3
 
 



 
 
SET Rowcount 1




--Section 4
 
 

 
select @ConnString = Connstring, @ClientCodeCode = clientCode from clientsProcessList where ds_id = 2 and Dataprocessing = 2



 
 
-- 1 is active processing

--2 is ready

--print @ConnString + space(5) + cast(@hospCode as varchar)
 
 




--section 5
 
 

UPDATE clientsProcessList

WITH (TABLOCK)

SET Dataprocessing = 1

WHERE clientCode = @clientCode

and ds_id = 2 and Dataprocessing = 2



 

 
 
--section 6
 
 



 
 
SET Rowcount 0



 
 
--section 7
 
 



 
 
SELECT isnull(@ConnString,'empty') as ConnectionString, isnull(@HospCode,0) as ClientCode




--section 9
 
 

COMMIT TRAN TRAN1



 

 
 
END TRY



 
 
BEGIN CATCH



 

 
 
print 'error here'



 

 
 
SELECT

ERROR_NUMBER() AS ErrorNumber

,ERROR_SEVERITY() AS ErrorSeverity

,ERROR_STATE() AS ErrorState

,ERROR_PROCEDURE() AS ErrorProcedure

,ERROR_LINE() AS ErrorLine

,ERROR_MESSAGE() AS ErrorMessage

,ERROR_PROCEDURE() AS ErrorProcedure

,ERROR_LINE() AS ErrorLine;

print 'rollback'



 

 
 
ROLLBACK TRANSACTION TRAN1 ;




 
END CATCH




 

 
Section 1
The first thing that we do is declare our @ConnString and  @clientCode
 Section 2
Next we start a Begin Tran
1.       NOTE: The reason for this is so that we can actually lock the table whilst this transaction is happening.
2.       NOTE 2: This is so that when the SSIS Packages are running in parallel, we know for a fact that each package will only get a valid ConnString   and clientCode when trying to get another value. If it tries whilst another SSIS Package is busy it will wait until the transaction has been          completed.
Section 3
We then set the RowCount to 1, this is so that we will only get one row back.
1.       NOTE: we are doing this because we only ever want to get back one ConnString  and clientcode

Section 4
Next is our TSQL Select statement
1.       Here we are getting any ConnString, clientcode from our table, where the DataProcessing is set to 2.( ready to process)
2.       We are then putting this into our @ConnString variabl and @ClientCode
Section 5
Next we are updating our table using the TABLOCK hint so that we can once again lock the entire table, to ensure that for our specific clientcode row it gets updated from a 2 to 1.
1.       NOTE: This then means that this data is and has been processed when the next package comes along looking for data to process.
 Section 6
We then set the RowCount back to 0 (zero)

 Section 7
 Then we run a TSQL Select statement so that we can then pass our  @ConnString and  @clientCode
( is null value to pass if reached EOR which is later used in the EXIT  LOOP precedence)
1.       NOTE: This is because we are using the varChildConnString and varClientCode passing this into a variable in our Execute SQL Task.
2.       NOTE 2: We also set the isNull to 0 (zero) so that when there are no more rows to process it defaults to zero, which is explained laterin the Exit Loop.
Section 8
Finally we are then committing our transaction.
Within our Execute SQL Task we also map the result set to our variable called:
 

 
 
 
Now the last thing to configure in this SSIS package is the Precedence Constraint which can be seen in the picture below

 We execute the  Execute SQL Task: Execute SPs while there is a  value in the variable ( while the sp is returning a row)
 
 We exit once the varHospitalCode is 0

 
The last step is to set the parent variable varLoopQuitParent = 1 in the EXIT loop by binding the parent variable in the child package .
 
Click on this LINK on how to bind (Passing Values To and From Child Packages)
 
The script for the EXIT LOOP
 
public void Main()
 
 

{

 

 
           
Dts.Variables["varLoopQuitParent"].Value = 1;
Dts.TaskResult = (int)ScriptResults.Success;
 
 

}


Make the varLoopQuitParent as ReadWriteVaroable.

 
 
 
 
 
 


Monday, March 28, 2016

Check if a table name exists in stored procedures

 use [yorDB]
 GO


SELECT [Scehma]=schema_name(o.schema_id), o.Name, o.type

FROM sys.sql_modules m

INNER JOIN sys.objects o

ON o.object_id = m.object_id

WHERE m.definition like '%tablename%'









GO

Wednesday, March 23, 2016

Backup SSISDB

I came across a very good instructions on MSDN for this .

https://blogs.msdn.microsoft.com/mattm/2012/03/23/ssis-catalog-backup-and-restore/

SSIS Catalog – Backup and Restore

 
Integration Services catalog (SSISDB) uses the encryption mechanism available in SQL Server to protect its sensitive data. So backup and restore of SSIS catalog across machines need some extra steps in addition to the usual backup and restore steps. This post describes all the steps involved in backup and restore of SSIS catalog.

Backup
1. Backup the master key used for encryption in SSISDB database and protect the backup file using a password. This is done using BACKUP MASTER KEY statement.
 USE SSISDB
 BACKUP MASTER KEY TO FILE = 'c:\DMK\SSISDB\key'
 ENCRYPTION BY PASSWORD = 'SS1SC@talogMKBKUP'
 This step is not necessary every time you do backup unless you have lost the file or the password or if you have changed the master key of the SSISDB database.
2. Backup SSISDB database using SQL Server Management Studio or BACKUP DATABASE statement in TSQL.
3. If SSISDB database will be restored in a SQL Server instance that never had SSIS catalog, follow steps 3.1. & 3.2. listed below in additional backup steps section.

Restore
4. If SSISDB database will be restored in a SQL Server instance that never had any SSIS catalog, follow preparatory steps 4.1. & 4.2. listed below in additional restore steps section.
5. Restore SSISDB database using SQL Server Management Studio or RESTORE DATABASE statement in TSQL.
6. If SSISDB is restored in a SQL Server instance that never had any SSIS catalog, follow steps 6.1. thru 6.3. listed below in additional restore steps section.
7. Restore backup of the master key from the source server using the backup file created in step 1 in Backup section above.
 USE SSISDB
 RESTORE MASTER KEY FROM FILE = 'D:\MasterKeyBackup\SSIS-Server1234\key'
 DECRYPTION BY PASSWORD = 'SS1SC@talogMKBKUP'
 ENCRYPTION BY PASSWORD = 'NewC@talogPassw0rd'
 FORCE
 
“SS1SC@talogMKBKUP” is the password used to protect the file containing backup of the master key and “NewC@talogPassw0rd” is the new password to encrypt database master key.
The warning reported when carrying out this step “The current master key cannot be decrypted. The error was ignored because the FORCE option was specified.” can be ignored.
Decrypting all keys using the currently active master key and re-encrypting using the restored master key is a resource-intensive operation should be scheduled when server usage is low.
SSIS catalog should be fully functional in the restored server now.

Additional Backup Steps
Following steps are necessary during backup if you will be restoring SSISDB database to a SQL Server instance where the catalog was never created.
3.1. Generate create script for sp_ssis_startup stored procedure which is created when SSIS catalog is created in a SQL Server. The script is generated using SQL Server Management Studio. Right-click on the stored procedure in master database in SSMS Object Explorer, select “Script Stored Procedure as” -> “CREATE TO” -> “File” options to save the script to a file (for example, sp_ssis_startup.sql).
3.2. Generate create script for Agent job [SSIS Server Maintenance Job] which is created in SQL Server Agent automatically when SSIS catalog is created in a SQL Server. The script is generated using SQL Server Management Studio. Right-click on the Agent job in SSMS Object Explorer, select “Script Job as” -> “CREATE TO” -> “File” options to save the job to a file (for example, ssis_server_maintenance_job.sql).

Additional Restore Steps
Following steps are necessary during restore if you are restoring SSISDB database to a SQL Server instance where the catalog was never created.
4.1. Enable CLR functionality in SQL Server that SSISDB database depends on.
 USE MASTER
 EXEC sp_configure 'clr enabled', 1
 RECONFIGURE
4.2. Create asymmetric key and unsafe assembly loading principal that SSISDB database depends on. The login is used only for granting permission and hence does not have to be mapped to a database user.
 USE MASTER
 CREATE ASYMMETRIC KEY MS_SQLEnableSystemAssemblyLoadingKey FROM EXECUTABLE FILE = 'C:\Program Files\Microsoft SQL Server\110\DTS\Binn\ISServerExec.exe'
 CREATE LOGIN MS_SQLEnableSystemAssemblyLoadingUser FROM ASYMMETRIC KEY MS_SQLEnableSystemAssemblyLoadingKey
 GRANT UNSAFE ASSEMBLY TO MS_SQLEnableSystemAssemblyLoadingUser
You may need to change the file system path to ISServerExec.exe depending on your install location.

6.1. Create login [##MS_SSISServerCleanupJobLogin##] using CREATE LOGIN TSQL statement. This login is for internal use in SSISDB maintenance.
6.2. Map SSISDB user ##MS_SSISServerCleanupJobUser## to server login ##MS_SSISServerCleanupJobLogin##
 USE SSISDB
 ALTER USER [##MS_SSISServerCleanupJobUser##] with LOGIN = [##MS_SSISServerCleanupJobLogin##]
6.3. Create startup stored procedure and agent job by executing scripts (sp_ssis_startup.sql  & ssis_server_maintenance_job.sql) created in steps 3.1 & 3.2 under additional backup steps section above in the master database in the SQL Server instance in which SSISDB database is restored. You need to update @servername parameter for sp_add_jobserver step in ssis_server_maintenance_job.sql with the name of the new server replacing old server name.