暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SQL Server中TempDB管理(版本存储区的一个example)

SQLServer走起 2020-08-01
765

我们从一个例子开始来了解版本存储区。本例中数据库启用RCSI(使用行版本控制的已提交读隔离级别)和SI(快照隔离级别)

当数据库启用了RCSI或者SI时,每当行有更新时就会创建一个行版本。此行版本在版本存储器保存到不需要为止。那么SQL Server什么时候不再保存这个行版本呢?

您可能联想到一些相关的问题,比如,如果不回收(删除)行版本会有什么影响?一次回收一个还是一组行版本?每个用户表都有不同的结构,那么SQL Server是不是分别存储每个表的行版本的?行版本控制的开销大不大?

首先,我们创建一个数据库并开启SI/RCSI

    CREATE DATABASE snapshottest;

    GO



    -- Setting database for snapshot based isolations. AS you can

    -- see that enabling SI/RCSI is a simple DDL operation.

    ALTER DATABASE snapshottest
    SET READ_COMMITTED_SNAPSHOT ON;

    GO



    ALTER DATABASE snapshottest
    SET ALLOW_SNAPSHOT_ISOLATION ON;

    GO



    -- check the snapshot state of the database and it will

    -- show that both SI and RCSI have been enabled.

    SELECT is_read_committed_snapshot_on ,
    snapshot_isolation_state_desc ,
    snapshot_isolation_state
    FROM sys.databases
    WHERE name = 'snapshottest';

    GO



    --create a table with each row > 1000 bytes

    CREATE TABLE t_version
    (
    c1 INT ,
    c2 CHAR(1000)
    );

    GO



    --Load 50 rows. Note,I start the transaction but did not

    --commit it yet.

    BEGIN TRAN;

    DECLARE @i INT;

    SELECT @i = 0;

    WHILE ( @i < 50 )
    BEGIN

    INSERT INTO t_version
    VALUES ( @i, 'hello' );

    SET @i = @i + 1;

    END;

     

    接下来可以通过DMV查看版本存储区,你会发现显示版本存储区行数为0,这是我们实验的第一个结论,插入(Insert)命令不会产生行版本,因为根本没有之前的版本可言(有一个特例使插入产生行版本,我们将稍后讨论)。这同时意味着批量导入也不会产生行版本。

      select COUNT(*) from sys.dm_tran_version_store

      -- Now commit the transaction

      commit

       

      接下来让我们更新表格中的前50行。因为行数据被更新了,SQL Server将复制旧版本进入版本存储区。所以版本存储区中将有50行行版本。

        -- update all the rows in the table

        update t_version set c2 ='test10'



        -- the following statement returns the count of versioned row.

        -- And, for the case here, it will return 50

        select COUNT(*) from sys.dm_tran_version_store

         

        请注意,我们没有使用显式事务,因此这个Update语句是一个隐式事务,并且是这个隐式事务中唯一的语句。同时没有并发的事务需要使用行版本,所以这些行版本会被SQL Server当做垃圾数据处理。如果过几分钟在运行下面语句,就能发现行版本被回收处理了。

         

          -- the following statement returns 0 if run after a minute or so

          select COUNT(*) from sys.dm_tran_version_store

                   SQL Server根据事务状态判断版本是否不再需要,从而决定垃圾处理该版本。

          在最差的情况下,如果有一个长事务正在运行,而且这个长事务要么创建了行版本要么需要用到它,那么这个行版本就不能被删除,版本存储区就会一直增长甚至会用尽TempDb的空间,就像长事务可以用尽事务日志空间一样。

          UPDATE操作一样,如果行被删除也会创建行版本。

           

          资料来自:

          http://blogs.msdn.com/b/sqlserverstorageengine/archive/tags/tempdb/

          http://blogs.msdn.com/b/sqlserverstorageengine/archive/2008/12/31/managing-tempdb-in-sql-server-tempdb-basics-version-store-simple-example.aspx

          文章转载自:

          http://blogs.msdn.com/b/apgcdsd/archive/2012/04/05/sql-server-tempdb-example.aspx

          文章经作者授权转载,版权归原文作者所有

          图片来源于网络,侵权必删!

          文章转载自SQLServer走起,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论