Merge pull request #1 from microsoft/master

catching up the main repo
This commit is contained in:
Alex Protsenko
2019-09-23 18:52:47 +03:00
committed by GitHub
24 changed files with 410 additions and 185 deletions
@@ -0,0 +1,85 @@
![](./media/solutions-microsoft-logo-small.png)
# OPTIMIZE_FOR_SEQUENTIAL_KEY
In SQL Server 2019, a new index option was added called [OPTIMIZE_FOR_SEQUENTIAL_KEY](https://docs.microsoft.com/sql/t-sql/statements/create-index-transact-sql#sequential-keys) that is intended to address an issue known as [last page insert contention](https://support.microsoft.com/kb/4460004). Most of the solutions to this problem that have been suggested in the past involve making changes to either the application or the structure of the contentious index, which can be costly and sometimes involve performance trade-offs. Rather than making major structural changes, OPTIMIZE_FOR_SEQUENTIAL_KEY addresses some of the SQL Server scheduling issues that can lead to severely reduced throughput when last page insert contention occurs. Using the OPTMIZE_FOR_SEQUENTIAL_KEY index option can help maintain consistent throughput in high-concurrency environments when the following conditions are true:
- The index has a sequential key
- The number of concurrent insert threads to the index far exceeds the number of schedulers (in other words logical cores)
- The index has a high rate of new page allocations (page splits), which is most often due to a large row size
This sample illustrates how OPTIMIZE_FOR_SEQUENTIAL_KEY can be used to improve throughput on workloads that are suffering from severe last page insert contention bottlenecks.
### Contents
[About this sample](#about-this-sample)<br/>
[Before you begin](#before-you-begin)<br/>
[Run this sample](#run-this-sample)<br/>
[Disclaimers](#disclaimers)<br/>
[Related links](#related-links)<br/>
<a name=about-this-sample></a>
## About this sample
- **Applies to:** SQL Server 2019 (or higher)
- **Workload:** High-concurrency OLTP
- **Programming Language:** T-SQL
- **Authors:** Pam Lahoud
- **Update history:** Created August 15, 2019
<a name=before-you-begin></a>
## Before you begin
To run this sample, you need the following prerequisites.
1. SQL Server 2019 (or higher)
2. A server (physical or virtual) with multiple cores
3. The [AdventureWorks2016_EXT](https://github.com/Microsoft/sql-server-samples/releases/download/adventureworks/AdventureWorks2016_EXT.bak) sample database
[!NOTE]
> This sample was designed for a server with 8 logical cores. If you run the sample on a server with more cores, you may need to increase the number of concurrent threads in order to observe the improvement.
<a name=run-this-sample></a>
## Run this sample
1. Copy the files from the root folder to a folder on the SQL Server.
2. Download [AdventureWorks2016_EXT.bak](https://github.com/Microsoft/sql-server-samples/releases/download/adventureworks/AdventureWorks2016_EXT.bak) and restore it to your SQL Server 2019 instance.
3. From SQL Server Management Studio or Azure Data Studio, run the Setup.sql script.
4. Modify the SequentialInserts_Optimized.bat and SequentialInserts_Unoptimized.bat files and change the -S parameter to point to the server where the setup script was run. For example, `-S.\SQL2019` points to an instance named SQL2019 on the local server.
5. Open the SQL2019_LatchWaits.htm file to open a Performance Monitor session in your default browser.
6. Right-click anywhere in the browser window to clear the existing data from the session.
7. Click the play button to start the Performance Monitor session.
8. From a Command Prompt, browse to the folder that contains the demo files and run SequentialInserts_Unoptimized.bat, then return to the Performance Monitor window. You should see a high number of Page Latch waits as well as high average wait times. Note the time it takes for the script to complete.
9. Run the SequentialInserts_Optimized.bat script from the same Command Prompt window and again return to the Performance Monitor window. This time you should see much lower number and duration of Page Latch waits, along with higher Batch requests/sec. Note the time it takes for the script to complete, it should be significantly faster than the Unoptimized script.
10. **OPTIONAL** - Modify the `-n256` parameter in the Optimized and Unoptimized scripts to see the effect on performance. Generally, the larger the number of concurrent sessions, the greater the improvement will be with OPTIMIZE_FOR_SEQUENTIAL_KEY.
<a name=disclaimers></a>
## Disclaimers
The code included in this sample is not intended to be a set of best practices on how to build scalable enterprise grade applications. This is beyond the scope of this quick start sample.
<a name=related-links></a>
## Related Links
For more information, see these articles:
[CREATE INDEX - Sequential Keys](https://docs.microsoft.com/sql/t-sql/statements/create-index-transact-sql#sequential-keys)
[Behind the Scenes on OPTIMIZE_FOR_SEQUENTIAL_KEY](https://techcommunity.microsoft.com/t5/SQL-Server/Behind-the-Scenes-on-OPTIMIZE-FOR-SEQUENTIAL-KEY/ba-p/806888)
@@ -0,0 +1,5 @@
ECHO OFF
rd /s /q %temp%\output
"ostress.exe" -E -S.\SQL2019 -dAdventureWorks2016_EXT -Q"EXEC usp_InsertLogRecord @Optimized = 1" -mstress -quiet -n1 -r1 | FINDSTR "Cantfindthisstring"
rd /s /q %temp%\output
"ostress.exe" -E -S.\SQL2019 -dAdventureWorks2016_EXT -Q"EXEC usp_InsertLogRecord @Optimized = 1" -mstress -quiet -n256 -r250 | FINDSTR "QEXEC Starting Creating elapsed"
@@ -0,0 +1,5 @@
ECHO OFF
rd /s /q %temp%\output
"ostress.exe" -E -S.\SQL2019 -dAdventureWorks2016_EXT -Q"EXEC usp_InsertLogRecord" -mstress -quiet -n1 -r1 | FINDSTR "Cantfindthisstring"
rd /s /q %temp%\output
"ostress.exe" -E -S.\SQL2019 -dAdventureWorks2016_EXT -Q"EXEC usp_InsertLogRecord" -mstress -quiet -n256 -r250 | FINDSTR "QEXEC Starting Creating elapsed"
@@ -0,0 +1,91 @@
USE AdventureWorks2016_EXT;
GO
-- Create regular table
DROP TABLE IF EXISTS [dbo].[TestSequentialKey];
GO
CREATE TABLE [dbo].[TestSequentialKey](
[DatabaseLogID] [bigint] IDENTITY(1,1) NOT NULL,
[PostTime] [datetime2] NOT NULL,
[DatabaseUser] [sysname] NOT NULL,
[Event] [sysname] NOT NULL,
[Schema] [sysname] NULL,
[Object] [sysname] NULL,
[TSQL] [nvarchar](max) NOT NULL
CONSTRAINT [PK_TestSequentialKey_DatabaseLogID] PRIMARY KEY NONCLUSTERED
(
[DatabaseLogID] ASC
));
CREATE CLUSTERED INDEX CIX_TestSequentialKey_PostTime ON TestSequentialKey (PostTime);
GO
-- Create optimized table
DROP TABLE IF EXISTS [dbo].[TestSequentialKey_Optimized];
GO
CREATE TABLE [dbo].[TestSequentialKey_Optimized](
[DatabaseLogID] [bigint] IDENTITY(1,1) NOT NULL,
[PostTime] [datetime2] NOT NULL,
[DatabaseUser] [sysname] NOT NULL,
[Event] [sysname] NOT NULL,
[Schema] [sysname] NULL,
[Object] [sysname] NULL,
[TSQL] [nvarchar](max) NOT NULL
CONSTRAINT [PK_TestSequentialKey_Optimized_DatabaseLogID] PRIMARY KEY NONCLUSTERED
(
[DatabaseLogID] ASC
)
WITH (OPTIMIZE_FOR_SEQUENTIAL_KEY=ON));
CREATE CLUSTERED INDEX CIX_TestSequentialKey_Optimized_PostTime ON TestSequentialKey_Optimized (PostTime) WITH (OPTIMIZE_FOR_SEQUENTIAL_KEY=ON);
GO
-- Create INSERT stored procedure
CREATE OR ALTER PROCEDURE usp_InsertLogRecord @Optimized bit = 0 AS
DECLARE @PostTime datetime2 = SYSDATETIME(), @User sysname, @Event sysname, @Schema sysname, @Object sysname, @TSQL nvarchar(max)
SELECT @User = name
FROM sys.sysusers
WHERE issqlrole = 0 and hasdbaccess = 1 and status = 0
ORDER BY NEWID();
SELECT @Object = t.name, @Schema = s.name
FROM sys.tables t
INNER JOIN sys.schemas s ON s.schema_id = t.schema_id
ORDER BY NEWID();
IF DATEPART(ms, @PostTime) % 4 = 0
BEGIN
SET @Event = N'SELECT';
SET @TSQL = N'SELECT * FROM ' + @Schema + '.' + @Object
END
ELSE IF DATEPART(ms, @PostTime) % 4 = 1
BEGIN
SET @Event = N'INSERT';
SET @TSQL = N'INSERT ' + @Schema + '.' + @Object + ' SELECT * FROM ' + @Schema + '.' + @Object
END
ELSE IF DATEPART(ms, @PostTime) % 4 = 2
BEGIN
SET @Event = N'UPDATE';
SET @TSQL = N'UPDATE ' + @Schema + '.' + @Object + ' SET 1=1';
END
ELSE IF DATEPART(ms, @PostTime) % 4 = 3
BEGIN
SET @Event = N'DELETE';
SET @TSQL = N'DELETE FROM ' + @Schema + '.' + @Object + ' WHERE 1=1';
END
IF @Optimized = 1
INSERT TestSequentialKey_Optimized (PostTime, DatabaseUser, [Event], [Schema], [Object], [TSQL])
VALUES (@PostTime, @User, @Event, @Schema, @Object, @TSQL);
ELSE
INSERT TestSequentialKey (PostTime, DatabaseUser, [Event], [Schema], [Object], [TSQL])
VALUES (@PostTime, @User, @Event, @Schema, @Object, @TSQL);
GO
@@ -1,2 +1,3 @@
#!/bin/bash -e
apt update
apt install microsoft-mlserver-mml-r-9.3.0
@@ -41,12 +41,14 @@ if NOT EXIST tpcxbb_1gb.bak (
set SQLCMDSERVER=%SQL_MASTER_INSTANCE%
set SQLCMDUSER=sa
set SQLCMDPASSWORD=%SQL_MASTER_SA_PASSWORD%
for /F "usebackq" %%v in (`sqlcmd -I -b -h-1 -Q "print RTRIM((CAST(SERVERPROPERTY('ProductLevel') as nvarchar(128))));"`) do SET CTP_VERSION=%%v
if /i "%CTP_VERSION%" EQU "CTP2.4" (set MASTER_POD_NAME=mssql-master-pool-0) else (set MASTER_POD_NAME=master-0)
for /F "usebackq tokens=1,2" %%v in (`sqlcmd -I -b -h-1 -W -Q "SET NOCOUNT ON; SELECT @@SERVERNAME, SERVERPROPERTY('IsHadrEnabled');"`) do (
SET MASTER_POD_NAME=%%v
SET HADR_ENABLED=%%w
)
REM Copy the backup file, restore the database, create necessary objects and data file
echo Copying sales database backup file to SQL Master instance...
%DEBUG% kubectl cp tpcxbb_1gb.bak %CLUSTER_NAMESPACE%/%MASTER_POD_NAME%:var/opt/mssql/data -c mssql-server || goto exit
%DEBUG% kubectl cp tpcxbb_1gb.bak %CLUSTER_NAMESPACE%/%MASTER_POD_NAME%:var/opt/mssql/data/ -c mssql-server || goto exit
REM Download and copy the sample backup files
if /i "%AW_WWI_SAMPLES%" EQU "--install-extra-samples" (
@@ -57,7 +59,10 @@ if /i "%AW_WWI_SAMPLES%" EQU "--install-extra-samples" (
%DEBUG% curl -L -G "https://github.com/Microsoft/sql-server-samples/releases/download/adventureworks/%%f" -o %%f
)
echo Copying %%f database backup file to SQL Master instance...
%DEBUG% kubectl cp %%f %CLUSTER_NAMESPACE%/%MASTER_POD_NAME%:var/opt/mssql/data -c mssql-server || goto exit
%DEBUG% kubectl cp %%f %CLUSTER_NAMESPACE%/%MASTER_POD_NAME%:var/opt/mssql/data/ -c mssql-server || goto exit
echo Removing database backup file...
%DEBUG% kubectl exec %MASTER_POD_NAME% -n %CLUSTER_NAMESPACE% -c mssql-server -i -t -- bash -c "rm -rvf /var/opt/mssql/data/%%f"
)
set FILES=WideWorldImporters-Full.bak WideWorldImportersDW-Full.bak
@@ -67,40 +72,50 @@ if /i "%AW_WWI_SAMPLES%" EQU "--install-extra-samples" (
%DEBUG% curl -L -G "https://github.com/Microsoft/sql-server-samples/releases/download/wide-world-importers-v1.0/%%f" -o %%f
)
echo Copying %%f database backup file to SQL Master instance...
%DEBUG% kubectl cp %%f %CLUSTER_NAMESPACE%/%MASTER_POD_NAME%:var/opt/mssql/data -c mssql-server || goto exit
%DEBUG% kubectl cp %%f %CLUSTER_NAMESPACE%/%MASTER_POD_NAME%:var/opt/mssql/data/ -c mssql-server || goto exit
echo Removing database backup file...
%DEBUG% kubectl exec %MASTER_POD_NAME% -n %CLUSTER_NAMESPACE% -c mssql-server -i -t -- bash -c "rm -rvf /var/opt/mssql/data/%%f"
)
)
REM If HADR is enabled then port-forward 1533 temporarily to connect to the primary directly
REM Default timeout for port-forward is 5 minutes so start command in background & it will terminate automatically
if /i "%HADR_ENABLED%" EQU "1" (
%DEBUG% start kubectl port-forward pods/%MASTER_POD_NAME% 1533:1533 -n %CLUSTER_NAMESPACE%
SET SQLCMDSERVER=127.0.0.1,1533
)
echo Configuring sample database(s)...
%DEBUG% sqlcmd -i "%STARTUP_PATH%bootstrap-sample-db.sql" -o "bootstrap.out" -I -b -v SA_PASSWORD="%KNOX_PASSWORD%" || goto exit
REM remove files copied into the pod:
echo Removing database backup files...
%DEBUG% kubectl exec %MASTER_POD_NAME% -n %CLUSTER_NAMESPACE% -c mssql-server -i -t -- bash -c "rm -rvf /var/opt/mssql/data/*.bak"
echo Removing database backup file...
%DEBUG% kubectl exec %MASTER_POD_NAME% -n %CLUSTER_NAMESPACE% -c mssql-server -i -t -- bash -c "rm -rvf /var/opt/mssql/data/tpcxbb_1gb.bak"
for %%F in (web_clickstreams inventory customer) do (
if NOT EXIST %%F.csv (
echo Exporting %%F data...
if /i %%F EQU web_clickstreams (set DELIMITER=,) else (SET DELIMITER=^|)
%DEBUG% bcp sales.dbo.%%F out "%%F.csv" -S %SQL_MASTER_INSTANCE% -Usa -P%SQL_MASTER_SA_PASSWORD% -c -t"!DELIMITER!" -o "%%F.out" -e "%%F.err" || goto exit
%DEBUG% bcp sales.dbo.%%F out "%%F.csv" -S %SQLCMDSERVER% -Usa -P%SQL_MASTER_SA_PASSWORD% -c -t"!DELIMITER!" -o "%%F.out" -e "%%F.err" || goto exit
)
)
if NOT EXIST product_reviews.csv (
echo Exporting product_reviews data...
%DEBUG% bcp "select pr_review_sk, replace(replace(pr_review_content, ',', ';'), char(34), '') as pr_review_content from sales.dbo.product_reviews" queryout "product_reviews.csv" -S %SQL_MASTER_INSTANCE% -Usa -P%SQL_MASTER_SA_PASSWORD% -c -t, -o "product_reviews.out" -e "product_reviews.err" || goto exit
%DEBUG% bcp "select pr_review_sk, replace(replace(pr_review_content, ',', ';'), char(34), '') as pr_review_content from sales.dbo.product_reviews" queryout "product_reviews.csv" -S %SQLCMDSERVER% -Usa -P%SQL_MASTER_SA_PASSWORD% -c -t, -o "product_reviews.out" -e "product_reviews.err" || goto exit
)
REM Copy the data file to HDFS
echo Uploading web_clickstreams data to HDFS...
%DEBUG% curl -i -L -k -u root:%KNOX_PASSWORD% -X PUT "https://%KNOX_ENDPOINT%/gateway/default/webhdfs/v1/clickstream_data?op=MKDIRS" || goto exit
%DEBUG% curl -i -L -k -u root:%KNOX_PASSWORD% -X PUT "https://%KNOX_ENDPOINT%/gateway/default/webhdfs/v1/clickstream_data/web_clickstreams.csv?op=create&overwrite=true" -H "Content-Type: application/octet-stream" -T "web_clickstreams.csv" || goto exit
%DEBUG% curl -L -k -u root:%KNOX_PASSWORD% -X PUT "https://%KNOX_ENDPOINT%/gateway/default/webhdfs/v1/clickstream_data?op=MKDIRS" || goto exit
%DEBUG% curl -L -k -u root:%KNOX_PASSWORD% -X PUT "https://%KNOX_ENDPOINT%/gateway/default/webhdfs/v1/clickstream_data/web_clickstreams.csv?op=create&overwrite=true" -H "Content-Type: application/octet-stream" -T "web_clickstreams.csv" || goto exit
:: del /q web_clickstreams.*
echo.
echo Uploading product_reviews data to HDFS...
%DEBUG% curl -i -L -k -u root:%KNOX_PASSWORD% -X PUT "https://%KNOX_ENDPOINT%/gateway/default/webhdfs/v1/product_review_data?op=MKDIRS" || goto exit
%DEBUG% curl -i -L -k -u root:%KNOX_PASSWORD% -X PUT "https://%KNOX_ENDPOINT%/gateway/default/webhdfs/v1/product_review_data/product_reviews.csv?op=create&overwrite=true" -H "Content-Type: application/octet-stream" -T "product_reviews.csv" || goto exit
%DEBUG% curl -L -k -u root:%KNOX_PASSWORD% -X PUT "https://%KNOX_ENDPOINT%/gateway/default/webhdfs/v1/product_review_data?op=MKDIRS" || goto exit
%DEBUG% curl -L -k -u root:%KNOX_PASSWORD% -X PUT "https://%KNOX_ENDPOINT%/gateway/default/webhdfs/v1/product_review_data/product_reviews.csv?op=create&overwrite=true" -H "Content-Type: application/octet-stream" -T "product_reviews.csv" || goto exit
:: del /q product_reviews.*
REM %DEBUG% del /q *.out *.err *.csv
@@ -122,4 +137,4 @@ goto :eof
:usage
echo USAGE: %0 ^<CLUSTER_NAMESPACE^> ^<SQL_MASTER_IP^> ^<SQL_MASTER_SA_PASSWORD^> ^<KNOX_IP^> [^<KNOX_PASSWORD^>] [--install-extra-samples] [SQL_MASTER_PORT] [KNOX_PORT]
echo Default ports are assumed for SQL Master instance ^& Knox gateway unless specified.
exit /b 0
exit /b 0
@@ -51,18 +51,10 @@ then
$DEBUG curl -G "https://sqlchoice.blob.core.windows.net/sqlchoice/static/tpcxbb_1gb.bak" -o tpcxbb_1gb.bak
fi
CTP_VERSION=$(sqlcmd -S $SQL_MASTER_INSTANCE -Usa -P$SQL_MASTER_SA_PASSWORD -I -b -h-1 -Q "print RTRIM((CAST(SERVERPROPERTY('ProductLevel') as nvarchar(128))));")
if [ "$CTP_VERSION" == "CTP2.4" ]
then
MASTER_POD_NAME=mssql-master-pool-0
else
MASTER_POD_NAME=master-0
fi
read -r MASTER_POD_NAME HADR_ENABLED <<<$(sqlcmd -S $SQL_MASTER_INSTANCE -Usa -P$SQL_MASTER_SA_PASSWORD -I -b -h-1 -Q "SET NOCOUNT ON; SELECT @@SERVERNAME, SERVERPROPERTY('IsHadrEnabled');")
echo Copying sales database backup file...
$DEBUG kubectl cp tpcxbb_1gb.bak $CLUSTER_NAMESPACE/$MASTER_POD_NAME:var/opt/mssql/data -c mssql-server || (echo $ERROR_MESSAGE && exit 1)
# $DEBUG rm tpcxbb_1gb.bak
if [ "$AW_WWI_SAMPLES" == "--install-extra-samples" ]
then
@@ -75,6 +67,9 @@ then
fi
echo Copying $file database backup file to SQL Master instance...
$DEBUG kubectl cp $file $CLUSTER_NAMESPACE/$MASTER_POD_NAME:var/opt/mssql/data -c mssql-server || (echo $ERROR_MESSAGE && exit 1)
echo Removing database backup file...
$DEBUG kubectl exec $MASTER_POD_NAME -n $CLUSTER_NAMESPACE -c mssql-server -i -t -- bash -c "rm -rvf /var/opt/mssql/data/$file"
done
@@ -87,17 +82,28 @@ then
fi
echo Copying $file database backup file to SQL Master instance...
$DEBUG kubectl cp $file $CLUSTER_NAMESPACE/$MASTER_POD_NAME:var/opt/mssql/data -c mssql-server || (echo $ERROR_MESSAGE && exit 1)
echo Removing database backup file...
$DEBUG kubectl exec $MASTER_POD_NAME -n $CLUSTER_NAMESPACE -c mssql-server -i -t -- bash -c "rm -rvf /var/opt/mssql/data/$file"
done
fi
# If HADR is enabled then port-forward 1533 temporarily to connect to the primary directly
# Default timeout for port-forward is 5 minutes so start command in background & it will terminate automatically
if [ "$HADR_ENABLED" == "1" ]
then
$DEBUG kubectl port-forward pods/$MASTER_POD_NAME 1533:1533 -n $CLUSTER_NAMESPACE &
SQL_MASTER_INSTANCE=127.0.0.1,1533
fi
echo Configuring sample database...
# WSL ex: "/mnt/c/Program Files/Microsoft SQL Server/Client SDK/ODBC/130/Tools/Binn/SQLCMD.EXE"
export SA_PASSWORD=$KNOX_PASSWORD
$DEBUG sqlcmd -S $SQL_MASTER_INSTANCE -Usa -P$SQL_MASTER_SA_PASSWORD -I -b -i "$STARTUP_PATH/bootstrap-sample-db.sql" -o "bootstrap.out" || (echo $ERROR_MESSAGE && exit 2)
# remove files copied into the pod:
echo Removing database backup files...
$DEBUG kubectl exec $MASTER_POD_NAME -n $CLUSTER_NAMESPACE -c mssql-server -i -t -- bash -c "rm -rvf /var/opt/mssql/data/*.bak"
echo Removing database backup file...
$DEBUG kubectl exec $MASTER_POD_NAME -n $CLUSTER_NAMESPACE -c mssql-server -i -t -- bash -c "rm -rvf /var/opt/mssql/data/tpcxbb_1gb.bak"
for table in web_clickstreams inventory customer
do
@@ -111,26 +117,26 @@ for table in web_clickstreams inventory customer
# WSL ex: "/mnt/c/Program Files/Microsoft SQL Server/Client SDK/ODBC/130/Tools/Binn/bcp.exe"
if [ ! -f $table.csv ]
then
$DEBUG bcp sales.dbo.$table out "$table.csv" -S $SQL_MASTER_INSTANCE -Usa -P$SQL_MASTER_SA_PASSWORD -c -t"$DELIMITER" -e "$table.err" || (echo $ERROR_MESSAGE && exit 3)
$DEBUG bcp sales.dbo.$table out "$table.csv" -S $SQL_MASTER_INSTANCE -Usa -P$SQL_MASTER_SA_PASSWORD -c -t"$DELIMITER" -e "$table.err" > "$table.out" || (echo $ERROR_MESSAGE && exit 3)
fi
done
if [ ! -f product_reviews.csv ]
then
echo Exporting product_reviews data...
$DEBUG bcp "select pr_review_sk, replace(replace(pr_review_content, ',', ';'), char(34), '') as pr_review_content from sales.dbo.product_reviews" queryout "product_reviews.csv" -S $SQL_MASTER_INSTANCE -Usa -P$SQL_MASTER_SA_PASSWORD -c -t, -e "product_reviews.err" || (echo $ERROR_MESSAGE && exit 3)
$DEBUG bcp "select pr_review_sk, replace(replace(pr_review_content, ',', ';'), char(34), '') as pr_review_content from sales.dbo.product_reviews" queryout "product_reviews.csv" -S $SQL_MASTER_INSTANCE -Usa -P$SQL_MASTER_SA_PASSWORD -c -t, -e "product_reviews.err" > "$table.out" || (echo $ERROR_MESSAGE && exit 3)
fi
# Copy the data file to HDFS
echo Uploading web_clickstreams data to HDFS...
$DEBUG curl -i -L -k -u root:$KNOX_PASSWORD -X PUT "https://$KNOX_ENDPOINT/gateway/default/webhdfs/v1/clickstream_data?op=MKDIRS" || (echo $ERROR_MESSAGE && exit 4)
$DEBUG curl -i -L -k -u root:$KNOX_PASSWORD -X PUT "https://$KNOX_ENDPOINT/gateway/default/webhdfs/v1/clickstream_data/web_clickstreams.csv?op=create&overwrite=true" -H 'Content-Type: application/octet-stream' -T "web_clickstreams.csv" || (echo $ERROR_MESSAGE && exit 5)
$DEBUG curl -L -k -u root:$KNOX_PASSWORD -X PUT "https://$KNOX_ENDPOINT/gateway/default/webhdfs/v1/clickstream_data?op=MKDIRS" || (echo $ERROR_MESSAGE && exit 4)
$DEBUG curl -L -k -u root:$KNOX_PASSWORD -X PUT "https://$KNOX_ENDPOINT/gateway/default/webhdfs/v1/clickstream_data/web_clickstreams.csv?op=create&overwrite=true" -H 'Content-Type: application/octet-stream' -T "web_clickstreams.csv" || (echo $ERROR_MESSAGE && exit 5)
#$DEBUG rm -f web_clickstreams.*
echo
echo Uploading product_reviews data to HDFS...
$DEBUG curl -i -L -k -u root:$KNOX_PASSWORD -X PUT "https://$KNOX_ENDPOINT/gateway/default/webhdfs/v1/product_review_data?op=MKDIRS" || (echo $ERROR_MESSAGE && exit 6)
$DEBUG curl -i -L -k -u root:$KNOX_PASSWORD -X PUT "https://$KNOX_ENDPOINT/gateway/default/webhdfs/v1/product_review_data/product_reviews.csv?op=create&overwrite=true" -H "Content-Type: application/octet-stream" -T "product_reviews.csv" || (echo $ERROR_MESSAGE && exit 7)
$DEBUG curl -L -k -u root:$KNOX_PASSWORD -X PUT "https://$KNOX_ENDPOINT/gateway/default/webhdfs/v1/product_review_data?op=MKDIRS" || (echo $ERROR_MESSAGE && exit 6)
$DEBUG curl -L -k -u root:$KNOX_PASSWORD -X PUT "https://$KNOX_ENDPOINT/gateway/default/webhdfs/v1/product_review_data/product_reviews.csv?op=create&overwrite=true" -H "Content-Type: application/octet-stream" -T "product_reviews.csv" || (echo $ERROR_MESSAGE && exit 7)
#$DEBUG rm -f product_reviews.*
echo
@@ -18,7 +18,16 @@ BEGIN
END;
GO
CREATE OR ALTER PROCEDURE #restore_database (@backup_file nvarchar(255))
-- Enable option to allow INSERT against external table defined on HADOOP data source
DECLARE @config_option nvarchar(100) = 'allow polybase export';
IF NOT EXISTS(SELECT * FROM sys.configurations WHERE name = @config_option and value_in_use = 1)
BEGIN
EXECUTE sp_configure @config_option, 1;
RECONFIGURE WITH OVERRIDE;
END;
GO
CREATE OR ALTER PROCEDURE #restore_database (@backup_file nvarchar(255), @db_name nvarchar(128))
AS
BEGIN
DECLARE @restore_filelist_tmpl nvarchar(1000) = N'RESTORE FILELISTONLY FROM DISK = N''/var/opt/mssql/data/%F''';
@@ -53,7 +62,7 @@ BEGIN
INSERT INTO @files
EXECUTE(@restore_cmd);
SET @restore_cmd = REPLACE(REPLACE(@restore_database_tmpl, '%F', @backup_file), '%D', LEFT(@backup_file, CHARINDEX('.', @backup_file)-1));
SET @restore_cmd = REPLACE(REPLACE(@restore_database_tmpl, '%F', @backup_file), '%D', @db_name);
SET @restore_cur = CURSOR FAST_FORWARD FOR SELECT LogicalName, REVERSE(LEFT(REVERSE(PhysicalName), CHARINDEX('\', REVERSE(PhysicalName))-1)) FROM @files;
OPEN @restore_cur;
WHILE(1=1)
@@ -84,50 +93,58 @@ BEGIN
WITH (LOCATION = 'sqlhdfs://controller-svc/default');
IF NOT EXISTS(SELECT * FROM sys.external_data_sources WHERE name = 'HadoopData')
IF SERVERPROPERTY('ProductLevel') = 'CTP3.1'
CREATE EXTERNAL DATA SOURCE HadoopData
WITH(
TYPE=HADOOP,
LOCATION='hdfs://nmnode-0-svc:9000/',
RESOURCE_MANAGER_LOCATION='master-svc:8032'
);
ELSE IF SERVERPROPERTY('ProductLevel') = 'CTP3.2'
CREATE EXTERNAL DATA SOURCE HadoopData
WITH(
TYPE=HADOOP,
LOCATION='hdfs://nmnode-0-svc:9000/',
RESOURCE_MANAGER_LOCATION='sparkhead-svc:8032'
);
CREATE EXTERNAL DATA SOURCE HadoopData
WITH(
TYPE=HADOOP,
LOCATION='hdfs://nmnode-0-svc:9000/',
RESOURCE_MANAGER_LOCATION='sparkhead-svc:8032'
);
END;
GO
--- Sample dbs:
DECLARE @sample_dbs CURSOR, @proc nvarchar(255);
SET @sample_dbs = CURSOR FAST_FORWARD FOR
SELECT file_or_directory_name
FROM sys.dm_os_enumerate_filesystem('/var/opt/mssql/data', '*.bak')
WHERE DB_ID(REPLACE(REPLACE(file_or_directory_name, 'tpcxbb_1gb', 'sales'), '.bak', '')) IS NULL;
DECLARE @file nvarchar(260);
SELECT file_or_directory_name, d.db_name
FROM sys.dm_os_enumerate_filesystem('/var/opt/mssql/data', '*.bak') as f
CROSS APPLY (VALUES(REPLACE(REPLACE(file_or_directory_name, 'tpcxbb_1gb', 'sales'), '.bak', ''))) as d(db_name)
WHERE DB_ID(d.db_name) IS NULL;
DECLARE @file nvarchar(260), @db_name nvarchar(128);
OPEN @sample_dbs;
WHILE(1=1)
BEGIN
FETCH @sample_dbs INTO @file;
FETCH @sample_dbs INTO @file, @db_name;
IF @@FETCH_STATUS < 0 BREAK;
-- Restore the sample databases:
EXECUTE #restore_database @file;
EXECUTE #restore_database @file, @db_name;
-- Get database name used in restore:
SET @proc = CONCAT(QUOTENAME(LEFT(@file, CHARINDEX('.', @file)-1)), N'.sys.sp_executesql');
SET @db_name = QUOTENAME(@db_name);
SET @proc = CONCAT(@db_name, N'.sys.sp_executesql');
EXECUTE @proc N'#create_data_sources';
-- Set compatibility level to 150:
EXECUTE @proc N'ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL = 150';
-- Rename TPCx-BB database:
IF DB_ID('tpcxbb_1gb') IS NOT NULL
ALTER DATABASE tpcxbb_1gb MODIFY NAME = sales;
-- Check for HADR & add database to containedag:
IF SERVERPROPERTY('IsHadrEnabled') = 1
BEGIN
DECLARE @command nvarchar(1000);
IF EXISTS(SELECT * FROM sys.databases WHERE name = PARSENAME(@db_name,1) and recovery_model_desc = 'SIMPLE')
BEGIN
-- Set recovery to full
EXECUTE @proc N'ALTER DATABASE CURRENT SET RECOVERY FULL';
SET @command = CONCAT(N'BACKUP DATABASE ', @db_name, ' TO DISK = ''NUL'';' );
EXEC(@command);
END;
-- Add database to AG
SET @command = CONCAT(N'ALTER AVAILABILITY GROUP containedag ADD DATABASE ', @db_name);
EXEC(@command);
END;
END;
GO
@@ -4,12 +4,8 @@ GO
-- Create external data source for Data Pool inside a SQL big data cluster
--
IF NOT EXISTS(SELECT * FROM sys.external_data_sources WHERE name = 'SqlDataPool')
IF SERVERPROPERTY('ProductLevel') = 'CTP3.0'
CREATE EXTERNAL DATA SOURCE SqlDataPool
WITH (LOCATION = 'sqldatapool://controller-svc:8080/datapools/default');
ELSE IF SERVERPROPERTY('ProductLevel') = 'CTP3.1'
CREATE EXTERNAL DATA SOURCE SqlDataPool
WITH (LOCATION = 'sqldatapool://controller-svc/default');
CREATE EXTERNAL DATA SOURCE SqlDataPool
WITH (LOCATION = 'sqldatapool://controller-svc/default');
-- Create external table in a data pool in SQL Server 2019 big data cluster.
-- The SqlDataPool data source is a special data source that is available in
@@ -17,20 +17,12 @@ GO
-- execution.
--
IF NOT EXISTS(SELECT * FROM sys.external_data_sources WHERE name = 'HadoopData')
IF SERVERPROPERTY('ProductLevel') = 'CTP3.1'
CREATE EXTERNAL DATA SOURCE HadoopData
WITH(
TYPE=HADOOP,
LOCATION='hdfs://nmnode-0-svc:9000/',
RESOURCE_MANAGER_LOCATION='master-svc:8032'
);
ELSE IF SERVERPROPERTY('ProductLevel') = 'CTP3.2'
CREATE EXTERNAL DATA SOURCE HadoopData
WITH(
TYPE=HADOOP,
LOCATION='hdfs://nmnode-0-svc:9000/',
RESOURCE_MANAGER_LOCATION='sparkhead-svc:8032'
);
CREATE EXTERNAL DATA SOURCE HadoopData
WITH(
TYPE=HADOOP,
LOCATION='hdfs://nmnode-0-svc:9000/',
RESOURCE_MANAGER_LOCATION='sparkhead-svc:8032'
);
-- Create file format for RCFILE with appropriate properties.
@@ -7,20 +7,12 @@ GO
-- execution.
--
IF NOT EXISTS(SELECT * FROM sys.external_data_sources WHERE name = 'HadoopData')
IF SERVERPROPERTY('ProductLevel') = 'CTP3.1'
CREATE EXTERNAL DATA SOURCE HadoopData
WITH(
TYPE=HADOOP,
LOCATION='hdfs://nmnode-0-svc:9000/',
RESOURCE_MANAGER_LOCATION='master-svc:8032'
);
ELSE IF SERVERPROPERTY('ProductLevel') = 'CTP3.2'
CREATE EXTERNAL DATA SOURCE HadoopData
WITH(
TYPE=HADOOP,
LOCATION='hdfs://nmnode-0-svc:9000/',
RESOURCE_MANAGER_LOCATION='sparkhead-svc:8032'
);
CREATE EXTERNAL DATA SOURCE HadoopData
WITH(
TYPE=HADOOP,
LOCATION='hdfs://nmnode-0-svc:9000/',
RESOURCE_MANAGER_LOCATION='sparkhead-svc:8032'
);
-- Create file format for orc file with appropriate properties.
@@ -7,20 +7,12 @@ GO
-- execution.
--
IF NOT EXISTS(SELECT * FROM sys.external_data_sources WHERE name = 'HadoopData')
IF SERVERPROPERTY('ProductLevel') = 'CTP3.1'
CREATE EXTERNAL DATA SOURCE HadoopData
WITH(
TYPE=HADOOP,
LOCATION='hdfs://nmnode-0-svc:9000/',
RESOURCE_MANAGER_LOCATION='master-svc:8032'
);
ELSE IF SERVERPROPERTY('ProductLevel') = 'CTP3.2'
CREATE EXTERNAL DATA SOURCE HadoopData
WITH(
TYPE=HADOOP,
LOCATION='hdfs://nmnode-0-svc:9000/',
RESOURCE_MANAGER_LOCATION='sparkhead-svc:8032'
);
CREATE EXTERNAL DATA SOURCE HadoopData
WITH(
TYPE=HADOOP,
LOCATION='hdfs://nmnode-0-svc:9000/',
RESOURCE_MANAGER_LOCATION='sparkhead-svc:8032'
);
-- Create file format for orc file with appropriate properties.
@@ -42,7 +42,7 @@ python deploy-sql-big-data-aks.py
When prompted, provide your input for Azure subscription ID, Azure resource group to create the resources in, and Docker credentials. Optionally, you can also provide your input for below configurations or use the defaults provided:
- azure_region
- vm_size - we recommend to use a VM size to accommodate your workload. For an optimal experience while you are validating basic scenarios, we recommend at least 8 vCPUs and 32GB memory across all agent nodes in the cluster. The script uses **Standard_L8s** as default.
- vm_size - we recommend to use a VM size to accommodate your workload. For an optimal experience while you are validating basic scenarios, we recommend at least 8 vCPUs and 64GB memory across all agent nodes in the cluster. The script uses **Standard_L8s** as default. A default size configuration also uses about 24 disks for persistent volume claims across all components.
- aks_node_count - this is the number of the worker nodes for the AKS cluster, excluding master node. The script is using a default of 1 agent node. This is the minimum required for this VM size to have enough resources and disks to provision all the necessary persistent volumes.
- cluster_name - this value is used for both AKS cluster and SQL big data cluster created on top of AKS. Note that the name of the SQL big data cluster is going to be a Kubernetes namespace
- password - same value is going to be used for all accounts that require user password input: SQL Server master instance SA account, controller user and Knox user
@@ -68,7 +68,7 @@ command="az group create --name "+GROUP_NAME+" --location "+AZURE_REGION
executeCmd (command)
print("Creating AKS cluster: "+CLUSTER_NAME)
command = "az aks create --name "+CLUSTER_NAME+" --resource-group "+GROUP_NAME+" --generate-ssh-keys --node-vm-size "+VM_SIZE+" --node-count "+AKS_NODE_COUNT+" --kubernetes-version 1.12.8"
command = "az aks create --name "+CLUSTER_NAME+" --resource-group "+GROUP_NAME+" --generate-ssh-keys --node-vm-size "+VM_SIZE+" --node-count "+AKS_NODE_COUNT+" --kubernetes-version 1.13.10"
executeCmd (command)
command = "az aks get-credentials --overwrite-existing --name "+CLUSTER_NAME+" --resource-group "+GROUP_NAME+" --admin"
@@ -78,7 +78,7 @@ print("Creating SQL Big Data cluster:" +CLUSTER_NAME)
command="azdata bdc config init --source aks-dev-test --target custom --force"
executeCmd (command)
command="azdata bdc config replace -c custom/cluster.json -j ""metadata.name=" + CLUSTER_NAME + ""
command="azdata bdc config replace -c custom/bdc.json -j ""metadata.name=" + CLUSTER_NAME + ""
executeCmd (command)
# Use this only if you are using a private registry different than default Micrososft registry (mcr).
@@ -7,4 +7,8 @@ This folder contains scripts that provide a template for deploying a Kubernetes
## __[ubuntu-single-node-vm](ubuntu-single-node-vm/)__
This folder contains a sample script that can be used to deploy a single-node Kubernetes cluster on a Linux machine.
This folder contains a sample script that can be used to create a single-node Kubernetes cluster on a Linux machine and deploy SQL Server big data cluster.
## __[ubuntu-single-node-vm-ad](ubuntu-single-node-vm-ad/)__
This folder contains a sample script that can be used to create a single-node Kubernetes cluster on a Linux machine and deploy SQL Server big data cluster with Active Directory integration.
@@ -1,20 +1,19 @@
{
"patch": [
{
"op": "replace",
"path": "spec.pools[?(@.spec.type=='Master')].spec",
"value": {
"type": "Master",
"dnsName": "mastersql.contoso.local",
"replicas": 1,
"endpoints": [
{
"name": "Master",
"serviceType": "NodePort",
"port": 31433
}
]
}
"op": "add",
"path": "spec.resources.master.spec.endpoints[0].dnsName",
"value": "mastersql.contoso.local"
},
{
"op": "add",
"path": "spec.resources.gateway.spec.endpoints[0].dnsName",
"value": "knox.contoso.local"
},
{
"op": "add",
"path": "spec.resources.appproxy.spec.endpoints[0].dnsName",
"value": "app.contoso.local"
}
]
}
@@ -4,10 +4,9 @@
"op": "add",
"path": "security",
"value": {
"useInternalDomain": false,
"ouDistinguishedName":"OU=bdc,DC=contoso,DC=local",
"dnsIpAddresses": ["11.11.111.11"],
"domainControllerFullyQualifiedDns": ["VM.CONTOSO.LOCAL"],
"dnsIpAddresses": ["00.00.000.00"],
"domainControllerFullyQualifiedDns": ["DC.CONTOSO.LOCAL"],
"realm":"CONTOSO.LOCAL",
"domainDnsName":"contoso.local",
"bdcAdminPrincipals": [
@@ -20,12 +19,13 @@
},
{
"op": "add",
"path": "spec.endpoints/0",
"value": {
"name": "Kerberos",
"serviceType": "NodePort",
"port": 30088
}
"path": "spec.endpoints[0].dnsName",
"value": "controller.contoso.local"
},
{
"op": "add",
"path": "spec.endpoints[1].dnsName",
"value": "serviceproxy.contoso.local"
}
]
}
@@ -22,19 +22,7 @@ while true; do
[ "$password" = "$password2" ] && break
echo "Password mismatch. Please try again."
done
echo ""
# Get docker credentials for private release.
#
read -p "Enter Docker username: " DOCKER_USERNAME
while true; do
read -s -p "Enter Docker Password: " docker_password
echo
read -s -p "Confirm Docker Password: " docker_password2
echo
[ "$docker_password" = "$docker_password2" ] && break
echo "Password mismatch. Please try again."
done
export DOCKER_PASSWORD=$docker_password
echo ""
# Get Domain Service Account Username and Password.
@@ -75,9 +63,9 @@ RETRY_INTERVAL=5
# Variables for pulling dockers.
#
export DOCKER_REGISTRY="private-repo.microsoft.com"
export DOCKER_REPOSITORY="mssql-private-preview"
export DOCKER_TAG="ctp3.2.1"
export DOCKER_REGISTRY="mcr.microsoft.com"
export DOCKER_REPOSITORY="mssql/bdc"
export DOCKER_TAG="2019-RC1-ubuntu"
# Variables used for azdata cluster creation.
#
@@ -91,9 +79,10 @@ export STORAGE_CLASS=local-storage
export PV_COUNT="30"
IMAGES=(
mssql-app-service-proxy
mssql-appdeploy-init
mssql-app-service-proxy
mssql-control-watchdog
mssql-controller
mssql-dns
mssql-hadoop
mssql-mleap-serving-runtime
mssql-mlserver-py-runtime
@@ -105,10 +94,13 @@ IMAGES=(
mssql-monitor-influxdb
mssql-monitor-kibana
mssql-monitor-telegraf
mssql-security-domainctl
mssql-security-knox
mssql-security-support
mssql-server
mssql-server-controller
mssql-server-data
mssql-server-ha
mssql-service-proxy
mssql-ssis-app-runtime
)
@@ -320,25 +312,24 @@ echo "Kubernetes master setup done."
# Pull docker images of SQL Server big data cluster.
#
echo ""
echo "############################################################################"
echo "Starting to pull docker images..."
echo "Pulling images from repository: " $DOCKER_REGISTRY"/"$DOCKER_REPOSITORY
docker login $DOCKER_REGISTRY -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
for image in "${IMAGES[@]}";
do
docker pull $DOCKER_REGISTRY/$DOCKER_REPOSITORY/$image:$DOCKER_TAG
echo "Docker image" $image " pulled."
done
docker logout $DOCKER_REGISTRY
echo "Docker images pulled."
# Deploy azdata bdc create cluster.
#
echo ""
echo "############################################################################"
echo "Starting to deploy azdata cluster..."
echo "Starting to deploy big data cluster..."
# Command to create cluster for single node cluster.
#
@@ -346,13 +337,15 @@ azdata bdc config init --source kubeadm-dev-test --target kubeadm-custom -f
azdata bdc config replace -c kubeadm-custom/control.json -j ".spec.docker.repository=$DOCKER_REPOSITORY"
azdata bdc config replace -c kubeadm-custom/control.json -j ".spec.docker.registry=$DOCKER_REGISTRY"
azdata bdc config replace -c kubeadm-custom/control.json -j ".spec.docker.imageTag=$DOCKER_TAG"
azdata bdc config replace -c kubeadm-custom/cluster.json -j "$.spec.pools[?(@.spec.type == "Data")].spec.replicas=1"
azdata bdc config replace -c kubeadm-custom/bdc.json -j "$.spec.resources.data-0.spec.replicas=1"
azdata bdc config replace -c kubeadm-custom/control.json -j "spec.storage.data.className=$STORAGE_CLASS"
azdata bdc config replace -c kubeadm-custom/control.json -j "spec.storage.logs.className=$STORAGE_CLASS"
azdata bdc config patch -c kubeadm-custom/control.json -p $STARTUP_PATH/security-patch.json
azdata bdc config patch -c kubeadm-custom/cluster.json -p $STARTUP_PATH/endpoint-patch.json
azdata bdc config patch -c kubeadm-custom/bdc.json -p $STARTUP_PATH/endpoint-patch.json
azdata bdc create -c kubeadm-custom --accept-eula $ACCEPT_EULA
echo "Azdata cluster created."
echo "Big data cluster created."
# Setting context to cluster.
#
@@ -46,7 +46,7 @@ RETRY_INTERVAL=5
#
export DOCKER_REGISTRY="mcr.microsoft.com"
export DOCKER_REPOSITORY="mssql/bdc"
export DOCKER_TAG="2019-CTP3.2-ubuntu"
export DOCKER_TAG="2019-RC1-ubuntu"
# Variables used for azdata cluster creation.
#
@@ -60,9 +60,10 @@ export STORAGE_CLASS=local-storage
export PV_COUNT="30"
IMAGES=(
mssql-app-service-proxy
mssql-appdeploy-init
mssql-app-service-proxy
mssql-control-watchdog
mssql-controller
mssql-dns
mssql-hadoop
mssql-mleap-serving-runtime
mssql-mlserver-py-runtime
@@ -74,10 +75,13 @@ IMAGES=(
mssql-monitor-influxdb
mssql-monitor-kibana
mssql-monitor-telegraf
mssql-security-domainctl
mssql-security-knox
mssql-security-support
mssql-server
mssql-server-controller
mssql-server-data
mssql-server-ha
mssql-service-proxy
mssql-ssis-app-runtime
)
@@ -313,11 +317,11 @@ azdata bdc config init --source kubeadm-dev-test --target kubeadm-custom -f
azdata bdc config replace -c kubeadm-custom/control.json -j ".spec.docker.repository=$DOCKER_REPOSITORY"
azdata bdc config replace -c kubeadm-custom/control.json -j ".spec.docker.registry=$DOCKER_REGISTRY"
azdata bdc config replace -c kubeadm-custom/control.json -j ".spec.docker.imageTag=$DOCKER_TAG"
azdata bdc config replace -c kubeadm-custom/cluster.json -j "$.spec.pools[?(@.spec.type == "Data")].spec.replicas=1"
azdata bdc config replace -c kubeadm-custom/bdc.json -j "$.spec.resources.data-0.spec.replicas=1"
azdata bdc config replace -c kubeadm-custom/control.json -j "spec.storage.data.className=$STORAGE_CLASS"
azdata bdc config replace -c kubeadm-custom/control.json -j "spec.storage.logs.className=$STORAGE_CLASS"
azdata bdc create -c kubeadm-custom --accept-eula $ACCEPT_EULA
echo "Azdata cluster created."
echo "Big data cluster created."
# Setting context to cluster.
#
@@ -26,26 +26,30 @@ TARGET_DOCKER_USERNAME = input("Provide Docker username for the target registry:
TARGET_DOCKER_PASSWORD = getpass.getpass("Provide Docker password for the target registry:")
TARGET_DOCKER_TAG = input("Provide Docker tag for the images at the target: ") or "latest"
images = [ 'mssql-appdeploy-init',
'mssql-monitor-fluentbit',
'mssql-monitor-collectd',
'mssql-server-data',
'mssql-hadoop',
'mssql-monitor-elasticsearch',
'mssql-monitor-influxdb',
'mssql-security-knox',
'mssql-mlserver-r-runtime',
'mssql-mlserver-py-runtime',
'mssql-controller',
'mssql-mleap-serving-runtime',
'mssql-server-controller',
'mssql-monitor-grafana',
'mssql-monitor-kibana',
'mssql-service-proxy',
'mssql-app-service-proxy',
'mssql-ssis-app-runtime',
'mssql-monitor-telegraf',
'mssql-security-support']
images = ['mssql-app-service-proxy',
'mssql-control-watchdog'
'mssql-controller'
'mssql-dns'
'mssql-hadoop'
'mssql-mleap-serving-runtime'
'mssql-mlserver-py-runtime'
'mssql-mlserver-r-runtime'
'mssql-monitor-collectd'
'mssql-monitor-elasticsearch'
'mssql-monitor-fluentbit'
'mssql-monitor-grafana'
'mssql-monitor-influxdb'
'mssql-monitor-kibana'
'mssql-monitor-telegraf'
'mssql-security-domainctl'
'mssql-security-knox'
'mssql-security-support'
'mssql-server'
'mssql-server-controller'
'mssql-server-data'
'mssql-server-ha'
'mssql-service-proxy'
'mssql-ssis-app-runtime']
# Use this only if your source is a private Docker registry
# print("Execute docker login to source registry: " + SOURCE_DOCKER_REGISTRY)
+1 -1
View File
@@ -9,7 +9,7 @@ One of the most popular tools for calling an API on `http:` endpoints is [curl](
[About this sample](#about-this-sample)<br/>
[Build the CLR/CURL extension](#build-functions)<br/>
[Add RegEx functions to your SQL database](#add-functions)<br/>
[Add CURL functions to your SQL database](#add-functions)<br/>
[Test the functions](#test)<br/>
[Disclaimers](#disclaimers)<br/>
[Appendix](#appendix) - quick install script for your dev environment.<br/>
@@ -18,6 +18,11 @@ select property = 'TEMPDB:'+y.v.value('local-name(.)', 'nvarchar(300)'),
value = y.v.value('.[1]', 'nvarchar(300)')
from @source.nodes('//tempdb') x(v)
cross apply x.v.nodes('*') y(v)
UNION ALL
select property = 'INSTANCE:'+y.v.value('local-name(.)', 'nvarchar(300)'),
value = y.v.value('.[1]', 'nvarchar(300)')
from @source.nodes('//instance') x(v)
cross apply x.v.nodes('*') y(v)
),
tgt as(
select property = x.v.value('name[1]', 'nvarchar(300)'),
@@ -33,6 +38,11 @@ select property = 'TEMPDB:'+y.v.value('local-name(.)', 'nvarchar(300)'),
value = y.v.value('.[1]', 'nvarchar(300)')
from @target.nodes('//tempdb') x(v)
cross apply x.v.nodes('*') y(v)
UNION ALL
select property = 'INSTANCE:'+y.v.value('local-name(.)', 'nvarchar(300)'),
value = y.v.value('.[1]', 'nvarchar(300)')
from @target.nodes('//instance') x(v)
cross apply x.v.nodes('*') y(v)
),
diff as (
select property = isnull(src.property, tgt.property),
@@ -43,7 +53,7 @@ where (src.value <> tgt.value
or src.value is null and tgt.value is not null
or src.value is not null and tgt.value is null)
)
select *
select property, source, [target]
from diff
where is_missing = 0 or @verbose = 1 -- in the earlier versions you had to comment out this line. Now just set the value of the flag up
order by property
@@ -53,6 +53,20 @@ where name in ('cost threshold for parallelism','cursor threshold','fill factor
for xml raw, elements
);
set @result += (select name = 'version', value = @@VERSION for xml raw, elements)
select cast(@result as xml);
end;
set @result += isnull
((SELECT scheduler_count, scheduler_total_count FROM sys.dm_os_sys_info
for xml raw('instance'), elements),''
);
set @result +=
isnull((SELECT name = REPLACE([type], 'MEMORYCLERK_', 'MEMORY:')
, value = CAST(sum(pages_kb)/1024.1/1024 AS NUMERIC(6,1))
FROM sys.dm_os_memory_clerks
GROUP BY type
HAVING sum(pages_kb) /1024. /1024 > 1
for xml raw, elements),'');
select cast(@result as xml);
end;