Je couronne une table d'alter, alter colonne sur une table avec près de 30 millions de rangées et SQL Azure échoue après environ 18 minutes disant que The session has been terminated because of excessive transaction log space usage. Try modifying fewer rows in a single transaction.
Je suppose qu'il n'est pas possible de rompre cela dans la modification de moins de lignes à la fois, je me demande donc quelles sont mes options pour effectuer cette modification à la base de données. SQL Azure ne me laissera pas changer la taille du journal des transactions (limitée à 1 Go).
Je suppose que mon meilleur pari va créer une nouvelle table avec la nouvelle mise en page, la migration des données dans celle-ci, supprimant la table d'origine, puis renommer la nouvelle table pour correspondre au nom de l'ancienne table. Si tel est le cas, comment est-il préférable de structurer ces commandes?
Le temps d'arrêt prévu pour notre système n'est pas un problème actuellement afin que cette opération puisse prendre aussi longtemps que nécessaire.
Vous voudrez charger vos données dans une nouvelle table, ce faisant cela dans de petits lots, puis déposez la table existante. Je mets un exemple rapide à l'aide de la table des ventes.customer à Aventureworks, quelque chose de similaire devrait fonctionner pour vous aussi.
Tout d'abord, créez votre nouvelle table, complétez le nouveau DataType que vous souhaitez utiliser:
CREATE TABLE [Sales].[Currency_New](
[CurrencyCode] [nchar](4) NOT NULL,
[Name] [varchar](128) NOT NULL,
[ModifiedDate] [datetime] NOT NULL,
CONSTRAINT [PK_Currency_New_CurrencyCode] PRIMARY KEY CLUSTERED
(
[CurrencyCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
Ensuite, insérez vos enregistrements et définissez votre lot. J'utilise 10 ici, mais vous voudrez probablement utiliser quelque chose de plus grand, disons 10 000 rangées à la fois. Pour les lignes de 30 mm, je vous suggère même d'aller à la taille du lot de 100k rangée à la fois, c'est la limite que j'utilise généralement avec des tables plus grandes:
DECLARE @RowsInserted INT, @InsertVolume INT
SET @RowsInserted = 1
SET @InsertVolume = 10 --Set to # of rows
WHILE @RowsInserted > 0
BEGIN
INSERT INTO [Sales].[Currency_New] ([CurrencyCode]
,[Name]
,[ModifiedDate])
SELECT TOP (@InsertVolume)
SC.[CurrencyCode]
,SC.[Name]
,SC.[ModifiedDate]
FROM [Sales].[Currency] AS SC
LEFT JOIN [Sales].[Currency_New] AS SCN
ON SC.[CurrencyCode] = SCN.[CurrencyCode]
WHERE SCN.[CurrencyCode] IS NULL
SET @RowsInserted = @@ROWCOUNT
END
Je fais habituellement une vérification de la santé mentale et vérifie que les rangées sont les mêmes avant de nettoyer:
SELECT COUNT(*) FROM [Sales].[Currency]
SELECT COUNT(*) FROM [Sales].[Currency_New]
Une fois que vous êtes confiant, vous avez migré vos données, vous pouvez déposer la table d'origine:
DROP TABLE [Sales].[Currency]
Dernière étape, renommez la nouvelle table, de sorte que les utilisateurs ne doivent pas changer de code:
EXEC sp_rename '[Sales].[Currency_New]', '[Sales].[Currency]';
GO
Je ne sais pas combien de temps cela prendra. Je vous suggérerais d'essayer de faire cela lorsque vous avez une fenêtre de maintenance claire et que les utilisateurs ne sont pas connectés.
Ht
Je suis sur un téléphone en ce moment mais je viens de répondre à une question très similaire sur Stackoverflow il y a quelques jours. Les noms de colonne ne vous sont probablement pas applicables, mais voici ce que j'ai donné.
SELECT
[ID],
[Title],
[Abstract],
[Value],
[UserID],
[GroupID],
[Date],
[Views],
[Hates],
[Likes],
[Source]
INTO dbo.[News-News_Newest]
FROM [dbo].[News-News];
DROP TABLE [dbo].[News-News_Newest];
GO
EXEC sp_rename '[News-News_Newest]' , '[News-News]';
GO
ALTER TABLE [News-News]
ADD CONSTRAINT PK_News_ID PRIMARY KEY CLUSTERED (ID ASC);
La même merveille s'applique à vous comme nous. Écrivez vos relations clés étrangères aussi, puis reconstruisez le. Après la charge avec chèque chèque