Bernd Jungbluth: Seminar - SQL Server Integration Services

Es gibt einen neuen Termin für das Seminar SQL Server Integration Services: 17. Juni 2014 im Hotel Best Western Premier Bellevue Rheinhotel in Boppard am Rhein SQL Server Integration Services - kurz SSIS - wird in erster Linie im Segment Business Intelligence zur Konsolidierung und Integration von Daten aus den unterschiedlichsten Datenquellen verwendet, um so [...]

Tillmann Eitelberg: Power Query team up with SSIS

Power Query is one of my favorite tools of the Power BI suite, the self-service BI offering of Microsoft. The strategy of Microsoft self-service BI (the very very short version) is to empower people to to analyze and report on data without the direct evolvement of IT-professionals. With Power Pivot Microsoft offers in the self-service […]

Christoph Muthmann: OneNote Mac - The Song

Microsoft: This is a parody of One Day More from Les Miserables celebrating our recent OneNote Mac launch on 3/17/2014. It was recorded and produced by the OneNote Engineering Team. To get OneNote for free and learn more: www.onenote.com

CMU: Thanks to Microsoft! It's great to see the people behind! Thanks to Torsten, who showed me the first steps in OneNote.

Christoph Muthmann: SQLPodcast

Bestimmt kennen viele Leser diese Seite noch nicht, aber wer Zeit und Lust hat mal etwas über SQL Server Themen zu hören statt zu lesen, ist hier gut bedient.

Full story »

Christoph Muthmann: Failed to create kernel event for collection set

Gelegentlich kommt es vor, dass die Datensammlung auf unserem Cluster (SQL Server 2012 SP1 CU #7) ihren Dienst einstellt. In den Protokollen findet man dann z. B. diese Meldung: Cannot create a file when that file already exists.

Full story »

Uwe Ricken: Löschen von Daten aus Heap gibt Datenseiten nicht frei

Wenn alle Datensätze aus einem Heap gelöscht werden, mag man meinen, dass Microsoft SQL Server nach dem Löschvorgang auch die allozierten Datenseiten wieder frei gibt. Das macht der Microsoft SQL Server jedoch nur, wenn bestimmte Voraussetzungen vorhanden sind wie der nachfolgende Artikel zeigt.

Was ist ein Heap

Unter einem HEAP versteht man eine Relation, die kein Clustered Index ist. Daten werden in einem HEAP nicht nach einer spezifizierten Ordnung gespeichert! Ebenso wenig verfügt ein Heap über ein definiertes Ordnungskriterium. Heaps werden in Datenbanken verwendet, um möglichst effizient Daten in Staging-Tabellen einzufügen um sie anschließend weiter zu verarbeiten (siehe “Neue Daten in einen Heap eintragen…”).

Testumgebung

Zunächst wird ein Heap erstellt, der mit 100 Datensätzen gefüllt wird. Anschließend wird die interne Struktur dieser Relation untersucht.

SET NOCOUNT ON;
GO
 
CREATE TABLE dbo.heap
(
    Id    int         NOT NULL IDENTITY (1, 1),
    c1    char(1000)  NOT NULL DEFAULT ('A')
);
GO
 
-- Insert 100 records and check the number of pages
INSERT INTO dbo.heap DEFAULT VALUES
GO 100

Die erste Frage ist natürlich, wie viele Datenseiten die Relation beim Befüllen alloziert hat. Das kann mit sys.dm_db_partition_stats herausgefunden werden:



-- Partition information
SELECT  index_id,
        in_row_data_page_count,
        in_row_used_page_count,
        in_row_reserved_page_count
FROM    sys.dm_db_partition_stats
WHERE   object_id = OBJECT_ID('dbo.heap');

sys.dm_db_partition_stats_01


Wie die obige Abbildung zeigt, belegt die Relation dbo.Heap 22 Datenseiten im Leaf. Das die Gesamtzahl der belegten Datenseiten höher ist, errechnet sich aus ALLEN von der Relation belegten Datenseiten. Ein Heap besitzt neben den reinen Datenseiten im Leaf die IAM-Seite (Index Allocation Map). Die Anzahl der reservierten Datenseiten lässt sich relativ leicht errechnen, wenn man weiß, dass Microsoft SQL Server beim Speichern von Daten in einer Tabelle die ersten 8 Datenseiten (Leaf) in einem Mixed Extent verwaltet. Alle weiteren Belegungen erfolgen ab der 9. Datenseite immer in einem Extent (entspricht 8 Datenseiten).


Nun werden Daten aus der Relation dbo.Heap gelöscht und erneut geprüft, wie sich die Datenstruktur verhält! Um das Transaktionsprotokoll besser analysieren zu können, wird die Operation in einer benannten Transaktion ausgeführt.



BEGIN TRANSACTION DeleteRecords
DELETE dbo.heap;
COMMIT TRANSACTION DeleteRecords

Nachdem alle Datensätze aus der Relation entfernt wurden, wird erneut überprüft, welche Datenseiten durch die Relation in der Datenbank alloziert sind. Nach dem allgemeinen Verständnis sollte nun nur noch die IAM-Seite vorhanden sein. Führt man die weiter oben beschriebene Prüfung in sys.dm_db_partition_stats erneut aus, wird man feststellen, dass immer noch alle Datenseiten von der Relation belegt sind. Ein Blick in das Transaktionsprotokoll zeigt, dass die Datenseiten NICHT freigegeben worden sind.



SELECT  [Current LSN],
        Operation,
        Context,
        AllocUnitName,
        [Page ID],
        [Slot ID],
        [Lock Information]
FROM    sys.fn_dblog(NULL, NULL) WHERE [Current LSN] LIKE
(
    SELECT  LEFT([Current LSN], LEN([Current LSN]) - 5) + '%'
    FROM    sys.fn_dblog(NULL, NULL)
    WHERE   [Transaction Name] = 'DeleteRecords'
)
ORDER BY
        [Current LSN] ASC;

fn_dblog_01




Der Auszug aus dem Transaktionsprotokoll zeigt, dass Datensätze von den Datenseiten gelöscht werden [LOP_DELETE_ROWS] aber die Datenseiten nicht entfernt werden sondern lediglich auf der PFS protokolliert wird, wie viel Platz (in Prozent) auf den allozierten Datenseiten verfügbar ist (Siehe auch “Wie alloziert Microsoft SQL Server freien Speicher in einem HEAP?


Warum werden die Datenseiten nicht wieder freigegeben?


Die ideale Erklärung hat der von mir sehr geschätzte Kollege Hugo Kornelis (Blog | Twitter | LinkedIn) dazu gegeben. Führt eine andere Session (SELECT-Session) einen Table Scan aus, während eine Delete-Operation (DELETE-Session) initiiert wird, hat die SELECT-Session bereits die IAM-Datenseite abgerufen. Auf der IAM-Datenseite werden Informationen zu den allozierten Datenseiten im Leaf gespeichert.


DBCC_PAGE_IAM_01


Die Abbildung zeigt die ersten 8 Datenseiten, die in einem Mixed Extent gespeichert sind. Die Datenseiten, Alle anderen Datenseiten werden in Extents (8 zusammengehörige Datenseiten) gespeichert.


In dem oben beschriebenen Szenario kann es nun zu zwei Problemsituationen kommen:



  • Die SELECT-Session hat einen Shared Lock auf der IAM-Datenseite. In diesem Fall muss die DELETE-Session warten, bis der Shared Lock aufgehoben wird um anschließend einen Exclusive Lock zu setzen.

  • Die SELECT-Session hat keine Sperre auf der IAM-Datenseite und die DELETE-Session löscht die Zuordnungen der Datenseiten. Nachdem die Datenseiten wieder an das System (Datenbank) zurück gegeben wurden, werden sie von einem anderen Objekt alloziert. Da die SELECT-Session die vorherige Zuordnung aus der IAM gelesen hat, wird sie die Datenseiten lesen wollen. Was dann passiert, dürfte jedem klar sein.

Aus diesem Grund werden die Datenseiten von Heaps, die nicht exklusiv gesperrt sind, nicht wieder freigegeben; eine gute Entscheidung, wie man sicherlich nachvollziehen kann. Der Beweis für diese Aussage wird mit dem nachfolgenden Skript geführt. Nachdem die Relation erneut mit 100 Datenseiten gefüllt wurde, besteht die folgende Situation / Struktur:



-- Partition information
SELECT  index_id,
        in_row_data_page_count,
        in_row_used_page_count,
        in_row_reserved_page_count
FROM    sys.dm_db_partition_stats
WHERE   object_id = OBJECT_ID('dbo.heap');
 
-- Page structure
SELECT  allocated_page_iam_page_id,
        allocated_page_page_id
FROM sys.dm_db_database_page_allocations
(
    db_id(),
    OBJECT_ID('dbo.heap', 'U'),
    NULL,
    NULL,
    'DETAILED'
)
ORDER BY
    is_iam_page DESC,
    allocated_page_page_id;
GO


ALL_SITUATION_BEFORE_TABLOCK


Es werden erneut 23 Datenseiten alloziert. Seite 411 ist die IAM-Datenseite während die eigentlichen Daten der Relation auf 22 Datenseiten im LEAF-Bereich gespeichert werden. Die ersten 8 Datenseiten werden auf Mixed Extents gespeichert; alle weiteren Datensätze werden auf Exclusive Extents gespeichert.



BEGIN TRANSACTION DeleteRecords
DELETE dbo.heap WITH (TABLOCK);
COMMIT TRANSACTION DeleteRecords
GO
 
SELECT  [Current LSN],
        Operation,
        Context,
        AllocUnitName,
        [Page ID],
        [Slot ID],
        [Lock Information]
FROM    sys.fn_dblog(NULL, NULL) WHERE [Current LSN] LIKE
(
    SELECT LEFT([Current LSN], LEN([Current LSN]) - 5) + '%'
    FROM   sys.fn_dblog(NULL, NULL)
    WHERE  [Transaction Name] = 'DeleteRecords'
)
ORDER BY
        [Current LSN] ASC;
GO


Das Löschen der Daten in der Relation geschieht nun mit einer exklusiven Tabellensperre. Interessant ist nun, welche Änderungen sich aus dieser Tabellensperre im Transaktionsprotokoll ergeben – das zeigt die nächste Abbildung:


fn_dblog_02


Es soll nicht jede Zeile dokumentiert werden aber auffällig sind besonders die Zeilen 11 – 16. Bei Löschen der Datensätze passiert nun Folgendes:



  • Zunächst wird die PFS (Page Free Space) aktualisiert, da zuvor Datensätze von der Datenseite gelöscht wurden (Zeile 11).

  • Die betroffene Datenseite (0x019A = 410) wird aktualisiert, nachdem alle Datensätze entfernt worden sind. (Zeile 12).

  • Die Datenseite 410 ist nun leer und dieser Umstand wird von Microsoft SQL Server dazu verwendet, die IAM-Datenseite ebenfalls zu aktualisieren. Dort wird die Datenseite als “not allocated” gekennzeichnet. (Zeile 13)

  • Die Datenseite 410 wurde auf einem Mixed Extent gespeichert. Da die Datenseite nun wieder an die Datenbank für weitere Aufgaben zurück gegeben wird, muss SGAM (Shared Global Allocation Map) ebenfalls aktualisiert werden. Das Bit für die Zuordnung der Datenseite (Verwaltung) in SGAM wird aktualisiert und die Datenseite ist offiziell nicht mehr aktiviert (Zeile 14)

  • Auch die PFS benötigt diese Informationen, da die Datenseite nun wieder für die Datenbank zur Verfügung steht (Zeile 15)

  • Zum Schluss wird die Anzahl der Datenseiten aktualisiert (HOBT steht für Heap Or B-Tree)

Wenn die Operation abgeschlossen ist, werden weitere Datenseiten gelöscht.


Zusammenfassung


Es ist immer wieder interessant, zu sehen, wie sehr sich Heaps von Clustered Indexen unterscheiden. Um die Datenseiten eines Heaps endgültig wieder als Ressource an die Datenbank zurück zu geben, muss die Tabelle exklusiv gesperrt sein. In einem Clustered Index werden die Datenseiten unmittelbar freigegeben, sobald keine Datensätze mehr auf der Seite gespeichert werden. Das wäre aber auf jeden Fall einen weiteren Artikel wert.


Herzlichen Dank fürs Lesen!

Andreas Wolter: New Extended Events for Tracing in SQL Server 2014

Neue “Erweiterte Ereignisse” (XEvents) für Tracing in SQL Server 2014

(de)
Dieser Artikel enthält eine Liste der neuen Erweiterte Ereignisse (“Extended Events”), dem Tracing Framework in SQL Server in dem neuen 2014 Release.

Zunächst gibt es 3 neue Pakete („Packages“), die alle zu der neuen Arbeitsspeicher(„In-Memory“) -OLTP Engine: XTP, aufgeteilt auf 3 DLLs:

(en)
This article contains a list of new Extended Events, the tracing framework in SQL Server in the new 2014 release.

To begin with there are 3 new packages, all belonging to the new In-Memory OLTP Engine: XTP, split up into 3 dlls:

 

Package

description

Module name

XtpRuntime

Extended events for the XTP Runtime

{InstanceDir}\MSSQL\Binn\
hkruntime.dll

XtpEngine

Extended events for the XTP Engine

{InstanceDir}\MSSQL\Binn\
hkengine.dll

XtpCompile

Extended events for the XTP Compile

{InstanceDir}\MSSQL\Binn\
hkcompile.dll

 

Die Anzahl der Extended Events ist von 625 in SQL Server 2012 (SP1) auf 870 in SQL Server 2014 (RTM) angestiegen. Das sind 245 neue Events! – Reichlich Möglichkeiten, in Internas einzutauchen :-)
2 Events sind umbenannt worden:

recovery_incremental_checkpoint in

recovery_indirect_checkpoint

und hekaton_slow_param_passing in

natively_compiled_proc_slow_parameter_passing

Ja, richtig gelesen. Es gab bereits im SQL Server 2012 eine Anzahl an Events für die XTP Engine. Es kommt recht häufig vor, dass man Bits von zukünftigen Entwicklungen in der aktuellen Release findet.

Nebenbei: SQL Trace wurde nicht im geringsten angefasst. Die Anzahl von SQL Trace Events bleibt mit 180 seit SQL Server 2008 stabil. – Here ist ein Überblick von Extended Events gegen SQL Trace Events in den verschiedenen SQL Server Versionen: Extended Events vs SQL Trace im Vergleich – oder warum SQL Trace & Profiler einfach von gestern sind :-)

Weiter zu XEvents: es gibt keine neuen Prädikate, aber eine Anzahl neuer Maps, was natürlich nicht überrascht bei der Menge neuer Events.
Targets, Actions, Typen und Session Optionen  sind unverändert.

Und hier ist die Liste der neuen Extended Events:

The number of Extended Events increased from 625 in SQL Server 2012 (SP1) to 870 in SQL Server 2014 (RTM). That makes 245 new events! – Plenty of opportunities to look into internals :-)
2 events have been renamed:

recovery_incremental_checkpoint into

recovery_indirect_checkpoint

and hekaton_slow_param_passing into

natively_compiled_proc_slow_parameter_passing

Yes, you read correctly. There have already been a couple of events for the new XTP engine within SQL Server 2012. It’s quite common that you can find bits of future developments within the current release.

By the way: SQL Trace has not been touched by the slightest bit. The number of SQL Trace events stays at 180 since SQL Server 2008. – here you find an overview of the number of Extended Events vs SQL Trace events in the various SQL Server versions: Comparing Extended Events vs SQL Trace – or why SQL Trace & Profiler are just a thing of the past :-)

Continuing with XEvents: There are no new predicates, but a couple more maps, which is of course not surprisingly considering the amount of new events.
Targets, actions, types and session options are unchanged.

And here is the list of all new extended events:

 




