Tag: SQLNewBlogger

  • Renaming MDF/LDF Files–SQLNewBlogger

    Another post for me that is simple and hopefully serves as an example for people trying to get blogging as #SQLNewBloggers.

    I would guess many people would run into this situation at some point. A developer or DBA creates a database, then decides to rename it, but the logical and physical names aren’t correct. This post will look at how to do this. A couple of notes and then the process below.

    This might not matter to many of you, but in development, I sometimes find I’ll rename a database and then attempt to recreate (or deploy) a new database with the old name. The mdf/ldf files don’t match, and I realize it’s because I’m using defaults.

    However, I’d also say this is an issue in a DR situation. If the filenames don’t seem to match, someone might restore the wrong database or the wrong files. Or worse, think the can delete a file on the file system because there’s no database with that name.

    Renaming the Database

    This is easy. Right click, select Rename.

    2017-06-07 09_38_49-

    Then type the name name. In this case, I’m going from WideWorldImporters-SSDT to WideWorldImporters-RR.

    2017-06-07 09_38_59-SQLQuery1.sql - (local)_SQL2016.msdb (PLATO_Steve (52)) - Microsoft SQL Server M

    That renames the database, but what about the files? If I run this:

    sp_helpdb ‘WideWorldImporters-RR’

    I get this:

    2017-06-07 09_42_00-SQLQuery1.sql - (local)_SQL2016.msdb (PLATO_Steve (53)) - Microsoft SQL Server M

    Not really what I want. I need these mdf/ldf files to be changed. How do I do this?

    I can get to the properties for the database and select the “Files” pane to get a list of files. Here I can change the logical name by clicking that field and typing a new name. I’ve done that here.

    2017-06-07 09_43_29-Database Properties - WideWorldImporters-RR

    However, if I scroll to the right to the File Name column, I can’t change anything.

    2017-06-07 09_43_44-SQLQuery1.sql - (local)_SQL2016.msdb (PLATO_Steve (53))_ - Microsoft SQL Server

    What I need to do is use the ALTER DATABASE command with the MODIFY FILE command. I need to do this twice.

    1. Change the physical file name
    2. Change the logical file name

    Let’s do that. Here’s the code to change the physical name.

    ALTER DATABASE [WideWorldImporters-RR]
     MODIFY FILE
     (   NAME = 'WideWorldImporters-SSDT_Data',
         FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL13.SQL2016\MSSQL\DATA\WideWorldImporters-RR.mdf'
     );

    I need to repeat this for the log file and the MOT file. Once I change the names, I get this message.

    2017-06-07 09_48_38-SQLQuery1.sql - (local)_SQL2016.WideWorldImporters-RR (PLATO_Steve (53))_ - Micr

    This is key. If I were to restart my system now, when the database attempted to start and go through recovery, the files would not have been found. Now, I need to change the physical file names.

    To do that, I first need to take the database offline.

    USE master
    go
    ALTER DATABASE [WideWorldImporters-RR] SET OFFLINE

    Then I go to the location of the physical files and rename them in Windows Explorer.

    2017-06-07 09_53_35-DATA

    Now I bring the database online.

    ALTER DATABASE [WideWorldImporters-RR] SET ONLINE

    Once that’s done, I can then use ALTER DATABASE again to change the logical file names.

    ALTER DATABASE [WideWorldImporters-RR]
      MODIFY FILE (NAME='USERDATA_612671E2',
                   NEWNAME = 'WWI_UserData'
                   );

     

    And run a final sp_helpdb.

    2017-06-07 09_54_13-SQLQuery1.sql - (local)_SQL2016.master (PLATO_Steve (53))_ - Microsoft SQL Serve

    SQLNewBlogger

    An easy task, with a touch of research in Books Online, but not too difficult. This took me about 10 minutes to do, and since I realized this was a good skill, I took screenshots and saved code as I went.

    Then about 10 minutes to write this up.

  • Why Does My Log Grow–SQLNewBlogger

    Another post for me that is simple and hopefully serves as an example for people trying to get blogging as #SQLNewBloggers.

    This is a great topic, and really, every DBA or admin should blog this and be sure they understand the issue.

    I saw a posting from someone that said this: they kept running low on disk space where the transaction log was kept. They would shrink the log, and they had 3 log backups per day, but the log kept growing, and this was an issue. What can they do?

    Let’s examine what happens: first, assume you have a trans‌‌action log that gets 2 transactions an hour. You have enough log space for 4 transactions in your log file. You back up 3 times a day (every 8 hours). Here’s your log size in transactions:

    1:00am - 2 transactions
    2:00am - 4 transactions‌‌‌
    3:00am - 6 transactions (log grows)
    4:00am - 8 transactions (log grows) 
    ‌5:00am‌‌ - 10 transactions (log grows)
    ‌5:00am‌‌ - 12 transactions (log grows)
    ‌5:00am‌‌ - 14 transactions (log grows)
    8:00am‌‌ - log backup with 14 transactions. Log is large enough for 14 transactions
    ‌9:00am - 2 transactions
    10:00am - 4 transactions‌‌‌
    11:00am - 6 transactions 
    12:00pm - 8 transactions 
    1:00pm‌‌ - 10 transactions 
    ‌2:00pm‌‌ - 12 transactions 
    ‌3:00pm‌‌ - 14 transactions 
    4:00pm‌‌ - log backup with 14 transactions. Log is large enough for 14 transactions
    ‌4:30 - you shrink the log back to 4 transaction size
    5:00pm - 2 transactions
    6:00pm - 4 transactions‌‌‌
    7:00pm - 6 transactions (log grows)
    8:00pm - 8 transactions (log grows) 
    9:00pm‌‌ - 10 transactions (log grows)
    ‌10:00pm‌‌ - 12 transactions (log grows)
    11:00pm‌‌ - 14 transactions (log grows)
    12:00am‌‌ - log backup with 14 transactions. Log is large enough for 14 transactions
    ‌

    Repeat this every day.

    Now, how does this change if we run log backups more often? Let’s say we decide to run log backups every hour. Now I get:

    1:00am - 2 transactions‌‌‌, log backup runs
    2:00am - 2 transactions‌‌‌, log backup runs
    3:00am -2 transactions‌‌‌, log backup runs
    4:00am - 2 transactions‌‌‌, log backup runs
    ‌5:00am‌‌ - 2 transactions‌‌‌, log backup runs
    ‌5:00am‌‌ - 2 transactions‌‌‌, log backup runs
    ‌5:00am‌‌ - 2 transactions‌‌‌, log backup runs
    8:00am‌‌ - 2 transactions‌‌‌, log backup runs
    ‌9:00am - 2 transactions, log backup runs
    10:00am - 2 transactions‌‌‌, log backup runs
    11:00am - 2 transactions‌‌‌, log backup runs
    12:00pm - 2 transactions‌‌‌, log backup runs
    1:00pm‌‌ - 2 transactions‌‌‌, log backup runs
    ‌2:00pm‌‌ - 2 transactions‌‌‌, log backup runs
    ‌3:00pm‌‌ - 2 transactions‌‌‌, log backup runs
    4:00pm‌‌ - 2 transactions‌‌‌, log backup runs
    5:00pm - 2 transactions‌‌‌, log backup runs
    6:00pm - 2 transactions‌‌‌, log backup runs
    7:00pm - 2 transactions‌‌‌, log backup runs
    8:00pm - 2 transactions‌‌‌, log backup runs
    9:00pm‌‌ - 2 transactions‌‌‌, log backup runs
    ‌10:00pm‌‌ - 2 transactions‌‌‌, log backup runs
    11:00pm‌‌ - 2 transactions‌‌‌, log backup runs
    12:00am‌‌ - 2 transactions‌‌‌, log backup runs

    In both scenarios, the total log transaction load across the day is the same. The total log backup size is the same across the day. However, a log backup allows me to reuse the log, so I never run out of space and get growths in the second scenario.

    If you aren’t sure how things work, or want to write your own blog, I would also recommend you read this:  http://www.sqlservercentral.com/articles/Administration/64582/

     

    ‌‌

  • Restore a BACPAC–#SQLNewBlogger

    Another post for me that is simple and hopefully serves as an example for people trying to get blogging as #SQLNewBloggers.

    I needed to get the WideWorldImporters sample database for a project and noticed that there was a BACPAC available. I downloaded it and needed to restore this as a database. At least, that’s what many people would think.

    However, if you go to the restore dialog, and select Device and then pick your location, there’s no filter for a .bacpac. In fact, if you choose one, it won’t restore. You’ll get the “no backupset selected” error.

    2017-05-30 08_51_40-Locate Backup File - PLATO_SQL2016

    How do you restore a .bacpac? Well, you import it. If you right click the databases folder in SSMS, you’ll see this:

    2017-05-30 08_54_40-SQLQuery16.sql - (local)_SQL2016.model (PLATO_Steve (60))_ - Microsoft SQL Serve

    The BACPAC is a DACPAC with data, in other words, a data-tier application with the data included. Once we click this, we get a wizard. Of course, there’s a introduction screen.

    2017-05-30 08_57_17-Import Data-tier Application

    Then we get to choose the file, or import one from Windows Azure storage. I’ll limit the image here to the relevant parts. You can see below I’ve selected the file I downloaded.

    2017-05-30 08_57_33-Import Data-tier Application

    Once I do that, the next screen allows me to set the database name and the paths. I shot this screen, and then changed the name, but forgot to reshoot. However, this is where you’d set the paths for files and change the name of the database.

    2017-05-30 08_58_30-Import Data-tier Application

    You get to verify your settings. I know many people blow by this screen, but make sure you double check this is what you want. Notice I moved the data, but not the log. I went back and fixed things, again, forgetting to reshoot the image.

    2017-05-30 08_59_25-Import Data-tier Application

    Once you click Finish, the import begins. This can take time, depending on the system you use.

    2017-05-30 08_59_31-Import Data-tier Application

    However, you get detailed progress. As you can see, I get a lot of details on what happened. There’s plenty more below this.

    2017-05-30 09_06_28-Import Data-tier Application

    But it worked, and I have my data.

    2017-05-30 09_07_28-SQLQuery1.sql - (local)_SQL2016.WideWorldImporters (PLATO_Steve (59))_ - Microso

    You should practice this. It’s simple, but know how to import a BACPAC. You never know when you might get one and someone is at your desk. Having to google to import a simple database is a little embarrassing.

    SQLNewBlogger

    This is a simple post, one that took longer to write than setup and perform, but a good skill to showcase. If you’re looking for something to blog, create a bacpac on another instance and import it into your local SQL Server.

  • Restore to a point in time–#SQLNewBlogger

    Another post for me that is simple and hopefully serves as an example for people trying to get blogging as #SQLNewBloggers. This is also a part of a basic series on git and how to use it.

    One of the things I had to show recently was a restore to a point in time, and I needed to actually lookup syntax. That’s a good excuse for a #SQLNewBlogger post, so here we go.

    When you restore, the default is to restore to the end of the backup file, whether full, diff, or log. In the latter, you have the option to stop early, and only restore part of the log. In doing this, you have two choices:

    • restore to a time
    • restore to a marked transaction

    Relatively few of us use marked transactions, but they can be useful. However, this post looks at time.

    Let’s do a few things and show how this works.

    Setup

    The first thing I need to do is get a database, with some data. I’ll create a database, add a table with a row, and then back up the database.

    CREATE DATABASE RestoreTime;
    GO
    USE RestoreTime
    GO
    CREATE TABLE BackupLog
    ( logdate DATETIME2 DEFAULT SYSDATETIME()
    , logmessage VARCHAR(200)
    )
    -- add a message
    INSERT dbo.BackupLog
            ( logdate, logmessage )
        VALUES ( SYSDATETIME(), '1st Log, before a backup' )
    GO
    BACKUP DATABASE RestoreTime TO disk = 'RestoreTime.bak'
    GO

    Next we want to add some data to the table and get some log records. In this case, I’ll use a simple loop to add a new row to the table every second. This gives me some points in time to look for and use to show I  am restoring to a point in time.

    DECLARE @seconds INT = 10,
            @starttime DATETIME2 = SYSDATETIME();
    
    WHILE (SYSDATETIME() < DATEADD( SECOND, @seconds, @starttime))
     BEGIN
      INSERT dbo.BackupLog
            ( logdate, logmessage )
        VALUES ( SYSDATETIME(), 'Log record entered at ' + CAST(SYSDATETIME() AS VARCHAR(30)) )
      WAITFOR DELAY '00:00:01'
     END
    
    GO
    BACKUP LOG RestoreTime TO DISK = 'RestoreTime.trn'
    GO

    I’ve added data, and my table looks like this:

    2017-05-23 15_23_12-SQLQuery8.sql - (local)_SQL2016.RestoreTime (PLATO_Steve (57))_ - Microsoft SQL

    My log backup contains all these records. If I restore the full backup and log now, by default I’ll end up in this state, with all these rows in my table. However, what if I want to only get the first 5?

    I can use the STOPAT syntax in my restore. I start by restoring the full with NORECOVERY and then the log. However, in the log, I’ll choose a time that is after row 5, but before 6. In this case, that’s 2017-05-23T15:22:57. Here’s the code:

    USE master
    GO
    RESTORE DATABASE RestoreTime FROM DISK = 'RestoreTime.bak' WITH NORECOVERY, replace
    GO
    RESTORE LOG RestoreTime FROM DISK = 'RestoreTime.trn' WITH RECOVERY, STOPAT = '2017-05-23T15:22:57'
    GO
    USE RestoreTime
    GO
    SELECT 
     *
     FROM dbo.BackupLog

    I have my results below

    2017-05-23 15_31_10-SQLQuery8.sql - (local)_SQL2016.RestoreTime (PLATO_Steve (57))_ - Microsoft SQL

    Only the log activity before this time is restored.

    SQLNewBlogger

    After I’d looked up the syntax, I spent only about 10 minutes setting up the demo and getting this ready. Practice skills and write about it. Show your next employer you are always learning and working.