En algunos casos, Query Store puede hacer que se produzcan escrituras como efecto de una instrucción select y en la misma sesión.
Esto se puede reproducir de la siguiente manera:
USE master;
GO
CREATE DATABASE [Foo];
ALTER DATABASE [Foo] SET QUERY_STORE (OPERATION_MODE = READ_WRITE,
CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 30),
DATA_FLUSH_INTERVAL_SECONDS = 900,
INTERVAL_LENGTH_MINUTES = 60,
MAX_STORAGE_SIZE_MB = 100,
QUERY_CAPTURE_MODE = ALL,
SIZE_BASED_CLEANUP_MODE = AUTO);
USE Foo;
CREATE TABLE Test (a int, b nvarchar(max));
INSERT INTO Test SELECT 1, 'string';
Cree una sesión de eventos extendidos para monitorear:
CREATE EVENT SESSION [Foo] ON SERVER
ADD EVENT sqlserver.rpc_completed(SET collect_data_stream=(1)
ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.client_pid,sqlserver.database_name,sqlserver.is_system,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.session_server_principal_name,sqlserver.sql_text)
WHERE ([writes]>(0))),
ADD EVENT sqlserver.sql_batch_completed(SET collect_batch_text=(1)
ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.client_pid,sqlserver.database_name,sqlserver.is_system,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.session_server_principal_name,sqlserver.sql_text)
WHERE ([writes]>(0)))
ADD TARGET package0.event_file(SET filename=N'C:\temp\FooActivity2016.xel',max_file_size=(11),max_rollover_files=(999999))
WITH (MAX_MEMORY=32768 KB,EVENT_RETENTION_MODE=ALLOW_MULTIPLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF);
Luego ejecute lo siguiente:
WHILE @@TRANCOUNT > 0 COMMIT
SET IMPLICIT_TRANSACTIONS ON;
SET NOCOUNT ON;
GO
DECLARE @b nvarchar(max);
SELECT @b = b FROM dbo.Test WHERE a = 1;
WAITFOR DELAY '00:00:01.000';
GO 86400
Una transacción implícita puede o no ser necesaria para reproducir esto.
De forma predeterminada, en la parte superior de la próxima hora, el trabajo de recopilación de estadísticas del Almacén de consultas escribirá los datos. Esto parece ocurrir (¿a veces?) Como parte de la primera consulta de usuario ejecutada durante la hora. La sesión de eventos extendidos mostrará algo similar a lo siguiente:
El registro de transacciones muestra las escrituras que se han producido:
USE Foo;
SELECT [Transaction ID], [Begin Time], SPID, Operation,
[Description], [Page ID], [Slot ID], [Parent Transaction ID]
FROM sys.fn_dblog(null,null)
/* Adjust based on contents of your transaction log */
WHERE [Transaction ID] IN ('0000:0000042c', '0000:0000042d', '0000:0000042e')
OR [Parent Transaction ID] IN ('0000:0000042c', '0000:0000042d', '0000:0000042e')
ORDER BY [Current LSN];
La inspección de la página DBCC PAGE
muestra que las escrituras son para sys.plan_persist_runtime_stats_interval
.
USE Foo;
DBCC TRACEON(3604);
DBCC PAGE(5,1,344,1); SELECT
OBJECT_NAME(229575856);
Tenga en cuenta que las entradas de registro muestran tres transacciones anidadas pero solo dos registros de confirmación. En una situación similar en la producción, esto condujo a una biblioteca de cliente posiblemente defectuosa que usó transacciones implícitas comenzando inesperadamente una transacción de escritura, evitando que el registro de transacciones se borre. La biblioteca se escribió para emitir solo una confirmación después de ejecutar una instrucción de actualización, inserción o eliminación, por lo que nunca emitió un comando de confirmación y dejó abierta una transacción de escritura.