Package
name
Event name Description
qds query_store_async_shutdown_failed Fired when query store encounters an error during async query store shutdown
qds query_store_background_cleanup_task_failed Fired if the background task for cleanup of QDS stale data is not completed successfully
qds query_store_background_task_creation_failed Fired if the background task for QDS data persistence could not be created
qds query_store_background_task_initialization_failed Fired if the background task for QDS data persistence could not be initialized
qds query_store_background_task_persist_failed Fired if the background task for QDS data persistence is not completed successfully
qds query_store_begin_persist_runtime_stat Fired immediately before current runtime statistics for a query plan is persisted to the database.
qds query_store_bloom_filter_false_positive Fired if the Bloom filter for QDS statement texts gives a false positive result
qds query_store_check_consistency_init_failed Fired when check consistency task fails during initialization
qds query_store_database_initialization_failed Fired if initialization of the Query Store for database has failed. The Query Store will be disabled for this database
qds query_store_db_cleanup__finished Fired if cleanup of QDS stale data finished for particular database.
qds query_store_db_cleanup__started Fired if cleanup of QDS stale data started for particular database.
qds query_store_disk_size_check_failed Fired when a check against Query Store on-disk size limit fails
qds query_store_disk_size_info Fired when a check against QDS on-disk size is performed
qds query_store_execution_runtime_info Fired when runtime information is sent to the query store.
qds query_store_execution_runtime_info_discarded Fired when runtime information sent to the query store is discarded.
qds query_store_execution_runtime_info_evicted Fired when runtime information sent to the query store is evicted.
qds query_store_flush_failed Fired when query store failed to flush dirty data
qds query_store_loaded Fired when query store is loaded
qds query_store_notify_dirty_shutdown_on_partition_startup Fired when previous instance of query store for the partition is shutdown by force in order to allow creation of a new instance
qds query_store_notify_force_failure_failed Fired when query store failed to notify force failure
qds query_store_persist_task_init_failed Fired when persist task fails during initialization
qds query_store_plan_forcing_failed Occurs when forcing of plan from qds fail
qds query_store_plan_persistence_failure Fired if there's a failure to persist plan
qds query_store_plan_removal Fired when plan is removed
qds query_store_query_persistence_failure Fired if there's a failure to persist query
qds query_store_read_write_failed Fired if the read/write to Query Store internal tables failed
qds query_store_statement_not_found Fired in case when statement couldn't be found due to race condition or ambiguous user request.
qds query_store_unloaded Fired when query store is unloaded from memory
sqlos nonpreemptive_long_syncio record long sync io operation in nonpreemptive worker
sqlos stuck_dispatcher_callback_executed Stuck dispatcher callback executed
sqlos wait_completed Occurs when there is a wait completed on a SQLOS controlled resource.  Use this event to track wait completion.
sqlserver after_natively_compiled_proc_entry_removal_on_drop Fired after the procedure cache entry is flushed when dropping a natively compiled procedure.
sqlserver availability_replica_state Occurs when the Availability Replica is starting or shutting down.
sqlserver before_natively_compiled_proc_entry_removal_on_drop Fired before the procedure cache entry is flushed when dropping a natively compiled procedure.
sqlserver before_redo_lsn_update Occurs just prior to the update of the EOL LSN
sqlserver buffer_pool_eviction_thresholds_recalculated Lazywriter and/or worker clock has wrapped the BUF array and thresholds are re-calculated.
sqlserver buffer_pool_extension_pages_evicted Page is evicted from the buffer pool extension cache.
sqlserver buffer_pool_extension_pages_read Page is read from the buffer pool extension cache.
sqlserver buffer_pool_extension_pages_written Page or contiguous set of pages evicted into the buffer pool extension cache.
sqlserver check_phase_tracing Occurs when DBCC CHECK enters a new phase of the checking. Use this event to trace the phases of DBCC CHECK process.
sqlserver check_thread_message_statistics Occurs when a phase of DBCC CHECK is finished. Use this event to collect the number of messages a DBCC CHECK thread has sent or received.
sqlserver check_thread_page_io_statistics Occurs when a phase of DBCC CHECK is finished. Use this event to collect the number of logical, physical, and read-ahead IOs a DBCC CHECK thread has performed.
sqlserver check_thread_page_latch_statistics Occurs when a phase of DBCC CHECK is finished. Use This event to collect the number and time of page latch and IO latch waits.
sqlserver clustered_columnstore_index_rebuild Occurs when clustered index on the table was rebuilt. This event is raised three times for ALTER index rebuild operation on CCSI. The event is raised when the operation takes lock on index rebuild resource, when lock is taken on the table and when S lock on the table is upgraded to SCH_M lock to switch indexes in metadata.
sqlserver column_store_code_coverage Code coverage Xevent for columnstore code.
sqlserver column_store_index_build_low_memory Occurs when Storage Engine detects low memory condition and the rowgroup size is reduced.
sqlserver column_store_index_build_process_segment Occurs when a segment is processed
sqlserver column_store_index_build_throttle Shows the statistics of columnstore index build parallelism throttling
sqlserver columnstore_tuple_mover_begin_compress Occurs when column store tuple mover starts compressing a deltastore.
sqlserver columnstore_tuple_mover_end_compress Occurs when column store tuple mover is done compressing a deltastore.
sqlserver database_xml_deadlock_report Produces a deadlock report for a victim, with information scoped to the victim's database.
sqlserver db_lock_acquired_from_cache Occurs when a DB lock is acquired from the XactWorkspace DB lock cache.
sqlserver db_lock_released_from_cache Occurs when a DB lock is released from the XactWorkspace DB lock cache.
sqlserver ddl_with_wait_at_low_priority A DDL statement was executed using the WAIT_AT_LOW_PRIORITY options
sqlserver diag_quantum_end Occurs when the diag is notified of quantum end.
sqlserver dyn_throttle_checkpoint Occurs when checkpointing has been dynamically throttled with a new Checkpoint rate.
sqlserver feature_extension Occurs when received and parses data for a feature in feature extension.
sqlserver file_handle_in_use Fired when a file handle we're trying to delete is in use and we don't expect it to be. The typical response is dumping all the handles in the system via SysInternals HANDLE.EXE
sqlserver file_read_enqueued File read enqueued
sqlserver file_read_throttled File read throttled
sqlserver file_write_enqueued File write enqueued
sqlserver file_write_throttled File write throttled
sqlserver ghost_cleanup_task_packet_enqueue A task packet is enqueued
sqlserver ghost_cleanup_task_process_packet A task packet is dequeued and processed
sqlserver ghost_cleanup_task_process_pages_for_db_packet Purge the pages that contain ghost records found in a database
sqlserver ghost_cleanup_task_start Ghost cleanup task start
sqlserver ghost_cleanup_task_suspend Ghost cleanup task suspend
sqlserver hadr_tds_synchronizer_payload_skip Hadron Tds Listener Synchronizer skipped a listener payload because there were no changes since the previous payload.
sqlserver lock_request_priority_state The priority state of a lock request
sqlserver log_cache_write_block Writing a log block to the log cache
sqlserver metadata_ddl_add_column Occurs when an ALTER TABLE ADD column operation is updating base index.
sqlserver metadata_ddl_alter_column Occurs when an ALTER TABLE ALTER column operation is updating base index.
sqlserver metadata_ddl_drop_column Occurs when an ALTER TABLE DROP column operation is updating base index.
sqlserver mixed_extent_activation Track mixed extent activation and deactivation operations.
sqlserver mixed_extent_allocation Track mixed extent allocation operations
sqlserver mixed_extent_deallocation Track mixed extent deallocation operations.
sqlserver mixed_page_allocation Track mixed page allocation operations
sqlserver mixed_page_deallocation Track mixed page allocation operations
sqlserver mixed_page_scan_file Track the activity of SGAM scans for mixed page allocation
sqlserver mixed_page_scan_page Track the activity of SGAM scans for mixed page allocation
sqlserver mixed_page_skipextent Track the activity of SGAM scans for mixed page allocation
sqlserver natively_compiled_proc_execution_started Fired before a natively compiled procedure is executed.
sqlserver natively_compiled_proc_slow_parameter_passing Occurs when a Hekaton procedure call dispatch goes to slow parameter passing code path
sqlserver process_killed_by_abort_blockers A process is killed by an ABORT = BLOCKERS DDL statement
sqlserver query_execution_batch_hash_aggregation_finished Occurs at the end of batch hash aggregation.
sqlserver query_execution_batch_hash_children_reversed Occurs each time when hash join reverses build and probe side while processing data spilled to disk.
sqlserver query_execution_batch_hash_join_spilled Occurs each time when hash join spills some data to disk in batch processing.
sqlserver query_optimizer_estimate_cardinality Occurs when the query optimizer estimates cardinality on a relational expression.
sqlserver query_optimizer_force_both_cardinality_estimation_behaviors Both traceflags 2312 and 9481 were enabled, attempting to force both old and new cardinality estimation behaviors at the same time. The traceflags were ignored. Disable one or both of the traceflags.
sqlserver query_store_failed_to_capture_query Fired if the Query Store failed to capture query. The Query Store will not track statistics for this query
sqlserver query_store_failed_to_load_forced_plan Fired if the query failed to load forced plan from QDS. Forcing policy will not be applied
sqlserver query_store_persist_on_shutdown_failed Occurs when SQL Server fails to store dirty entries in Query Store on database shutdown.
sqlserver recovery_indirect_checkpoint Chose to enqueue an indirect checkpoint as we are near our recovery target
sqlserver remove_database_cache Remove database cache
sqlserver server_max_workers Occurs when a request enqueue fails because a worker was not guaranteed.
sqlserver session_recoverable_state_change Occurs when the server determines a state change in term of session recovery on a connectionresilency-enabled connection.
sqlserver sql_transaction_commit_single_phase Occurs when a sql transaction is committed with single phase commit.
sqlserver xfcb_blob_properties_obtained Windows Azure Storage blob property is obtained from response header.
sqlserver xfcb_failed_request Failed to complete a request to Windows Azure Storage.
sqlserver xfcb_header_obtained Response header is obtained from request to Windows Azure Storage.
sqlserver xfcb_read_complete Read complete from Windows Azure Storage response.
sqlserver xfcb_request_opened A request is opened to Windows Azure Storage.
sqlserver xfcb_send_complete Request send to Windows Azure Storage is complete.
sqlserver xfcb_write_complete Request send to Windows Azure Storage is complete.
sqlserver xtp_create_procedure Occurs at start of XTP procedure creation.
sqlserver xtp_create_table Occurs at start of XTP table creation.
sqlserver xtp_db_page_allocation_allowed Indicates that page allocations for the database are allowed.
sqlserver xtp_db_page_allocation_disallowed Indicates that page allocations for the database are disallowed due to memory pressure.
sqlserver xtp_deploy_done Occurs at completion of XTP object deployment.
sqlserver xtp_matgen Occurs at start of MAT generation.
sqlserver xtp_offline_checkpoint_scan_start Fired by XTP offline checkpoint when the checkpoint thread begins.
sqlserver xtp_offline_checkpoint_scan_stop Fired by XTP offline checkpoint when the checkpoint thread stops.
sqlserver xtp_recover_done Occurs at completion of log recovery of XTP table.
sqlserver xtp_recover_table Occurs at start of log recovery of XTP table.
sqlserver xtp_storage_table_create Occurs at just before the XTP storage table is created.
ucs ucs_connection_rejected_by_proxy_whitelist After a connection attempt to the UCS proxy endpoint is rejected by whitelist check
ucs ucs_proxy_connect_next_hop UCS proxy next hop connection
ucs ucs_proxy_receive_proxy_connect_message UCS proxy receive proxy connect message
ucs ucs_proxy_route_add UCS proxy route added
ucs ucs_proxy_route_disable UCS proxy route disabled
ucs ucs_proxy_route_refresh UCS proxy route refreshed
ucs ucs_proxy_send_proxy_connect_message UCS proxy send proxy connect message
XtpCompile cgen Occurs at start of C code generation.
XtpCompile invoke_cl Occurs prior to the invocation of the C compiler.
XtpCompile mat_export Occurs at start of MAT export.
XtpCompile pitgen_procs Occurs at start of PIT generation for procedures.
XtpCompile pitgen_tables Occurs at start of PIT generation for tables.
XtpEngine after_changestatetx_event Fires after transaction changes state.
XtpEngine alloctx_event  
XtpEngine attempt_committx_event Is raised when a transaction is asked to commit.
XtpEngine before_changestatetx_event Fires before transaction changes state.
XtpEngine dependency_acquiredtx_event Raised after transaction takes a dependency on another transaction.
XtpEngine endts_acquiredtx_event Fires after transaction acquires an end timestamp.
XtpEngine gc_base_generation_evaluation Indicates that an evaluation of updating the GC base generation has been made.
XtpEngine gc_base_generation_updated Indicates that the oldest active transaction hint used for calculating the GC base generation has been updated.
XtpEngine gc_cycle_completed Indicates that a GC notification has been enqueued.
XtpEngine gc_notification Indicates that GC is processing a notification.
XtpEngine redo_single_hk_record Redo on a HK log record
XtpEngine trace_add_delta_filter_begin Adding delta filter.
XtpEngine trace_add_duplicate_delta_filter Adding duplicate delta filte.
XtpEngine trace_adding_tx_filter Adding tx filter.
XtpEngine trace_begin_close_ckpt_processing Beginning close checkpoint processing: checkpoint flush fence = $2 ($3 state).
XtpEngine trace_cfd_entry_deleted Cleaned up data CFD entry for file $2 $3.
XtpEngine trace_cfd_rows_created Successfully created CFD rows.
XtpEngine trace_cfdtable_dump CfdTable dump
XtpEngine trace_cfp_handles_opened Opened CFP handles for {data: $2 delta: $3} in section $4.
XtpEngine trace_cfp_removed_from_freelist Removed CFP from freelist for destination file.
XtpEngine trace_checkpoint_file_flush Indicating that a file has started a flush operation.
XtpEngine trace_checkpoint_load_begin Starting Checkpoint load with checkpoint timestamp=$2.
XtpEngine trace_checkpoint_write_io Logs an event indicating that an IO has started (when event_type == IoStarted) or that an IO has completed (when event_type == IoComplete).
XtpEngine trace_checksum_validation_succeeded Checksum validation for Hekaton checkpoint file during backup succeeded.
XtpEngine trace_ckpt_close_begin Closing checkpoint in active/passive state.
XtpEngine trace_ckpt_close_signaled Signaling checkpoint close. The checkpoint policy object is flagged to close the current checkpoint
XtpEngine trace_ckpt_closed Checkpoint closed
XtpEngine trace_ckpt_load_thread_stats Statistics of the checkpoint load thread.
XtpEngine trace_ckpt_mrt_dump Mrt dump
XtpEngine trace_ckpt_serialization_state_dump Checkpoint serialization state dump.
XtpEngine trace_ckpt_stream_io_stats Io statistics for this particular stream.
XtpEngine trace_close_file_log_rec_created Successfully created close file log record.
XtpEngine trace_data_file_pages_txs This event gives the number of pages and the transaction range for a data file.
XtpEngine trace_data_from_page_deserialized Deserialized data from page $2 in file $4.
XtpEngine trace_data_row_modified Data row modified/deleted.
XtpEngine trace_delete_cfd_rows_begin Matching MRT not found for the Data CFD. Deleting corresponding CFD Rows.
XtpEngine trace_delete_DeletedObjectTable_row_begin Deleting row from DeletedObjectTable in the context of transaction: $5.
XtpEngine trace_delete_merged_source_file Deleting merged source $7 file $5:$6. DeleteLSN = $2:$3:$4.
XtpEngine trace_delete_mrtrow_for_target_begin Deleting mrt row for target.
XtpEngine trace_delta_entry_skipped Skipping delta {$3, $4, $5} because it is beyond the snapshot checkpoint: $6.
XtpEngine trace_delta_file_future_count_rows_pages_update Updating future count pages and count rows for delta file.
XtpEngine trace_delta_file_lastgood_count_rows_pages_update Updating lastgood count pages and count rows for delta file.
XtpEngine trace_delta_file_pages_txs This event gives the number of pages and the transaction range while reading a delta file for a particular operations.
XtpEngine trace_delta_file_processed Completed processing of Delta file.
XtpEngine trace_delta_file_set_clean_or_dirty Delta file set clean or dirty.
XtpEngine trace_delta_filter_removed Removing delta filter from DeltaFilterMap due to transaction filter.
XtpEngine trace_delta_watermark_removed Removed delta watermark.
XtpEngine trace_delta_watermark_updated Updated delta watermark row for FileId: $4.
XtpEngine trace_deserialize_chained_records Info pertaining to the deserialized content of the mrtRecords chain.
XtpEngine trace_deserialize_data_from_page_begin Deserializing data from page $2 in file $4.
XtpEngine trace_deserialize_source_delta_file_begin Deserializing source delta file $4: page range [$2, $3).
XtpEngine trace_dump_cfd_row Dump cfd row
XtpEngine trace_dump_mrt_row Merge Request
XtpEngine trace_file_close_skipped Skipping file close for $2 as the cfp had been merged, It could not be found in the Storage array.
XtpEngine trace_file_skipped Skipping file $4 due to reason $5.
XtpEngine trace_file_skipped_with_tx_range Skipping file $5 with TX range { $3 -> $4 } due to MaxTxId == InvalidTxId.
XtpEngine trace_first_page_header_flushed Flushed first page header for file.
XtpEngine trace_flush_io_operation_for_delta_file This trace is trying to catch pages issued for flush that didn't make it to the file, or were lacking the correct DeltaWatermark Timestamp.
XtpEngine trace_flush_skipped_for_closed_data_file Skipping flush for data file ('$2') as it is closed.
XtpEngine trace_future_count_pages_update Updating future count pages.
XtpEngine trace_initial_merge Doing initial merge for destination $3 at CheckpointTs: $2.
XtpEngine trace_insert_DeletedObjectTable_row_begin Inserting row to DeletedObjectTable in the context of transaction: $5.
XtpEngine trace_intialize_worker_file_begin Processing file close.
XtpEngine trace_mark_data_file_closed Marking the active data file as closed to prevent the offline worker fom flushing them.
XtpEngine trace_merge_cancelled Merge was cancelled for destination $2.
XtpEngine trace_merge_complete_log_rec_ignored MergeCompleteLogRecord ignored for destination file $3.
XtpEngine trace_merge_complete_log_rec_processed Successfully processed MergeCompleteLogRecord.
XtpEngine trace_mrt_dump Mrt dump.
XtpEngine trace_mrt_row_inplace_update Mrt row updated in place.
XtpEngine trace_mrtrow_not_found Could not find row with Destination ID: $2 in MRT table.
XtpEngine trace_new_delta_watermark_inserted Inserted new delta watermark row for FileId $3.
XtpEngine trace_offline_process_stale_merge_item Offline processing of stale merge item {$2, $3} Destination $4.
XtpEngine trace_pending_tx Pending Transaction
XtpEngine trace_populate_storage_array Populating the storage array.
XtpEngine trace_post_writefile This event is fired after issuing IO on the proxy.
XtpEngine trace_process_file_close_begin Processing file close.
XtpEngine trace_process_merge_complete_log_record Process merge complete log record.
XtpEngine trace_process_merge_request Process Merge Request
XtpEngine trace_process_source_file Processing source $4 file $2.
XtpEngine trace_process_target_file Processing target $4 file $2.
XtpEngine trace_queue_merge_work_item Queue work item: {$2, $3} $5 - $6 with CheckpointTs as $4.
XtpEngine trace_recovered_existing_file Recovered exising files files allocated during forward processing that are not already part of the CCB.
XtpEngine trace_resyncing_state_of_file Resyncing state of file $4 ('$5') post recovery:  $2 pages, $3 rows.
XtpEngine trace_serialization_object_cleaned Cleaned serialization object.
XtpEngine trace_serialize_abort_transaction_begin Serializing the abort transaction filter to the delta cache corresponding to its own transaction range.
XtpEngine trace_serialize_tx_begin Serialize TS begin for completing the checkpoint in active state.
XtpEngine trace_serialize_tx_end Serialize TS end for completing the checkpoint.
XtpEngine trace_serialized_delta_rows_to_file Serialized delta rows to file.
XtpEngine trace_source_file_load_stats Load stats for source files in merge.
XtpEngine trace_storage_refreshed_for_file Storage refreshed for file.
XtpEngine trace_uninitialize_file uninitializing_file
XtpEngine trace_wrote_delta_watermark Wrote delta watermark for file: $3, checkpointTs: $2.
XtpEngine waiting_for_dependenciestx_event Raised when we have explicitly waited for dependencies to clear.
XtpEngine xtp_before_create_log_record Fired before submitting a request to the host to serialize a non-transactional log record.
XtpEngine xtp_checkpoint_file_flush Indicates the point at which a given file has been flushed to disk.
XtpEngine xtp_checkpoint_file_flush_complete Indicates the point at which all in-flight buffers have been flushed to disk.
XtpEngine xtp_checkpoint_file_read Indicates reading of a file in XTP checkpoint recovery.
XtpEngine xtp_checkpoint_worker_active_log Indicates that the checkpoint worker has started processing the log records in the active portion of the log.
XtpEngine xtp_checkpoint_worker_started Indicates that the checkpoint worker has started processing the log records.
XtpEngine xtp_checkpoint_worker_stopped Indicates that the checkpoint worker has started processing the log records.
XtpEngine xtp_checkpoint_write_io Indicates that the checkpointing subsystem has issued or completed a write IO.
XtpEngine xtp_complete_checkpoint Indicates the begin and end of complete checkpoint processing.
XtpEngine xtp_create_log_record Fires when the XTP engine creates a log record.
XtpEngine xtp_delta_marked_dirty Indicates that a delete/update was serialized and marked a delta file dirty
XtpEngine xtp_merge_complete_log_record Indicates merge complete log record is posted to the log.
XtpEngine xtp_merge_log_complete_log_record Indicates merge log record was interpreted by the offline worker.
XtpEngine xtp_merge_process_log_record Indicates merge log record was interpreted by the offline worker.
XtpEngine xtp_merge_request_log_record Indicates merge request log record is posted to the log.
XtpEngine xtp_merge_request_started Indicates merge request has been picked up by the merge worker thread.
XtpEngine xtp_root_deserialized Indicates that the load of a checkpoint root is complete.
XtpEngine xtp_root_serialized Indicates that the write of the checkpoint root is complete.
XtpRuntime bind_md Occurs prior to binding metadata for a memory optimized table.
XtpRuntime bind_tables Occurs prior to binding tables for a natively compiled procedure.
XtpRuntime create_table Occurs prior to creating memory optimized table.
XtpRuntime deserialize_md Occurs prior to deserializing metadata.
XtpRuntime load_dll Occurs prior to loading the generated DLL.
XtpRuntime recover_done Occurs at completion of checkpoint recovery of a memory optimized table.
XtpRuntime recover_table Occurs at start of checkpoint recovery of a memory optimized table.
XtpRuntime serialize_md Occurs prior to serializing metadata.
XtpRuntime unload_dll Occurs prior to unloading the generated DLL.

Happy tracing,

 

Andreas

Andreas Wolter: Received MVP Award for SQL Server // Ausgezeichnet mit dem MVP-Award

Ausgezeichnet mit dem MVP-Award für SQL Server

(de)
Gestern, am 1. April 2014 erhielt ich die frohe Botschaft: Für meine Beiträge zur Community bin ich von Microsoft mit dem MVP Award (MVP=Most Valuable Professional) ausgezeichnet worden (zum MVP-Profil).

(en)
Yesterday, on 1 April 2014, I got great news:
I have been awarded with the MVP Award by Microsoft (MVP=Most Valuable Professional) for my contributions to the community (click here for MVP profile).

 

 

MVP_Award_SQL_Server

 

 

 

Ich freue mich riesig über diese Anerkennung meiner zahlreichen Konferenz-Beiträge, Usergroup-Meetings und anderen Aktivitäten!

So bin ich seit 2009 bis Stand heute auf 27 Konferenzen als Redner zu verschiedenen SQL Server Themen, von Sicherheit über Performance & Indexdesign bis hin zu Reporting Services aufgetreten und habe auf weiteren 34 Usergroup-Meetings Vorträge gehalten.

2013 hat sich meine Aktivität noch einmal gesteigert, so dass ich allein in diesem Jahr auf 11 Konferenzen, von Istanbul/Türkei bis Charlotte/USA, und 14 PASS Regionalgruppentreffen (Liste) als Sprecher angetreten bin.
Und auch 2014 habe ich bereits 2 Konferenzen und 4 Regionalgruppentreffen (Liste) hinter mir – weitere werden folgen: Portugal, England und wenn es hoffentlich? klappt zum 6. Mal in den USA :-)

Damit bin ich fast so viel auf Konferenzen unterwegs wie drei weitere deutsche MVP-Kollegen, die diese Auszeichnung bereits hochverdient für ihren Einsatz für die deutsche SQL Server Community PASS Deutschland e.V. erhalten haben: Tillmann Eitelberg, Oliver Engels – beide im Vorstand der PASS – und Constantin Klein, der unter anderem den Just Community e.V. und die .NET User Group Frankfurt leitet. – Ich freue mich, zu dieser illustren Runde dazustoßen zu können!

Dieser Award ist für mich daher eine tolle Anerkennung und ein Ansporn weiterzumachen – was natürlich nicht heißt, dass ich es nicht auch ohne diesen tun würde, denn die Interaktion mit der Community ist für sich gesehen schon eine echte Bereicherung, von der alle profitieren.

An dieser Stelle möchte ich einigen Personen persönlich meinen Dank aussprechen, die meine Nominierung zum MVP auf verschiedene Weise unterstützt haben:

I am very excited about this recognition of my many contributions to conferences, usergroup meetings, and other activities!

In fact, since 2009 till today, I have appeared as a speaker in 27 conferences, speaking on different SQL Server topics from security to performance & index design to reporting services, and have given presentations in 34 usergroup meetings.

2013 saw yet another boost in my activities: That year alone I was speaker at 11 conferences, from Istanbul/Turkey to Charlotte/USA, and at 14 PASS regional group meetings (list).
In 2014, too, I can already look back on 2 conferences and 4 regional group meetings (list) – with more to come: Portugal, England, and – hopefully it will work out – USA for the 6th time. :-)

Thus, I am participating in conferences to an almost similar extent as three other German MVP colleagues who have already been awarded, quite deservedly, the very award for their commitment to the German SQL Server Community PASS Deutschland e.V.: Tillmann Eitelberg, Oliver Engels – both of them in the chair of the PASS – and Constantin Klein who heads the Just Community e.V. and the .NET User Group Frankfurt, among others. – I am honored to be joining this illustrious circle!

This award is indeed a fantastic acknowledgement and incentive to continue – of course, this doesn’t mean I wouldn’t do so without this award, because the interaction with the community is in itself already an enrichment from which everyone is benefiting.

I would like to express my personal thanks to the following people who have supported my nomination to MVP in various ways:

 

Anna Feth (Microsoft MVP Programmkoordinator Region DACH), @AnnaFeth), Constantin Klein (MVP, Blog, @KostjaKlein), Daniel Weinmann (Product Marketing Manager - SQL Server/ BI Microsoft GmbH), Florian Endres (Community Program Manager, @senorf), Heike Ritter (Technical Evangelist Microsoft Deutschland GmbH, @HeikeRitter), Jack Richins (Principal Development Lead Microsoft SQL Server Security), Katrin Letzel (Microsoft MVP Community Program Manager, @katko), Niko Neugebauer (MVP, Blog, @NikoNeugebauer), Oliver Engels (MVP, @oengels), Scott Klein (SQL Server Evangelist, Microsoft, @SQLScott), Tillmann Eitelberg (MVP, Blog, @_Tillmann) and the Team of the datafino GmbH, to which I have a strong partnership as well as all anonymous supporters and technical sparring partners.

 

So bin ich mindestens genauso dankbar für all die wertvollen Kontakte, die Gesprächsmöglichkeiten und den Austausch untereinander wie für den Award selber.

Thus, I am at least equally grateful for all the valuable contacts, opportunities for dialogue and mutual exchange as for the award itself.

 

Andreas

MCSM, MCM and MVP :-)

Christoph Muthmann: SQL Server 2014 RTM

Wie bereits durch Torsten angekündigt, wurde gestern die RTM-Version des SQL Server 2014 zum Download freigegeben.

Full story »

Uwe Ricken: Berater / DBA / DEV – Dokumentation ist eine Hauptleistungspflicht!

Mit diesem Artikel möchte ich die technischen Berater für Microsoft SQL Server, DBAs und Entwickler erreichen, die täglich bei den Kunden sind, um technische Probleme zu analysieren und zu lösen. Der folgende Artikel beruht auf einem aktuellen Projekt. Ich wurde zu diesem Projekt hinzu gezogen, weil die technischen Analysen meines Vorgängers nicht ausreichend waren, um Probleme zu erkennen und zu beheben. Um mich mit dem Thema im Vorfeld beschäftigen zu können, habe ich um vorhandene Dokumentation(en) gebeten. Die dann zugesendeten Dokumente waren den Namen nicht wert, wie einige Auszüge im Artikel zeigen werden. Gleich Eines vorweg – es soll hier kein Finger Pointing stattfinden – ich möchte aufzeigen, welche Minimalanforderungen aus meiner Sicht an eine Analysedokumentation gestellt werden sollten.

Einleitung

Seit ca. 2 Jahren werde ich immer wieder mal bei Kurzprojekten eingesetzt (ca. 1 – 4 Wochen), bei denen es – wie soll es auch anders sein – die Performance-Analyse von implementierten Microsoft SQL Server-Umgebungen oder Hochverfügbarkeitsarchitekturen geht. Ich mag diese Art von Projekten, da sie neben den “Langläufern” immer wieder Abwechslung und neue Herausforderungen bieten. In den bisherigen Fällen wurden meine Dienstleistungen immer zu Beginn – bei Auftreten der Probleme – gebucht und in der Regel waren nach 2 – 3 Tagen die Probleme analysiert und es wurden Strategien für die Behebung entwickelt. Neben der Analyse steht für mich IMMER eine sorgfältige Dokumentation der Analyse und der daraus abgeleiteten Tätigkeiten im Fokus. Sie ist ein wesentlicher Bestandteil meiner Arbeit und hinterlässt so einen “Fingerprint” meiner Tätigkeiten.

