查找设置了哪些 SESSION_CONTEXT 键值对

tan*_*lle 7 sql-server session sql-server-2016

我发现以下查询显示设置了多少会话上下文变量:

SELECT cache_address
      ,name
      ,pages_kb
      ,pages_in_use_kb
      ,entries_count
      ,entries_in_use_count
FROM   sys.dm_os_memory_cache_counters
WHERE  TYPE = 'CACHESTORE_SESSION_CONTEXT';
Run Code Online (Sandbox Code Playgroud)

但现在我想知道设置了哪些键值对SESSION_CONTEXT()——如果有的话。

在对微软网站进行广泛研究后,我没有发现任何相关内容。

提前致谢。

Han*_*non 8

我已经检查了许多与上下文相关的系统视图、函数和存储过程的定义,但找不到任何涉及会话上下文变量的详细信息。

例如,sys.dm_os_memory_cache_counters您问题中引用的动态管理视图具有以下定义:

CREATE VIEW sys.dm_os_memory_cache_counters AS
    SELECT *
    FROM OpenRowSet(TABLE SYSMEMORYCACHECOUNTERS)
Run Code Online (Sandbox Code Playgroud)

SYSMEMORYCACHECOUNTERS系统表的定义不是直接可见的,即使从专用管理员连接或 DAC也是如此,因此这是一个死胡同。

我使用此查询来查找与上下文相关的系统对象:

;WITH types AS
(
    SELECT v.xType
        , v.TypeDescription
    FROM (VALUES 
          ('AF', 'Aggregate function (CLR)')
        , ('C', 'CHECK constraint')
        , ('D', 'Default or DEFAULT constraint')
        , ('F', 'FOREIGN KEY constraint')
        , ('L', 'Log')
        , ('FN', 'Scalar function')
        , ('FS', 'Assembly (CLR) scalar-function')
        , ('FT', 'Assembly (CLR) table-valued function')
        , ('IF', 'In-lined table-function')
        , ('IT', 'Internal table')
        , ('P', 'Stored procedure')
        , ('PC', 'Assembly (CLR) stored-procedure')
        , ('PK', 'PRIMARY KEY constraint (type is K)')
        , ('RF', 'Replication filter stored procedure')
        , ('S', 'System table')
        , ('SN', 'Synonym')
        , ('SQ', 'Service queue')
        , ('TA', 'Assembly (CLR) DML trigger')
        , ('TF', 'Table function')
        , ('TR', 'SQL DML Trigger')
        , ('TT', 'Table type')
        , ('U', 'User table')
        , ('UQ', 'UNIQUE constraint (type is K)')
        , ('V', 'View')
        , ('X', 'Extended stored procedure')
    )v(xType,TypeDescription)
)
, sc AS
(
    SELECT so.id
        , ColumnList = STUFF(((SELECT ', ' + sc.name FROM sys.syscolumns sc WHERE sc.id = so.id FOR XML PATH(''))), 1, 2, '')
    FROM sys.sysobjects so
)
SELECT t.TypeDescription
    , so.name
    --, sc.ColumnList
FROM sys.sysobjects so
    LEFT JOIN sc ON so.id = sc.id
    LEFT JOIN types t ON so.xtype = t.xType
WHERE so.name LIKE '%context%'
    OR sc.ColumnList LIKE '%context%'
ORDER BY t.TypeDescription
    , so.name;
Run Code Online (Sandbox Code Playgroud)

在 SQL Server 2016 中,查询的结果是:

