{"id":423,"date":"2017-03-29T09:00:51","date_gmt":"2017-03-29T08:00:51","guid":{"rendered":"https:\/\/sqldoubleg.live-website.com\/?p=423"},"modified":"2017-11-14T21:48:52","modified_gmt":"2017-11-14T21:48:52","slug":"spring-cleanup-lob-considerations","status":"publish","type":"post","link":"https:\/\/www.sqldoubleg.com\/es\/2017\/03\/29\/spring-cleanup-lob-considerations\/","title":{"rendered":"Limpieza de primavera, consideraciones con datos LOB"},"content":{"rendered":"<p>Para los DBA&#8217;s es importante tener la posibilidad de recuperar bases de datos de una forma r\u00e1pida en case de un desastre. Pasa maximizar ese potencial necesitamos tener nuestras bases de datos listas, pero a veces puede ser un camino espinoso&nbsp;La primavera ya est\u00e1 aqu\u00ed y probablemente te entren ganas de hacer una limpia en tus bases de datos, y eso est\u00e1 muy bien.<\/p>\n<p>En publicaciones anteriores, he explicado <a href=\"https:\/\/sqldoubleg.live-website.com\/2016\/10\/28\/database-design-matters-rto-and-filegroups\/\" target=\"_blank\">c\u00f3mo tener grupos de archivos dedicados para datos de usuarios puede mejorar nuestro RTO<\/a>, en caso de desastre, recuperando primero los datos cr\u00edticos y luego el resto.<\/p>\n<p>El problema es que cuando manejamos bases de datos que no fueron creadas de esta manera, necesitamos mover los datos de un grupo de archivos a otro antes de poder aplicar este tipo de t\u00e9cnicas.<\/p>\n<p>Aqu\u00ed es donde esta publicaci\u00f3n puede mostrar uno de los problemas que se pueden encontrar durante este proceso.<\/p>\n<p>&nbsp;<br \/>\n<strong>Antecedentes<\/strong><\/p>\n<p>De acuerdo con <a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/t-sql\/statements\/create-index-transact-sql\" target=\"_blank\">Books Online<\/a> <\/p>\n<blockquote><p><strong>Puede usar la cl\u00e1usula DROP_EXISTING para reconstruir el \u00edndice, agregar o quitar columnas, modificar opciones, modificar el orden de clasificaci\u00f3n de las columnas o cambiar el esquema de partici\u00f3n o el grupo de archivos<\/strong><\/p><\/blockquote>\n<p>Pero supongamos que tiene bases de datos antiguas que se crearon en su d\u00eda sin planificar el crecimiento futuro con solo un grupo de archivos y un archivo de datos y que ahora le est\u00e1 causando algunos problemas en forma de disputa o un tiempo de recuperaci\u00f3n muy largo.<\/p>\n<p>Tambi\u00e9n digamos que algunas de sus tablas usan tipos de datos LOB como MAX o incluso los BLOBS antiguos (TEXT, NTEXT, IMAGE).<\/p>\n<p>Para imaginar esto mejor, vamos a crear una base de datos simple de la vieja escuela y una tabla<\/p>\n<pre class=\"brush: tsql; title: ; notranslate\" title=\"\">\r\nUSE master\r\n\r\nCREATE DATABASE LOB_allocations\r\nGO\r\n\r\nUSE LOB_allocations\r\nGO\r\n\r\n-- Create table with NVARCHAR(MAX) column (LOB)\r\nCREATE TABLE dbo.blobs (\r\nId\tINT IDENTITY NOT NULL CONSTRAINT PK_blobs PRIMARY KEY\r\n, Column1 VARCHAR(50) DEFAULT 'a'\r\n, blob_column NVARCHAR(MAX) DEFAULT REPLICATE(CONVERT(NVARCHAR(MAX), N'b'), 10000)\r\n)\r\nGO\r\n\r\n-- populate the table\r\nINSERT INTO dbo.blobs ( Column1, blob_column )\r\nDEFAULT VALUES\r\nGO 20\r\n<\/pre>\n<p>Esto nos pone el escenario para comenzar, ahora dejadme mostraros como se distribuyen nuestros datos por tipo de unidad de asignaci\u00f3n.<\/p>\n<pre class=\"brush: tsql; title: ; notranslate\" title=\"\">\r\n-- Check the different allocation units\r\nSELECT OBJECT_NAME(ix.object_id)\r\n\t\t, ix.name\r\n\t\t, FILEGROUP_NAME(au.data_space_id) AS [Filegroup_name]\r\n\t\t, au.*\r\n\t\t, p.rows\r\n\tFROM sys.indexes AS ix\r\n\t\tINNER JOIN sys.partitions AS p\r\n\t\t\tON p.object_id = ix.object_id \r\n\t\t\t\tAND p.index_id = ix.index_id\r\n\t\tINNER JOIN sys.allocation_units AS au\r\n\t\t\tON au.container_id = p.hobt_id\t\r\nWHERE ix.object_id IN (OBJECT_ID('dbo.blobs'))\r\n<\/pre>\n<p><a href=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2017\/03\/01_allocations_on_PRIMARY.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2017\/03\/01_allocations_on_PRIMARY.png\" alt=\"\" width=\"1051\" height=\"155\" class=\"aligncenter size-full wp-image-424\" srcset=\"https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2017\/03\/01_allocations_on_PRIMARY.png 1051w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2017\/03\/01_allocations_on_PRIMARY-300x44.png 300w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2017\/03\/01_allocations_on_PRIMARY-768x113.png 768w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2017\/03\/01_allocations_on_PRIMARY-1024x151.png 1024w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2017\/03\/01_allocations_on_PRIMARY-150x22.png 150w\" sizes=\"(max-width: 1051px) 100vw, 1051px\" \/><\/a><\/p>\n<p>&nbsp;<br \/>\nAqu\u00ed vemos los diferentes tipos de asignaci\u00f3n y el grupo de archivos al que pertenecen.<\/p>\n<p>Y porque estamos en el modo limpieza de primavera, queremos mover nuestra table a un nuevo grupo de archivos y asi dejar PRIMARY solo para tablas de sistema. Primero hay que crear un nuevo grupo de archivos.<\/p>\n<pre class=\"brush: tsql; title: ; notranslate\" title=\"\">\r\n-- Add new filegroup and file \r\nALTER DATABASE LOB_allocations ADD FILEGROUP [USER_DATA]\r\nGO\r\nALTER DATABASE LOB_allocations \r\n\tADD FILE (NAME='LOB_allocations_user_data'\r\n\t\t\t, FILENAME = 'C:\\Program Files\\Microsoft SQL Server\\MSSQL13.MSSQL2016\\MSSQL\\DATA\\LOB_allocations_user_data.ndf'\r\n\t\t\t, SIZE= 16MB\r\n\t\t\t, FILEGROWTH=16MB) \r\n\tTO FILEGROUP [USER_DATA]\r\n\r\n<\/pre>\n<p>&nbsp;<br \/>\nY ahora podemos seguir las instrucciones y mover nuestra tabla de un grupo de archivos a otro si reconstruimos nuestro indice cluster con WITH DROP_EXISTING.<\/p>\n<pre class=\"brush: tsql; title: ; notranslate\" title=\"\">\r\n-- Move the clustered index to the new filegroup\r\nCREATE UNIQUE CLUSTERED INDEX PK_blobs ON dbo.blobs (Id) WITH (DROP_EXISTING = ON) ON [USER_DATA]\r\n<\/pre>\n<p>&nbsp;<br \/>\nAhora nuestra tabla est\u00e1 almacenada en un grupo de archivos diferente. Vamos a verlo<\/p>\n<pre class=\"brush: tsql; title: ; notranslate\" title=\"\">\r\n-- check again the allocation units.\r\nSELECT OBJECT_NAME(ix.object_id)\r\n\t\t, ix.name\r\n\t\t, FILEGROUP_NAME(au.data_space_id) AS [Filegroup_name]\r\n\t\t, au.*\r\n\t\t, p.rows\r\n\tFROM sys.indexes AS ix\r\n\t\tINNER JOIN sys.partitions AS p\r\n\t\t\tON p.object_id = ix.object_id \r\n\t\t\t\tAND p.index_id = ix.index_id\r\n\t\tINNER JOIN sys.allocation_units AS au\r\n\t\t\tON au.container_id = p.hobt_id\t\r\nWHERE ix.object_id IN (OBJECT_ID('dbo.blobs'))\r\n<\/pre>\n<p><a href=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2017\/03\/02_allocations_on_USER_DATA.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2017\/03\/02_allocations_on_USER_DATA.png\" alt=\"\" width=\"1060\" height=\"171\" class=\"aligncenter size-full wp-image-425\" srcset=\"https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2017\/03\/02_allocations_on_USER_DATA.png 1060w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2017\/03\/02_allocations_on_USER_DATA-300x48.png 300w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2017\/03\/02_allocations_on_USER_DATA-768x124.png 768w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2017\/03\/02_allocations_on_USER_DATA-1024x165.png 1024w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2017\/03\/02_allocations_on_USER_DATA-150x24.png 150w\" sizes=\"(max-width: 1060px) 100vw, 1060px\" \/><\/a><\/p>\n<p>&nbsp;<br \/>\nEjem, eso no mola nada&#8230; Parece que reconstruir el \u00edndice cluster no afecta a las unidaded de asignaci\u00f3n LOB, as\u00ed que para mover nuestros datos del todo, tenemos que crear una nueva tabla en el nuevo grupo de archivos y volcar los datos, con el consiguiente trastorno.<\/p>\n<p>&nbsp;<br \/>\n<strong>Conclusi\u00f3n<\/strong><\/p>\n<p>Obviamente es una buena idea el separar de manera l\u00f3gica y f\u00edsica nuestros datos usando multiples grupos de archivos, pero siempre es mejor si planeamos esto con la debida antelacion. De esta forma nos ahorraremos situaciones inc\u00f3modas en fases mas avanzadas.<\/p>\n<p>Y una vez mas, podemos ver la importancia de tener un poco de conocimiento sobre el funcionamiento internos y c\u00f3mo los datos son distribuidos por las diferentes unidades de asignaci\u00f3n que se usan en SQL Server.<\/p>\n<p>Espero que esta entrada haya side de ayuda y por favor usad los comentarios para cualquier pregunta que pueda surgir.<\/p>\n<p>Gracias!<\/p>\n<p>&nbsp;<br \/>\n<\/p>","protected":false},"excerpt":{"rendered":"<p>Para los DBA&#8217;s es importante tener la posibilidad de recuperar bases de datos de una forma r\u00e1pida en case de un desastre. Pasa maximizar ese potencial necesitamos tener nuestras bases de datos&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[35,52,32,50,12,25],"_links":{"self":[{"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/posts\/423"}],"collection":[{"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/comments?post=423"}],"version-history":[{"count":1,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/posts\/423\/revisions"}],"predecessor-version":[{"id":586,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/posts\/423\/revisions\/586"}],"wp:attachment":[{"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/media?parent=423"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/categories?post=423"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/tags?post=423"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}