Das Referenzprojekt, das Anlass dieses Artikels ist, wurde im letzten Jahr von einem Berater betreut, weil der Kunde massive Performanceprobleme auf dem Microsoft SQL Server vermutete. Aufgabe war die Analyse der Performance-Schwachstellen sowie die Erarbeitung einer Strategie für die Behebung. Sofortmaßnahmen – sofern sie sinnvoll erscheinen – sollten ebenfalls durchgeführt werden.

Warum dokumentieren?

“Unter Dokumentation versteht man die Nutzbarmachung von Informationen zur weiteren Verwendung. Ziel der Dokumentation ist es, schriftlich oder auf andere Weise dauerhaft niedergelegte Informationen (Dokumente) gezielt auffindbar zu machen.” (Quelle Wikipedia.de).

Eine Dokumentation ist für drei Parteien dieses Projekts von großem Nutzen:

  • Kunde
  • Autor
  • Berater

Wenn ich meine Arbeit dokumentiere, habe ich immer die Erwartungshaltung des Kunden im Blick. Dabei stelle ich mir die Frage, warum mich der Kunde zu sich gerufen hat. Weil er das Problem selbst nicht lösen kann! Die Erwartung des Kunden bei der Dokumentation besteht darin, dass eine Bestandsaufnahme, Problemanalyse sowie eine Aussicht auf Lösungen ermittelt wird.

Bei der Aussicht auf Lösungen ist es wichtig, die Dokumentation so zu formulieren, dass der Kunde die Probleme erkennt und auch die angestrebten Lösungen versteht. Aus diesem Grund verpflichte ich mich in meinen Dokumentationen, die Probleme in einer Form zu erläutern, dass es ein IT-verantwortlicher Mitarbeiter verstehen kann. Ist das Verständnis für das Problem vorhanden, bedarf es weniger Erläuterungen für die Lösungsbeschreibung. Gleichwohl hat der Kunde ein Referenzdokument für seine Unterlagen, das die Tätigkeiten des Autors belegt und – bei Bedarf – an Dritte ausgegeben werden kann, um sich schnell in den Sachverhalt einzuarbeiten.

Für mich als Autor von Dokumentationen ist sie eine Referenz und das Aushängeschild meiner Arbeit. Mit der Dokumentation gebe ich dem Kunden einen Leistungsnachweis und eine Referenz an die Hand. Nicht immer ist der Kunde darüber im Klaren, was “der Berater” so lange vor dem Computer macht; noch weniger ist es dem Kunden (in der Regel) möglich, nachzuvollziehen, was der Berater am System untersucht und – gegebenenfalls – geändert hat. Um so wichtiger ist also, dass der Kunde nachträglich erkennt, mit welchen Techniken der Berater das System untersucht und – eventuell – optimiert hat.

Für einen Berater ist eine vorhandene Dokumentation die Chance, sich möglichst schnell einen Überblick über das betroffene System zu verschaffen. Hat der Autor seine Schritte dokumentiert, kann der Berater viel Zeit sparen, indem er  bereits durchgeführte Prüfungen überspringt. Dies erfordert aus meiner Sicht aber eine sehr detaillierte Dokumentation der Ergebnisse eines Untersuchungsschrittes. Dazu aber im Nachfolgenden mehr:

Step by Step durch die Dokumentation

Microsoft SQL Server lebt davon, dass eine gute und stabile Hardware vorhanden ist. Für eine gute Performance von Microsoft SQL Server sind vor allen Dingen drei Hardwarekomponenten von Bedeutung: CPU, RAM und STORAGE. Um einen Gesamtüberblick zu erlangen, muss der Berater wie auch der DBA wissen, mit welcher Hardware-Ausstattung zu rechnen ist. Insbesondere die Information über die Ausstattung des Arbeitsspeichers ist für mich eine erste Anlaufstelle, wenn ich mir später die Datenbanken anschaue. Sind nur 16 GB RAM vorhanden und die Datenbanken haben Größen jenseits der 100 GB, kann ich erwarten, EINEN verbesserungswürdigen Punkt gefunden zu haben.

Document-01

Die obige Aussage zur Hardware ist nutzlos, da wirklich wichtige Informationen für eine Bewertung fehlen:

  • Wie viel RAM wurde der virtuelle Hardware zur Verfügung gestellt?
  • Wie viele CPUs wurde der virtuellen Hardware zur Verfügung gestellt?
  • Werden die CPU exklusiv der virtuellen Hardware zur Verfügung gestellt oder müssen sich mehrere Hosts die CPU-Leistung teilen?
  • Arbeitet der Server mit SAN-Komponenten oder nur mit lokalem Storage?
  • Welche CPU-Modelle werden im Server verwendet?
  • Welche Festplatten / SAN-Controller werden verwendet?

Sicherlich sind einige der obigen Fragen nicht unmittelbar zu beantworten aber die Aufgabe des Beraters besteht darin, sich einen Überblick über die Basis zu verschaffen. Was definiert ein ausreichendes System? Wenn die CPU-Last nicht mehr als 30% beträgt? Oder wenn SQL Server nur einen Bruchteil des RAM benötigt?

Ein ausreichendes System bestimmt sich nach den Anforderungen, die eine Applikation voraussetzt. Eine Hardware mit 4 GB RAM und 2 Cores wird für ein Datenbanksystem für den Versand von Weihnachtskarten  keine Probleme darstellen; die Plattform eines Internethändlers erwartet jedoch vollkommen andere Voraussetzungen. Bei der Dokumentation der Hardware spielen subjektive Bewertungskriterien keine Rolle; von einem ausreichenden System ohne Information über die vorgefundene Hardware zu sprechen, dient weder dem Kunden noch den Lesern.

Document-02

Ein Server, der ausschließlich für den Betrieb als Datenbankserver vorgesehen ist, sollte auf jeden einen Blockgröße von 64KBytes verwenden (siehe: Disk Partition Alignment Best Practices for SQL Server). Hier möge sich der Leser in die Rolle des Kunden versetzen – dann wird sofort die Frage aufkommen: “WARUM soll die Blockgröße 64KBytes betragen? Eventuell wird nicht jeder dieser Aussage zustimmen aber ich halte es für essentiell, dass bei Empfehlungen angegeben wird, WARUM man diese Empfehlung ausspricht. Es müssen keine riesigen Abhandlungen sein; jedoch kann mit zwei Sätzen erklärt werden, dass Microsoft SQL Server Datenseiten mit einer Größe von 8 KBytes und Extents mit jeweils 8 Datenseiten verwendet. Wenn es zu aufwändig ist, den Sachverhalt Detail zu erläutern, reichen auch weiterleitende Links zu “offiziellen” Webseiten, die eine Empfehlung untermauern (aber bitte NICHT irgendwelche Forendiskussionen!). Dieser geringe Aufwand erfüllt mehrere Anforderungen:

  • Der Kunde kann – bei Interesse – weitere Informationen über die Links abrufen.
  • Der Kunde kann die Empfehlung unmittelbar bewerten.
  • Der Berater zeigt seine Kompetenz und dass er sich mit dem beschriebenen Thema vor der Empfehlung auseinander gesetzt hat.
  • Ein nachfolgender Berater, dem eine Technik / ein Feature unbekannt ist, kann sich – wie der Kunde – sehr schnell einen Überblick verschaffen.

Document-03

Unabhängig vom WARUM? stellt sich die Frage danach, welche Analysen für diese Empfehlung verwendet wurden. Um noch einmal die Erwartungshaltung des Kunden in den Vordergrund zu stellen: Der Kunde erwartet sich von den Empfehlungen durch den Berater, dass die Verarbeitung im Microsoft SQL Server beschleunigt wird. Pauschal die obige kostenintensive Maßnahme zu empfehlen, wird beim Kunden keine Freudensprünge verursachen, da mehr Fragen offen bleiben als beantwortet werden.

Als Basis zur obigen Empfehlung fehlt – neben der technischen Erläuterung – vor allen Dingen eine Berücksichtigung der vorhandenen Workloads. Datenbanken werden vielfältig genutzt; es ist von elementarer Bedeutung, vor einer Aussage zum DISK-Layout die Anwendungsgebiete genau zu analysieren und zu beschreiben.

Nach meinem Verständnis fehlt für jedes oben beschriebene “Element” eine durch Messungen / Zahlen untermauerte Analyse der Workloads des Servers. Für einen Sharepoint-Server in einer Umgebung mit 20 Mitarbeitern würde die obige Empfehlung keinen Nutzen für den Kunden bringen – der Hardware-Lieferant hätte jedoch seine helle Freude bei der eingehenden Bestellung.

  • Wenn die Datenbanken ausschließlich Lesend auf die Daten zugreifen, ist die Empfehlung für die DATA- und LOG-Files eher schlecht, da sie teuer ist, wenn z. B. erkennbar ist, dass mehr RAM zur Verfügung steht als die Datenbanken an Datenvolumen aufweisen.
  • Die Verlagerung der TEMPDB auf ein schnelles IO-Subsystem ist nur dann von Vorteil, wenn im Vorfeld eine Workload- und Ausführungsplan-Analyse durchgeführt wurde.
  • Handelt es sich um ein OLTP-System, in dem hohe WAIT STATS gemessen werden, ist das oben skizzierte Layout sicherlich von Vorteil.

Leider werden keine Protokolle in der Dokumentation verwendet, die Basis für die Empfehlung sind. Die Empfehlung wurde vermutlich als “pauschale” Empfehlung (best practice) ausgesprochen. Es bleiben zu viele Fragen offen, die auch der Kunde nicht beantworten kann.

Document-04

Es mag langweilig sein – aber auch hier fehlt jegliche Erklärung dafür, warum der Berater diese Maßnahmen (wobei die erste sicherlich nicht verkehrt ist) durchgeführt hat. Viel wichtiger wäre im Sinne der Dokumentation jedoch folgende Information gewesen:

  • Warum wurden 8 Dateien angelegt?
  • Wurden die Dateien von TEMPDB auf einem dedizierten Laufwerk erstellt?
  • Mit welcher Größe wurden die einzelnen Dateien initial festgelegt?
  • Mit welchem Wachstumswert (Prozent oder Absolut) wurden die Dateien konfiguriert?
  • Sind alle Dateien mit identischen Größen und Wachstumswerten konfiguriert worden?

Noch bevor die Dateien angelegt / konfiguriert wurden, wäre die Präsentation von Zahlen / Messungen sinnvoll gewesen, die eine solche Maßnahme begründen.

Die zweite Maßnahme erschließt sich mir nicht – wie soll dann der Kunde diesen Handlungsschritt verstehen. Auch hier fehlt jegliche Begründung für die Maßnahme. Insbesondere wäre als Grundlage für diese Entscheidung eine Auswertung des Plan Cache sinnvoll gewesen. So bleibt mir dieser Schritt überlassen, wenn ich mir das System anschaue!

Document-05

Das ein Clustered Index deutlich mehr Schreib- als Lesevorgänge aufweist, liegt bei einem OLTP-System in der Natur der Sache – schließlich ist er ja die Tabelle (und somit die Daten) selbst. Außerdem fehlt erneut für eine neutrale Bewertung dieser Aussage die Informationen darüber, welche Werte gemessen wurden. Auch fehlt ganz deutlich, ob die Informationen aus sys.dm_db_index_usage_stats (das ist meine Vermutung) oder aber aus sys.dm_db_index_operational_stats abgeleitet werden. Hier besteht ein ERHEBLICHER Unterschied! Aber wieder zurück zu den Erwartungen des Kunden. Was soll der Kunde mit dieser Aussage anfangen?

  • Aha – zwei Clustered Indexe (was ist das?), in denen mehr geschrieben als gelesen wird?
  • Wie gestalten sich denn die die Lesevorgänge? Sind es eher SEEK oder SCAN Operationen?
  • Was soll ich – basierend auf der Aussage – denn nun machen?

Document-06

Spätestens bei dieser Aussage war mir dann klar, dass man von dem vorliegenden Dokument nicht von einer “Dokumentation” sprechen kann. Auch muss man – LEIDER – bei solchen Aussagen festhalten, dass eine Zertifizierung nicht immer das hält, was sie verspricht. Der Autor spricht von einer Optimierungsmöglichkeit! Der Neustart des Microsoft SQL Server bewirkt keine Verbesserung sondern insbesondere bei den ersten Zugriffen wird das System eher langsam als schnell! Beim Lesen dieser “Optimierungsmöglichkeit” wird der Kunde auf eine gefährliche Spur geleitet – er geht bei dieser Empfehlung (sie ist Bestandteil der Dokumentation!) davon aus, dass es eine zwingende Maßnahme ist. Leider fehlt es auch hier – wie bei ALLEN Empfehlungen und Maßnahmen – an einer Untermauerung für die Maßnahmen.

Meine Vermutung geht dahin, dass folgende Punkte thematisiert werden sollten:

Die obigen Beispiele sind Ausschnitte aus einer Dokumentation, die sich über 5 Seiten erstreckt. Ab Seite 2 habe ich die Verwendung von Beispielen beendet, da sie sich wiederholen. Die Beispiele zeigen vier wesentliche Merkmale, die sich – bedauerlicher Weise – durch das gesamte Dokument ziehen:

  • Es werden Thesen aufgestellt, die nicht durch Messungen / Analysen / Verfahren belegt sind.
  • Es werden technische Definitionen erläutert, die weder in einer fachlich ansprechenden Form kundengerecht erläutert wurden noch durch Verweise auf offizielle Dokumente des Herstellers beschrieben werden
  • Analysen (sofern man sie so bezeichnen kann) werden mit Empfehlungen und durchgeführten Handlungsschritten vermischt
  • Der Kunde liest ein Dokument, von dem er sich Hilfe verspricht und wird – vermutlich – deutlich ratloser zurückgelassen, als er vorher war

Bei dem obigen Beispiel von einer “Dokumentation” zu sprechen, wäre sicherlich übertrieben – es bleiben einfach zu viele Fragen offen. Hier hätte der Autor sich meiner Meinung nach einer strengeren Strukturierung bei der Erstellung des Dokuments unterwerfen sollen – es sind zu viele “Berater-Sprech”-Blubber Blasen im Dokument, die nicht genug in die Tiefe gehen und darauf abzielen, sich nicht auf eine konkrete Aussage festlegen zu müssen!

EIN KUNDE ERWARTET EINE LÖSUNG UND BEZAHLT DAFÜR! Als Autor einer Dokumentation (und insbesondere in der Rolle des externen Beraters) muss man sich vor Augen halten, dass der Kunde Hilfe anfordert und mit einer sehr großen Erwartungshaltung auf den Berater wartet. Gleichzeitig hatte der Kunde bereits im Vorfeld eine wichtige Entscheidung zu treffen, die seine Erwartungshaltung noch untermauert: Er sucht einen Berater nach seinen Skills aus und bestellt ihn dann für viel Geld in sein Unternehmen!

Ich kann für Dokumentationen / Analysen folgende Punkte mit auf den Weg geben, um ein gutes Ergebnis abzuliefern:

  • Denken Sie daran, dass der Kunden Sie teuer bezahlt
  • Der Kunde verbindet mit Ihrem Einsatz Lösungen, bei denen Sie ihn unterstützen sollen/können
  • Trennen Sie Analysen von Handlungsempfehlungen / Handlungsschritten
  • Wenn Sie technische Handlungsempfehlungen geben, beschreiben Sie die Technik VOR der Empfehlung
  • Belegen Sie Behauptungen durch Testergebnisse und beschreiben Sie die Grundlage der Testergebnisse
  • Wenn Sie Thesen aufstellen, untermauern Sie diese Thesen mit Fußnoten / Referenzen / Weblinks
  • Führen Sie immer eine Baseline-Analyse aus um – bei Änderungen am System – die Verbesserungen zu dokumentieren
  • Ihre Dokumentation ist ein wichtiger Baustein für den Betrieb von IT-Umgebungen
  • Ihre Dokumentation wird von vielen Menschen gelesen (vielleicht), achten Sie auf die Rechtschreibung.

Fader Beigeschmack

Die erhaltende Dokumentation war ihr Geld aus meiner Sicht nicht wert, da sie keine analytische Dokumentation sondern vielmehr ein Tätigkeitsprotokoll mit generischen Handlungsempfehlungen (copy / paste) darstellt. Es ist verständlich, dass der Kunde mit der Leistung “eher nicht” zufrieden war und sich nach Alternativen umschaut. Die Arbeit durch den Berater beschädigt nicht nur den eigenen Ruf sondern zeigt auch deutlich auf, dass Zertifizierungen nutzlos sind, wenn man sich – wie das Beispiel zeigt – oberflächlich mit einem Thema beschäftigt. Während ich die Dokumentation gelesen habe, ging mir immer wieder ein Artikel durch den Kopf, den ich erst vor wenigen Wochen geschrieben habe: “If you pay peanuts …”! Ein Schelm, wer Böses dabei denkt.

PPS: Eigene Anregungen, Ideen, Tipps für Dokumentationen sind in den Kommentaren willkommen!

Herzlichen Dank fürs Lesen!

Robert Panther: Neue Features für künftige Versionen von SQL Server

Zeitgleich mit dem Erscheinungstermin von SQL Server 2014 sind in Insider-Kreisen vereinzelte Infos über geplante Features für die nächsten Versionen von SQL Server durchgesickert. Da die Features alle noch in einem frühen Entwicklungsstadium sind, ist allerdings leider noch nicht abzusehen, in welcher Version von SQL Server diese implementiert werden.

Neues Energiespar-Feature – “Always-Off”

Die Energiepreise steigen in den letzten Jahren stetig. So ist es nur konsequent, dass im Zuge der “Green-IT” auch über Energiesparmöglichkeiten bei SQL Servern nachgedacht wird. Unter dem Codenamen “Always-Off” wird derzeit an einer Technologie gearbeitet, mit der SQL Server überwiegend quasi im Standby-Betrieb laufen und damit kaum Strom verbrauchen. Sobald Datenbank-Abfragen eintreffen, wechseln diese möglichst schnell wieder in den aktiven Modus zurück. Die daraus resultierenden erhöhten Latenzzeiten werden durch die kürzeren Boot-Zeiten der aktuellen Betriebssystemgeneration sowie durch hochperformante SSD-Platten möglichst gering gehalten. Erfolgt dann innerhalb einer gewissen Zeit keine weitere Abfrage, wechselt der Server wieder in den Standby-Betrieb zurück. Natürlich ist dieses Feature nicht für Umgebungen sinnvoll, die hochverfügbar sein müssen. Interessanter dürfte das Feature beispielsweise für Archivlösungen sein, in denen nur sporadisch Datenbankzugriffe erfolgen und eine Latenzzeit von wenigen Sekunden verschmerzbar ist.

Neue Form des Index-Alignment

Performance-Themen spielen seit einigen Jahren eine große Rolle bei jeder neuen SQL Server Version. So wird zur Zeit an einer neuen Variante des Index-Alignment gearbeitet, bei der – basierend auf Zugriffsstatistiken – die am meisten genutzten Daten an den Anfang des Indexes verschoben werden. Da das Erstellen dieser Statistiken selbst einen gewissen Verwaltungsoverhead mit sich bringt, muss dieses Feature über eine Datenbankoption erst einmal generell aktiviert werden. Anschließend können einzelne Indizes über eine ALTER-Anweisung so konfiguriert werden, dass diese das neue Index Alignment nutzen. Dafür ist bisher die folgende Syntax vorgesehen:

ALTER INDEX IX_IndexName ON Schema.Tabelle ALIGN FOR FASTSEEK

Neuer Datentyp: Pocket Money

Für Kleinbeträge, bei denen auch eine Genauigkeit von lediglich 3 Stellen (nicht 4 wie bei money und smallmoney) hinter dem Komma ausreicht ist ein neuer Datentyp namens Pocket Money geplant. Vorteil dabei ist, dass dieser Datentyp lediglich 2 Bytes benötigt. Hier eine Übersicht der dann verfügbaren Währungs-Datentypen mit deren Speicherbedarf und Wertebereichen:

  •  money (8 Bytes): -922,337,203,685,477.5808 bis 922,337,203,685,477.5807
  • smallmoney (4 Bytes): – 214,748.3648 bis 214,748.3647
  • pocketmoney (2 Bytes): -32.768 bis 32.767

Neuer Datentyp: varchar(min) / nvarchar(min)

Auch im Bereich der alphanumerischen Datentypen sind neue Varianten angedacht. Allerdings handelt es sich dabei streng genommen lediglich um Aliasse für bereits bestehende Datentypen, mit denen verhindert werden soll, dass unbedarfte SQL Server Anwender varchar/nvarchar-Spalten mit Längen definieren, bei denen der Speicherbedarf höher ist, als mit den vergleichbaren char/nchar-Varianten. Die neuen Datentypen varchar(min) und nvarchar(min) definieren damit die kleinstmögliche Breite, ab der die Verwendung eines alphanumerischen Datentyps variabler Länge sinnvoll sein kann. Somit entspricht varchar(min) dem Datentyp varchar(4), während nvarchar(min) eigentlich dasselbe ist, wie nvarchar(2).

Die hier aufgezählten Features sind nur eine kleine Auswahl von geplanten oder teilweise bereits in Entwicklung befindlichen Neuerungen. Die Zeit wird zeigen, welche davon auch morgen noch in der Planung bleiben.

 


Robert Panther: SQL Server Data Tools für SQL Server 2014 veröffentlicht

Kurz vor Erscheinen des neuen SQL Servers hat Microsoft nun eine neue Version der SQL Server Data Tools veröffentlicht. Diese beinhaltet bereits die Unterstützung für den kommenden SQL Server 2014 (und installiert sogar schon die SQL Server 2014 Express LocalDB mit). Es gibt aber auch ein paar Neuerungen, die sich selbst in Zusammenhang mit älteren SQL Server Versionen nutzen lassen:

  • Erstellung von eigenen Regeln für die statische Code-Analyse über eine SSDT API
  • nachträgliches Filtern von Daten, die über den SQL Server-Objekt-Explorer angezeigt werden
  • erweiterte Azure Integration (Link von Visual Studio auf Management Portal)
  • neue Features für den Transact SQL Editor: Verbindung ändern, Alle Abfragen trennen
  • Data Compare: Einstellungen in einer .dcmp-Datei speichern

Insbesondere die Möglichkeit, die Data Compare Settings zu speichern, ist ein Feature, das von vielen Benutzern gewünscht wurde. Allerdings ist die Umsetzung noch etwas fraglich, denn scheinbar werden vor allem die Connections, nicht aber die Auswahl der zu vergleichenden Tabellen gespeichert.

Im Gegensatz zur Vorgängerversion wird nun neben Visual Studio 2012 auch Visual Studio 2013 unterstützt. Dafür fällt die Variante für Visual Studio 2010 weg.

Weitere Infos:

 


Uwe Ricken: Tabellenvariablen – Mythos der Datenverarbeitung im Buffer Pool

Ich hatte am 22.03.2014 in Nürnberg während der SNEK (SQL Server + .NET Entwickler Konferenz) die Gelegenheit, nach meinem Vortrag ein interessantes Gespräch führen können, in dem unter anderen behauptet wurde, dass Tabellenvariablen Objekte seien, deren Datenoperationen (INSERT/UPDATE/DELETE)  im Buffer Pool – und somit im RAM – stattfinden und daher ein Grund für die bevorzugte Wahl von Tabellenvariablen sei. Diese Aussage ist nicht richtig wie der nachfolgende Artikel zeigen soll.

