<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Production on Tran Hai Dang</title><link>https://www.tranhaidang.com/categories/production/</link><description>Recent content in Production on Tran Hai Dang</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sun, 20 Feb 2022 00:00:00 +0000</lastBuildDate><atom:link href="https://www.tranhaidang.com/categories/production/index.xml" rel="self" type="application/rss+xml"/><item><title>New Chapter with Genesys</title><link>https://www.tranhaidang.com/2026/10/05/new-chapter-with-genesys/</link><pubDate>Mon, 05 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.tranhaidang.com/2026/10/05/new-chapter-with-genesys/</guid><description>&lt;img src="https://www.tranhaidang.com/2026/10/05/new-chapter-with-genesys/Genesys.png" alt="Featured image of post New Chapter with Genesys" />&lt;p>&lt;strong>Why no longer MSSQL?&lt;/strong>&lt;/p>
&lt;p>It has been years since last post on the MSSQL topic and now MSSQL is under the customer&amp;rsquo;s care instead of mine. The job scope has changed significantly since 2022 where the focus was shifted to Genesys Cloud (and Genesys Engage).&lt;/p>
&lt;p>&lt;strong>Why Genesys?&lt;/strong>&lt;/p>
&lt;p>For me, it is considered as a new challenge which addresses the questions from the previous role where Genesys platform was deployed. How can we build a Contact Center with multiple channels such as call, email, chat, social media and instant message? What about integration with CRM or other system used by contact center users? What are the options to improve efficiency? Looking back the past 4 years, some of the questions were already answered, and some deviate from the original ones, especially after the AI has entered the chat.&lt;/p>
&lt;p>One thing remains though. The knowledge sharing article will be updated regularly along with the Genesys journey where I am grateful to be taught by multiple mentors across all the regions. One Genesys is truly One Genesys.&lt;/p></description></item><item><title>Tranpose data using T-SQL and Python</title><link>https://www.tranhaidang.com/2022/02/26/tranpose-data-using-t-sql-and-python/</link><pubDate>Sat, 26 Feb 2022 00:00:00 +0000</pubDate><guid>https://www.tranhaidang.com/2022/02/26/tranpose-data-using-t-sql-and-python/</guid><description>&lt;img src="https://www.tranhaidang.com/2022/02/26/tranpose-data-using-t-sql-and-python/bg_Transpose.jpg" alt="Featured image of post Tranpose data using T-SQL and Python" />&lt;p>For this blog, let&amp;rsquo;s wear the Developer DBA hat and discuss how we can use T-SQL to transpose columns to rows using PIVOT and UNPTVOT operator (for MSSQL 2012 and newer).&lt;/p>
&lt;p>To be more specific, assuming that we got the end result of ETL process with various Stats with their datetime info as following&lt;/p>
&lt;p>&lt;figure
class="gallery-image"
style="
flex-grow: 103;
flex-basis: 248px"
>
&lt;a href="https://www.tranhaidang.com/2022/02/26/tranpose-data-using-t-sql-and-python/OriginalData.jpg" data-size="523x506">
&lt;img src="https://www.tranhaidang.com/2022/02/26/tranpose-data-using-t-sql-and-python/OriginalData.jpg"
width="523"
height="506"
srcset="https://www.tranhaidang.com/2022/02/26/tranpose-data-using-t-sql-and-python/OriginalData_hu309794adceee0aa361c9671371ca1813_84507_480x0_resize_q75_box.jpg 480w, https://www.tranhaidang.com/2022/02/26/tranpose-data-using-t-sql-and-python/OriginalData_hu309794adceee0aa361c9671371ca1813_84507_1024x0_resize_q75_box.jpg 1024w"
loading="lazy"
alt="Original data">
&lt;/a>
&lt;figcaption>Original data&lt;/figcaption>
&lt;/figure>&lt;/p>
&lt;p>whereas each row represents 1 day of various stats for the day. And then on one beautiful day your boss wanna review the result as something like below due to the water-fall dependency of those stats e.g. Stat3 = Stat4 + Stat5 etc.&lt;/p>
&lt;p>&lt;figure
class="gallery-image"
style="
flex-grow: 380;
flex-basis: 912px"
>
&lt;a href="https://www.tranhaidang.com/2022/02/26/tranpose-data-using-t-sql-and-python/EndResult.jpg" data-size="821x216">
&lt;img src="https://www.tranhaidang.com/2022/02/26/tranpose-data-using-t-sql-and-python/EndResult.jpg"
width="821"
height="216"
srcset="https://www.tranhaidang.com/2022/02/26/tranpose-data-using-t-sql-and-python/EndResult_huec45bee3077a95eef6f0b0e3c1f55fb7_60923_480x0_resize_q75_box.jpg 480w, https://www.tranhaidang.com/2022/02/26/tranpose-data-using-t-sql-and-python/EndResult_huec45bee3077a95eef6f0b0e3c1f55fb7_60923_1024x0_resize_q75_box.jpg 1024w"
loading="lazy"
alt="End Result">
&lt;/a>
&lt;figcaption>End Result&lt;/figcaption>
&lt;/figure>&lt;/p>
&lt;p>While Excel can accomplish this request easily, we are database professional and willing to take the challenge to tackle this issue using T-SQL, aren&amp;rsquo;t we?&lt;/p>
&lt;p>&lt;strong>What will be the T-SQL query then?&lt;/strong>&lt;/p>
&lt;p>You can refer to the answer using CTE + PIVOT + UNPIVOT below (pardon the misalignment, I am still figuring out how to make it what-you-type-is-what-you-see)&lt;/p>
&lt;pre tabindex="0">&lt;code>WITH HD_CTE AS
(
SELECT Timekey,[Stats], [Value]
FROM [HD1].[dbo].[tblStat]
UNPIVOT ( [Value] FOR [Stats] IN (
[Stat1]
,[Stat2]
,[Stat3]
,[Stat4]
,[Stat5]
,[Stat6]
,[Stat7]
,[Stat8]
,[Stat9]
)) AS U
)
SELECT Stats,
[20220201],[20220202],[20220203], [20220204], [20220205], [20220206], [20220207],[20220208],[20220209],
[20220210],
[20220211],[20220212],[20220213], [20220214], [20220215], [20220216], [20220217],[20220218],[20220219],
[20220220],
[20220221],[20220222],[20220223], [20220224], [20220225], [20220226], [20220227],[20220228]
FROM HD_CTE
PIVOT (SUM(VALUE) FOR Timekey IN (
[20220201],[20220202],[20220203], [20220204], [20220205], [20220206], [20220207],[20220208],[20220209],
[20220210],
[20220211],[20220212],[20220213], [20220214], [20220215], [20220216], [20220217],[20220218],[20220219],
[20220220],
[20220221],[20220222],[20220223], [20220224], [20220225], [20220226], [20220227],[20220228]
)
) AS P
ORDER BY Stats
&lt;/code>&lt;/pre>&lt;p>1 area of improvement can be the dynamic population of YYYYMMDD based on the input parameter of month and year.&lt;/p>
&lt;p>&lt;strong>Using Python instead of T-SQL&lt;/strong>&lt;/p>
&lt;p>There is a saying &amp;lsquo;There are more than one way to skin a cat&amp;rsquo; whereas we can use Python and leverage on the pandas library since it allows a single DataFrame function (.T) to accomplish the same result with the lengthy T-SQL script above. Full code can be found below&lt;/p>
&lt;pre tabindex="0">&lt;code>import pyodbc
import pandas as pd
# Reading the data from SQL Server
con = pyodbc.connect(&amp;#39;DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=HD1;UID=apps_login;PWD=apps_login&amp;#39;)
query = &amp;#34;&amp;#34;&amp;#34;
SELECT [Timekey]
,[Stat1]
,[Stat2]
,[Stat3]
,[Stat4]
,[Stat5]
,[Stat6]
,[Stat7]
,[Stat8]
,[Stat9]
FROM [HD1].[dbo].[tblStat]
WHERE [Timekey] LIKE &amp;#39;202202%&amp;#39;
&amp;#34;&amp;#34;&amp;#34;
TM = pd.read_sql(query, con)
# Transpose the original DataFrame TM into to TM_transposed
TM_transposed = TM.T
TM_transposed
&lt;/code>&lt;/pre>&lt;p>Hoping you like this blog post and feel free to share any comments/feedbacks below.&lt;/p>
&lt;p>Thank you for your time.&lt;/p></description></item><item><title>Verifying backup as part of the DR strategy</title><link>https://www.tranhaidang.com/2022/02/20/verifying-backup-as-part-of-the-dr-strategy/</link><pubDate>Sun, 20 Feb 2022 00:00:00 +0000</pubDate><guid>https://www.tranhaidang.com/2022/02/20/verifying-backup-as-part-of-the-dr-strategy/</guid><description>&lt;img src="https://www.tranhaidang.com/2022/02/20/verifying-backup-as-part-of-the-dr-strategy/bg_VerifyingBackup.jpg" alt="Featured image of post Verifying backup as part of the DR strategy" />&lt;p>&lt;strong>Why would you do this?&lt;/strong>&lt;/p>
&lt;p>As one of the responsibilities for Production DBA role, we would need to ensure that data is backup properly before the disaster strikes. And you wouldn&amp;rsquo;t know when that thing happens, be it the corrupted data pages, certain developers or even your DBA team members make any mistakes unintentionally/intentionally.&lt;/p>
&lt;p>Backing up data is just half of the process, you might want to verify whether you can restore the DB using that backup data. It is fair to say that only when the restoration is successful without any error, the data that you back up is in good shape.&lt;/p>
&lt;p>&lt;strong>High level of backup process&lt;/strong>&lt;/p>
&lt;p>The assumption is that there are 2 instances e.g, Production and DR/Testing instance with a shared folder in the network where it stores the precious backup data as per diagram below&lt;/p>
&lt;p>&lt;figure
class="gallery-image"
style="
flex-grow: 208;
flex-basis: 500px"
>
&lt;a href="https://www.tranhaidang.com/2022/02/20/verifying-backup-as-part-of-the-dr-strategy/TestingBackup.png" data-size="775x372">
&lt;img src="https://www.tranhaidang.com/2022/02/20/verifying-backup-as-part-of-the-dr-strategy/TestingBackup.png"
width="775"
height="372"
srcset="https://www.tranhaidang.com/2022/02/20/verifying-backup-as-part-of-the-dr-strategy/TestingBackup_hu7deacfd282d045e8949cd70b07b7b039_64852_480x0_resize_box_3.png 480w, https://www.tranhaidang.com/2022/02/20/verifying-backup-as-part-of-the-dr-strategy/TestingBackup_hu7deacfd282d045e8949cd70b07b7b039_64852_1024x0_resize_box_3.png 1024w"
loading="lazy"
alt="Backup Process">
&lt;/a>
&lt;figcaption>Backup Process&lt;/figcaption>
&lt;/figure>&lt;/p>
&lt;p>The OS of DR/Testing instance is Windows 2012/2016.&lt;/p>
&lt;p>&lt;strong>Upload backup&lt;/strong>&lt;/p>
&lt;p>I am using the backup script from &lt;a class="link" href="https://ola.hallengren.com" target="_blank" rel="noopener"
>Ola Hallengren&lt;/a> to do the back up from the PROD instance to a shared folder in the network. There are tons of options for you to consider and customize the backup process. Typically, @Verify, @Compress, @CheckSum are the useful paramters and @Directory will be the shared folder.&lt;/p>
&lt;p>As a common practice, a complete backup = Full + Differential + Log backup&lt;/p>
&lt;p>FULL&lt;/p>
&lt;p>&lt;code>EXECUTE dbo.DatabaseBackup @Databases = 'USER_DATABASES', @Directory = '\\ShareFolder\PRODinstance\Backup', @BackupType = 'FULL', @Compress = 'Y', @CheckSum = 'Y' &lt;/code>&lt;/p>
&lt;p>DIFFERENTIAL&lt;/p>
&lt;p>&lt;code>EXECUTE dbo.DatabaseBackup @Databases = 'USER_DATABASES', @Directory = '\\ShareFolder\PRODinstance\Backup', @BackupType = 'DIFF', @Compress = 'Y', @CheckSum = 'Y' &lt;/code>&lt;/p>
&lt;p>LOG&lt;/p>
&lt;p>&lt;code>EXECUTE dbo.DatabaseBackup @Databases = 'USER_DATABASES', @Directory = '\\ShareFolder\PRODinstance\Backup', @BackupType = 'LOG', @Compress = 'Y', @CheckSum = 'Y' &lt;/code>&lt;/p>
&lt;p>&lt;strong>Download backup&lt;/strong>&lt;/p>
&lt;p>You would need a simple script e.g. xcopy to copy the backups from shared folder to the server hosting the DR/Testing instance and running it under Task Scheduler&lt;/p>
&lt;p>&lt;code>xcopy &amp;quot;\\SharedFolder\PRODinstance\Backup&amp;quot; &amp;quot;E:\MSSQL15.MSSQLSERVER\MSSQL\Backup&amp;quot;&lt;/code>&lt;/p>
&lt;p>For example, we got the following backup files with mixture of FULL + DIFF + LOG
E:\MSSQL15.MSSQLSERVER\MSSQL\Backup\HaiDangSQL\ReportDatabase\FULL\HaiDangSQL_ReportDatabase_FULL_20220219_023000.bak
E:\MSSQL15.MSSQLSERVER\MSSQL\Backup\HaiDangSQL\ReportDatabase\FULL\HaiDangSQL_ReportDatabase_DIFF_20220220_023000.bak
E:\MSSQL15.MSSQLSERVER\MSSQL\Backup\HaiDangSQL\ReportDatabase\FULL\HaiDangSQL_ReportDatabase_DIFF_20220221_023000.bak
E:\MSSQL15.MSSQLSERVER\MSSQL\Backup\HaiDangSQL\ReportDatabase\FULL\HaiDangSQL_ReportDatabase_LOG_20220221_033000.trn
E:\MSSQL15.MSSQLSERVER\MSSQL\Backup\HaiDangSQL\ReportDatabase\FULL\HaiDangSQL_ReportDatabase_LOG_20220221_043000.trn
E:\MSSQL15.MSSQLSERVER\MSSQL\Backup\HaiDangSQL\ReportDatabase\FULL\HaiDangSQL_ReportDatabase_LOG_20220221_053000.trn
E:\MSSQL15.MSSQLSERVER\MSSQL\Backup\HaiDangSQL\ReportDatabase\FULL\HaiDangSQL_ReportDatabase_LOG_20220221_063000.trn
E:\MSSQL15.MSSQLSERVER\MSSQL\Backup\HaiDangSQL\ReportDatabase\FULL\HaiDangSQL_ReportDatabase_LOG_20220221_073000.trn&lt;/p>
&lt;p>There will be 3 steps to restore those backups automatically&lt;/p>
&lt;ol>
&lt;li>Create the restoration stored procedure &lt;a class="link" href="https://drive.google.com/file/d/1WrmrauE5WMttkwTHnqd6g7KxiwT9uR1D/" target="_blank" rel="noopener"
>Admin_RestoreDatabases_Daily&lt;/a> under a datbased used by SQL Admin team. (e.g. AdminDB). There are 5 parameters with their name indicating the purpose&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>@serverName&lt;/li>
&lt;li>@databaseName&lt;/li>
&lt;li>@backupPath&lt;/li>
&lt;li>@dataFilePath&lt;/li>
&lt;li>@logFilePath&lt;/li>
&lt;/ul>
&lt;ol start="2">
&lt;li>Create a SQL agent job with 2 steps calling to the stored procedure above to restore the database to &amp;lsquo;G:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Data' (@dataFilePath) and &amp;lsquo;H:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Data' (@logFilePath). The stored procedure will restore in the order of the FULL, followed by the latest DIFF then those LOG later than the latest DIFF.&lt;/li>
&lt;/ol>
&lt;p>Step 1:&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-USE" data-lang="USE">GO
ALTER DATABASE ReportDatabase SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
USE AdminDB;
GO
exec dbo.Admin_RestoreDatabases_Daily &amp;#39;HaiDangSQL&amp;#39;,&amp;#39;ReportDatabase&amp;#39;,
&amp;#39;E:\MSSQL15.MSSQLSERVER\MSSQL\Backup\&amp;#39;,
&amp;#39;G:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Data\&amp;#39;,
&amp;#39;H:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Data\&amp;#39;;
GO
ALTER DATABASE ReportDatabase SET MULTI_USER;
&lt;/code>&lt;/pre>&lt;p>Step 2: Link the &amp;lsquo;apps_login&amp;rsquo; user in this ReportDatabase to the existing &amp;lsquo;apps_login&amp;rsquo; login in the DR/Testing instance. You might need to create this login before doing this step 2 if required.&lt;/p>
&lt;pre tabindex="0">&lt;code>USE ReportDatabase
exec sp_change_users_login &amp;#39;Update_One&amp;#39;, &amp;#39;apps_login&amp;#39;, &amp;#39;apps_login&amp;#39;;
GO
&lt;/code>&lt;/pre>&lt;ol start="3">
&lt;li>Configure the SQL agent job schedule e.g. Daily @ 4.00 AM and alert in the event either of Step 1 or 2 above fails.&lt;/li>
&lt;/ol>
&lt;p>The task is completed!&lt;/p>
&lt;p>Last but not least, a gentle reminder not to query the data in this DR/Testing instance unless you have it covered by a proper license.&lt;/p>
&lt;p>Hoping you like this article and feel free to share any comments/feedbacks below.&lt;/p>
&lt;p>Thank you for your time.&lt;/p></description></item><item><title>MSSQL 2019 Standard Edition - Failover clustering for on-premise PROD site</title><link>https://www.tranhaidang.com/2021/12/25/sql2019-prod-design/</link><pubDate>Sat, 25 Dec 2021 00:00:00 +0000</pubDate><guid>https://www.tranhaidang.com/2021/12/25/sql2019-prod-design/</guid><description>&lt;img src="https://www.tranhaidang.com/2021/12/25/sql2019-prod-design/bg_2b1.jpg" alt="Featured image of post MSSQL 2019 Standard Edition - Failover clustering for on-premise PROD site" />&lt;p>This blog will continue the previous topic of the MSSQL 2019 Standard Edition for PROD and DR site. It however would cover the PROD site setup only for limited buget project. Hence, it assumes that you need to build the whole PROD site from the scratch and only focuses on the setup with the most minimal equipment involved e.g., SAS connection rather than FC/iSCSI and would use HPE equipment e.g. servers and SAN as the sample. For other hardware vendors, you might consult the local distributor of the respective ones.&lt;/p>
&lt;p>&lt;figure
class="gallery-image"
style="
flex-grow: 165;
flex-basis: 396px"
>
&lt;a href="https://www.tranhaidang.com/2021/12/25/sql2019-prod-design/MSSQL2019_SAS.png" data-size="699x423">
&lt;img src="https://www.tranhaidang.com/2021/12/25/sql2019-prod-design/MSSQL2019_SAS.png"
width="699"
height="423"
srcset="https://www.tranhaidang.com/2021/12/25/sql2019-prod-design/MSSQL2019_SAS_hu7f8a49819ccea11c1459fcf74afcf77c_39776_480x0_resize_box_3.png 480w, https://www.tranhaidang.com/2021/12/25/sql2019-prod-design/MSSQL2019_SAS_hu7f8a49819ccea11c1459fcf74afcf77c_39776_1024x0_resize_box_3.png 1024w"
loading="lazy"
>
&lt;/a>
&lt;/figure>&lt;/p>
&lt;p>As of Dec 2021, the following components can be used for this setup&lt;/p>
&lt;ol>
&lt;li>2 x DL360 Gen10 with HPE Smart Array E208e-p as HBA Adapter&lt;/li>
&lt;li>1 x HPE MSA 2040 12Gb SAS SFF Storage.&lt;/li>
&lt;/ol>
&lt;p>It is recommended to check with the local distributor for the compatibility of the equipment e.g., HBA, server and SAN.&lt;/p>
&lt;p>While servers and SAN path (SAS cables) are catered with multiple units, SAN is still the single point of failure as there is only 1 unit without redundancy. However, it is worth to mention that there are 2 Active-Active controllers for that HPE MSA and we also got a standby MSSQL failover instance on the DR site. It is again targeted for limited budget project which still requires redundancy.&lt;/p>
&lt;p>&lt;strong>Few tips on the hardware selection for MSSQL 2019 Standard&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>DL360 G10&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>CPU: Choose 2 x the highest CPU speed with 12 cores e.g., Intel Gold 6256 (3.6 GHz) if you plan to fully utilize the number of CPU cores (24 cores) supported by MSSQL 2019 Standard. If you purchase lesser licenses for CPU cores, you might need to adjust the CPU cores accordingly.&lt;/li>
&lt;li>RAM: at least 160 GB (128 GB for Database Engine and 32 GB for OS). If other components of MSSQL e.g., Integration Service, Reporting Service etc. are installed into the server, you would need to cater additional RAM for them. Refer to MSSQL 2019 features supported for more info.&lt;/li>
&lt;li>HDD: Including NVMe SSD for TempDB is highly recommended. Add on OS and/or MSSQL if the budget allows.&lt;/li>
&lt;/ul>
&lt;ol start="2">
&lt;li>HPE MSA&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>While there is a trend using Consumer SSD class e.g., Crucial, Samsung, ADATA as the customized SSD drives in the servers/storage product instead of paying the hefty cost of Enterprise SSD class, I would still prefer to use those drives supported by the HPE due to the hardware support and wouldn’t like going down the road of being rejected of compatibility issue. Do your research and check with the hardware vendor carefully before deciding on this.&lt;/li>
&lt;/ul>
&lt;p>Feel free to leave your comments below.&lt;/p>
&lt;p>Thank you for your time.&lt;/p></description></item><item><title>MSSQL 2019 Standard Edition - Failover clustering and DR design for on-premise system</title><link>https://www.tranhaidang.com/2021/12/01/sql2019-ha-and-dr-design/</link><pubDate>Wed, 01 Dec 2021 00:00:00 +0000</pubDate><guid>https://www.tranhaidang.com/2021/12/01/sql2019-ha-and-dr-design/</guid><description>&lt;img src="https://www.tranhaidang.com/img/bg_2a.jpg" alt="Featured image of post MSSQL 2019 Standard Edition - Failover clustering and DR design for on-premise system" />&lt;p>&lt;strong>Why MSSQL 2019?&lt;/strong>&lt;/p>
&lt;p>While MSSQL 2022 is around the corner, majority of the existing instances are still running MSSQL 2019 and earlier. More importantly, there is a cool feature offered by MSSQL 2019 license and it is worth to mention here&lt;/p>
&lt;ol>
&lt;li>The MSSQL 2019 licenses allows up 2 passive failover servers for 1 PROD instance. This is considered a major change compared to MSSQL 2017 licensing and earlier version whereas you need to pay extra licenses for the 2nd passive failover server.&lt;/li>
&lt;li>Software Assurance (SA) of MSSQL 2019 is still required to support the failover setup&lt;/li>
&lt;li>You can also deploy this setup (2 failover servers) on MSSQL 2017 and earlier as long as you purchase MSSQL 2019 + SA&lt;/li>
&lt;li>You shouldn&amp;rsquo;t run any data manipulation transactions on the databases on the 2nd passive failover server. If you do so, it is require to pay extra licenses for this server. Only maintenance-related operations Backup, Restore, DBCC e.g. are allowed.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Why Standard Edition?&lt;/strong>&lt;/p>
&lt;p>Because it is meant for limited budget project. As of Dec 2021, Standard Edition: 3,586 USD/2cores vs Enterprise Edition: 13,748 USD/2cores&lt;/p>
&lt;p>&lt;strong>Why on-premise ?&lt;/strong>&lt;/p>
&lt;p>While cloud is becoming the major force for the IT infrastructure, there are still lots of companies prefer on-premise due to the cost, internal requirement or complete control of the infrastructure&lt;/p>
&lt;p>&lt;strong>Out of scope&lt;/strong>&lt;/p>
&lt;p>This article breifly explains the high-level design and won&amp;rsquo;t discuss the virtualization and the details of equipment spec and redudancy e.g. multiple links for WAN network, multiple paths from Server to SAN, multiple SAN devices/SAN switch devices as it generally depends on the hardware provider, not MSSQL.&lt;/p>
&lt;p>&lt;strong>High-level design&lt;/strong>&lt;/p>
&lt;p>&lt;figure
class="gallery-image"
style="
flex-grow: 201;
flex-basis: 483px"
>
&lt;a href="https://www.tranhaidang.com/2021/12/01/sql2019-ha-and-dr-design/MSSQL2019_setup.png" data-size="1040x516">
&lt;img src="https://www.tranhaidang.com/2021/12/01/sql2019-ha-and-dr-design/MSSQL2019_setup.png"
width="1040"
height="516"
srcset="https://www.tranhaidang.com/2021/12/01/sql2019-ha-and-dr-design/MSSQL2019_setup_hu99554fbbc6e2c095bf28e72d65e167de_83040_480x0_resize_box_3.png 480w, https://www.tranhaidang.com/2021/12/01/sql2019-ha-and-dr-design/MSSQL2019_setup_hu99554fbbc6e2c095bf28e72d65e167de_83040_1024x0_resize_box_3.png 1024w"
loading="lazy"
>
&lt;/a>
&lt;/figure>&lt;/p>
&lt;p>&lt;strong>Advantages of the design&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>It can survive the disater strike on individual server and also the site. If both sites are down then it is another story :P&lt;/li>
&lt;li>In the event either Server1A/1B is not avai, apps won&amp;rsquo;t need to be reconfigured to point to MSSQL instance.&lt;/li>
&lt;li>Maximizing the benefit of MSSQL 2019 licensing by minizing the number of license required, for example, assuming that Server1A/1B/2 are having same number of CPU cores, you just need to buy enough core licenses for either server.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Disadvantages of the design&lt;/strong>&lt;/p>
&lt;p>In the event PROD site is not avai, apps would need to be reconfigured to point to MSSQL instance on Server 2 manually by PROD DBA / DNS system admin. Compared to MSSQL AlwaysOn solution on Standard Edition whereas it is auto failover to Server 2, this design is not that operational transparent and might introduce downtime depending on how fast the PROD DBA / DNS system admin reacts. However, AlwaysOn on Standard Edition will also carry extra complications e.g only support 1 database.&lt;/p>
&lt;p>&lt;strong>The Cost for Per-Code model&lt;/strong>&lt;/p>
&lt;p>Assuming each server 1A/1B/2 are equipped with 24 cores (&amp;lt;4 sockets) to maximize the CPU cores supported by Standard Edition, the total cost for MSSQL licenses is around 51,638.4 USD with the breakdown below&lt;/p>
&lt;ul>
&lt;li>Estimated MSSQL: 12 x 3,586 = 43,032 USD&lt;/li>
&lt;li>Estimated SA (20% of MSSQL cost above): 12 x 3,586 x 20% = 8,606.4 USD&lt;/li>
&lt;/ul>
&lt;p>In my experience, the actual cost is lower due to the discount offered by the local distributor, especially when they are closing on the quarter figure.&lt;/p>
&lt;p>For the Server+CAL model, it is not popular and more suitable for the system with small limted number of users. Therefore, the cost won&amp;rsquo;t be covered in this article.&lt;/p>
&lt;p>Feel free to share any comments/feedbacks below.&lt;/p>
&lt;p>Thank you for your time.&lt;/p></description></item></channel></rss>