Category: SQL Server

SQL Server Blog Archives, by Peter Whyte (Database Administrator).
Includes: Database Admin, Management Studio (SSMS), Windows Admin, PowerShell, WSL, MSSQL Backups, Restores & more…

  • Disk Usage by Top Tables Report in SQL Server

    Disk Usage by Top Tables Report in SQL Server

    The Disk Usage by Top Tables Report in SQL Server is a quick way to get the sizes of all tables within a database. It’ll show all tables largest to smallest tables by total size on disk.

    If you notice that a database is growing larger in size, then you will want to know what data is causing the increase. Knowing your largest table(s) on all SQL systems helps you make better decisions overall. For example, with this knowledge, you might want to consider performing a review of indexes or compressing some indexes to save space.

    There are many ways to check the size of a table in MS SQL Server. This post is to help show you how to open the SQL Server Disk Usage by Top Tables Report, which is what I find to be one of the more efficient ways to check table sizes in SQL.

    I have another post if of interest that shows a variety of ways to check table sizes in MSSQL. Below shows a demo of the Disk Usage by Top Tables Report in MSSQL as described.

    Disk Usage by Top Tables Report

    To open this report:-

    1. Open SQL Server Management Studio (SSMS).
    2. Expand Databases.
    3. Right-click the Database and select Reports > Standard Reports > Disk Usage by Top Tables

    Disk Usage by Top Tables SSMS

    The report shows that this database has 2 tables close to 700MB in size, both containing the same number of rows but there are some differences in the indexes.

    Disk Usage by Top Tables Report

    For more random tips for checking disk space in MSSQL, have a look at my Measuring Databases tag.

  • Show Last Backup Times in SQL Server

    Show Last Backup Times in SQL Server

    If you’re running a SQL Server and you care about the data held in it, you should already be backing up the databases. But it’s always surprising the number of times you encounter business-critical databases not being backed up as a DBA!

    When given the opportunity to look at a new SQL Server instance one of the first scripts I would run is to check when the databases were last backed up. I’m likely being asked to look at this server because there’s an issue. Issues need fixing, and before any of my changes are executed I need a point-in-time revert back to in-case I make things worse.

    This blog post is to note a script that’ll return last Full, Differential, and Log backups for all databases on a SQL Server instance.


    Get Last Backup Times in SQL Server

    -- Show last backups on all databases
    SELECT 
      ISNULL(d.[name], bs.[database_name]) AS [Database], d.recovery_model_desc AS [Recovery Model], 
        MAX(CASE WHEN [type] = 'D' THEN bs.backup_finish_date ELSE NULL END) AS [Last Full Backup],
        MAX(CASE WHEN [type] = 'I' THEN bs.backup_finish_date ELSE NULL END) AS [Last Differential Backup],
        MAX(CASE WHEN [type] = 'L' THEN bs.backup_finish_date ELSE NULL END) AS [Last Log Backup]
    FROM 
      sys.databases AS d WITH (NOLOCK)
      LEFT OUTER JOIN msdb.dbo.backupset AS bs WITH (NOLOCK)
      ON bs.[database_name] = d.[name] 
      AND bs.backup_finish_date > GETDATE()- 30
    WHERE d.name <> N'tempdb'
    GROUP BY ISNULL(d.[name], bs.[database_name]), d.recovery_model_desc, d.log_reuse_wait_desc, d.[name] 
    ORDER BY d.recovery_model_desc, d.[name] OPTION (RECOMPILE);

    The above shows my simple wee test database ‘blah’ is the only database that has had a backup on this instance.


  • Why use WHERE 1=1 in SQL Queries

    Why use WHERE 1=1 in SQL Queries

    A common SQL question is, why would anyone use WHERE 1=1 in their queries? And what does it do?

    The WHERE 1=1 condition means WHERE TRUE. It returns the same query result as it would without the WHERE Clause. There is no impact on query execution time.

    This is something you can add to a SQL query for convenience for adding & replacing conditions on the statement. If you have WHERE 1=1 on a SQL query you are writing, all conditions thereafter will contain AND, so it’s easier when commenting out conditions on exploratory SQL queries.

    Example: WHERE 1 Equals 1

    /* where 1=1 example */
    SELECT *
    FROM TABLE
    WHERE 1=1
    --  and column1='blah'
        and column2='more_blah'
    --  and column3 is not null

    You can see this would be easier for commenting out WHERE conditions in the SQL ^

    Example (Extra): Commenting Columns

    This is similar to another SQL querying technique where you have commas before column names, rather than after the column name.

    Again, this might work out well for you when commenting out columns on a work-in-progress SQL query.

    SELECT
         Column1
    --  ,Column2
        ,Column3
        ,Column4
    --  ,Column5
    FROM TABLE

    Personally, I often make use of both of the above techniques when I write SQL queries.

    Convenience is everything when working behind a computer. We have to keep exploring new short keys and any general ways of working to optimize our efficiency. Some things you might not like and won’t adopt, and sometimes GUI is better than CLI. It’s all personal preference, in the end, choose what you are most optimal with.

    If you wonder what would happen if we change the WHERE 1=1 to WHERE 1=2, have a look at my other blog post – Why Use WHERE 1=2 in SQL

  • Creating a Linked Server with a MySQL Database

    Creating a Linked Server with a MySQL Database

    This is my 3rd Linked Server demo post, and this time it’s to a MySQL database.

    Noteworthy weblinks:
    # My Linked Server Blog Posts.
    # Microsoft Docs – Linked Servers.

    Here is a simple diagram of the setup in this post.

    The above was setup similar to what’s included in some of my previous posts:
    # Install SQL Server on Windows.
    # Install MySQL on Windows.
    # Test Connectivity to Remote Servers.

    Once the above is done, this post runs through the following steps to get a Linked Server configured:

    MySQL
    # Create MySQL Linked Server Login.
    SQL Server
    # Configure ODBC Data Source Settings.
    # Create a Linked Server to a MySQL Database.


    Create Linked Server Login on MySQL

    As always, this kind of task can be done using a management tool like MySQL WorkBench or via command.

    First up, I’ll get connected to MySQL via CLI.

    CREATE USER and then GRANTING SELECT capabilities for all tables* within a ‘milk’ database.  The first SQL steps here for me are to create the test database & table.

    -- Create test database & table
    CREATE DATABASE milk;
    USE milk;
    CREATE TABLE animal (id INT, type VARCHAR(50), breed VARCHAR(50), age DATE);
    INSERT INTO animal (1,'cow','white with black spots','2009-10-06');
    INSERT INTO animal VALUES (2,'cow','black with white spots','2011-12-16');
    
    -- Create Linked Server user
    CREATE USER 'linked_server_sql1'@'172.31.1.%' IDENTIFIED BY 'eCh0Ch4rl1E';
    GRANT SELECT ON milk.* TO 'linked_server_sql1'@'172.31.1.%';

    My connections are within the 172.31.1.0 network, so I’m adding in a wildcard (%) for all addresses on this range to be allowed to connect with this login.

    If I want to test this new MySQL login locally, I can create the user using ‘localhost’ too. Below I’m opening the mysql.exe file rather than using the MySQL Command Line Client application which logs in as root.

    Put on the User hat and do what you need to do.

    I only wanted read-only access, which I can confirm with a quick write test.

    That’s our Linked Server MySQL login ready!

    The above can also be done with a tool like MySQL WorkBench too; run the same commands above in a query window or via the Users and Privileges window. The new user account below would be able to connect from any host address.


    Configure ODBC Data Source Settings

    The MySQL ODBC driver download can be found here. Download & install on the SQL Server host machine.

    Note; at the time of writing this the most recent MySQL ODBC Driver version is 8.0.20. I’ve had to install version 8.0.18 as the 2 most recent versions were showing an error message on install.

    Run ODBC Data Sources as Administrator.

    Click into the System DSN tab and click Add.

    Select the MySQL ODBC Unicode driver.

    Enter all details required as shown. If you can see the database names the connection is all good so click OK.


    Create Linked Server to a MySQL Database

    Within SSMS; expand Server Objects, right-click Linked Servers and select New Linked Server.

    The Linked server name at the top of the next window is what you’ll need to include in queries, so choose that wisely.

    Then choose a provider for ODBC and enter the Data Source name which you named within the ODBC driver settings above.

    Enter the MySQL login details as created above within this post.

    I’m leaving all Server Options as defaults.

    Before I hit OK I’m scripting this out to code.

    USE [master]
    GO
    EXEC master.dbo.sp_addlinkedserver 
    	@server = N'MYSQL_SERVER_1', 
    	@srvproduct=N'', 
    	@provider=N'MSDASQL', 
    	@datasrc=N'MySQL_Linked_Server'
    
    USE [master]
    GO
    EXEC master.dbo.sp_addlinkedsrvlogin 
    	@rmtsrvname = N'MYSQL_SERVER_1', 
    	@locallogin = NULL , 
    	@useself = N'False', 
    	@rmtuser = N'linked_server_sql1', 
    	@rmtpassword = N'eCh0Ch4rl1E'
    GO

    When ready, take a breath, then hit OK or execute the SQL.

    Have a look in the SSMS Object Explorer to view the new Linked Server. We should be able to drill into the database & objects we have permission to.

    Now run queries to our MySQL Server using OPENQUERY.


  • Check & Restart SQL Server Services on Linux

    Check & Restart SQL Server Services on Linux

    As of the 2017 Edition of SQL Server we have been able to install SQL Server on Linux. Linux will likely be more of an unfamiliar environment for traditional Microsoft SQL DBAs. This guide should hopefully help you when you need to check the status of SQL Services and Stop/Start services on a Linux host.

    Microsoft Docs have a page on this – Start, stop, and restart SQL Server services on Linux

    The examples provided in this post utilise the systemctl command. Many Linux distributions use systemctl as a tool for managing services including CentOS, Ubuntu, Debian & RedHat.

    Note that the systemctl command is not available in some Linux distributions, including if you are running Linux on WSL (Windows Subsystem for Linux). This is because Ubuntu WSL does not use the systemd init system, which is what systemctl is designed to manage.

    The following should help you check and restart SQL Services on a Linux host:
    # Show Enabled Services on Linux
    # Check Status of SQL Server Service Linux
    # Stop, Start and Restart SQL Server Services on Linux

    Show Enabled Services on Linux

    To show all enabled services on a Linux system, use the following command:

    systemctl list-unit-files | grep enabled
    
    systemctl list unit files enabled

    If your service is not on the list of enabled services, it will not start automatically on the next system reboot. To enable the SQL Server service with systemctl, use the following command : sudo systemctl enable mssql-server

    Check Status of SQL Server Service on Linux

    The systemctl status mssql-server command is used to check the current status of the SQL Server service on your system. This command will display information about the service, including whether its currently active or not.

    sudo systemctl status mssql-server
    
    systemctl SQL Server Status

    If the SQL Service is active, the output of the command will include the text “active (running)” in green. This indicates that the service is currently running and is available to process requests.

    If the service is not active, the output will include the text “inactive (dead)” in red. This indicates that the service is not currently running, and may need to be started or restarted in order to be used.

    Stop, Start or Restart the SQL Server Services on Linux

    To stop, start, or restart the SQL Server service on Linux, you can use the systemctl command.

    sudo systemctl stop mssql-server
    

    To start the service again, use the following command:

    sudo systemctl start mssql-server
    

    To restart the service, use the following command:

    sudo systemctl restart mssql-server
    systemctl Restart SQL Server

    After running any of these commands, it is always a good idea to check the status of the service to make sure that the desired action was completed successfully. You can do this using the systemctl status mssql-server command as shown in the screenshot.

  • Forcing Encryption in SQL Server

    Forcing Encryption in SQL Server

    If you’re ever planning to allow external connections to a SQL Server, one of the first things to ensure is that the data is encrypted at rest and in transit.

    SQL Server has an option where we can force all connections on a SQL Server to be encrypted, which ensures us that we’re achieving encryption for our SQL connectivity.

    This post follows Microsoft Docs – Enable Encrypted Connections to the Database engine. It’s quite a complex piece so a full read of this would be necessary before planning this change.

    # Create Certificate (PowerShell)
    # Import PK to Trusted Root Certificates
    # Import Certificate into SQL Server
    # Force Encryption in SQL Server
    # Verify SQL Server Connectivity is Encrypted


    Create Certificate (PowerShell)

    The certificate must be issued for Server Authentication. The name of the certificate must be the fully qualified domain name (FQDN) of the computer.

    The above is a little note in amongst a bunch of pertinent info, found here; Microsoft Docs – Enable Encrypted Connections – Remarks

    I’m using a New-SelfSignedCertificate for this tutorial and creating it with PowerShell.

    Before running the following PowerShell script, amend .pfk output file location & DNS Names.

    New-SelfSignedCertificate -DnsName lab-sql1.whyte.net -CertStoreLocation cert:\LocalMachine\My -FriendlyName lab-sql1-cert -KeySpec KeyExchange -NotAfter (get-date).AddYears(99)
    $thumbprint = $(Get-ChildItem Cert:\LocalMachine\My).thumbprint
    $Pwd = ConvertTo-SecureString -String "Str0ngePassword1!" -Force -AsPlainText
    Export-PfxCertificate -Cert "Cert:\LocalMachine\My\$thumbprint" -FilePath "C:\temp_certificates\lab-sql1pk.pfx" -Password $Pwd -Force
    PowerShell New-SelfSignedCertificate
    Certificate File Windows Explorer

    Import PK to Trusted Root Certificates

    Open MMC and add the Certificates (Local Computer) Snap-in.

    MMC Local Computer
    MMC Console

    Expand Trusted Root Certification Authorities, right-click & select All Tasks > Import…

    Trusted Root Certificate Import

    Navigate to the .pfx file.

    Import pfx File

    Enter a password & continue.

    Private Key Password

    Finish up the wizard.

    Certificate Import Wizard
    Certificate Import Wizard

    Have a look at the new certificate within MMC.

    MMC

    Import Certificate into SQL Server

    Open SQL Server Configuration Manager, then right-click Protocols for MSSQLSERVER and select Properties.

    SQL Server Protocols

    Open the Certificate tab and you should be able to view & select the new certificate from the drop-down menu.

    Click to Apply & Ok out of the window – I’m doing the Forcing of Encryption separate (below).

    Protocols for MSSQLSERVER

    You’ll get this prompt.

    Any changes made will be saved, however, they will not take effect until the service is stopped and restarted

    Restart the SQL Services from the configuration manager. If your services don’t start back up again, then ensure the service accounts have the appropriate permissions. For this demo, my AD Service Accounts are members of the local Administrators group.  

    SQL Server Configuration Manager

    Force Encryption in SQL Server

    Right click Protocols for MSSQLSERVER, select Properties and within the Flags tab enable the Force Encryption option.

    SQL Server Force Encryption

    Restart the SQL Services.

    SQL Server Service Restart

    Verify SQL Server Connectivity is Encrypted

    Open a local and/or remote query session. You may have to ensure the Encrypt connection & Trust server certificate options are checked.

    SSMS Connection Properties

    Now query sys.dm_exec_connections to check the encryption_option of all SQL connections.

    SELECT * FROM sys.dm_exec_connections
    sys.dm_exec_connections
  • Include Execution Trace Messages in SQL Server Error Logs

    Include Execution Trace Messages in SQL Server Error Logs

    Logs are always important if you’re supporting systems. The SQL Server Agent has always been a heavily used tool in my experience, so writing execution trace messages to the logs might help investigate an issue one day.

    This guide follows the Microsoft Docs page – Write Execution Trace Messages to the SQL Server Agent Error Log

    This option comes with the following warning:

    Because this option can cause the error log to become large, only include execution trace messages in SQL Server Agent error logs when investigating a specific SQL Server Agent problem.

    I’ve never enabled this before and discovered the option today. It does appear to make a big difference in the volume of Error Logs.


    Write Execution Trace Messages to the SQL Agent Error Log

    1. Right-click SQL Server Agent within the SSMS Object Explorer.

    SSMS SQL Agent Properties Selection

    2. Enable the ‘Include execution trace messages’ box.

    SSMS SQL Agent Properties

  • Backing up a SQL Server Database with Encryption

    Backing up a SQL Server Database with Encryption

    To backup a database in SQL Server with Encryption, run the BACKUP DATABASE command with the ENCRYPTION option added to the SQL statement, and specify the valid encryption certificate name.

    Backing up a SQL Server Database with Encryption is the secure way of performing your SQL Server backups. If your MSSQL database backups are off-site and/or you have sensitive customer information stored on them, then you may consider encrypting your database backups.

    Since SQL Server 2012, it has not been possible to create a SQL backup with a password (PASSWORD/MEIAMPASSWORD backup options).

    The demo below guide was done following Microsoft Docs – Create an Encrypted Backup.

    Backup Database with Encryption

    Create a Database Master Key (stored in the database).

    Create a Certificate to use for the database backups (gets stored in the Master Database) – Microsoft Docs; Create Certificate

    SQL Server Create Certificate

    Have a look at the new certificate by querying sys.certificates (think about expiry dates).

    SQL Server Select Sys.Certificates

    Now backup the database.

    -- backup database with encryption mssql
    BACKUP DATABASE [Computer_World] TO DISK = N'C:\Temp_MSSQL_Backups\computer_world_full.bak'  
    WITH COMPRESSION, ENCRYPTION (ALGORITHM = AES_256,SERVER CERTIFICATE = AT_Backup_Cert),STATS
    GO
    SQL Server Backup Database With Encryption

    The database has successfully been backed up with encryption.

    The warning we see is regarding the certificate created prior to the backup.

    Warning: The certificate used for encrypting the database encryption key has not been backed up. You should immediately back up the certificate and the private key associated with the certificate. If the certificate ever becomes unavailable or if you must restore or attach the database on another server, you must have backups of both the certificate and the private key or you will not be able to open the database.

    I have another post to guide through a certificate backup here.

  • Backing up a SQL Server Certificate

    Backing up a SQL Server Certificate

    It’s important to backup SQL Server Certificates, but only if you’re using them really.

    If for example, your SQL Server database backups are encrypted and you need to restore it on another server, then you will need both the certificate and private key that was used.

    This post is a guide on backing up a SQL Server certificate, ensuring we have a copy of the certificate and private keys.


    Backup a SQL Server Certificate

    Check your existing server certificates by querying sys.certificates, you’ll need the certificate name.

    Use Master  
    GO  
    	SELECT name, pvt_key_encryption_type_desc, subject, start_date, expiry_date, key_length
    	FROM sys.certificates
    GO
    SQL Server Select Sys.Certificates

    Backup certificate (Microsoft Docs – Backup Options) – amending file paths & password.

    BACKUP CERTIFICATE AT_Backup_Cert TO FILE ='C:\Temp_MSSQL_Backups\mssql_at_backup_cert.cer'  
          WITH PRIVATE KEY (   
    		FILE ='C:\Temp_MSSQL_Backups\mssql_at_backup_key.pvk',  
    		ENCRYPTION BY PASSWORD ='Str0ng3P4sSw0rd!' ) 

    Then, move those files into a safe space.


  • How to Check What Features are Installed in SQL Server

    How to Check What Features are Installed in SQL Server

    This is a quick guide on how to check which features are installed on a SQL Server.


    Open your SQL Server installation files. You may find them within the Setup Bootstrap folder (“C:\Program Files\Microsoft SQL Server\150\Setup Bootstrap\SQL2019”) or you might already have the ISO handy.

    SQL Server Installation Files

    We can open cmd.exe from the top navigation bar.

    Open CMD from Folder

    Then run the Setup.exe with the /ACTION=RunDiscovery parameter (Microsoft Docs – Installation Parameters).

    SQLSetup RunDiscovery

    The SQL Server discovery report is saved to %ProgramFiles%\MicrosoftSQL Server\nnn\Setup Bootstrap\Log\<last Setup Session>.

    ‘nnn’ is whatever version of SQL Server you have:
    # SQL Server 2012 (110)
    # SQL Server 2014 (120)
    # SQL Server 2016 (130)
    # SQL Server 2016 (130)
    # SQL Server 2017 (140)
    # SQL Server 2019 (150)

    SQLSetup Summary File

    If you’re using PowerShell, Get-Content will work… tab your way through the sub-folders.

    SQLSetup Summary File PowerShell

    The highlighted area above shows only the Database Engine Services are installed of SQL Server 2019 Developer Edition.