Was sind Tabellenvariablen?

Tabellenvariablen wurden mit Microsoft SQL Server 2000 als Alternative zu temporären Tabellen eingeführt. Tabellenvariablen haben Vor- und Nachteile gegenüber temporären Tabellen, die aber in diesem Beitrag nicht thematisiert werden sollen. Ein besonderer Vorteil einer Tabellenvariablen ist die Deklaration ihrer Struktur mit einem DECLARE-Statement, wie es auch für andere Variablen gilt. Der Mythos der Verarbeitung aller Daten, die in einer Tabellenvariablen gespeichert werden, im Buffer Pool hält sich – aus welchen Gründen auch immer – beständig. Das folgende Beispiel zeigt, dass Tabellenvariablen – wie auch temporäre Tabellen – ihre DML-Aktivitäten in der TEMPDB ausführen!

Testszenario

Im folgenden Beispiel wird eine Tabellenvariable @t deklariert, die eine feste Datensatzläge von 4.000 Bytes besitzt. Anschließend werden 1.000 Datensätze in diese Tabellenvariable eingetragen. Um die Schreib- und Leseaktivitäten zu messen, werden vor als auch nach dem Schreiben der Daten das aktuelle I/O der TempDB-Datenbank gemessen.

Um das Testergebnis nicht zu verfälschen, wird der Test natürlich in einer isolierten Umgebung ausgeführt, in der keine weiteren Benutzerprozesse die Messungen – deutlich – beeinflussen können!

DECLARE    @sum_of_reads    decimal (18, 0);
DECLARE    @sum_of_writes   decimal (18, 0);
 
-- Messung des IO der TEMPDB vor der Ausführung des Codes
SELECT  @sum_of_reads  = SUM(num_of_bytes_read),
        @sum_of_writes = SUM(num_of_bytes_written)
FROM    sys.dm_io_virtual_file_stats(2, NULL)
 
-- Deklaration einer Tabellenvariablen
DECLARE    @t TABLE
(
    c1 int        NOT NULL  PRIMARY KEY CLUSTERED,
    c2 char(3996) NOT NULL  DEFAULT ('just stuff')
);
 
-- 1.000 Datensätze in Tabellenvariable eintragen
DECLARE    @i int = 1;
WHILE @i <= 1000
BEGIN
    INSERT INTO @t (c1) VALUES (@i);
    SET    @i += 1;
END
 
-- Berechnung des IO-Delta für TEMPDB
;WITH io_analysis
AS
(
    SELECT  SUM(num_of_bytes_read)      AS sum_of_reads,
            SUM(num_of_bytes_written)   AS sum_of_writes
    FROM    sys.dm_io_virtual_file_stats(2, NULL)
)
SELECT  @sum_of_reads = sum_of_reads - @sum_of_reads,
        @sum_of_writes = sum_of_writes - @sum_of_writes
FROM    io_analysis;
 
-- Ausgabe des IO-Delta für TEMPDB
SELECT  @sum_of_reads / POWER(1024, 2)  AS diff_read_MB,
        @sum_of_writes / POWER(1024, 2) AS diff_write_MB;

Um zu analysieren, wie viele Schreib- und Lesevorgänge in einer Datenbankdatei vorgenommen werden, wird die Funktion [sys].[dm_io_virtual_file_stats] verwendet. TEMPDB besitzt die Datenbank-Id 2. In meinem Testsystem ist TempDB auf mehrere Dateien verteilt und das I/O muss daher aggregiert werden. Wird das Skript ausgeführt, wird man erkennen, dass insgesamt ca. 4 MB in TEMPDB geschrieben werden, der Wert kann auf Grund von Hintergrundaktivitäten variieren – die Differenz ist jedoch vernachlässigbar.


Fügt man am Ende des obigen Skripts noch die folgenden Anweisungen hinzu, kann man deutlich erkennen, dass auch eine Tabellenvariable – im Hintergrund – nichts anderes ist, als eine temporäre Tabelle (aber mit weniger Funktionalität):



-- SELECT Statement für Ausgabe von I/O
SET STATISTICS IO ON;
SELECT * FROM @t WHERE c2 = 'irgendwas';
SET STATISTICS IO OFF;

#BDB0B5EA-Tabelle. Scananzahl 1, logische Lesevorgänge 501, physische Lesevorgänge 0,


Der “Mythos” der Verarbeitung von Daten einer Tabellenvariablen im RAM ist definitiv FALSCH!


Herzlichen Dank fürs Lesen!

Thomas Glörfeld: SQL Server 2014 kommt am ersten April

Klingt wie ein April-Scherz… ist wohl aber so, steht auf dem SQL Server-Blog. Die Featureliste ist spannend, hier der Vergleich zwischen den Editionen.

Falk Krahl: Erscheinungstermin SQL Server 2014

Gestern wurde von Quentin Clark, dem Corporate Vice President der Data Platform Group, bekannt gegeben, dass der SQL Server 2014 für die Fertigung freigegeben worden ist und am 1. April verfügbar sein wird. In dieser Version werden die neue In-Memory-Technologie und dieOLTP-Hybrid-Cloud-Funktionen zur Verfügung stehen. Weitere Einzelheiten zu diesen Funktionen und Highlights werden von der SQL Server-Blog zur Verfügung gestellt.
Hoffentlich ist diese Version kein Aprilscherz. ;-)

Uwe Ricken: Wie viele Datensätze passen auf eine Datenseite

Es versteht sich von selbst, dass diese Frage eher akademischer Natur ist und mehr dem Spaß am Ausprobieren gewidmet ist. Dennoch wurde diese Frage auf LinkedIn gestellt (http://tinyurl.com/q4zuxzc) und ich habe mir einfach mal die Arbeit gemacht, dieser Frage – aus rein akademischer Neugier – nachzugehen. Wer wissen möchte, wie viele Datensätze maximal auf eine Datenseite in einer Datenbank von Microsoft SQL Server 2012 passen, dem wünsche ich viel Spaß beim Lesen.

Struktur einer Datenseite

DataPage_01Eine Datenseite in Microsoft SQL Server hat immer eine Größe von 8.192 Bytes. Von diesen 8.192 Bytes sind 96 Bytes ausschließlich für den Header reserviert. Somit stehen 8.060 Bytes für die Speicherung von Daten zur Verfügung. Die Informationen über den Offset, an dem ein Datensatz auf einer Datenseite beginnt, werden im sogenannten Slot Array gespeichert. Für die Speicherung des Offset eines Datensatzes werden 2 Bytes benötigt!

Der Slot Array ist von großer Bedeutung, da die Datensätze von Microsoft SQL Server nicht zwischen bestehende Datensätze “sortiert” werden sondern – um möglichst schnell die Operation zu beenden – in einem Bereich, in den der Datensatz vollständig gespeichert werden kann. Anschließend wird das Offset mit den Informationen über den Beginn des Datensatzes im Slot Array hinterlegt um schnell auf den Datensatz in der Datenseite zugreifen zu können.

Struktur eines Datensatzes

Ein auf einer Datenseite gespeicherter Datensatz besteht nicht nur aus den Daten selbst sondern zusätzlich weitere Informationen über die Art des Datensatzes (Status), Spaltenzahl, Werte, etc. Die nachfolgende Aufzählung listet nur die Informationen auf, die in jeder Datensatzstruktur vorkommen.

  • 2 Bytes für den Datensatztypen und den Datensatzstatus
  • 2 Bytes für die Länge der Daten, die in Attributen mit fester Länge gespeichert werden
  • 2 Bytes für die Speicherung der Anzahl aller Attribute des Datensatzes
  • 2 Bytes für das NULL-Bitmap und die Anzahl der Attribute mit variabler Länge

Mögliche Anzahl von Datensätzen

Ausgehend von einer Tabelle mit einem Attribut von einem Datentypen, der nur 1 Byte benötigt (tinyint, byte) sieht die Gesamtlänge eines einzelnen Datensatzes wie folgt aus:

  • 8 Bytes für die Datensatzstruktur
  • 1 Byte für die Speicherung des Datenwerts
  • 2 Bytes für die Speicherung des Slot Arrays

Insgesamt hat ein solcher Datensatz – intern – eine Länge von 11 Bytes. Verteilt man die verbleibenden 8.060 Bytes auf die möglichen Datensätze, könnten 732 Datensätze gespeichert werden – rein rechnerisch; mal sehen, was der nachfolgende Test bringt…

Test

Das folgende Script erstellt eine Tabelle mit einem Attribut [C1] vom Datentypen [tinyint]. Das ist – neben dem Datentypen [bit] – der kleinste Datentyp und benötigt 1 Byte für die Speicherung von Daten.

CREATE TABLE dbo.little_table
(c1    tinyint    DEFAULT (1));
GO
 
-- 732 Datensätze in die Tabelle eintragen
INSERT INTO dbo.little_table DEFAULT VALUES;
GO 732
 
-- Anzeige der physikalischen Position
SELECT  *
FROM    dbo.little_table
        CROSS APPLY sys.fn_PhysLocCracker(%%physloc%%);
FN_PHYSLOCCRACKER_01

Das Ergebnis ist etwas überraschend. Der letzte belegte Slot auf der Datenseite 26.466 ist der Slot 700 und nicht – wie berechnet – 732! Der Datensatz 701 wird auf der Datenseite 24.468 weiter geführt.


Eine Datenseite in Microsoft SQL Server 2012 speichert nicht zwingend so lange Informationen, bis die Seite vollständig gefüllt ist sondern maximal 700 Datensätze. Berücksichtigt man die Tatsache, dass Datensätze in Microsoft SQL Server in der Regel eine Länge von mehr als 1 Byte besitzen, dürfte diese “Grenze” wohl nie erreicht werden.


Wie viel Platz ist auf der Datenseite noch vorhanden?


Wenn 700 Datensätze auf der Datenseite gespeichert wurden, statt – wie berechnet – 732, sollte auf der Datenseite noch ausreichend Platz vorhanden sein. Ein Blick auf den Header der Datenseite zeigt die Details:



DBCC TRACEON (3604);
DBCC PAGE ('demo_db', 1, 26466, 1);

DBCC_PAGE_01


Die obige Abbildung zeigt den Header der Datenseite. Es stehen insgesamt noch 396 Bytes an freiem Speicher zur Verfügung. Dieser Wert errechnet sich wie folgt:


8.192 Bytes – (700 * 2 Bytes) – 6.396 Bytes (Offset des nächsten freien Bereichs) = 396 Bytes


Obwohl also noch ausreichend Platz zur Verfügung steht, werden von Microsoft SQL Server nicht mehr als 700 Datensätze auf eine Datenseite gespeichert. Sollte als mal in einer Diskussionsrunde diese Frage auftauchen so lautet die Antwort nicht “42” sondern “700”


Herzlichen Dank fürs Lesen!

Christoph Muthmann: Updates für SQL Server 2012, 2008 R2 und 2008 (März 2014)

Ganz frisch erschienen und im SQL Server Releaseblog veröffentlicht wurden diese drei CUs.

Full story »

Torsten Schuessler: SQL Server 2014 has been released to manufacturing

Yesterday, Quentin Clark, corporate vice president of the Data Platform Group, announced that SQL Server 2014 has been released to manufacturing and will be generally available on April 1. Quentin’s blog discussed the tremendous momentum with the SQL Server business as well as SQL Server 2014’s new in-memory OLTP technology and hybrid cloud capabilities. Additional details on those capabilities and highlights are provided by the SQL Server Blog.

I wish you a nice day,
tosc

Falk Krahl: Neues Updates für SQL Server 2008 SP3

Auch für den SQL Server 2008 mit Servicepack 3 ist heute ein neues Update erschienen. Es handelt sich um das kumulative Update 16. Es kann unter folgendem Link angefordert werden:
SQL Server 2008 SP3 CU16

Falk Krahl: Neues Update für SQL Server 2012 SP1

Heute ist für den SQL Server 2012 mit Servicepack 1 ein neues Update erschienen. Es handelt sich um das kumulative Update 09. Es kann unter folgendem Link angefordert werden:
SQL Server 2012 SP1 CU09

Robert Panther: Neues kostenfreies SQL Server Tool: Idera SQL XEvent Profiler

Bekannterweise ist der SQL Server Profiler bereits abgekündigt, so dass er in einer der kommenden SQL Server Versionen nicht mehr verfügbar sein wird. Stattdessen empfiehlt Microsoft die Extended Events zu nutzen, die es bereits schon länger gibt. Während diese in früheren Versionen aber nur per T-SQL nutzbar waren, sind die Extended Events seit SQL Server 2012 endlich auch mehr oder minder komfortabel in das SQL Server Management Studio integriert.
Für die Leute, denen das aber noch zu umständlich ist, oder denen der Umstieg vom gewohnten SQL Server Profiler schwer fällt hat Tool-Anbieter Idera gerade den SQL XEvent Profiler als kostenfreies Tool veröffentlicht. Dabei lehnt sich die Oberfläche stark an den SQL Server Profiler an, nutzt aber intern die Extended Events, so dass der Server deutlich weniger belastet wird.
Ich habe das Tool gerade kurz getestet und bin soweit positiv beeindruckt. Zwar stehen je nach gewählter Vorlage wohl nur 10 verschiedene Events zur Verfügung, aber durch diese bewusste Reduktion ist es auf der anderen Seite sehr schnell und einfach möglich einen Überblick über die laufenden Aktivitäten eines SQL Servers zu bekommen. Was der SQL Server Profiler selbst nicht konnte ist die Möglichkeit, die Übersicht anhand einer Eigenschaft (z.B. der Datenbank) zu gruppieren. Ein Export der Liste nach Excel rundet das Ganze noch ab.
Die Reduktion aus wesentliche Features ist erfahrungsgemäß typisch für die kostenfreien Tools von Idera. Dadurch kommt man einerseits sehr schnell zu nutzbaren Ergebnissen. Andererseits bleibt so noch genug Spielraum für die kostenpflichtigen Tools, die einen wesentlich höheren Leistungsumfang bieten.

Verwendbare Extended Events:

  • existing_connection
  • login
  • logout
  • module_end
  • module_start
  • rpc_starting
  • rpc_completed
  • sp_statement_starting
  • sql_batch_completed
  • sql_batch_starting

Das Tool kann nach einer Registrierung bei Idera (www.idera.com) kostenfrei heruntergeladen und genutzt werden. Eine Installation erfolgt nur auf dem Client. Allerdings können nur SQL Server ab Version 2012 ausgewertet werden, da die älteren SQL Server noch nicht alle benötigten Extended Events bereitstellen.

Download Link: http://www.idera.com/productssolutions/freetools/sqlxeventprofiler

IderaSqlXEventProfiler


Marcel Franke: Conference time – From data to business advantage

imageI’m happy to say that I will present another session on Data Analytics together with Rafal Lukawiecki on the 21st of March in Zurich. This event is organized by Microsoft and Rafal and is focused on Data Analytics with the Microsoft platform.

I already met Rafal on the SQL Server Conference 2014 where he was giving the key not and he is a fantastic speaker. Beside conferences Rafal Lukwiecki is also a strategic Consultant at Project Botticelli Ltd (projectbotticelli.com) and he focuses on making advanced analytics easy, insightful, and useful, helping clients achieve better organizational performance. I’m a big fan of projectboticelli.com and I can encourage everybody who want’s to learn about Data Analytics to use his trainings and videos.

So if you are interested and you have some time, please join. You can register yourself here: https://msevents.microsoft.com/cui/EventDetail.aspx?EventID=1032573660&culture=de-CH


Marcel Franke: Analytic Powerhouse–Parallel Data Warehouse and R

It’s already some weeks ago since I presented this session about PDW and R at the SQL Server Conference in Darmstadt. The conference itself was very nice, we had about 350 participants, mostly from Germany. I wanted to take the chance to say thank you to organization team, especially to PASS and Microsoft.

For everybody who missed my talk, I uploaded my slides to slideshare: http://de.slideshare.net/marcelfranke/analytic-powerhouse-parallel-data-warehouse-und-r

All slides are still in German but I will write another blog post in English about the R integration and findings. If you have any questions or feedback, please let me know.

 

Tillmann Eitelberg: Google Analytics V3

In den letzten Monaten konnte ich nun endlich mal wieder Zeit in die Weiterentwicklung der SSIS GoogleAnalyticsSource Komponente stecken, und wesentliche Änderungen vornehmen. Neben vielen kleineren Bugfixes, sind im Wesentlichen 3 Kernfunktionen an der Komponente geändert worden. 1. Unterstützung von OAuth2 Google Analytics API V3 unterstützt das OAuth 2.0 Protokoll für die Authentifizierung und Autorisierung. […]

Andreas Wolter: DISABLE and DENY LOGIN, DENY USER & Effect on Impersonation and Permissions

DISABLE und DENY LOGIN, DENY USER & Effekt auf Impersonierung und Berechtigungen

(de)
Ein kurzer Artikel zu den Effekten – oder fehlenden Effekten – in Bezug auf das Deaktivieren & Verbieten von Connect für Logins und Users auf Impersonierung und Berechtigungen.

(en)
A short article on the effects - or missing effects - regarding the disabling & denying connect of Logins & Users on impersonation and permission.

Immer mal wieder kann man beobachten, dass Logins oder Usern die Connect-Berechtigung verboten bekommen wurde, oder ein Login deaktiviert wurde.

Die richtige Erwartung und Verständnis kann daher kritisch sein.

Sehen wir uns also eine einfache Demo an:
Wir werden das eingebaute sa-Konto, welches von vielen unter anderem als Datenbankbesitzer (mehr dazu bald in einem anderen Artikel – zwischenzeitlich lade ich Sie dazu ein, noch Daten zu der Umfrage zu diesem Thema einzusenden), ein weiteres frisch angelegtes Konto und eine Datenbank, genannt ImpersonateLogin mit dem entsprechenden User + einem weiteren User ohne Login: SQLUser.

Every once in a while one can observe that Logins or Users have been denied the Connect permission or a Login has been disabled.

Therefore a correct expectation and understanding can be critical.

So let’s see a simple demo:
We will use the built-in sa-Account, which is used by many as database owner among other (more on that soon in another article - meanwhile I do invite you to still send in data for the survey on that topic), another freshly created Account DeniedLogin and a database called ImpersonateLogin with the according User + another User without Login: SQLUser.

 DisabledPrincipals_Script

Ich deaktiviere also das sa-Konto ebenso wie das „DeniedLogin“-Konto – letzterem verbiete ich außerdem die Connect-Berechtigung (Erinnern wir uns daran: „Berechtigungen können nicht für sa, dbo, Entitäts-Besitzer, information_schema, sys oder für den Benutzer selbst erteilt, verweigert oder aufgehoben werden.“)

Der Datenbank-User „SQLUser“ bekommt die Connect-Berechtigung auf die Datenbank verboten.
In der GUI sieht das Ergebnis so aus:

So I am disabling the sa-account as well as the “DeniedLogin”-Account – the latter I also Deny the Connect permission (Remember we “Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.”)

The Database-User “SQLUser” gets denied the Connect permission on the database.

In the GUI the result looks like this:

 DisabledPrincipals_Setup_Disabled_Login

DisabledPrincipals_Setup_Disabled_sa

Nun führen wir 4 Tests durch:

Now let’s run 4 tests.

 DisabledPrincipals_Test1

Was diese Abfragen im Wesentlichen machen, ist, zu versuchen, den entsprechenden Login oder User zu impersonieren – und den Erfolg dadurch belegen, dass sie die dann jeweils aktiven Rollen-Mitgliedschaften zurückgeben.
Ergebnisse:

So essentially what those queries do, is trying to impersonate the respective Login or User – and proofing success by returning the then respective active role-memberships.

Results:

 DisabledPrincipals_Result

DeniedLogin: Impersonierung funktioniert + kein Verlust an Berechtigungen.
In other words: Denying Connect to a Login does not disallow Impersonation.
Impersonation is actually another permission which one can use and is not affected even by Disabling the Login!

DeniedLogin: Impersonation works + No loss of permissions.
In other words: Denying Connect to a Login does not disallow Impersonation.
Impersonation is actually another permission which one can use and is not affected even by Disabling the Login!

 DisabledPrincipals_Result

Dasselbe gilt für den sa: Impersonierung funktioniert + kein Verlust a Berechtigungen.

Im Folgenden ein Test für den User, dem die Connect-Berechtigung auf die Datenbank entzogen worden ist – und nicht als Login verwendet werden kann.

Same applies for sa: Impersonation works + No loss of permissions.

In the following test for the User which has been denied the Connect-permission onto the database – and cannot be used as a Login.

 DisabledPrincipals_Test2

Ergebnisse:

Msg 15517, Level 16, State 1, Line 3

Die Ausführung als Datenbankprinzipal ist nicht möglich, weil der Prinzipal 'DeniedLogin' nicht vorhanden ist,
für diesen Typ von Prinzipal kein Identitätswechsel möglich ist, oder Sie nicht die erforderliche Berechtigung haben.

 

Msg 916, Level 14, State 1, Line 3

Der Serverprinzipal 'S-1-9-3-4049223906-1289824279-1154161590-488313048.'
kann unter dem aktuellen Sicherheitskontext nicht auf die ImpersonateLogin-Datenbank zugreifen.

Results:

Msg 15517, Level 16, State 1, Line 3

Cannot execute as the database principal because the principal "DeniedLogin" does not exist,
this type of principal cannot be impersonated, or you do not have permission.

 

Msg 916, Level 14, State 1, Line 3

The server principal "S-1-9-3-4049223906-1289824279-1154161590-488313048."
is not able to access the database "ImpersonateLogin" under the current security context.

 

Das Ergebnis ist für beide Datenbank-User effektiv das gleiche.

Die GUID repräsentiert keinen reellen Server-Prinzipal, denn der User SQLUser hat keinen entsprechenden Login.
Daher sagt es uns, dass die User nicht innerhalb der Datenbank impersoniert werden können.

Der Unterschied für den 2. User ist, dass dieser User nur innerhalb der Datenbank existiert, aber zugleich expliziert verboten wurde, sich mit ihr zu verbinden Das hat im Endeffekt dasselbe Resultat, wie ihn zu deaktivieren – genau wie der Guest-User es ist.

The GUID does not represent a real server-principal, because the User SQLUser does not have a matching Login.
So it tells us, that the users cannot be impersonated inside the database.

The difference for the second user is, that this user only exists inside the database but at the same time has been explicitly denied to connect to it. This has essentially the same result as “disabling” it – just as the guest-user is.

 

Damit wäre gezeigt, dass das Deaktivieren von Logins keinerlei Sicherheit gegenüber Angriffen von Innen gibt. Und sogenannte Privilegien Erweiterung findet in aller Regel z.B. von innen heraus statt.

Auch der alte „Trick“, die Standard-Datenbank des Logins zu löschen, ist da keine Hilfe.

Für Datenbank-User hat es durchaus Effekt und verhindert das Anmelden an der jeweiligen Datenbank – auch „von Innen heraus“.

 

Thereby it is shown, that disabling of Logins does not give any security against attacks from inside. And so-called privilege elevation (/-escalation) usually takes part from internal.

Also the old “trick”, to drop the default-database of a Login, is of little help.

For database-users is indeed does have an effect and prevents logon/connect to the respective database – also “from inside”.

 

Konsequenterweise bleiben alle Berechtigungen (natürlich abgesehen von dem jeweiligen Deny) der jeweiligen Logins und User absolut unbeeinflusst von einer Deaktivierung jeglicher Weise.

Das gilt auch im Zusammenhang mit „External Access“-Berechtigung für Logins basierend auf asymmetrischen Schlüsseln.
(Hier ein Forum-Thread, in dem die Frage auftauchte: “SQL Login "disabled" flag does not work with asymmetric key??”)

ALTER LOGIN ist auch hier in BOL erklärt: technet.microsoft.com/en-us/library/ms189828.aspx

 

Ich hoffe, diese Dinge erklären einiges und speziell Empfehlungen in Sicherheits-Aspekten.

Consequentially all permissions (besides the one denied of course) of the respective Login and User stay totally unaffected by and method of deactivation.

This is also true in the context of “external access”-permission for Logins based on asymmetric keys.
(Here a forum-thread where the question appeared: “SQL Login "disabled" flag does not work with asymmetric key??”)

ALTER LOGIN is also explained in BOL here: technet.microsoft.com/en-us/library/ms189828.aspx

 

I hope those things clarified some things and especially recommendations in security-matters

 

Happy securing

Andreas

Christoph Muthmann: Prüfung auf mehrere Kriterien

Kürzlich erreichte mich die Anfrage aus unserer PASS-Gruppe, wie man am effektivsten aus einer Menge von Lieferungen diejenigen herausfinden könnte, wo mehrere Kriterien erfüllt sein müssten. Eine Kombination von Joins oder AND-Bedingungen schien nicht der richtige Weg zu sein.

Full story »

Falk Krahl: Neues Update für SQL Server 2008 R2 SP2

Für den SQL Server 2008 R2 mit SP 2 ist jetzt ein neues Update erschienen. Es handelt sich dabei um das kumulative Update 11. Es kann unter folgendem Link angefordert werden.
Kumulatives Update 11 für SQL Server 2008 R2 SP2

Andreas Wolter: Upcoming Conferences: SQLSaturdays in Denmark and Portugal. – Presenting In-Memory OLTP Deep-Dive for Administrators

 

(de)
Im März und April finden 2 europäischen SQLSaturdays statt, die Potential zu einem Geheimtipp haben:

Am 29. März in Kopenhagen, Dänemark
ind am 12. April in Lissabon, Portugal.

Da ich auch letztes Jahr bereits in Kopenhagen als Sprecher dabei war, kann ich aus erster Hand für die exzellente Organisation und Sprecherauswahl verbürgen.

Und für Portugal verbürgt mein sehr geschätzter Kollege Niko Neugebauer (Blog, Twitter:@NikoNeugebauer) – nach allem, was bisher „geleaked“ ist, wird es wieder ein Kongeniales Event. Würdig der ersten SQLSaturday-Location in Europa überhaupt.

(en)
In March and April, 2 European SQLSaturdays take place, which have the potential for a real insiders’ tip:

On March 29th in Copenhagen, Denmark
and April 12th in Lisbon, Portugal.

Since I already participated as a speaker in Copenhagen last year, I can avouch from “insider information” for the excellent organization and speaker choice.

And my much valued collegue Niko Neugebauer (Blog, Twitter:@NikoNeugebauer) vouches for Portugal – after all what has “leaked” in th emeantine, it will be another congenial event. Condign to the first SQLSaturday-Location in Europe ever.

SQLSaturday275_Denmark

Ich möchte zumindest einige, mir persönlich bekannte Sprecher namentlich erwähnen, aber gleich betonen, dass auch alle anderen Sessions definitiv einen Blick Wert sind(!):

In Dänemark sind dabei:

Die vollständige Agenda befindet sich hier: www.sqlsaturday.com/275/schedule.aspx

I would like to at least name some speakers, which I personally know, by name, but I would also like to stress immediately, that also all other sessions are definitely worth looking at just as well:

In Denmark there will be:

I am excited to see all of you again soon!

The complete Agenda can be found here: www.sqlsaturday.com/275/schedule.aspx

I am excited to see all of you again soon in Copenhagen!

SQLSaturday267_Portugal

In Portugal sind dabei:

Die vollständige Agenda befindet sich hier:

www.sqlsaturday.com/267/schedule.aspx

In Portugal there will be:

The complete Agenda can be found here: www.sqlsaturday.com/267/schedule.aspx

I am excited to see all of you again soon in Lisbon!

Und meine Wenigkeit, was präsentiere ich?
Nachdem ich mich nun seit November 2013, wo ich die neue Technologie in Deutschland erstmalig öffentlich präsentierte, eingehend mit eXtreme Transactional Processing, der neuen, integrierten, In-Memory Engine des SQL Server beschäftige, gibt es nun den Deep-Dive für Administratoren:

And my humble self, what am I presenting?
After I have been engaged deeply with eXtreme Transactional Processing, the new, integrated, In-Memory Engine of SQL Server, since November 2013, where I presented this new technology for the first time publically in Germany, I will now give a Deep-Dive for Administrators:

 

SQL Server 2014 In-Memory OLTP / XTP Management Deep Dive
@SQLSaturday Denmark & Portugal

You have heard about Hekaton, respectively the new acronym XTP (eXtreme Transactional Processing) and you want to know how it works under the cover? In this session we will take a closer look at the architecture, where the performance benefits come from and how it works in detail. What kind of files is SQL Server using for transactional consistency, what happens when you delete data inside the log and inside the data files. We will see the Merge-Process and the Garbage Collector in action, see how memory management works for XTP enabled databases, and thereby get an in-depth understanding of how this completely new storage engine works and how to optimize for it.

 

CU in Copenhagen, Lisbon.. or at another conference soon :-)

 

