Those who have studied In-Memory OLTP are aware that in the event of “database restart”, durable memory-optimized data must be streamed from disk to memory. But that’s not the only time data must be streamed, and the complete set of events that cause this is not intuitive. To be clear, if your database had to stream data back to memory, that means all your memory-optimized data was cleared from memory. The amount of time it takes to do this depends on:
- the amount of data that must be streamed
- the number of indexes that must be rebuilt
- the number of containers in the memory-optimized database, and how many volumes they’re spread across
- how many indexes must be recreated (SQL 2017 has a much faster index rebuild process, see below)
- the number of LOB columns
- BUCKET count being properly configured for HASH indexes
The following list is for standalone SQL Server instances (under some circumstances, the streaming requirements are different between FCIs and AGs).
Database RESTORE – this is a no brainer – if you restore a database with durable memory-optimized data, of course your data must be streamed from disk into memory. And if you are under the impression that SQL Server verifies if your server has enough memory to complete the RESTORE, you would be mistaken. See my post here.
SQL Service restart – in this case, all databases will go through the recovery process, and all memory-optimized databases will stream durable memory-optimized data to memory.
Server reboot – same as “SQL Service restart”
In addition to the list above, there are a few database settings that cause data to be streamed.
- Changing a database from READ_ONLY to READ_WRITE, or from READ_WRITE to READ_ONLY
- Setting READ_COMMITTED_SNAPSHOT OFF or ON
- Taking a database OFFLINE and then ONLINE
A database that contains durable memory-optimized data will not be online until all memory-optimized data is finished streaming, which affects the availability of “traditional” tables (while a database is waiting for streaming to complete, the wait type is “WAIT_XTP_RECOVERY”). There’s nothing you can do to speed up the process, other than having initially defined enough containers on enough volumes, so that streaming executes in parallel.
SQL 2017 enhancements
Because modifications to HASH and NONCLUSTERED/RANGE indexes are not logged for memory-optimized tables, they must be rebuilt when data is streamed to memory. Both SQL 2014 and SQL 2016 have a limit of 8 NONCLUSTERED indexes per memory-optimized table (any combination of HASH and RANGE). Microsoft has designed a new process for enhancing index rebuild speed in SQL 2017. This dovetails perfectly with the removal of the 8-indexes-per-table limit in SQL 2017 (I have personally created a table with 298 NONCLUSTERED indexes in SQL 2017).