Import remote data using SqlWatchImport
Since version 3.x
, a new console application has been made available to efficiently handle imports from the remote instances. This is the preferred way to import data from the remote SQLWATCH databases.
Overview
The SqlWatchImport.exe
leverages the performance of the .NET SqlBulkCopy
and data streaming for fast inserts as well as framework’s Thread and Connection pooling which makes it very efficient and lightweight. In my test setup, importing data from the same, single remote instance takes ~10 seconds in SSIS and Linked Server and 1.2 second using the console application.
The more often the import runs, the quicker it is because it has less work to do. You will have to find the best balance in your environment, as a reference, I have it running every 1 minute and as you can see, some servers take less tha 1 second to import:
2020-08-23 20:36:31.669 SQLWATCH Remote Instance Importer
Imports remote SQLWATCH data into the Central Repository
Marcin Gminski 2020, SQLWATCH.IO
Version: 1.1.7537.25291 (8/20/2020 2:03:02 PM)
2020-08-23 20:36:31.732 Got 3 instances to import
2020-08-23 20:36:31.732 Got 44 tables to import from each instance
2020-08-23 20:36:31.748 Importing: "SQLWATCH-TEST-1"
2020-08-23 20:36:32.107 Importing: "SQL-1"
2020-08-23 20:36:32.138 Finished: "SQLWATCH-TEST-1". Time taken: 379.5364ms
2020-08-23 20:36:32.424 Importing: "SQLWATCH-TEST-2"
2020-08-23 20:36:33.201 Finished: "SQLWATCH-TEST-2". Time taken: 768.9659ms
2020-08-23 20:36:33.857 Finished: "SQL-1". Time taken: 1746.7494ms
2020-08-23 20:36:33.857 Import completed in 2176.7349ms
Prior to version 3.x
the data import was done with SSIS or via Linked Server. The application was written to address the following problems:
- SSIS is fast but cumbersome to maintain - every time new table or column is changed or added to the SqlWatch database, the package requires manual changes to reflect database changes. This is very time consuming and error prone. I am also trying to stay away from BIML to reduce complexity of the solution.
- Threading in SSIS is limited by the design of the package.
- Not everyone has Integration Server.
- Linked Server does not require as much maintenance but it does rely on SQL Agent for data collection so cannot be run on SQL Express directly.
- Linked Server is not as fast as SSIS and does not handle XML fields.
Configuration
The application configuration items are in the App.config
file, included in the application folder. Before the first run, you are going to have to configure Central Repository connection parameters:
<!-- Central repository connection details -->
<add key="CentralRepositorySqlInstance" value="REPOSITORY-SQLSERVER" />
<add key="CentralRepositorySqlDatabase" value="SQLWATCH" />
Add and manage remote instance
The application allows adding new and updating existing remote Sql Instances.
Examples
Add remote Sql Instance “SQLSERVER1” with SqlWatch database “SQLWATCH” using Windows Authentication:
SqlWatchImport.exe --add -s SQLSERVER1 -d SQLWATCH
Add remote Sql Instance “SQLSERVER1” with SqlWatch database “SQLWATCH” using Sql user “Marcin” and Sql password “Password”:
SqlWatchImport.exe --add -s SQLSERVER1 -d SQLWATCH -u Marcin -p Password
Add remote Sql Instance with custom hostname and port:
SqlWatchImport.exe --add -s SQLSERVER1 -d SQLWATCH -h 192.168.1.10 -o 1433
You only have to configure hostname if your
@@SERVERNAME
does not match the physical hostname. Normally this would be a configuration error apart from rare scenarios, such as running Sql as a Docker container.
Update existing remote instance:
SqlWatchImport.exe --update -s SQLSERVER1 -d SQLWATCH -u Marcin -p NewPassword
Display help:
SqlWatchImport.exe -h
The configuration data is saved in table [dbo].[sqlwatch_config_sql_instance]
.
Data Import
Once all remote instances have been added, data import can be simply invoked by running the SqlWatchImport.exe
without any arguments.
Credential encryption
It is advisable to use Windows Authentication instead of Sql Authentication. If you really have to use Sql Authentication you have to keep in mind few things.
The credentials will be encrypted and stored in the [dbo].[sqlwatch_config_sql_instance]
table. The encryption will be done using .NET MachineKey.Protect
method. This is a standard method often used to encrypt connection strings on web servers running .NET applications.
By default, the encryption will use the Machine Key, which means, the application will be able to decrypt passwords on the same machine where the password was encrypted. For example, if you run SqlWatchImport.exe --add -s SQLSERVER1 -d SQLWATCH -u Marcin -p Password
on your laptop, you will only be able to run the data import on your laptop. If you want to re-save the use secret on a new machine you will have to run the update command SqlWatchImport.exe --update ...
You can also use custom MachineKey stored in the App.config
file. You can generate new key on https://www.allkeysgenerator.com/Random/ASP-Net-MachineKey-Generator.aspx and save it in the config file. This will allow the application to work from any machine.
If you ever decide to change the MachineKey, you will have generate new Sql Secrets by running the --update
option.
Please note that anyone who has access to the machine, will be able to access the MachineKey and your config file. If they also have access to the SQLWATCH database where the secrets are saved, they will be able to decrypt it. Limit Read Only access to only authorised persons. If you use Sql Authentication, please create dedicated Sql Accounts for importing data. They should only have Read Only access to the remote database so if the passwords are broken, the intruder will not gain access to anything else but meaningless SQLWATCH data.