Andreas

Robert Panther: Tipps & Tricks: Datenbanken richtig verkleinern

Manchmal ist es tatsächlich sinnvoll, Datenbanken zu verkleinern, damit ungenutzter Platz wieder freigegeben wird. Auch wenn viele ausgewiesene SQL-Experten wie Brent Ozar, Paul Randal das Verkleinern von Datenbanken generell verteufeln, gibt es doch Ausnahmefälle, in denen eine Verkleinerung angebracht ist, sofern man diese richtig durchführt und sich der Auswirkungen bewusst ist.

“normale” Vergrößerung und Verkleinerung des Datenvolumens

In den meisten Datenbanken, werden Daten nicht nur gelesen, sondern auch geändert, hinzugefügt und gelöscht. Dabei sind die Datenbanken oft so konfiguriert, dass sie automatisch vergrößert werden, wenn durch Hinzufügen von neuen Daten mehr Platz benötigt wird. Das ist zwar nicht die optimale Variante (effektiver ist es, die Datenbank explizit so zu vergrößern, dass der benötigte Platz von vornherein schon zur Verfügung steht), aber immer noch besser als zu riskieren, dass keine Daten mehr geschrieben werden können, da das Datenfile komplett gefüllt ist. Wenn dagegen Daten aus der Datenbank gelöscht werden, so wird das eigentliche Datenvolumen zwar kleiner, das Datenfile aber nicht, da lediglich Lücken innerhalb des Datenfiles entstehen. Diesen Platz kann man nun für andere Dateien zur Verfügung stellen, indem man das Datenfile per SHRINK verkleinert. Dabei werden die Datenseiten vom Ende der Datei in die Lücken verschoben um diese zu schließen. Anschließend kann dann der nicht mehr verwendete Platz am Ende des Datenfiles freigegeben werden. Das klingt zwar auf den ersten Blick ganz gut, bringt jedoch diverse Probleme mit sich, weshalb allgemein empfohlen wird, Datenbanken nicht zu shrinken:

  1. Durch das Verschieben der Datenseiten im File werden die Indizes massiv fragmentiert. Während also die externe Fragmentierung der Datendatei aufgelöst wird, entsteht eine interne Fragmentierung der Indizes, was schnell dazu führen kann, dass diese nicht mehr verwendet werden können.
  2. Wenn später wieder neue Daten in die Datenbank geschrieben werden, muss das Datenfile wieder wachsen, was zusätzlichen Aufwand bedeutet und außerdem zu erneuter externer Fragmentierung führt.

Aus diesen Gründen ist insbesondere das regelmäßige Verkleinern von Datenbanken über SQL Agent Jobs im Zuge von Wartungstasks keine gute Idee. Schlimmer noch ist die Verwendung der AUTO SHRINK Option in den Datenbankeigenschaften, da dies in Kombination mit der Automatischen vergrößerung zu einem ständigen Verkleinern und Vergrößern der Datenbankdatei führt, was eine hohe I/O-Last zur Folge hat und die Datenbank extrem fragmentiert. Geoff N. Hiten zieht daher in seinem Blog treffenderweise die Analogie von Auto-Shrink zu Auto-Fragmenting.

Wenn schon verkleinern, dann aber richtig!

Aber wie bereits eingangs erwähnt, bin ich der festen Überzeugung, dass es gelegentlich auch Situationen gibt, in denen ein Shrink sinnvoll sein kann. Das ist genau dann der Fall, wenn aufgrund einer größeren Bereinigungsaktion große Datenmengen aus der Datenbank gelöscht werden. Achtung: Ich rede hier nicht von regelmäßigen (z.B. jährlichen) Bereinigungsaktionen, denn dann kann man sich den Aufwand für den Shrink sparen, da der Platz bis zur nächsten Bereinigungsaktion ohnehin wieder benötigt wird. Es geht vielmehr um einmalige Aktionen, beispielsweise wenn eine große Tabelle mit mehreren hundert GB komplett entfernt wird, so dass der damit frei werdende Platz auch in absehbarer Zeit nicht durch das natürliche Wachstum der Datenbank benötigt wird.

Was ist nun zu beachten, um bei dieser SHRINK-Aktion keinen Schaden anzurichten:

  1. Nach dem Shrink eine Defragmentierung der Indizes durchführen.
  2. Genügend Zeit einplanen (sowohl Shrink als auch Index-Defrag können sehr lange dauern).
  3. Notfalls in mehreren kleinen Steps (z.B. 50 GB) Shrinken und danach jeweils Defragmentierung durchführen, dann kann die Aktion auf mehrere Wartungsfenster verteilt werden. Allerdings muss man sich dann bewusst sein, dass sich die Gesamtdauer der Aktion durch die mehrfach notwendige Index-Defragmentierung weiter erhöht.
  4. Wenn der Shrink unbeaufsichtigt (z.B. am Wochenende) läuft, einen separaten SQL Agent-Job einplanen, der den Shrink-Prozess rechtzeitig abbricht (falls dieser noch nicht fertig ist) und den Index-Defrag startet. Das Shrinken selbst kann jederzeit problemlos abgebrochen werden (selbst durch einen KILL des Prozesses). Die bis dahin verschobenen Speicherseiten bleiben an der neuen Position, auch wenn sich das Datenfile selbst erst nach komplettem Abschluss einer Shrink-Anweisung verkleinert. Bei erneuter Ausführung der Shrink-Anweisung wird dann im Prinzip an derselben Stelle weiter gemacht.
  5. Der Shrink sollte nie bis zur kleinstmöglichen Datenbankgröße durchgeführt werden. Stattdessen immer das natürliche Wachstum der Datenbank mit einplanen, so dass nicht kurz danach wieder ein Vergrößern des Datenfiles erforderlich wird (und zu erneuter externer Fragmentierung führt).

Zusammenfassend kann man also festhalten:

  • Regelmäßiges SHRINKen ist böse!
  • Auto-Shrink ist sehr böse!
  • Aber: Gezieltes Shrinken kann in Ausnahmefällen sinnvoll sein, wenn man danach auch die Indizes defragmentiert!

Weitere Blog-Beiträge zum Thema:


Philipp Lenz: SQL Server 2008/R2 – out of Mainstream Support – vote here!

Microsoft-SQL-Server-2008-R2Der SQL Server 2008 und R2 laufen im Juli aus dem Mainstream Support raus, falls Microsoft hier kein Service Pack mehr ausliefert. Daher hoffe ich, dass hier genügend Stimmen zusammen kommen, damit hier je ein SP veröffentlicht wird und es so abschliessend nicht zu einer Sammlung von CU oder Hotfixen kommt.

Hier zur Wahl auf MS Connect: https://connect.microsoft.com/SQLServer/feedback/details/814658/release-final-service-packs-for-sql-server-2008-and-2008-r2

Andreas Wolter: Spezialrabattaktionen: 22% zum Jubiläumsjahr der PASS Deutschland e.V für Sicherheits- XEvent Tracing, sowie SQL Server 2014 Seminare + 10% Microsoft TechNet Aktion für alle

Damit auch alle, die vor 2 Wochen nicht auf der SQL Konferenz in Darmstadt (www.sqlkonferenz.de) waren, oder nicht regelmäßig bei TechNet vorbeischauen, eine Chance haben, poste ich es hier einmal öffentlich:

1)       Zum Jubiläumsjahr der PASS Deutschland e.V erhalten alle Mitglieder den „Jubiläums-Rabatt“ von 22 Prozent (!) auf die folgenden SQL Server Master-Classes:

birthday-cake

(SES) SQL Server Security Essentials für Entwickler & Administratoren – am 3. April 2014 in Düsseldorf
- Dieses Seminar ist für alle Einsteiger geeignet, die hier alle Grundlagen für die Sicherheitsverwaltung & Architektur von SQL Server erlernen.

(SIA) Securityworkshop for SQL Server Administrators (advanced) – 4. April 2014 in Düsseldorf
- In diesem Workshop werden sicherheitsrelevante Internas der Authentifizierung, das Konzept der Contained Databases, Daten- & Backupverschlüsselung mit Transparent Data Encryption (TDE) bis hin zu Überwachungstechniken in SQL Server erlernt.

(XE1) Einsteiger-Workshop Tracing mit Extended Events in SQL Server - am 7. März 2014 in Frankfurt am Main
- Das Grundlagentraining für alle, die den Nachfolger von SQL Trace & Profiler von Grund auf beherrschen möchten.

(XE3) FastTrack to Tracing with Extended Events for SQL Server - am 1. April 2014 in Frankfurt am Main
- Für Einsteiger, die die Funktionalitäten und Einsatzmöglichkeiten der Extended Events von A-Z an einem verlängerten Tag kennenlernen möchten.

(UP2014) Aktualisierung der Kenntnisse von SQL Server 2012 auf SQL Server 2014 - am 15. Mai 2014 in Frankfurt am Main
- Der neue SQL Server 2014 steht vor der Tür. Von Buffer-Pool Erweiterungen bis zu In-Memory OLTP enthält dieser viele wichtige neue Technologien, die an diesem Tag praxisnah kennengelernt werden.

(XTC) Workshop In-Memory OLTP & ColumnStore - New Storage Engines in SQL Server 2014 - am 16. Mai 2014 in Frankfurt am Main
- An diesem eintägigen Workshop werden die neuen und verbesserten In-Memory Technologien XTP für extrem performantes OLTP und Clustered Columnstore Indexes für DataWarehousing in aller Tiefe praktisch kennengelernt.

Und das ist der Gutschein-Code (exklusiv für Mitglieder der PASS Deutschland e.V.):
10PASSDE2014 *1 *2

Tipp: jeder kann sich jederzeit noch schnell und kostenlos(!) als Mitglied bei der PASS Deutschland e.V. anmelden – Details dazu auf der Webseite der PASS: www.sqlpass.de/Mitgliedschaft/Mitgliedwerdenistkostenlos.aspx

 

2)       Außerdem freue ich mich, noch auf eine andere Aktion, und zwar in Zusammenarbeit mit der  Microsoft Technet IT Pro Academy hinweisen zu können. Für ausgewählte Seminare gibt es einen speziellen Rabattcode *1, der hier über die TechNet-Seite zu finden ist: technet.microsoft.com/de-de/bb291022?it_product=sql-server&it_topic=zertifizieren, für 10% auf weitere Seminare:


(PAT) Workshop Performance und Analyse, Techniken & -Tools
- 17./18. März 201

(SHA) Workshop Hochverfügbarkeit für SQL Server - 6./7. Mai 2014


*1  Rabatt-Codes können nicht mit anderen Codes kombiniert werden
*2 Dieser Code ist gültig bei Verwendung bis zum bis 30.4.2014


Und hier findet Ihr die Gesamtübersicht der SQL Server Master-Classes und Links zur Anmeldung:
www.sarpedonqualitylab.com/SQL_Master-Classes.htm



Viel Spaß beim Lernen wünscht

Der Andreas

 

Microsoft Certified Solutions Master Data Platform (SQL Server 2012)
Microsoft Certified Master SQL Server 2008
Microsoft Certified Trainer

Uwe Ricken: Performancevorteile durch Instant File Initialization

Beim Anlegen von Datenbankdateien (Daten, Log) werden standardmäßig die zu erstellenden Dateien beim Initialisieren mit 0 aufgefüllt, damit eventuell auf dem Datenträger zurückgebliebene Daten von vorherigen (gelöschten) Dateien überschrieben werden. Dieses Verfahren betrifft nicht nur das Erstellen neuer Datenbanken sondern auch die Wiederherstellung von Datenbanken aus einem Backup oder die stetige Vergrößerung einer Datenbank. Welchen Einfluss diese Vorgänge auf die Leistung von Microsoft SQL Server hat, beschreibt der nachfolgende Artikel.

Was ist Instant File Initialization?

Mit Instant File Initialization lässt sich der Prozess des Erstellens oder Vergrößerns von Dateien beschleunigen, indem das Überschreiben von neuem Speicher für die Datenbankdatei (Zeroing out) nicht durchgeführt wird. Microsoft SQL Server erstellt die Datei und alloziert ihn zwar; aber der langwierige Prozess des Überschreibens bleibt aus. Dieser Vorteil kann nur auf Datenbankdateien angewendet werden, Transaktionsprotokolle können diesen Vorteil nicht nutzen. Dass Transaktionsprotokoll-Dateien diesen Vorteil nicht nutzen können, hängt damit zusammen, dass das Transaktionsprotokoll ein rotierendes Verfahren verwendet, um freie / ungenutzte VLF (Virtual Log File) wieder zu verwenden.

Vorteil von Instant File Initialization

Durch das Verhindern von “Zeroing Out” steht eine Datenbank schneller (wieder) zur Verfügung. Instant File Initialization kann bei den folgenden Prozessen einen erheblichen Geschwindigkeitsvorteil bringen:

  • CREATE DATABASE
  • ALTER DATABASE … MODIFY FILE
  • RESTORE DATABASE
  • AUTOGROWTH für Datenbanken

Alle vier genannten Prozesse haben eines gemeinsam; sie erstellen oder ändern Datenbankdateien, die von Microsoft SQL Server verwaltet werden.

Nachteil von Instant File Initialization

Da Instant File Initialization vorhandenen und allozierten Speicher nicht überschreibt, besteht die Gefahr, dass mit geeigneter Software Daten, die vorher von der Festplatte gelöscht wurden, ausgelesen werden können. Es muss vor der Aktivierung eine Sicherheitsbewertung erfolgen; wird der Speicher auch für “normale” Filesystem-Aktivitäten verwendet oder werden Datenbanken häufig gelöscht, sollte auf Instant File Initialization eventuell verzichtet werden.

Wie kann man erkennen, ob Microsoft SQL Server “Instant File Initialization” verwendet?

Instant File Initialization kann man NICHT in Microsoft SQL Server konfigurieren, da es sich dabei nicht um eine Funktionalität von Microsoft SQL Server handelt, sondern ein Sicherheitsprivileg, dass dem Dienstkonto der ausgeführten Instanz von Microsoft SQL Server zugewiesen werden kann.

Um festzustellen, ob Instant File Initialization aktiviert ist, gibt es zwei Möglichkeiten:

  • Außerhalb von Microsoft SQL Server: Überprüfung der lokalen Sicherheitsrichtlinie
  • In Microsoft SQL Server: Anlegen einer neuen Datenbank bei gleichzeitiger Protokollierung in das Fehlerprotokoll

Lokale Sicherheitsrichtlinie

Instant File Initialization ist ein Sicherheitsprivileg, dass standardmäßig nur Administratoren zugewiesen ist. Die lokalen Sicherheitsrichtlinien wird durch den Start von [secpol.msc] ausgeführt.

Lokale_Sicherheitsrichtlinie_01

In einem englischsprachigen System heißt die oben gezeigte Richtlinie “Perform Volume Maintenance Tasks” und findet sich in [User Rights Assignment]. Ist das Dienstkonto von Microsoft SQL Server dieser Sicherheitsrichtlinie zugeordnet, ist Instant File Initialization für Microsoft SQL Server aktiviert.

Prüfung aus Microsoft SQL Server

In einem Umfeld, in dem ein DBA keinen unmittelbaren Zugang zum Betriebssystem besitzt (Segregation of Duty), gibt es ebenfalls eine Möglichkeit, zu testen, ob das Dienstkonto von Microsoft SQL Server das Privileg besitzt. Das nachfolgende Script startet die Protokollierung und legt eine neu Datenbank mit einer Initialgröße von 1.500 MB (1 GB für Daten und 500 MB für das Protokoll) an.

-- Aktivierung der Protokollierung
DBCC TRACEON (3004, 3605, -1);
 
-- Erstellung einer neuen Database mit einer initialen Größe
-- von 1 GB für Daten und 500 MB für das Log
CREATE DATABASE Test
ON PRIMARY
(
    NAME = 'Test',
    FILENAME = 'S:\BACKUP\Test.mdf',
    SIZE = 1000MB,
    MAXSIZE = 10000MB,
    FILEGROWTH = 0MB
)
LOG ON
(
    NAME = 'Test_Log',
    FILENAME = 'S:\BACKUP\Test.ldf',
    SIZE = 500MB,
    MAXSIZE = 500MB,
    FILEGROWTH = 0MB
);
GO
 
-- Auslesen des Fehlerprotokolls von Microsoft SQL Server
EXEC xp_readerrorlog;

Nachdem die neue Datenbank angelegt wurde, wird das Fehlerprotokoll ausgelesen, dessen Inhalt in der nachfolgenden Abbildung gezeigt wird.


XP_READERRORLOG_01


Die Zeilen 12 – 18 zeigen, dass “Instant File Initialization” für das Dienstkonto NT Service\MSSQL$SQL_2012 nicht zur Verfügung steht; die Datendatei wurde mittels “Zeroing” mit 0 gefüllt. Für das Anlegen einer Datenbankdatei für die TEST-Datenbank benötigte das System 17 Sekunden (Zeile 12 - 13). Für das Anlegen der Protokolldatei wurden 9 Sekunden benötigt. Insgesamt werden für das Erstellen der Datenbank [Test] 26 Sekunden benötigt. Das Protokoll für das Erstellen der Datenbank bei Zuweisung des Rechts für das Dienstkonto sieht wie folgt aus:


XP_READERRORLOG_02


Deutlich ist zu erkennen, dass – wie bereits oben ausgeführt – ausschließlich die Protokolldatei den Prozess des “Zeroing” über sich ergehen lassen muss. Da die Datenbankdatei unmittelbar erstellt wurde, ist die Datenbank innerhalb von 9 Sekunden betriebsbereit.


