After another Patch Tuesday™ has come and gone, I have seen more confusion about build numbers and what they mean.
The Real Problem
The underlying problem is that servicing complex software is, well, complex. Microsoft simplified this for our little corner of the world when they announced that SQL Server 2016 would be the last release to get service packs. We still have Cumulative Updates (CUs) and General Distribution Releases (GDRs) to deal with, but they tend to only cause confusion around Patch Tuesday (or the – cough – odd time a CU breaks things). Before I explain, let's define these:
A cumulative update contains all the functional and security fixes (and, occasionally, added features) for a major version. During the first year of a major version release, they are offered monthly; then, roughly, every other month until that version is no longer in mainstream support. This period is, generally, four years.
These updates are always cumulative – hey, it's even in the name. If you install Cumulative Update #3, you get all of the fixes in CU #1 and CU #2 without having to install those first.
A GDR update contains one or more fixes that Microsoft deems critical. These are usually security-related (but not always), and are sometimes offered via Windows Update. Depending on severity, they may be issued even after a branch is out of mainstream support.
GDRs usually come in two flavors:
- A GDR for the RTM branch – this does not include any of the non-GDR fixes in CUs, but they are also cumulative within RTM: if you install the GDR from last week, you also get all of the other GDR fixes before it.
- A GDR for the CU branch – that GDR does include all the fixes from the prior CU (and all the CUs before it), even though those fixes won't be mentioned in the KB article for the GDR. Just like CU #15 includes the fixes from CU #14, CU #13, etc., but the CU #15 KB does not say so.
An exception might be if a GDR release happens to align perfectly with an already-scheduled CU release that can also include the fix.
CUs and GDRs (for versions that still matter) are listed in official articles here:
[ SQL Server 2022 | SQL Server 2019 | SQL Server 2017 | SQL Server 2016 ]
But other sources can be both more reliable and more exhaustive:
[ SQLServerUpdates.com | Microsoft SQL Server Versions List ]
If you're using Docker, be sure to keep your images up to date, e.g. using:
docker pull mcr.microsoft.com/mssql/server:2022-latest
Shouldn't I Always Choose CU?
Occasionally someone will ask why the GDR path exists at all. The primary reason is that non-critical fixes can require additional testing. An organization may not have the bandwidth or testing infrastructure to validate such a wide range of changes, so they opt instead to reduce their test coverage and risk of regression to just the areas that are fixed in GDRs. They can always jump to the CU path later – but the reverse is not necessarily as easy. You can uninstall a Cumulative Update to try to downgrade back to GDR, for example, but this is not something I'd be excited to try in production.
That said, I always strive for staying up to date on the CU path, and recommend customers and peers do the same. I can understand some short-term restrictions and even some hesitancy for a new major version, but this shouldn't be permanent state. The caveat is that you should apply any new CU in a dev or staging environment first, and really test your workloads (including backups and other scheduled jobs) against it, for at least a business cycle, before planning to deploy to production.
Build Numbers
Every update bumps SQL Server to a new build number. You should not infer anything meaningful from specific build numbers, the size of an update, or the date an update was released. For example:
- A higher build number does not necessarily mean it contains all the fixes in a lower build number.
- A newly-released update does not necessarily mean it contains all the fixes in an earlier update.
- The delta in build numbers (or an increase or decrease in size) between two updates does not necessarily reflect the number of fixes or changed lines of code.
A Fictional Timeline
I'll illustrate some of these examples below. Imagine it is October 15th, 2022, and SQL Server 2022 has just been released. The build number for the initial release is 16.0.1000:
Remember that software is imperfect. Before you've even had a chance to install RTM, at t0
, there are already two branches created somewhere in the depths of Microsoft's repo: one for CU, and one for GDR.
A couple of known issues from RTM (let's call them fixes A
and B
) are packaged into CU #1, and released as build # 16.0.2025 on November 10th (t1
):
Then December's Patch Tuesday happens, where fix S1
fixes a vulnerability in, I don't know, Reporting Services. This gets two releases at t2
, one for CU (16.0.2055) and one for GDR (16.0.1050):
At this point, yes, you could look at two different instances in your environment and have a build with a lower build number (GDR with the patch) that contains fixes not in a higher build number (CU #1 without patch). At the same time, you can have a build produced later that has fewer fixes in it than one produced earlier. So, just looking at the date or build number does not really tell you which one is more complete or current.
Later in December (at t3
), the regularly scheduled CU #2 comes out, with build # 16.0.2070. This update includes the fixes from CU #1, the security patch from earlier in the month, and a new fix (C
):
GDR customers sit on their hands, and in January (at t4
), CU #3 is released, with additional fixes (D
and E
):
At the end of January (at t5
), a new exploit is fixed in Security Update 2, with builds for CU (16.0.2115) and GDR (16.0.1075).
Again it is possible to have a GDR build with fixes not in a higher build.
At this point a GDR customer could opt to switch paths and upgrade to a later CU, for example from 16.0.1050 to any CU build containing at least the same GDR fixes:
It is less advisable, but possible, to go from a GDR build to a "lower" CU build, meaning a build number that is higher but was released before the current GDR build (just note that you'll lose any of the later GDR fixes):
It is almost certainly a Bad Idea™ to try to downgrade from a CU build to a GDR build, particularly to an older GDR build:
Note that, in all of these cases, there is no mention of how many fixes are in a given CU, whether the file sizes have gone up or down, or what meaning the difference in build numbers might have. There also isn't a single KB article where you can see a list of everything fixed in a given CU. In this fictitious example above, fixes A
, B
, S1
, C
, D
, E
, and S2
will be documented across multiple KB articles and CVE alerts.
Microsoft is working on their efforts in this area, including maintaining an Excel workbook with details about each release and all of the fixes therin. You will see this disclaimer and prompt to download in modern KB articles:
Some other links you might find useful:
- Latest updates and version history for SQL Server
- Microsoft SQL Server Versions List
- SQLServerUpdates.com
- #BackToBasics : Definitions of SQL Server release acronyms
- Description of the standard terminology that is used to describe Microsoft software updates
- A changed approach to Service Packs
- Announcing the Modern Servicing Model for SQL Server
- An incremental servicing model (ISM) for SQL Server
- Announcing updates to the SQL Server Incremental Servicing Model (ISM)
- Determine the version, edition, and update level of SQL Server
1 Response
[…] Aaron Bertrand clarifies two concepts: […]