-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[DNM] [PM-27605] Populate MaxStorageGbIncreased for storage increase from 1GB to 5GB. #6579
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This migration populates the MaxStorageGbIncreased column for Users and Organizations by setting it to MaxStorageGb + 4, representing the storage increase from 1GB to 5GB. This migration depends on PM-27603 being deployed first to create the MaxStorageGbIncreased column. Target release: January 6th, 2026 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
|
I'll analyze this and get back to you. |
| @@ -0,0 +1,13 @@ | |||
| -- Populate MaxStorageGbIncreased for Users | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❌ Missing column existence check
This migration will fail with a cryptic error if the MaxStorageGbIncreased column doesn't exist (PM-27603 not deployed).
Recommendation: Add a check at the start of the migration:
-- Verify MaxStorageGbIncreased column exists before proceeding
IF NOT EXISTS (
SELECT * FROM sys.columns
WHERE object_id = OBJECT_ID('[dbo].[User]')
AND name = 'MaxStorageGbIncreased'
)
BEGIN
RAISERROR('MaxStorageGbIncreased column does not exist in User table. PM-27603 must be deployed first.', 16, 1);
RETURN;
END;
IF NOT EXISTS (
SELECT * FROM sys.columns
WHERE object_id = OBJECT_ID('[dbo].[Organization]')
AND name = 'MaxStorageGbIncreased'
)
BEGIN
RAISERROR('MaxStorageGbIncreased column does not exist in Organization table. PM-27603 must be deployed first.', 16, 1);
RETURN;
END;
GOThis provides a clear deployment dependency error rather than "invalid column name" errors.
| UPDATE [dbo].[User] | ||
| SET [MaxStorageGbIncreased] = [MaxStorageGb] + 4 | ||
| WHERE [MaxStorageGb] IS NOT NULL; | ||
| GO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💭 Transaction safety consideration
The GO statement here commits the User table update as a separate transaction from the Organization update. This means:
- ✅ Pro: Reduces lock duration, better for production with 148k User records
⚠️ Con: If Organization update fails, User table will have been updated but Organization table won't (partial completion)
Question: Is this intentional to minimize lock contention, or should both updates be wrapped in a single transaction for atomicity?
If atomicity is needed:
BEGIN TRANSACTION;
-- User update
-- Organization update
COMMIT TRANSACTION;
GOPlease clarify the intended behavior for this migration.
|
New Issues (3)Checkmarx found the following issues in this Pull Request
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6579 +/- ##
=======================================
Coverage 56.83% 56.83%
=======================================
Files 1909 1909
Lines 84810 84810
Branches 7633 7633
=======================================
Hits 48199 48199
Misses 34785 34785
Partials 1826 1826 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change looks fine to me - I'm going to lean on @bitwarden/dept-dbops for the PopulateMaxStorageGbIncreased.sql file. Also, looks like you have some CI failures.
util/Migrator/DbScripts/2025-11-14_00_PopulateMaxStorageGbIncreased.sql
Outdated
Show resolved
Hide resolved
mkincaid-bw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is the logic going to correlate with the actual enablement of the additional 4GB? From what I can tell, once this PR deploys, then any new Users/Orgs that get created, or Users/Orgs that get updated, will have the MaxStorageGbIncreased set to the same as MaxStorageGb. Is that logic correct? It seems like if we deploy this PR but don't enable the actual increase until later, then new Users/Orgs will get set to the old default, and then won't get updated since the migration will have already run. Am I missing something?
|
|
||
| WHILE @RowsAffected > 0 | ||
| BEGIN | ||
| UPDATE TOP (@BatchSize) [dbo].[User] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This migration is going to take quite a while. There's no index on the MaxStorageGb column so the script as-is will force hundreds (or thousands) of table scans - one for each update statement in the batch.
I tested this alternative against a backup (creating an index first) and it ran in 3-4 minutes:
IF NOT EXISTS (
SELECT 1
FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.User')
AND name = 'IX_TEMP_User_MaxStorageGb_MaxStorageGbIncreased'
)
BEGIN
CREATE INDEX IX_TEMP_User_MaxStorageGb_MaxStorageGbIncreased
ON [User]([MaxStorageGb], [MaxStorageGbIncreased]);
END
GO
DECLARE @BatchSize INT = 5000;
DECLARE @RowsAffected INT = 1;
DECLARE @TotalUpdated INT = 0;
PRINT 'Starting User table update...';
WHILE @RowsAffected > 0
BEGIN
UPDATE TOP (@BatchSize) [dbo].[User]
SET [MaxStorageGbIncreased] = [MaxStorageGb] + 4
WHERE [MaxStorageGb] IS NOT NULL
AND [MaxStorageGbIncreased] IS NULL; -- Only update rows not yet processed
SET @RowsAffected = @@ROWCOUNT;
SET @TotalUpdated = @TotalUpdated + @RowsAffected;
PRINT 'Users updated: ' + CAST(@TotalUpdated AS VARCHAR(10));
WAITFOR DELAY '00:00:00.100'; -- 100ms delay to reduce contention
END
PRINT 'User table update complete. Total rows updated: ' + CAST(@TotalUpdated AS VARCHAR(10));
GO
DROP INDEX IF EXISTS [dbo].[User].[IX_TEMP_User_MaxStorageGb_MaxStorageGbIncreased];
GOThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic works correctly when both changes deploy together or in the correct sequence:
- This migration script (2025-11-14_00_PopulateMaxStorageGbIncreased.sql):
- Runs once during deployment
- Updates existing records: MaxStorageGbIncreased = MaxStorageGb + 4
- Migrates old 1GB quota → new 5GB quota - Stored procedures (e.g., User_Create, Organization_Create,User_Update,Organization_Update):
- For new records created after this PR
- Set MaxStorageGbIncreased = @MaxStorageGb (same value, not +4)
- The @MaxStorageGb parameter comes from the API/Pricing Service - Pricing Service (separate deployment):
- Updates plan definitions: 1GB → 5GB
- API calls stored procedures with @MaxStorageGb = 5
mkincaid-bw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
@cyprain-okeke This looks good - however, it has to be merged for a specific release so leave the |



🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-27605
📔 Objective
This PR implements the transition migration for PM-27605: Populate MaxStorageGbIncreased for storage increase from 1GB to 5GB.
This migration populates the MaxStorageGbIncreased column (added in PM-27603) by setting it to MaxStorageGb + 4 for all User and Organization records that have a storage quota defined.
Changes
Dependencies
Database Impact
According to the ticket, as of October 28th, 2025:
📸 Screenshots
⏰ Reminders before review
🦮 Reviewer guidelines
:+1:) or similar for great changes:memo:) or ℹ️ (:information_source:) for notes or general info:question:) for questions:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion:art:) for suggestions / improvements:x:) or:warning:) for more significant problems or concerns needing attention:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt:pick:) for minor or nitpick changes