Instant File Initialization bei neuen Datenbanken


Wie die Tests demonstrieren, liegt der Vorteil bei der Anlage von neuen Datenbanken in der Bereitstellung der Datenbank innerhalb weniger Sekunden. In der Regel ist das Erstellen von neuen Datenbanken – sofern es nicht aus Applikation selbst geschieht – kein zeitkritischer Vorgang.


Instant File Initialization bei Wiederherstellung von Datensicherungen


Die Wiederherstellung einer Datenbank kann ein zeitkritisches Problem werden, wenn zum Beispiel die Produktionsdatenbank betroffen ist. Exakt dieser Umstand wurde einem Kunden zum Opfer, der eine Datenbank mit einer Dateigröße für die Daten von 750 GB wiederherstellen musste. Tragisch an dieser Situation war, dass die Datenbank selbst nur zu ca. 50% mit Daten gefüllt war. Die Wiederherstellung verzögert sich um die Zeit, die für das “Zeroing” benötigt wird. Dieser Vorgang kann jedoch eingespart werden, da die Daten unmittelbar nach der Initialisierung in die neu angelegten Datenbank-Dateien geschrieben werden.


Instant File Initialization beim Vergrößern von Datenbanken


In vielen Microsoft SQL Server Installationen ist auffällig, dass die Vergrößerung einer Datenbank entweder sehr klein gewählt wurde (1 MB) oder aber – für den angegebenen Workload – zu groß. Entscheidend für beide Szenarien ist, dass bei fehlendem Recht für “Instant File Initialization” die Anwendungen unverhältnismäßig lange warten müssen, bis das “Zeroing” abgeschlossen ist. Ist ein hoher Workload in der Applikation erkennbar, wird bei einem Vergrößerungsintervall von 1 MB zu oft die Datenbank erweitert und ein “Zeroing” initiiert. Bei einer Größe von 500 MB müsste die Applikation ca. 9 Sekunden warten, bis der Prozess abgeschlossen ist. Für eine Anwendung, die fast ausschließlich auf hohe OLTP-Vorgänge beschränkt ist, ein absolutes K.O-Kriterium.


Testmessungen



Um ein Gefühl für die Zeitunterschiede zu vermitteln, wurde eine Testdatenbank mit verschiedenen Größen und auf verschiedenen Medien erstellt. Für die Messungen wird die Testdatenbank in vier unterschiedlichen Größen (100 MB, 500 MB, 1.000 MB, 2.000 MB) mit identischer Größe für die Protokolldatei (100 MB) sowohl auf einer HDD als auch einer SDD erstellt. Eine Messung erfolgt mit jeweils aktivierter (IFI) und deaktivierter (No IFI) Berechtigung. Für die Messungen wurden als HDD eine [Toshiba MK5061GSY] mit einer Blockgröße von 64 KBytes verwendet. Für die Tests auf der SSD wurde eine [CRUCIAL CT960M500] verwendet, die ebenfalls eine Blockgröße von 64 KBytes verwendet.


Tabelle_Messergebnisse


Klar erkennbar ist, dass – unabhängig von HDD und/oder SDD die Erstellungszeiten fast proportional wachsen, wenn “Instant File Initialization” nicht möglich ist. Bei Aktivierung sind die Zeiten nahezu identisch, da die Größe der Protokolldatei in allen Tests identisch ist. Die Variationen rühren wohl eher aus Streuungen!


Messungen_Grafik


Bei einer 500 GB großen Datenbank würde die Erstellung auf einer HDD bei deaktiviertem “Instant File Initialization” nahezu 3 Stunden benötigen! Selbst auf einer SSD müssen immer noch ca. 35 Minuten vergehen, bevor die Datenbank online ist. Da in der Regel neue Datenbanken eher in kleineren Dimensionen erstellt werden, sind diese Zeiten wohl eher zu vernachlässigen. Jedoch sieht es bei der Wiederherstellung von Datenbanken ganz anders aus. Müssen erst die erstellten Datenbankdateien mittels “Zeroing out” überschrieben werden, kann so eine nicht unerhebliche Zeit für die Wiederherstellung vergehen. Ein Umstand, der in einer Produktionsumgebung bei entsprechendem SLA schnell zu Problemen führen kann.


Zeitweise Deaktivierung von Instant File Initialization


Die durchgeführten Tests kann man auf dem eigenen Datenbanksystem selbst durchspielen, ohne die Berechtigung immer wieder zu ändern (und damit einen Neustart des Dienstes durchzuführen). Sollte auf den eigenen Systemen Instant File Initialization aktiviert sein, so kann man diese Option zeitweilig mit dem Traceflag 1806 zwischenzeitlich deaktivieren.


Der Vorteil dieses Traceflags besteht vor allen darin, dass Datenbanken, die einer höhere Sicherheitsstufe unterliegen, bei der Erstellung  einem “Zeroing out” unterzogen werden.


Einschränkungen von Instant File Initialization


Instant File Initialization unterliegt besonderen Einschränkungen, die im Vorfeld geprüft werden müssen. So ist Instant File Initialization nur möglich, wenn die nachfolgenden Voraussetzungen erfüllt sind:



Zusammenfassung


Instant File Initialization gibt dem DBA die Möglichkeit, Datenbankoperationen, die einen unmittelbaren Einfluss auf die Eigenschaften der Datenbankdateien besitzen, durch “Instant File Initialization” zu beschleunigen. Bevor man Instant File Initialization aktiviert, sollte das betriebliche Umfeld sehr genau geprüft werden. Insbesondere ein Blick auf das Dateisystem in Verbindung mit der Sensibilität der Daten ist ein wichtiges Kriterium für die Aktivierung / Deaktivierung. In größeren Unternehmen gibt es eine klare Trennung von Aufgaben (Segregation of Duty). Ein Gespräch mit dem verantwortlichen Administrator für das Betriebssystem schafft schnell Klarheit.


Insgesamt kommt die Bedeutung von Instant File Initialization nicht bei der Erstellung von “neuen” Datenbanken zum tragen. Vielmehr ist bei zeitkritischen Wiederherstellungsszenarien diese Option von größerer Bedeutung. Auch bei Applikationen, die sehr viele Daten schreiben und somit die Datenbank regelmäßig vergrößern müssen, ist Instant File Initialization ein Gewinn für die Geschwindigkeit und Stabilität der Applikation.


Sollten die Richtlinien des Unternehmens Instant File Initialization verhindern, so wäre aus meiner Sicht das Recht zu erteilen und der SQL Server Dienst mit dem Traceflag 1806 zu starten. Somit wäre Instant File Initialization grundsätzlich nicht möglich – es wäre aber für einen Administrator im Falle einer Wiederherstellung einer großen Datenbank aus einem Backup möglich, für diese Operation Instant File Initialization zeitweise zu aktivieren.


Herzlichen Dank fürs Lesen!

Christoph Muthmann: Unable to find the requested .Net Framework Data Provider

Unsere Umstellung auf SQL Server 2012 läuft und nun hat man sich mit den ersten Schwierigkeiten auseinanderzusetzen. Ein SSIS-Paket lief nicht mehr unter SQL Server 2012, obwohl es auf dem Entwicklungs-PC (Windows 7) problemlos funktionierte.

Full story »

Torsten Schuessler: SQL Server 2012 System Views Map

Something I forgot... we talk about, Christoph :-)

SQL Server 2012 System Views Map

The Microsoft SQL Server 2012 System Views Map shows the key system views included in Microsoft SQL Server 2012, and the relationships between them. The map is similar to the prior versions of Microsoft SQL Server System Views Maps and includes updates for the Microsoft SQL Server 2012. Note that not all possible relationships are shown.

You can download it from here!

And...

Microsoft Business Intelligence at a Glance Poster

The poster summarizes the benefits of Microsoft's BI technologies and depicts them by layer: client (such as BI in Excel), the presentation subsystem (such as SharePoint 2013), information sources (such as Reporting Services), and data sources (such as relational databases). It focuses on the enterprise architect and IT implementer audience. It includes Office 2013 client and server, SQL Server 2012 with SP1, and BI services in Windows Azure.

You can download it from here!

I wish you a nice  day,
tosc

Christoph Muthmann: Erste Bilder der SQL Konferenz Online

Vielen Dank an Dirk Hondong, der mir die ersten Bilder der SQL Konferenz zur Verfügung gestellt hat.

Full story »

Sascha Lorenz: Clipboard Calculator – Neue Version

Im Januar habe ich ein neues kleines Tool von mir vorgestellt, den Clipboard Calculator.

Von der Menge an Feedback und den Download Statistiken war ich sehr überrascht. Anscheinend haben viele von Euch auf genau so etwas nur gewartet.

Nun wurde es Zeit für eine erste kleine Erweiterung. Der Dialog wurde ein wenig vergrößert. Hinzugekommen ist eine Historisierungsfunktion für die errechneten Summen und um ein Feld, welches immer die Differenz zwischen dem aktuellen “großen” Wert und dem in der Listbox selektierten Wert ausgibt. Die letzten Wochen haben gezeigt, dass sich damit Summen in Data Warehouse Entwicklungen usw. leichter mal schnell im Management Studio verproben lassen ohne immer alles aufzuschreiben oder weitere Tools zu bemühen.

image

Die aktuelle Version findet Ihr als Download wieder am bekannten Ort.

Und wieder bin ich für Feedback dankbar. Als Nächstes kommt dann die Formatierung der Werte dran. Versprochen! 

Uwe Ricken: Eigene Systemprozeduren im Kontext der aktuellen Datenbank nutzen

Während der Vorbereitungen zu meinem Vortrag “DMO für die Analyse von Indexen” für die SQL Server Konferenz 2014 in Darmstadt wollte ich es mir einfach machen und eine Stored Procedure für die Ausgabe der Analyse programmieren, die in jeder Benutzerdatenbank verwendet werden kann. Dieser Prozedur wird nur noch der Name des zu analysierenden Objekts sowie die Index Id für die Ausgabe übergeben. Während der Tests gab es jedoch Schwierigkeiten, weil ein Aufruf in der Demo-Datenbank keine Daten lieferte. Die Ursache war schnell gefunden; einige Objekte in der Prozedur wurden im Kontext der master- Datenbank ausgeführt. Wie man eine Prozedur dazu veranlassen kann, dass sie trotz Speicherung in der master-Datenbank immer im Kontext der aktuellen Datenbank ausgeführt wird, zeigt dieser Artikel.

Systemprozeduren

In Microsoft SQL Server versteht man als Systemprozedur eine Stored Procedures, die in der master-Datenbank gespeichert wird und mit dem Präfix ‘sp_’ beginnt”; das ist die weit verbreitete Erklärung für diese Art von Objekten. Ich lasse diese Behauptung zunächst einmal zu stehen und gehe darauf weiter unten noch einmal genauer ein! “Alle Objekte in der master-Datenbank mit diesem Präfix können aus jeder beliebigen Datenbank aufgerufen und verwendet werden.”; auch das ist eine weit verbreitete Aussage, die so – pauschal –  nicht richtig ist! Dennoch werde ich für den Rest dieses Abschnitts auch weiterhin den Ausdruck der “Systemprozedur” verwenden.

Systemprocedures

Die Abbildung zeigt einen Ausschnitt aus der master-Datenbank. Systemprozeduren sind im sys-Schema gespeichert. In dieses Schema können keine eigenen Objekte gespeichert werden.

Der Versuch wird mit einem entsprechenden Fehler quittiert. Systemprozeduren werden jedoch auch im dbo-Schema erkannt. Dort können eigene Tabellen / Views / Prozeduren hinterlegt werden.

Systemprozeduren unterscheiden sich von “normalen” Prozeduren durch die Möglichkeit des Aufrufs. Eine Systemprozedur kann unter bestimmten Voraussetzungen aus jedem beliebigen Kontext und aus jeder beliebigen Benutzerdatenbank aufgerufen werden. Dieses Verfahren habe ich bereits im Artikel “Optimierung von Datenbankmodellen – Richtige Wahl von Datentypen und Indexen (2)” beschrieben, in dem es darum ging, Informationen aus DBCC IND in einer Tabelle zu speichern, um die Daten nachträglich zu analysieren. Diesen Tipp habe ich während meiner Vorbereitungen zum Microsoft Certified Master von Kimberly L. Tripp (Blog) übernommen.

sp_ = Systemprozedur?

Sehr häufig wird behauptet, dass Prozeduren, deren Namen mit “sp_” eingeleitet werden, automatisch Systemprozeduren sind. Das ist aber nicht der Fall;  diese Aussage resultiert aus der Tatsache, dass Microsoft bereits in früheren Versionen von Microsoft SQL Server Systemobjekte mit dem Präfix sp_ benannt hat. Irgendwie hat sich dadurch der Eindruck verstärkt, dass Objekte dieser Art immer Systemobjekte sind. Das nachfolgende Beispiel zeigt, dass nicht nur der Name sondern – besonders – der Speicherort wesentlich zur Behauptung beiträgt.

USE master;
GO
 
CREATE PROC dbo.sp_demo
AS
    PRINT 'Ich bin eine Prozedur aus master'
GO
 
GRANT EXECUTE ON dbo.sp_demo TO public;
GO
 
USE demo_db;
GO
 
CREATE SCHEMA sp AUTHORIZATION dbo;
GO
 
CREATE PROC dbo.sp_demo
AS
    PRINT 'Ich bin eine Prozedur im Schema [dbo] aus demo_db'
GO
 
CREATE PROC sp.sp_demo
AS
    PRINT 'Ich bin eine Prozedur im Schema [sp] aus demo_db';
GO
 
GRANT EXECUTE ON dbo.sp_demo TO public;
GRANT EXECUTE ON sp.sp_demo TO public;
GO
 
CREATE USER sp_user WITHOUT LOGIN WITH DEFAULT_SCHEMA = [sp];
GO

Das Skript erzeugt in der master-Datenbank ein Objekt mit dem Namen [sp_demo] im [dbo]-Schema und gewährt die Berechtigung zur Ausführung für alle Benutzer. Anschließend werden zwei weitere Objekte mit gleichem Namen in der Datenbank [demo_db] erzeugt. Eines der genannten Objekte wird in dem zuvor erstellten Schema [sp] erstellt. Nachdem die Rechte an den Objekten in der Datenbank erteilt wurden, wird ein Testbenutzer für die Demonstration erstellt. Dieser Testbenutzer verwendet als Standardschema [sp]! Zunächst wird “die Prozedur” als dbo ausgeführt. Das Ergebnis sieht wie folgt aus:


EXECUTE_AS_DBO_01


Es ist zu erkennen, dass nicht die “Systemprozedur” aus der master-Datenbank ausgeführt wurde.


Das Standardschema des Datenbankbenutzers [dbo] ist das Schema [dbo]. Im Standardschema des angemeldeten Benutzers wird zuerst nach einem Objekt gesucht, wenn keine voll qualifizierte Objektangabe  ([Schema].[objectname]) gemacht wird. Da ein Schema nicht explizit angegeben wurde, wird die Prozedur aus dem Standardschema ausgeführt. Gleiches Spiel – aber diesmal für den Benutzer sp_user:


EXECUTE_AS_SP_USER_01


Im gezeigten Skript wird im Kontext des zuvor erstellten Datenbankbenutzers sp_user die Prozedur [sp_demo] in zwei unterschiedlichen Varianten ausgeführt.


Die Prozedur wird ohne Schema-Qualifikation aufgerufen und das Ergebnis zeigt, dass die Prozedur aus dem Schema [sp] ausgeführt wurde.


Im zweiten Beispiel wird das Schema angegeben und somit wird Microsoft SQL Server angewiesen, unmittelbar im dbo-Schema nach dem Objekt zu suchen und es auszuführen.


Nun wird das Objekt [sp].[sp_demo] aus der Datenbank gelöscht und der Benutzer sp_user führt erneut die obige Befehlsreihenfolge aus.



-- Ausführung als dbo
USE demo_db;
GO
 
DROP PROC sp.sp_demo;
GO
 
EXECUTE AS User = 'sp_user';
EXEC sp_demo;
EXEC dbo.sp_demo;
REVERT;
EXECUTE_AS_SP_USER_02

Das Ergebnis zeigt, dass die weiter oben beschriebene Aufrufreihenfolge funktioniert. Die Prozedur [sp].[sp_demo] wurde gelöscht und wenn der Datenbankbenutzer nun die Ausführung startet, stellt Microsoft SQL Server fest, dass ein Objekt im Standardschema nicht existiert.


Es folgt der nächste Aufruf aus dem Schema [dbo]. Dort wird die Prozedur gefunden und ausgeführt. Das Ergebnis ist die Meldung in der ersten Zeile. Sie ist identisch mit dem Ergebnis des zweiten Aufrufs, der das Schema explizit angibt.


Ist jedoch in der Datenbank kein Objekt mit dem Namen vorhanden, sieht das Ergebnis anders aus:



USE demo_db;
GO
 
DROP PROC dbo.sp_demo;
GO
 
EXECUTE AS User = 'sp_user';
EXEC sp_demo;
EXEC dbo.sp_demo;
REVERT;
EXECUTE_AS_SP_USER_03

Da nun in der Benutzerdatenbank weder ein gültiges Objekt im Standardschema des Datenbankbenutzers noch im dbo-Schema vorhanden ist, sucht Microsoft SQL Server in der master-Datenbank.


Dieses Verfahren funktioniert nur mit Objekten, die das Präfix ‘sp_’ besitzen. Bei diesem Verhalten jedoch von “Systemprozeduren” auszugehen, ist nicht korrekt wie der nächste Abschnitt deutlich zeigt.


Ausführungskontext einer Prozedur in master-Datenbank


NO_SYSTEM_PROC_SQL_SSMS_01Wie beschrieben, definiert sich eine Systemprozedur weder durch das Präfix noch durch ihren Speicherort. Eine Prozedur, die in der master-Datenbank gespeichert wird, ist zunächst einmal ein gewöhnliches Objekt, wie die anderen Objekte auch. Es hat lediglich einen Namen, der Microsoft SQL Server dazu veranlasst, das Objekt dann zu finden, wenn ein Objekt mit gleichem Namen nicht in der aktuellen Benutzerdatenbank vorhanden ist.


Die Stored Procedures werden nicht unter dem Knoten [Gespeicherte Systemprozeduren] angezeigt, sondern sind “normale”Prozeduren”. Genau dieser Umstand führt aber dazu, dass in den Prozeduren verwendete Systemobjekte nicht korrekt funktionieren. Wie erwähnt, sollte die von mir entwickelte Prozedur Indexstatistiken aus meiner Benutzerdatenbank ermitteln und ausgeben. Das Skript – beispielhaft – dazu sieht wie folgt aus:



USE master
GO
 
CREATE PROC dbo.sp_IndexInformation
    @Object_Name    sysname,
    @Index_id       int
AS
    SET NOCOUNT ON;
 
    -- Wenn das Objekt nicht existiert, Fehlermeldung
    IF OBJECT_ID(@Object_Name) IS NULL
    BEGIN
        RAISERROR ('Das Objekt %s existiert nicht', 0, 1, @Object_Name) WITH NOWAIT;
        RETURN (0);
    END
 
    SELECT  db_id()                                        AS    database_name,
            QUOTENAME(s.name) + '.' + QUOTENAME(t.name)    AS    object_name,
            i.name                                         AS    index_name,
            i.index_id                                     AS    index_id,
            ps.fragment_count,
            ps.avg_fragmentation_in_percent,
            ps.avg_page_space_used_in_percent,
            ps.page_count,
            ps.record_count
    FROM    sys.schemas s INNER JOIN sys.tables t
            ON    (s.schema_id = t.schema_id) INNER JOIN sys.indexes i
            ON    (t.object_id = i.object_id) CROSS APPLY sys.dm_db_index_physical_stats
            (
                db_id(),
                i.object_id,
                i.index_id,
                NULL,
                'DETAILED'
            ) ps
    WHERE    i.object_id = OBJECT_ID(@Object_Name) AND
            i.index_id = @Index_id;
 
    SET NOCOUNT OFF;
    RETURN (1);
GO

Der Inhalt der Prozedur selbst ist für die Problemstellung nicht relevant – jedoch die in der Abfrage verwendeten Objekte.
























ObjektBeschreibung
OBJECT_IDId des angegebenen Datenbankobjekts aus sys.all_objects
DB_ID()Id der aktuellen Datenbank (siehe sys.databases)
sys.schemasVerfügbare Schemata in einer Datenbank
sys.tablesTabellenobjekte in einer Datenbank
sys.indexesIndexobjekte in einer Datenbank
sys.dm_db_index_physical_stats()physikalischer Zustand eines Index.
interne DMF

Nachdem die Prozedur in der master-Datenbank erstellt wurde, wird die Prozedur in der Benutzerdatenbank [AdventureWorks2012] ausgeführt. Das Ergebnis entspricht aber nicht den Erwartungen.



USE AdventureWorks2012;
GO
 
EXEC sp_IndexInformation @object_name = 'sales.salesorderheader', @Index_id = 1;

Die Prozedur wird aus der master-Datenbank ausgeführt und als Ergebnis wird NICHTS zurück geliefert. Grund dafür sind mehrere Objekte, die in der Prozedur verwendet werden. Tatsächlich sind die Objekte [sys].[schemas], [sys.tables] und [sys.indexes] die Spielverderber. Alle genannten Objekte sind datenbankspezifische Objekte und werden im Kontext der Datenbank verwendet, in dem sich das aufrufende Objekt (die Stored Procedure) befindet. OBJECT_ID, DB_ID() und [sys].[dm_db_index_physical_stats] sind Systemobjekte, die nicht in einer Benutzerdatenbank gespeichert sind sondern in der Ressourcendatenbank von Microsoft SQL Server – sie können datenbankunabhängig aufgerufen werden und werden im Kontext der aktuellen Benutzerdatenbank verwendet.


Dieses Verhalten ist sehr gut zu erkennen, da KEINE Fehlermeldung ausgegeben wird, wenn die Prüfung auf Existenz des zu prüfenden Objekts stattfindet. OBJECT_ID() wird im Kontext der Benutzerdatenbank [AdventureWorks2012] aufgerufen; in dieser Datenbank befindet sich die Tabelle [sales].[salesorderheader] und es wird keine Nachricht ausgegeben.


Das dennoch kein Ergebnis ausgegeben wird, liegt daran, dass die oben genannten Objekte mittels INNER JOIN und CROSS APPLY miteinander verbunden sind. Das führt dazu, dass die Ergebnisse aus master mit dem Ergebnis von [sys].[dm_db_index_physical_stats] aus AdventureWorks2012 verbunden werden soll – das kann zu keinem Ergebnis führen.


Lösung


Die zuvor erstellte Prozedur [sys].[IndexInformation] muss von einer “normalen” Prozedur zu einer echten Systemprozedur geändert werden. Mit Hilfe der – undokumentierten – Systemprozedur [sp_MS_marksystemobject] kann ein beliebiges Objekt in der master-Datenbank zu einem Systemobjekt hochgestuft werden. “Undokumentiert” bedeutet, dass die Funktionalität von Microsoft jederzeit eingestellt und/oder geändert werden kann – also bitte immer erst in einer Entwicklungsumgebung prüfen!