?????????????????????????????????????????????????????? ????????????????????????
? 扩展存储过程 ? sp_reset_session_context ?
?????????????????????????????????????????????????????? ????????????????????????
? 扩展存储过程 ? sp_set_session_context ?
? 扩展存储过程 ? sp_try_set_session_context ?
? 内联表函数 ? dm_exec_cursors ?
? 内联表函数 ? fn_dblog ?
? 内联表函数 ? fn_dblog_xtp ?
? 内联表函数 ? fn_dump_dblog ?
? 内联表函数 ? fn_dump_dblog_xtp ?
? 内表 ? plan_persist_context_settings ?
? 内表 ? plan_persist_query ?
? 存储过程 ? sp_MSadd_repl_error ?
? 存储过程 ? sp_MSsetcontext_bypasswholeddleventbit ?
? 存储过程 ? sp_MSsetcontext_replagent ?
? 存储过程 ? sp_sqlagent_verify_database_context ?
? 看法 ?dm_db_task_space_usage ?
? 看法 ?dm_exec_query_stats ?
? 看法 ?dm_exec_requests ?
? 看法 ?dm_exec_sessions ?
? 看法 ?dm_filestream_file_io_handles ?
? 看法 ?dm_filestream_file_io_requests ?
? 看法 ?dm_filestream_non_transacted_handles ?
? 看法 ?dm_os_memory_cache_entries ?
? 看法 ?dm_os_schedulers ?
? 看法 ?dm_os_tasks ?
? 看法 ?dm_os_threads ?
? 看法 ?dm_os_waiting_tasks ?
? 看法 ?dm_os_workers ?
? 看法 ?dm_tran_locks ?
? 看法 ?查询上下文设置?
? 看法 ?query_store_query ?
? 看法 ?系统进程?
?????????????????????????????????????????????????????? ????????????????????????
  • 扩展存储过程在各种 SQL Server DLL 中实现,如果不进行逆向工程就不容易查看;出于这个问题的目的,我认为它们是黑匣子。

  • sys.dm_exec_cursors,虽然很明显与我们感兴趣的“上下文”没有直接关系,但具有以下定义:

    CREATE FUNCTION sys.dm_exec_cursors (@spid int)
    RETURNS table
    AS
        RETURN SELECT *
        FROM OpenRowSet(TABLE DM_EXEC_CURSORS, @spid)
    
    Run Code Online (Sandbox Code Playgroud)

    正如你在上面看到的,这个函数实际上只是一个围绕 system-table 的包装器DM_EXEC_CURSORS;像这样的系统表的定义再次在 SQL Server 引擎内部实现,不容易检查。

    上面查询输出中列出的其他内联表函数都使用相同的OpenRowSet(TABLE ...)功能。

  • sys.sp_MSsetcontext_bypasswholeddleventbit外观耐人寻味:

    create procedure sys.sp_MSsetcontext_bypasswholeddleventbit @onoff bit -- 1 to turn on
    as
    begin
        declare @cur_context varbinary(128)
        declare @cur_context_first_byte binary(1)
        declare @bitmask tinyint
        declare @retcode int
    
        /*
        ** Security Check
        */
        EXEC @retcode = sys.sp_MSreplcheck_subscribe_withddladmin
        IF @@ERROR <> 0 or @retcode <> 0
            return (1)
    
        -- bit to set: snapshot=1, logreader=2, distrib=4, merge=8, 
        -- replication_agent=16, merge_identityrange_alterconstraint=32
        -- merge_bypasswholeddleventbit=64
        if @onoff=1
            set @bitmask=64
        else
            set @bitmask=255-64
    
        -- get the current context_info. remember we only want to modify a bit without changing the rest of the info
        select @cur_context = isnull(context_info(),0x00)
    
        -- get the first byte out. the replication agent flags are set in the first byte.
        select @cur_context_first_byte = substring(@cur_context, 1, 1)
        -- set the appropriate bit in this one byte (leaving other bits unchanged).
        if @onoff=1
            select @cur_context_first_byte = (convert(tinyint,@cur_context_first_byte) | @bitmask)
        else
            select @cur_context_first_byte = (convert(tinyint,@cur_context_first_byte) & @bitmask)
    
        -- replace the first byte of the 128 byte binary variable, so that now it has the appropriate bit set.
        select @cur_context = convert(varbinary(128),stuff (@cur_context, 1, 1, @cur_context_first_byte))
        -- set the context_info again with the new binary(128) value.
        set context_info @cur_context
    
        if @@error <> 0
            return 1
    
        return 0
    end
    
    Run Code Online (Sandbox Code Playgroud)

    但是,它仅使用SET CONTEXT_INFOCONTEXT_INFO()来检查和修改上下文信息。这里没有运气。

  • 也许sys.query_context_settings含有一些黄金?不:

    CREATE VIEW sys.query_context_settings AS
        SELECT
            context_settings_id,
            CONVERT(varbinary(8), set_options) AS 'set_options',
            language_id,
            date_format,
            date_first,
            CONVERT(varbinary(2), status) AS 'status',
            required_cursor_options,
            acceptable_cursor_options,
            merge_action_type,
            default_schema_id,
            is_replication_specific,
            CONVERT(varbinary(1), status2) AS 'is_contained'
        FROM (
            SELECT * FROM sys.plan_persist_context_settings
            UNION ALL
            SELECT TOP 0 * FROM OpenRowSet(TABLE QUERY_STORE_CONTEXT_SETTINGS)
        ) AS ContextSettings
    
    Run Code Online (Sandbox Code Playgroud)

我还通过以下查询检查了 SQL 模块的定义,例如存储过程、函数等:

SELECT so.name
    , asm.definition
FROM sys.all_sql_modules asm
    INNER JOIN sys.sysobjects so ON asm.object_id = so.id
WHERE asm.definition LIKE '%context%'
ORDER BY so.name;
Run Code Online (Sandbox Code Playgroud)

该查询中列出的项目也不包含任何相关内容。

简而言之,我找不到与会话上下文相关的任何内容。我希望这是设计使然,因为会话上下文可以很容易地用于在会话期间存储敏感数据。