[sp_MS_Marksystemobject] verwendet die Parameter @objname und @namespace, um ein Systemobjekt zu erstellen. Der Parameter @objname bestimmt das Objekt (voll qualifiziert), das zu einem Systemobjekt geändert werden soll; der Parameter @namespace ist nur relevant, wenn es gilt, einen Trigger (Server / Datenbank) in ein Systemobjekt umzuwandeln. Das nächste Skript zeigt die Umstellung sowie die Ergebnisse vor und nach der Umstellung:



USE AdventureWorks2012;
GO
 
-- Informationen aus sys.objects in master-Datenbank
SELECT name, type, is_ms_shipped FROM master.sys.objects WHERE name = 'sp_IndexInformation';
 
-- Auführung der Prozedur ohne Ergebnisse
EXEC sp_IndexInformation @object_name = 'sales.salesorderheader', @Index_id = 1;
 
-- Prozedur wird zu einer Systemprozedur gewandelt
USE master;
EXEC sp_MS_marksystemobject @objname = 'dbo.sp_IndexInformation', @namespace = NULL;
USE AdventureWorks2012;
 
-- Ausführung der Prozedur mit Ergebnissen
EXEC sp_IndexInformation @object_name = 'sales.salesorderheader', @Index_id = 1;
 
-- Informationen aus sys.objects in master-Datenbank
SELECT name, type, is_ms_shipped FROM master.sys.objects WHERE name = 'sp_IndexInformation';

Bei der ersten Ausführung der Prozedur werden noch keine Ergebnisse gezeigt, nachdem aber die Prozedur zu einer Systemprozedur umgewandelt wurde, werden die Ergebnisse korrekt angezeigt. Die abschließende Abfrage zeigt, was “im Hintergrund” passiert – die Prozedur wird zu einer “von Microsoft ausgelieferten” Prozedur gemacht.


Herzlichen Dank fürs Lesen!

Sascha Lorenz: In-Memory OLTP in SQL Server 2014 - Das Erlebnis (PASS Deutschland e.V. Treffen)

Am Donnerstag, den 13. Februar 2014, trifft sich wieder die Hamburger PASS Gruppe. Thema ist dieses Mal das für viele Kunden wohl spannendste Feature des SQL Server 2014, die In-Memory OLTP Funktion.

Hier der Abstract meiner Session:

“Der SQL Server 2014 steht als Major Release vor der Tür und für viele Kunden ist die In-Memory OLTP Technologie das wohl spannendste Feature. In dieser Session möchten wir die Gelegenheit geben sowohl einen ersten Einblick in die Technologie zu erhalten als auch die Geschwindigkeit live erleben zu können. Des Weiteren wird gezeigt, wie im eigenen Lab mit der CTP 2 erste  Beispiele getestet werden können, um ein Gefühl für die Möglichkeiten zu bekommen.

Diese Session spricht speziell sowohl Entwickler (Inhouse/ISVs) als auch Administratoren an. Das Thema ELT-Strecke wird ebenfalls bedient, daher auch für BI’ler sicherlich von Interesse. Vom technischen Level her darf auch gerne eine Kollegin/ein Kollege mit Budget Verantwortung mitgebracht werden.”

Das Treffen findet wieder ab 18:30 Uhr in der Microsoft Niederlassung Hamburg statt:

Microsoft Deutschland GmbH
Geschäftsstelle Hamburg
Gasstraße 6a
22761 Hamburg

Bitte meldet Euch vorher rechtzeitig unter rgv_hamburg@sqlpass.de an, weil wir aufgrund des Themas mit sehr vielen Interessierten rechnen. Vielen Dank!

Uwe Ricken: If you pay peanuts …

Beim Stöbern in Projektangeboten, die in den einschlägigen Netzwerken und Projektbörsen angeboten werden, bin ich auf ein Angebot aufmerksam geworden, das ich sehr interessant fand. Die Ausschreibung umfasste die folgenden Merkmale (Auszug):

  • Gewährleistung eines verlässlichen und kosteneffizienten Betriebs der vorhandenen MS SQL Server- Systeme
  • Spezialkenntnisse im Bereich MS SQL Server
  • praktische administrative Erfahrungen im 2nd und 3rd Level Support für MS SQL Server
  • Gute Kenntnisse der MS SQL Server Architektur und Administration, möglichst einschließlich spezieller Features wie Log Shipping, Replikation, DB Mirroring, Cluster und DTS/SSIS

Die Anforderungen klangen interessant und so habe ich bei der Projektagentur angerufen um weitere Informationen zu diesem Projekt zu erhalten. Der Ansprechpartner war nett und erzählte, wie toll es doch sei, für “den Kunden” zu arbeiten und das man viel Wert auf langfristige Engagements und Leistungsbereitschaft lege. Prima – hörte sich toll an! Irgendwann fragte man nach meinen Qualifikationen und ich erzählte, dass ich einer von wenigen MCM (Microsoft Certified Master) in Deutschland und MVP (Microsoft Valued Professional) sei und mich professionell mit der Optimierung als auch dem Betrieb / Architektur von Hochverfügbarkeitslösungen und Desaster Recovery beschäfte. Leider musste ich dann – wie doch recht häufig – dem Mitarbeiter der Projektagentur erläutern, was die Zertifizierung “MCM” bedeutet und welche technischen Anforderungen an das Bestehen geknüpft sind. Anschließend kam dann die – überraschende – Antwort: “Oh, da werden Sie dem Kunden sicherlich zu teuer sein – der Kunde sucht einen JUNIOR DBA”. Das Gespräch wurde dann doch recht schnell beendet – den angebotenen Stundensatz möchte ich hier nicht publizieren; es wäre eine Beleidigung für alle engagierten DBA, die Leistungsbereitschaft zeigen.

Höchste Ansprüche…

Die Anforderungen in der Projektbeschreibung mit einem “Junior DBA” abzudecken, ist meines Erachtens grob fahrlässig. Damit ist weder dem Kunden noch dem potentiellen Kandidaten gedient.  Wer sich nur ein wenig mit Hochverfügbarkeitslösungen auskennt, weiß, dass die genannten Anforderungen auf keinem Fall von einem “Junior DBA” gemeistert werden können. Hierbei handelt es sich klar um Aufgaben, die ein Profi mit vielen Jahren Erfahrungen in der Administration von Hochverfügbarkeitslösungen ausführen sollte. Nur mal von “Log Shipping” oder “Mirroring” gehört zu haben, reicht nicht aus; hier gehört sehr viel Kenntnisse über Backup-Strategien ins Portfolio. Replikation? Welche Art der Replikation ist denn gewünscht? … Liest man sich die Skills durch, soll durch EINEN Anfänger das Wissen von vier Experten abgedeckt werden:

  • dba Operations für 2nd und 3rd Level
    • Security
    • Optimierung
    • Backup / Recovery
    • Configuration
  • Professional DBA / Architekt mit Erfahrung in Hochverfügbarkeitslösungen / Desaster Recovery Lösungen
  • Professional Windows Administrator mit Erfahrungen im Clusterbetrieb
  • BI-Experte für die Bearbeitung von DTS/SSIS Paketen
    (und vermutlich auch SSRS und AS)

für wenig Geld…

Natürlich möchte die Projektagentur mitverdienen. Es sei ihr auch gegönnt; schließlich muss sie die Akquisition betreiben und den Kunden betreuen. Vermutlich darf man bei der oben genannten Ausschreibung wohl nicht ausschließlich der Agentur der “Schwarze Peter” zuzuschieben; vielmehr scheint der Kunde selbst kein Verständnis für die Anforderungen in Verbindung mit den am Markt geforderten Preisen zu haben.

Den Projektagenturen (hier kann man schon pauschalieren) darf man vorzuwerfen, dass sie sich nicht ausreichend mit dem Kunden beraten und die Anforderungen besprechen. Statt mit “ihrem” Kunden gemeinsam die Anforderungen mit dem Markt abzugleichen, wird die Ausschreibung OHNE Prüfung einfach mittels “Copy & Paste” in die Netzwerke verbreitet. Auch würde es nicht schaden, wenn sich der Mitarbeiter der Projektgesellschaft mit den Anforderungen der Ausschreibung etwas intensiver beschäftigt; nur so kann dem Kunden mögliche Erfolgsaussichten bei der Suche gewährleisten! Schaut man sich die Projektbörsen mal genauer an, muss man sich fragen, wer eigentlich von wem kopiert!

Liest man die Anforderungen und hört dann von den möglichen Raten, fällt auf, dass die Projektagentur sich nicht im entferntesten mit “Wollen” und “Können” auseinander gesetzt hat – das geht natürlich zu Lasten des Kunden. Nur ein wenig eigene Recherche durch den Mitarbeiter der Projektgesellschaft und man wird man schnell feststellen, dass die Anforderungen einen – wirklichen – Spezialisten erfordern und überhaupt nicht von einem “Junior” zu meistern sind. Sollte der Kunde dennoch auf seine Preisvorstellungen bestehen, wäre es der Projektgesellschaft anzuraten, eher mal auf ein Geschäft zu verzichten, als um jeden Preis einen “Kopf” auf die ausgeschriebene Stelle zu suchen/setzen!

If you pay peanuts you get monkeys!

Ich habe diesen Spruch von einem lieben Freund aufgegriffen; und er trifft das oben beschriebene Problem zu 100%. Die Projektagentur/der Kunde muss sich einfach im Klaren sein, dass Experten durch viele Jahre Erfahrung und durch entsprechende Zertifizierungen ihr Wissen gefestigt haben. Das die oben beschriebene Aufgabe nicht durch einen “Spezialisten” mit 2-3 Jahren Berufserfahrung zu meistern ist, sollte jedem Einkäufer klar sein. Auch eine Projektagentur sollte nicht immer nur auf den – kurzfristigen – Umsatz schauen sondern realistisch hinterfragen, was passiert, wenn was passiert. Eine Eigenschaft, die heute – im Zeitalter des schnellen Euro – wohl nicht mehr zeitgemäß zu sein scheint.

Der Projektmarkt ist überschaubar; die seriösen Projektbörsen sind bekannt – und somit der Wettbewerb groß. Eine Projektgesellschaft, die im Vorfeld Erfolgsaussichten bei Projektausschreibungen bewertet und ggfls. auch mal  verzichtet, wäre eine Bereicherung für den Markt – einzig der Wunsch ist der Vater des Gedanken!

Mit großer Wahrscheinlichkeit wird sich für das beschriebene Projekt jemand finden, der sich den Herausforderungen stellt. Mit genau so großer Wahrscheinlichkeit werden anschließend die “Experten” nach den “Spezialisten” gerufen werden; nur ist es dann sehr häufig schon recht teuer geworden. Mir tut der “Spezialist”, der sich den obigen Anforderungen stellt, eher leid; jeder lebt von Erfolgserlebnissen – die sind jedoch für obiges Projekt für einen “Junior” unerreichbar. Davon bin ich überzeugt!

Wer billig kauft, kauft zwei mal– und die GUTEN Experten sind auch nicht blöd; sie kenne ihren Marktwert und kennen den Markt! Werte Projektgesellschaft, werter Kunde – wer/was bleibt dann noch übrig, um die angebotene Position zu besetzen?

Herzlichen Dank fürs Lesen!

Uwe Ricken: Tabellarische Darstellung von IO Statistiken

Mehr durch Zufall bin ich auf eine sehr interessante Webseite gestoßen, die im täglichen Geschäft mit Microsoft SQL Server bei einem DBA / Entwickler nicht fehlen darf. Jeder SQL Experte, der schon einmal Ausführungspläne analysieren musste, ist unweigerlich mit dem I/O konfrontiert worden, das durch die Abfrage generiert wird. Das Ergebnis wird anschließend in einem Meldungsfenster angezeigt. Nun sind die Daten nicht gerade benutzerfreundlich angeordnet und man muss sich mühsam durch das Ergebnis lesen. Die nachfolgende Abfrage – aus AdventureWorks2012 – liefert das folgende Ergebnis für den produzierten I/O:

-- Ausgabe des IO aktivieren
SET STATISTICS IO ON;
 
SELECT  CAST (CONVERT(char(6), h.OrderDate, 112) + '01' AS datetime)    AS OrderMonth,
        SUM(h.TotalDue)                                                 AS TotalAmt,
        COUNT(d.SalesOrderDetailID)                                     AS ProductLines
FROM    sales.SalesOrderHeader h INNER JOIN sales.SalesOrderDetail d
        ON (h.SalesOrderID = d.SalesOrderID)
WHERE   OrderDate >= '20050101' AND
        OrderDate < '20060101'
GROUP BY
        CAST (CONVERT(char(6), h.OrderDate, 112) + '01' AS datetime)
 
-- Ausgabe des IO deaktivieren
SET STATISTICS IO OFF;

Das Ergebnis dieser Abfrage – in Bezug auf IO – ist schlecht lesbar und man muss sich durch die Ergebnisse “quälen”.

IO_UNTABELLARISCH

Um das Ergebnis leichter lesbar und besser aufbereitet zu präsentieren, gibt es von Richie Rump (blog | twitter) eine fantastische Webseite, in die das Ergebnis nur noch in eine dafür vorbereitete Textbox kopiert werden muss. Unter http://www.statisticsioparser.com/statisticsioparser/index.html kann man diesen tollen Parser finden.

IO_TABELLARISCH

Coole Sache. Herzlichen Dank an Richie. Eine – aus meiner Sicht – tolle Entwicklung wenn man nur die Management Konsole für Microsoft SQL Server zur Verfügung hat.

Herzlichen Dank fürs Lesen!

Falk Krahl: Neues Updates für SQL Server 2008 SP3

Auch für den SQL Server 2008 mit Servicepack 3 ist Anfang der Woche ein neues Update erschienen. Es handelt sich um das kumulative Update 15. Es kann unter folgendem Link angefordert werden:
SQL Server 2008 SP3 CU15

Falk Krahl: Neues Update für SQL Server 2012 SP1

Bereits Anfang der Woche ist für den SQL Server 2012 mit Servicepack 1 ein neues Update erschienen. Es handelt sich um das kumulative Update 08. Es kann unter folgendem Link angefordert werden:
SQL Server 2012 SP1 CU08

Rick Kutschera: AppLocks in Hekaton

All of you who followed the development of the SQL Server 2014 InMemory OLTP Engine (aka “HEKATON”) will know that Hekaton per definition does not support locks. While this is a good thing per se, after all it’s all about speed, there are scenarios where you would need locks to ensure data integrity and avoid massive amounts of retries. Now you can of course go down the easy road and use sp_getapplock to take your own, application intended, lock to circumvent the problem, but that approach comes with major drawbacks:

1) To do that you need to have a transaction around your code block, which can unnecessarily slow down your operations and in case of “interlocking locks” be a real annoyance.

2) More importantly if you go down that road you are bound to hit the transaction log, even if all your tables in the transaction are in memory only. And THAT can really bring your performance down.

So… What to do about it? Well… If you are me… Write your own sp_getapplock using Hekton tables. The Pro’s of that are that you neither need a transaction nor hit the TLog of your database, the Con is that you are outside the control of SQLs Lock Manager, meaning that you have to ensure you cleanly release those “locks” on all possible codepaths.

What does that look like? Well… Take a look…

1) You need a table to store your locks in. I used a 200 characters nvarchar as a key, but you are really open to do whatever suits you:

CREATE TABLE dbo.HK_AppLock
(
    LockKey nvarchar(200) COLLATE LATIN1_GENERAL_100_BIN2 NOT NULL,
    LockDate datetime NOT NULL

   CONSTRAINT PK_HK_AppLock PRIMARY KEY NONCLUSTERED HASH (LockKey) WITH (BUCKET_COUNT=300000)
   ,INDEX IX_HK_AppLock_Expired (LockDate)
) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_ONLY)

Note that I have two indexes on that table. The Primary Key is built as a Hash Index to ensure maximum speed on point lookup (which is the normal scenario), the Expiry-Index is used for orphaned lock cleanup only (Range Scan). Also note that I use SCHEMA_ONLY duarability as persisting locks is not really something you need in daily operations…

2) Build Sprocs for GetAppLock and ReleaseAppLock

CREATE PROCEDURE sp_HK_GetAppLock
    @Key nvarchar(200)
AS
    SET NOCOUNT ON

    DECLARE @Error int
    DECLARE @LockTaken bit=0
    WHILE @LockTaken=0
    BEGIN
        BEGIN TRY
            INSERT INTO HK_AppLock(LockKey, LockDate)
            VALUES (@Key, GETUTCDATE())

            SET @LockTaken=1
        END TRY
        BEGIN CATCH
            SET @Error=ERROR_NUMBER()

            IF (@Error = 41302 OR @Error = 41301 OR @Error = 41305 OR @Error = 41325)
                WAITFOR DELAY '00:00:00:001'
            ELSE IF (@Error = 2627 OR @Error = 2601)
                WAITFOR DELAY '00:00:00:050'
            ELSE
                THROW
        END CATCH
    END

The idea is pretty simple here… Insert the requested lock into the table. If someone else holds the lock already (=the record is already in the table) we will see a PK violation, which is the indicator here. The Catch-Block handles three scenarios: First block handles W/W conflicts with a very short delay + retry, second block handles the PK violation, taking a longer delay in sort of a “spin lock” approach, third block throws whatever other exception we run into up to the client. So effectively what you get is a block until the Insert succeeds.

Note that I do not use native compilation here. Reason for that is that in Native sprocs you have no way of “retrying”, as the transaction context will never change in there.

CREATE PROCEDURE sp_HK_ReleaseAppLock
    @Key nvarchar(200)
AS
    SET NOCOUNT ON

    DECLARE @Error int
    DECLARE @LockReleased bit=0
    WHILE @LockReleased=0
    BEGIN
        BEGIN TRY
            DELETE FROM HK_AppLock
            WHERE LockKey=@Key

            SET @LockReleased=1
        END TRY
        BEGIN CATCH
            SET @Error=ERROR_NUMBER()

            IF (@Error = 41302 OR @Error = 41301 OR @Error = 41305 OR @Error = 41325)
                WAITFOR DELAY '00:00:00:001'
            ELSE
                THROW
        END CATCH
    END

Release goes the same way as Get, No magic here.

3) Last thing is to simulate SQLs lock manager. Meaning: Add a way to clean up orphaned locks.

CREATE PROCEDURE sp_HK_CleanupAppLock
AS
    SET NOCOUNT ON

    WHILE 1=1
    BEGIN
        BEGIN TRY
            DELETE FROM HK_AppLock
            WHERE LockDate<DATEADD(s, -30, GETUTCDATE())
        END TRY
        BEGIN CATCH
        END CATCH
        WAITFOR DELAY '00:00:05'
    END

What I do in my environment is have an Agent job starting every minute, calling that sproc. The sproc actually never finishes, so the 1-minute-schedule is just a precaution in case of problems and server restarts. In my implementation we assume that every lock existing longer than 30 seconds is orphaned. You can of course build more sophisticated logic in there, like including SPIDs or whatever else in the table to allow for a “real” lock management.

All in all the code is very simple and highly efficient. (at least compared to sp_GetAppLock…) It doesn’t solve all problems, but for us it sure solved many of them.

Sascha Dittmann: Microsoft HDInsight Podcast (Folge 02)

Microsoft HDInsight PodcastIm zweiten Teil dieser Video-Podcast Serie dreht sich alles um die Installation von HDInsight.
Dabei zeige ich einerseits wie man den lokalen Microsoft HDInsight Emulator mittels Web Platform Installer installiert.
Andererseits stelle ich vor wie der Windows Azure HDInsight Dienst via Management Portal, PowerShell Skript oder Windows Azure CLI Tool erstellt werden kann.

Microsoft HDInsight Installieren (Video)

Über Themenwünsche, sowie Feedback, würde ich mich selbstverständlich freuen!

 

Verwendete Windows Azure Skripte

Erstellen des Windows Azure Blog Storages

Mit diesem Powershell-Skript wird sowohl ein Storage Account wie auch ein Container angelegt:

$storageAccountName = "hdinsightacct" # Name des Storage Accounts
$containerName = "hdinsightcontainer" # Name des Container
$location = "West Europe" # Region / Rechenzentrum

New-AzureStorageAccount -StorageAccountName $storageAccountName -Location $location

$storageAccountKey = Get-AzureStorageKey $storageAccountName | %{ $_.Primary }
$destContext = New-AzureStorageContext -StorageAccountName $storageAccountName `
  -StorageAccountKey $storageAccountKey  

New-AzureStorageContainer -Name $containerName -Context $destContext

 

Das Gleiche wird wie folgt mit dem Windows Azure Cross-Platform Command-Line Interface umgesetzt:

azure storage account create -l "West Europe" hdinsightacct

REM Anzeigen der Storage Account Keys
REM azure storage account keys list hdinsightacct

azure storage container create -a hdinsightacct -k <StorageAcctKey> hdinsightcontainer

 

Erstellen des Windows Azure HDInsight Dienstes

Mit diesem Powershell-Skript wird ein Windows Azure HDInsight Dienst (mit 4 Data-Nodes) angelegt, der den oben erstellten Blog Storage verwendet:

$storageAccountName = "hdinsightacct" # Name des Storage Accounts
$containerName = "hdinsightcontainer" # Name des Container
$clusterName = "hdinsightcluster" # Name des HDInsight Clusters
$location = "West Europe" # Region / Rechenzentrum
$clusterNodes = 4 # Anzahl der Data-Nodes

$storageAccountKey = Get-AzureStorageKey $storageAccountName | %{ $_.Primary }

$secpasswd = Get-Content "HDInsightPassword.txt" | ConvertTo-SecureString
$creds = New-Object System.Management.Automation.PSCredential ("Admin", $secpasswd)

New-AzureHDInsightCluster -Name $clusterName `
   -Location $location `
   -ClusterSizeInNodes $clusterNodes `
   -DefaultStorageAccountName "$storageAccountName.blob.core.windows.net" `
   -DefaultStorageAccountKey $storageAccountKey `
   -DefaultStorageContainerName $containerName `
   -Credential $creds

 

Die Windows Azure Cross-Platform Command-Line Interface Umgesetzung:

azure hdinsight cluster create 
  --clusterName hdinsightcluster
  --location "West Europe"
  --nodes 4
  --storageAccountName hdinsightacct
  --storageAccountKey <Storage Account Key>
  --storageContainer hdinsightcontainer
  --username Admin
  --clusterPassword <Passwort>

 


Weitere Informationen Weitere Informationen:

Andreas Wolter: SQL Server Row- and Cell-Level Security – Disclosure vulnerability // Schwachstellen in Zeilen-basierter Sicherheit

 

(de)
Es ist Zeit für einen weiteren Artikel zum Thema Sicherheit.
Und durch einen Forum Thread zu „Datengesteuerter Sicherheit“ mittels der IS_MEMBER(), USER_NAME(), SUSER_SNAME() – Funktionen kam ich auf die Idee, ein kurzes Beispiel zu zeigen, wie sich solche Konstrukte leicht umgehen lassen und die geschützten/verborgenen Daten offengelegt werden können, wenn sie nicht mit weiteren Mitteln gesichert werden.
Sehen wir uns ein Beispiel an.

(en)
It’s time for another post on security matters.
And through a forum-thread on data-driven security by the means of views using the IS_MEMBER(), USER_NAME(), SUSER_SNAME() – functions, I came up with the idea of giving a short example how such constructs can easily be circumvented and the protected/hidden data become disclosed, when not being secured by further means.
So let’s look at an example.

Im Folgenden werden wir ein recht verbreitetes Szenario sehen, wie Sicherheit auf Zeilenebene / Row-Level Security (und auch Zellenebene/Cell-Level Security) implementiert werden kann.

Die Architektur ist recht einfach:
Eine Tabelle enthält Datenzeilen, von welchen einige von einer bestimmten Gruppe Personen gelesen werden darf, und andere Zeilen von anderen Personen – jeweils exklusiv.
Um das zu erreichen, wird eine Sicht angelegt. Diese Sicht muss natürlich denselben Besitzer haben, so dass der Prinzipal Berechtigungen auf die Sicht alleine erhalten kann, und durch die Besitzerkette an die Daten gelangt.
Innerhalb der Sicht ist eine Where-Klause, die einen Filter auf ein bestimmtes Attribut in der Tabelle enthält, durch das der Benutzer der aktuellen Sitzung erkannt wird und ausschließlich die Daten zurückgeliefert werden, die seiner Rollen-Mitgliedschaft entsprechen.
Natürlich gibt es auch komplexere Designs mit Zwischentabellen und mehrfachen Rollenmitgliedschaften/Rechten, aber am Ende teilen alle dieselbe Schwachstelle, die ich demonstrieren werde.
Im Folgenden zunächst ein Diagramm der Architektur.

In the following we will see a quite common scenario of how Row-Level Security (and also Cell-Level Security) can be implemented.

The architecture is quite simple:
A table is holding rows of data, some of which are supposed to be readable by a certain group of people, and other rows by other people – in each case exclusively.
In order to achieve this, a view is created. This view naturally must have the same owner, so the principal can be granted permissions on nothing but the view and get to the data by means of the ownership-chain.
Within the view there is a Where-clause which contains a filter on a certain attribute in the table, by which the user of the current session is detected and returned solely the data which matches his role-membership.

Of course there are also more complex designs with intermediate tables and multi-role-memberships/permissions, but it all comes down sharing the same vulnerability which I am about to demonstrate.

First of all here's a diagram of the high-level architecture:

 SQL_Row_Level_Security_Schema

 

Sehen wir uns das ganze also an.
Die Einrichtung Tabelle und der Sicht, inklusive 2er Beispieldatensätze:

So let’s see it in action.
The Setup of the Table and the View including 2 sample data rows:

 SQL_Row_Level_Security_Table_View_Setup

Die Spalte „Role“ wird von der Sicht verwendet, um die jeweilige Zeile, unter Verwendung der IS_MEMBER()-Funktion nur Mitgliedern der jeweils hinterlegten Datenbankrolle durchzureichen.

The column “Role” is used by the view to return the respective row by using the IS_MEMBER()-function only to members of the respectively stored database-role.

 SQL_Row_Level_Security_Table_View

Benutzer, Rollen und Berechtigungen:

User(s), Roles and Permissions:

 SQL_Row_Level_Security_User_Roles_Permissions

Erinnern wir uns, was die Tabelle enthält:

Now, remember what our table contains:

 SQL_Row_Level_Security_Data

In einer heilen Welt, vor dem Sündenfall, wäre dies ausreichend.
(Nachdem wir uns als „Andreas“, der Mitglied der Datenbankrolle RoleAlpha ist, einloggen) würden unsere Abfragen wie folgt aussehen, und lediglich die Zeilen zurückliefern, die der RoleAlpha „gehören“:

So in an innocent world, before the fall of mankind, this would be sufficient.
(After logging in as “Andreas”, who is member of the RoleAlpha database-role) our queries would look like this and only return the rows which “belong” to RoleAlpha:

 SQL_Row_Level_Security_Query

- Natürlich wird die Funktion User_Name() nur für Demo-Zwecke eingesetzt.
Ergebnis:

- Of course the function User_Name() is only used for demo-purposes.
Result:

 SQL_Row_Level_Security_Filtered_Data

Angriff
Aber Andreas spielt nicht fair. Er ist neugierig, was sonst noch in der Tabelle stehen könnte.
Also schreibt er eine Abfrage wie diese:

Attack
But, Andreas does not play nice.  He is curious on what else might be in the table.
So he crafts a query like this:

 SQL_Row_Level_Security_Attack

Und das Ergebnis ist:

And the result is:

 SQL_Row_Level_Security_Disclosure

Nicht „schön“, aber wir haben, was wir wollten: die „geschützten“ Daten.

Der bereits geschulte Leser erkennt diese Form des Angriffs vielleicht aus einem anderen Bereich wieder: SQL Injection.
Es ist eine Form des alten Freundes „Error Based Attack“ oder „Error Disclosure“, die auch bei schlecht geschriebenen Webanwendungen zum Zuge kommt. Das habe ich u.a. 2013 auf diversen Konferenzen gezeigt (Vortragsreihe).
Der Kontext ist ein wenig anders, aber die Idee dahinter ist dieselbe.

Not exactly “pretty”, but we got what we want: the “protected” data.

The well-educated reader may remember this kind of attack from a different area as well: SQL Injection.
It’s a form of the old fried “error based attack” or “error-disclosure”, which can also be used for badly written web-applications. I have also shown that amongst others in 2013 at several conferences (series of sessions).
The context is a little bit different, but the idea is the same.

 Security-Gate-Fail

Einigen kommt das Bild vielleicht schon bekannt vor :-)

Stellt sicher, dass das nicht Euer "Vorgarten" ist!

Wo wir davon reden:

To some, this picture may already look familiar :-)

Make sure it’s not your "front-yard"!

Speaking of which:

 

Schutzmaßnahmen

Was kann man gegen solche Angriffe tun?
Im Wesentlichen stehen einem 3 bekannte Möglichkeiten zur Verfügung:

1) Einsatz von gespeicherten Prozeduren, die alle Fehler abfangen, oder, wenn man unbedingt mit Sichten Arbeiten möchte, der Einsatz einer dazwischengeschalteten Multi-Statement-Tabellenwertfunktion

2) Datenverschlüsselung (Nicht TDE!)

3) Ähnlich wie 1, Aufbau einer Mittelschicht in der Anwendung, die derartiges unterbindet.

Und schlussendlich sollte man für kritische Daten auch über eine Überwachungslösung nachdenken.

Security-measures

What can prevent such forms of attack?
Essentially there are 3 well-known methods at hand:

1) The use of stored procedures which catch all errors, or, if one really wants to use views for some reason, using of a multi-statement table valued function which will be put between.

2) Data encryption (Not TDE!)

3) Similar to 1, implementation of a mid-tier in the application which prohibits such actions.

Finally one should also think about an Auditing solution for critical data.

Die hier gezeigte Technik der Row-Level Disclosure ist nicht wirklich etwas Neues, wird aber gerne immer mal vergessen.
Nachlesen kann man darüber zum Beispiel auch in diesem (alten, aber immer noch zutreffenden) Whitepaper:

The technique of Row-Level Disclosure shown above isn’t really new, but frequently forgotten about.
One can read about this, for example, in this (old, but still applicable) whitepaper:

Implementing Row- and Cell-Level Security in Classified Databases Using SQL Server 2005

 

Happy securing,

Andreas

 

Wer sich ermuntert fühlt, nun einmal richtig in das Thema „Sicherheit mit SQL Server“ einzusteigen, für den habe ich auch 3 erstklassige Trainings im Angebot:

If you now feel encouraged to really dive into the subject of “Security with SQL Server”, I do have 3 first-class Trainings on offer:

Für Beginner, die hier einen guten Überblick erhalten und Grundlegende Kenntnisse erlernen:

For Starters, who gain a good overview and learn essential knowledge in the basics:

(SES) SQL Server Security Essentials for Developers & Administrators (1 day)
3. April 2014 in Düsseldorf

Für Administratoren, die fortgeschrittene Sicherheitskonzepte umsetzen müssen:

For Administrators that have to implement advanced security concepts:

(SIA) Securityworkshop for SQL Server Administrators (advanced) (1 day)
4. April 2014 in Düsseldorf

Für Entwickler, die fortgeschrittene Sicherheitskonzepte umsetzen müssen:

For Developers that have to implement advanced security concepts:

(SID) Securitysworkshop for SQL Server Developers (advanced) (1 day)
24. April 2014 in Düsseldorf

Sascha Lorenz: Review und Reflektion meiner Data Warehouse Beiträge der letzten Jahre

2014 wird das Jahr der Jubiläen für mich. 20 Jahre eigene Firma, PSG Projekt Service – The SQL Server Company. 10 Jahre PASS Deutschland e.V. und das 100. PASS Treffen in Hamburg.

Da blickt man doch gerne mal zurück und schaut, was man so die letzten Jahre gemacht hat. Hier meine Reflektion meiner Blogposts zum Thema Data Warehouse. Einige davon sind laut den Statistiken zu echten Klassikern geworden und viele Kontakte sprechen mich heute noch auf diese an. Dauerbrenner ist natürlich das Mysterium des Repositorys in DWH/BI Projekten. Dazu habe ich auch international Vorträge gehalten.

Speziell die von mir vorgeschlagene Architektur eines Job Pools bzw. einer Job Queue für die automatische Skalierung von Aufgaben im Rahmen einer ETL/ELT-Strecke hat in vielen Projekten Anwendung gefunden und wurde über meine Vorträge auch außerhalb meines Kundenkreises in vielen Unternehmen adaptiert.

Vielleicht ist es mal an der Zeit einen Post zu verfassen, welcher die wichtigsten Designpunkte zusammenfasst, um eine entsprechende Führung in Projekten zu geben. Mal schauen.

Hier in chronologischer Reihenfolge die Blogposts zum Thema Data Warehouse Architektur. Jeweils mit einem Kommentar aus heutiger Sicht dazu.

2013 - SQL Server Data Warehouse – One Queue Pattern (OQP)
Für mich mittlerweile die Grundlage einer skalierbaren DWH Architektur.
Noch lesenswert? Definitiv ja!

2012 - SQL Server Data Warehouse - Ein erster Entwurf
Hier habe ich den Titel eventuell ungünstig gewählt. Es ging mir hier primär um die SQL Server Technologien, welche ein DWH ausmachen sollten.
Noch lesenswert? Auf jeden Fall, da vieles von dem am Anfang häufig ausgelassen wird.

2012 - SQL Server Data Warehouse - Mehr als nur SSIS !
Da hatte ich gerade mal wieder die Erfahrung gemacht, dass SSIS mit einem DWH verwechselt wird und dem Trend, dass DWHs bei der richtigen Auswahl eines BI Tools eigentlich total überflüssig sind.
Noch lesenswert? Leider ja.

2012 - Datenvirtualisierung vs. ETL / ELT Prozess
Ein weiteres Standort Statement zum Thema Datenvirtualisierung.
Noch lesenswert? Ja.

2012 - Datenvirtualisierung mit Master Data Services (und weiteren SQL Server Diensten) unterstützen
Das Thema Datenvirtualisierung war da gerade in einem Projekt Thema geworden bzw. das Verständnis dafür, da diese Disziplin eigentlich in jedes ernsthafte DWH gehört.
Noch lesenswert? Nur zu, ja!

2012 - Change Data Capture (CDC) mittels Metadaten Strukturen steuern
Eigentlich eine Einladung zu einem Vortrag von mir, dennoch der Hinweis, dass man doch bitte alle seine technischen Prozesse, wie zum Beispiel CDC, auch gern mittels eines mehrstufigen Repositorys steuern darf und vielleicht sogar sollte, um sich die Verwaltung bzw. die Beherrschbarkeit seiner Lösung zu vereinfachen.
Noch lesenswert? Nun ja, Thema ja, nur steht da in Summe wenig im Detail. Für mehr Informationen einfach fragen.

2011 - MERGE in T-SQL – Der unbekannte Befehl im BI Projekt für ELT
Grundlagen zum MERGE Befehl für ELT Skripte. Ein Klassiker!
Noch lesenswert? Natürlich!

2011 - MDXScript Service – Repository driven calculations
Ein kurzer Artikel, welcher aber eine sehr gute Idee skizziert, welche ich in einigen “komplexeren” Analysis Services Projekten verwende, um fast schon magische Dinge mit einem multidimensionalen Raum zu machen.
Noch lesenswert? Auf jeden Fall!

2011 - SSIS (Integration Services) – ETL vs. ELT Lösung?
Ein Klassiker aus vielen Meetings! Was ist ETL und ELT? Und warum sind wohl viele SSIS Lösungen eher ein ELT als ein “echtes” ETL? Und was ist gut oder schlecht daran? Es kommt eigentlich nur auf die bewusste Entscheidung in der Architektur an, dann ist alles gut!
Noch lesenswert? Definitiv Ja! Immer noch aktuell.

2011 - SSIS (Integration Services) als ETL Lösung – Entscheidungen vor dem Einsatz
Hier ging es mir um Grundlagen vor einem überstürzten Beginn einer Lösung mit den SSIS.
Noch lesenswert? Leider ja.

2011 - Landing Area (Zone) im SQL Server Data Warehouse
Ein Plädoyer für die Nutzung einer Landing Area/Zone im DWH bzw. ETL/ELT. Nenne das auch gern mal Stage-0.
Noch lesenswert? Klar! 

2011 - Der Presentation Layer im Allgemeinen und speziell in einem SQL Server Data Warehouse
Hier hatte ich ein paar Visualisierungen aus einem Proof-of-Concept wiederverwendet und mir Gedanken über die notwendige Abstraktion im DWH gemacht.
Noch lesenswert? Nicht wegen der Grafiken. Die Abstraktion ist immer noch wichtig!

2011 - Die reine Lehre vom SQL Server Data Warehouse Entwurf…
Okay, der Titel war eine gewollte Provokation. Dennoch ging es mir hier um die notwendige Granularität für ein DWH in Kontext eines SQL Server BI Projektes. Attribute stehen auch noch heute im Mittelpunkt meiner Architekturen.
Noch lesenswert? Sicherlich.

2011 - Meine Top 10 Ratschläge für komplexere SQL Server BI Projekte aus dem PASS Vortrag vom 9.3.2011 in Hamburg
Kurze Top 10 Liste für BI Projekte. Und ja, diese Ratschläge gebe ich heute noch genau in dieser Form.
Noch lesenswert? Klar.

2011 - Coaches’ Hell: Wie entwickle ich denn jetzt so ein Vorgehensmodell für Microsoft Business Intelligence Projekte?
Hier kam ich vom Vorgehensmodell zum Cube. Und dabei meinte ich eigentlich wieder mal das einzelne Attribute.
Noch lesenswert? Bedingt, dazu gab es zwischenzeitlich wesentlich bessere Vorträge von mir. Gut als Einstieg in Cube Räume.

2011 - Coaches’ Diary: Wie verwende ich SSIS & SSAS in Business Intelligence Projekten mit dem SQL Server denn nun wirklich richtig?
Und hier wieder das beliebte Thema: Wie macht man es denn nun richtig?
Noch lesenswert? Sicher!

2011 - Wieder einmal das Repository… oder auch Repository driven BI / everything in SQL Server FAQ…
Hier ging es mir um meinen Liebling, das Repository. Und um DSL bzw. meine PSLs. Da ich häufig in Projekten mit einer großen Anzahl von Servern etc pp unterwegs bin, hat sich dieses Vorgehen bewährt. Steuerung von über 1000 SQL Servern wird sonst leicht “anstrengend” im Betrieb.
Noch lesenswert? Immer noch die Grundlage für viele Architekturen!

2010 - Nutzung eines Jobpools in Business Intelligence Umgebungen
Noch so ein Klassiker, welcher noch heute dabei ist. Der Jobpool für die Skalierung von Farmen mit SSIS und vergleichbaren Diensten.
Noch lesenswert? Auf jeden Fall!

2010 - Die verwendeten Spalten und Tabellen einer beliebig komplexen SQL Query ermitteln
Hier mal etwas technisches und dabei nützlich. Dieses Vorgehen kommt u.a. in vielen DWHs zum Einsatz, um die Hotspots für die Nutzung zu ermitteln. Für Analysis Services habe ich so etwas auch, bisher aber nicht publiziert.
Noch lesenswert? Für DWH Entwickler quasi Pflicht.

2010 - Überlegungen über den Aufbau eines Repositorys in einer Business Intelligence Umgebung
Das Repository hat mich schon immer begleitet als Thema.
Noch lesenswert? Für den Einstieg ja.

2010 - Reifegradmodelle im Projektmanagement
Und noch so ein Klassiker! Jedem DWH/BI Projekt sein Reifegradmodell. Allein schon für das Projekt Marketing unverzichtbar. Und noch heute stresse ich “meine” Studenten an der Hochschule, wenn ich meinen Betrag zum Kurs über Konzeptarbeit und Reifegrade gebe.
Noch lesenswert? Aber so etwas von!

-- Dann kam eine Phase mit sehr viel Client Entwicklungen. Mache ich heute auch noch, sprechen wir ein anderes Mal drüber. :-)

2005 - Und was ist nun ein Data Warehouse?
Das war der Versuch einer Definition zum Thema DWH. Nun ja.
Noch lesenswert? Nur für Leser, welche weder Inmon noch Kimball kennen.

2005 - Was ist eigentlich Business Intelligence?
Okay, das war mal kurz.
Noch lesenswert? Geht so, die Welt wurde seit 2005 nicht weniger kompliziert. Wer hat denn 2005 wirklich an Big Data gedacht…

Sascha Dittmann: Microsoft HDInsight Podcast (Folge 01)

Microsoft HDInsight PodcastIn den vergangenen 1-2 Jahren durfte ich auf verschiedenen Konferenzen, und bei einigen User Groups, einen Überblick über Microsoft HDInsight bzw. Apache Hadoop geben.
Das 
Hadoop Ecosystem ist allerdings so umfangreich, dass man diesem weder innerhalb eines Session Slots, noch an einem User Group Abend, gerecht werden kann.
Deshalb möchte ich dem Wunsch einiger Teilnehmer nachkommen und dazu eine Podcast Serie starten.

Starten möchte ich im erste Teil der Microsoft HDInsight Podcast Serie mit den Fragen "Was ist Big Data?" und "Was ist Hadoop bzw. Microsoft HDInsight" (auch wenn dies für die bisherigen Teilnehmer meiner Sessons nicht Neu sein wird). ;-) 

Der Podcast kann über http://feeds.feedburner.com/HDInsightPodcast direkt abonniert werden.

Über Themenwünsche, sowie Feedback, würde ich mich selbstverständlich freuen!

 


Weitere Informationen Weitere Informationen:

Sascha Lorenz: Clipboard Calculator

Gestern hat ein kleines Tool spontan das Licht der Welt erblickt, welches ich jetzt schon nicht mehr in meinem SQL Alltag missen möchte.

Kurz die Geschichte dazu: Auf dem gestrigen PASS Treffen in Hamburg habe ich einen Vortrag über die Grundlagen der sogenannten Fenster Funktionen im SQL Server 2012 gehalten. Das sind u.a. Aggregat Funktionen wie SUM mit der OVER Klausel. Da geht es dann um Summen, fortlaufende Summen usw. Das Ganze wird recht schnell recht zahlenlastig.

Ich möchte in diesem Post gar nicht weiter auf die Fenster Funktionen eingehen. Vielmehr möchte ich über Ergebnisse im SQL Server Management Studio schreiben.

Hier ein Beispiel für eine meiner Abfragen gestern. Die zweite Spalte enthält immer die Summe vom Salesamount der aktuellen Zeile und den zwei Zeilen davor.

image

Um so etwas zu demonstrieren oder auch zu testen, kann man entweder Kopfrechnen üben oder, sofern vorhanden, die markierten Zellen kopieren und in ein Excel kopieren und dort addieren. Nicht immer sind die Aufgaben so übersichtlich wie in diesem Beispiel.

Mein Plan für Gestern war die Nutzung von Excel. Was ich als mehr oder weniger elegant empfand, dennoch war es ein Plan.

Nun war ich als Organisator und Sprecher ein wenig früher bei der Hamburger Microsoft Niederlassung angekommen, um den Raum und Beamer zu checken. Und als ich da so saß und alles geprüft war, bekam ich eine Idee für ein kleines Tool.

Und zwar sollte es doch überhaupt kein Problem sein den Inhalt der Zwischenablage aufzusummieren. Und zwar ohne Umweg. Idee war also, dass ich ein Ergebnis im SSMS in die Zwischenablage kopiere, zu meinem Tool wechsle und dort direkt, ohne ein Einfügen, der Inhalt der Zwischenablage ausgewertet bekomme.

Die verbleibenden 20 Minuten bis die ersten Teilnehmer kommen sollten, habe ich dann schnell genutzt, um einen ersten Prototypen meines Clipboard Calculator Tools zu schreiben. Und er funktionierte tatsächlich sofort und wurde in der gestrigen Session dann auch gleich mehrmals genutzt.

image

So schaut das Tool aus. Keine Knöpfe, keine Optionen. Sobald zu dieser Windows Anwendung gewechselt wird, addiert es den Inhalt der Zwischenablage auf.

Auf Wunsch einiger Teilnehmer des Treffens, stelle ich die aktuelle Version des Clipboard Calculator Tools nun zur Verfügung. Es benötigt nur ein .net Framework 4.

Ideen für Erweiterungen habe ich schon einige. Sehr gerne nehme ich auch Anregungen von Euch entgegen.

Marcel Franke: German SQL Server Conference in February

120x600_SQL_Server_Konferenz

I’m very happy to say that Germany has its own SQL Server conference this year. After the SQL Server 2012 Launch event in Cologne Microsoft and the PASS community organized another launch event for SQL Server 2014. This time the conference will take place in Darmstadt, close to Frankfurt.

Thanks to PASS and Microsoft who organized that event. Attendees will have the chance to listen to a lot of great speakers (http://www.sqlkonferenz.de/sprecher.aspx) and very well picked sessions (http://www.sqlkonferenz.de/agenda.aspx).

I’m also very happy to say that I’m allowed, together with my colleague Gerhard, to have a speaker slot at the first conference day. My session will be about “Analytic Powerhouse: Parallel Data Warehouse und R”.

So hurry up and register yourself here: https://www.event-team.com/events/sqlserverkonferenz2014/registration.aspx


Marcel Franke: 2013 in review

At the beginning of a new year it’s a good time to have a short view on what has happened in the last one. WordPress prepared a 2013 annual report for my blog. I was a Little bit impressed and also proud of these numbers. So I think this is the right time to say thank you to all my readers and followers. It gives me the Feedback that the content I write about is interesting and relevant for people and that’s the most important feedback for me. I promise to continue, I also heard the Feedback on the SAP ERP Integration Story and I will deliver. :) So stay tuned and have fun…

Here’s an excerpt:

Madison Square Garden can seat 20,000 people for a concert. This blog was viewed about 69,000 times in 2013. If it were a concert at Madison Square Garden, it would take about 3 sold-out performances for that many people to see it.

Click here to see the complete report.


Don't contact us via this (fleischfalle@alphasierrapapa.com) email address.