{"id":11476,"date":"2018-07-24T12:55:26","date_gmt":"2018-07-24T10:55:26","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/"},"modified":"2023-07-17T11:09:32","modified_gmt":"2023-07-17T09:09:32","slug":"sql-server-on-linux-io-internal-thoughts","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/","title":{"rendered":"SQL Server on Linux &#8211; I\/O internal thoughts"},"content":{"rendered":"<p>Let\u2019s start the story from the beginning with some funny testing I tried to perform with SQL Server on Linux a couple of months ago. At that time, I wanted to get some pictures of syscalls from SQL Server as I already did in a past on Windows side with <a href=\"https:\/\/docs.microsoft.com\/en-us\/sysinternals\/downloads\/sysinternals-suite\" target=\"_blank\" rel=\"noopener noreferrer\">sysinternal tools<\/a> as procmon and stack traces. On Linux <a href=\"https:\/\/linux.die.net\/man\/1\/strace\" target=\"_blank\" rel=\"noopener noreferrer\">strace<\/a> is probably one of the best counterparts.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-25635\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-140-0-0-banner.jpg\" alt=\"blog 140 - 0 - 0 - banner\" width=\"581\" height=\"238\" \/><\/p>\n<p>Firstly, <strong>please note this blog is just from my own researches and it doesn\u2019t constitute in any cases an official documentation from Microsoft and may lead likely to some inaccuracies. This kind of write up is definitely not easy especially when you&#8217;re not the direct developer of the product and because things change quickly nowadays making\u00a0at the same time\u00a0your blog post biased <\/strong>\ud83d\ude42 Anyway, I was just curious to figure out how SQL Server deals with I\/O on Linux side and the main safety point here is certainly to show how you may achieve it on Linux. So let\u2019s start from the beginning with already what we know on the Windows operating system: The SQL Server engine goes through Win32 API and functions like <em>CreateFile()<\/em>, <em>ReadFile()<\/em>, <em>WriteFile()<\/em> to deal with I\/O but let\u2019s focus specifically on the <em>CreateFile()<\/em> function here. <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/desktop\/api\/fileapi\/nf-fileapi-createfilea\" target=\"_blank\" rel=\"noopener noreferrer\">CreateFile()<\/a> is used to create or to open an existing file or an I\/O device with some specific flags. Some of them as FILE_FLAG_WRITE_THROUGH are used to meet the Write-Ahead Logging (WAL) Protocol by bypassing all system \/ disk caches (cf. <a href=\"https:\/\/support.microsoft.com\/en-us\/help\/234656\/information-about-using-disk-drive-caches-with-sql-server-that-every-d\" target=\"_blank\" rel=\"noopener noreferrer\">Microsoft article<\/a>).<\/p>\n<p>On April 10 2018 I did my first tests on the Linux side with SQL Server 2017 CU5 and here was my first strace output after creating dbi_db database:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-25616\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-140-0-2-strace-stack-twitter.jpg\" alt=\"blog 140 - 0 - 2 - strace stack twitter\" width=\"485\" height=\"259\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-25619\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-140-0-1-strace-stack-e1532429333620.jpg\" alt=\"blog 140 - 0 - 1 - strace stack\" width=\"700\" height=\"157\" \/><\/p>\n<p>It was an expected output for me because on Linux SQL Server uses an low-level <a href=\"http:\/\/man7.org\/linux\/man-pages\/man2\/open.2.html\">open()<\/a> system call \u2013 that is the counterpart of createfile() on Windows \u2013 but the surprising thing was with O_DIRECT flag only. I\u2019m not a system developer and from my position, I may understand benefits from using O_DIRECT with database systems because it is driving by <a href=\"https:\/\/github.com\/littledan\/linux-aio\" target=\"_blank\" rel=\"noopener noreferrer\">AIO<\/a> (asynchronous I\/O) and by the fact we may completely bypass any kernel space buffers (by default on Linux). I get the opportunity to thanks <a href=\"https:\/\/twitter.com\/dbaffaleuf\" target=\"_blank\" rel=\"noopener noreferrer\">@dbaffaleuf<\/a> with our interesting discussions on this topic<\/p>\n<p>But referring to the documentation we may read the following sample as well about O_DIRECT:<\/p>\n<blockquote><p><strong><em>File I\/O is done directly to\/from user-space buffers. The O_DIRECT flag on its own makes an effort to transfer data synchronously, but does not give the guarantees of the O_SYNC flag that data and necessary metadata are transferred<\/em><\/strong><\/p><\/blockquote>\n<p>From my understanding using O_DIRECT that implies durable writes on block devices are not guaranteed and from my trace I noticed the transaction log seemed to be open with O_DIRECT in this case \u2026<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">2837  20:44:32 open(\"\/u02\/sqlserverlog\/mssqlserver\/dbi_test_log.ldf\", O_RDWR|O_CREAT|O_EXCL|O_DIRECT, 0660) = 187\n2837  10:13:09 fstat(187, {st_mode=S_IFREG|0660, st_size=0, ...}) = 0<\/pre>\n<p>\u2026 From a WAL protocol perspective\u00a0using\u00a0such flag\u00a0might\u00a0lead to\u00a0not meet the requirements\u00a0because we might experience data loss in case of a system \/ storage outage unless either implementing another low-level mechanism like <a href=\"http:\/\/man7.org\/linux\/man-pages\/man2\/fdatasync.2.html\" target=\"_blank\" rel=\"noopener noreferrer\">fsync()<\/a> for transaction log and checkpoints or to be sure the storage guarantees writes are O_DIRECT safe. At this stage I expected to find out more fsync() related entries in my trace\u00a0but no chance as shown below (I put only a sample but in fact no other relevant syscalls in the entire trace that might indicate forcing synchronization stuff)<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">% time     seconds  usecs\/call     calls    errors syscall\n------ ----------- ----------- --------- --------- ----------------\n 72.59   12.993418        2089      6220      2503 futex\n 10.78    1.929811        7509       257           epoll_wait\n  9.08    1.625657       47813        34        28 restart_syscall\n  3.28    0.587733        8643        68           io_getevents\n  1.97    0.351806       70361         5           nanosleep\n  1.92    0.344254       34425        10        10 rt_sigtimedwait\n  0.32    0.056943           3     22116           clock_gettime\n  0.02    0.003530         101        35           munmap\n  0.01    0.002149          32        67           io_submit\n  0.01    0.001706           6       273           epoll_ctl\n  0.01    0.000897           6       154           read\n  0.00    0.000765          11        68           writev\n  0.00    0.000605           4       136        68 readv\n  0.00    0.000591           4       137           write\n  0.00    0.000381          10        40        23 open\n  \u2026\n------ ----------- ----------- --------- --------- ----------------\n100.00   17.900633                 29827      2638 total<\/pre>\n<p>A couple of weeks ago, I wanted to update my test environment with SQL Server 2017 CU8 (on Linux) I noticed the following messages (in the red rectangle):<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-25622 size-full\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-140-2-forceflush-e1532432677965.jpg\" alt=\"blog 140 - 2 - forceflush\" width=\"600\" height=\"260\" \/><\/p>\n<p>Hmm .. that\u00a0was pretty new and interesting and in fact, the aforementioned messages\u00a0were related to this <a href=\"https:\/\/support.microsoft.com\/en-us\/help\/4131496\/enable-forced-flush-mechanism-in-sql-server-2017-on-linux\" target=\"_blank\" rel=\"noopener noreferrer\">Microsoft article<\/a> (Thanks <a href=\"https:\/\/twitter.com\/bobwardms\" target=\"_blank\" rel=\"noopener noreferrer\">@Bobwardms<\/a> to pointed me out). This new behavior is available since SQL Server 2017 CU6 and the article\u00a0describes that how\u00a0Microsoft has introduced a change with a new &#8220;forced flush&#8221; mechanism for SQL Server on Linux system.<\/p>\n<p>In a nutshell for all scenarios, a new flush mechanism guarantees data is safely written to a stable media for transaction logs and during checkpoints. Let\u2019s dig further into the both methods.<\/p>\n<p>Let\u2019s say first\u00a0I applied the same pattern for all the tests that follow. The test\u2019s protocol included one <em>dbo.t1<\/em> table with only one column (id int). I inserted for each test a bunch of data rows (67 rows to be more precise related to 67 distinct implicit transactions) without any other user concurrent activities. It remains some internal stuff from SQL Server but I guess we may consider them as negligible compared to my tests.<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">insert dbo.t1 values (1)\ngo 67<\/pre>\n<ul>\n<li><b><strong>Default forced flush mechanism behavior <\/strong><\/b><\/li>\n<\/ul>\n<p>In this scenario referring to my strace file output database files are still open with O_DIRECT only as shown below (my database&#8217;s name is toto this time)<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">4745  10:54:34 open(\"\/u01\/sqlserverdata\/mssqlserver\/toto.mdf\", O_RDWR|O_CREAT|O_EXCL|O_DIRECT, 0660) = 188<\/pre>\n<p>I also used the following command to get directly a picture summary of the number of calls per syscall<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">$ sudo strace -f -c -o sql_strace.txt $(pidof sqlservr |sed 's\/\\([0-9]*\\)\/\\-p \\1\/g')<\/pre>\n<p>Here the sample output I got:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">$ cat sql_strace.txt\n% time     seconds  usecs\/call     calls    errors syscall\n------ ----------- ----------- --------- --------- ----------------\n 71.36   24.078231        2685      8969      3502 futex\n 12.13    4.093680      120402        34        30 restart_syscall\n 10.03    3.384817       12583       269           epoll_wait\n  2.67    0.901541       13258        68           io_getevents\n  1.77    0.598830       46064        13        13 rt_sigtimedwait\n  1.66    0.560893       93482         6           nanosleep\n  0.23    0.077873           2     31422           clock_gettime\n  0.09    0.030924         462        67           fsync\n  0.01    0.003212         321        10           madvise\n  0.01    0.003026          22       136           write\n  \u2026\n------ ----------- ----------- --------- --------- ----------------\n100.00   33.742080                 42195      3651 total<\/pre>\n<p>This time I noticed additional calls of fsync() to guarantee writes on blocks &#8211; 67 calls that seem to be related to 67 transactions right?\u00a0I double checked in my strace output and it seems that is the case but I may be wrong on this point so please feel free to comment.\u00a0Another interesting point is that I also\u00a0continued to\u00a0notice asynchronous IO\u00a0from <a href=\"https:\/\/github.com\/littledan\/linux-aio\">io_getevents<\/a> function that appeared from my trace. That make sense for me. Writes of data are asynchronous while those on transaction logs are synchronous by design. In this mode fsync() is triggered during transaction commits and checkpoints.<\/p>\n<ul>\n<li><b><strong>Enabling trace flag 3979<br \/>\n<\/strong><\/b><\/li>\n<\/ul>\n<p>Enabling trace flag 3979 has effect to disable the forced flush behavior replaced by <strong>writethrough<\/strong> and <strong>alternatewritethrough<\/strong> options. Referring to the <a href=\"https:\/\/support.microsoft.com\/en-us\/help\/4131496\/enable-forced-flush-mechanism-in-sql-server-2017-on-linux\" target=\"_blank\" rel=\"noopener noreferrer\">Microsoft article<\/a> the former will translate the well-known FILE_FLAG_WRITE_THROUGH flag requests into O_DSYNC opens but with some performance optimization stuff by using fdatasync() rather than fsync() Indeed, <a href=\"https:\/\/linux.die.net\/man\/2\/fdatasync\" target=\"_blank\" rel=\"noopener noreferrer\">fdatasync()<\/a> is supposed to generate less I\/O activity because it doesn\u2019t require to synchronize file metadata (only the data portion of the file is concerned here).<\/p>\n<p>Anyway, my strace sample file output below confirmed that both data file and transaction log were open with both O_DIRECT and O_DSYNC meaning we are bypassing the kernel buffer space and we are also forcing synchronous I\/O for both files.\u00a0\u00a0Does it matter? Well, from my understanding writing dirty data pages is still an asynchronous\u00a0process when\u00a0checkpoints occur. How much better it performs in this case? I don\u2019t know and it will require likely another bunch of strong tests on different use cases &#8211;<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">5279  11:07:36 open(\"\/u01\/sqlserverdata\/mssqlserver\/dbi_test.mdf\", O_RDWR|O_CREAT|O_EXCL|O_DSYNC|O_DIRECT, 0660) = 185\n\u2026\n5279  11:07:38 open(\"\/u02\/sqlserverlog\/mssqlserver\/dbi_test_log.ldf\", O_RDWR|O_CREAT|O_EXCL|O_DSYNC|O_DIRECT, 0660) = 185<\/pre>\n<p>As previously\u00a0I noticed 67 calls of fdatasync() (and not anymore fsync() here) related likely to my 67 implicit transactions and I still continued to notice asynchronous IO driving by io_getevents()\u00a0or io_submit() syscalls.<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">% time     seconds  usecs\/call     calls    errors syscall\n------ ----------- ----------- --------- --------- ----------------\n 73.90   12.678046        2360      5371      1927 futex\n 10.80    1.853571        7788       238           epoll_wait\n  9.05    1.551962       45646        34        30 restart_syscall\n  1.93    0.331275       47325         7         7 rt_sigtimedwait\n  1.84    0.316524      105508         3           nanosleep\n  1.61    0.276806        4131        67           io_getevents\n  0.71    0.121815           7     18259           clock_gettime\n  0.06    0.010184         152        67           fdatasync\n  0.02    0.003851          26       146           read\n  0.02    0.003217          12       272           epoll_ctl\n  0.01    0.002139          32        67           io_submit\n  0.01    0.002070          15       136           write\n  \u2026\n------ ----------- ----------- --------- --------- ----------------\n100.00   17.156630                 25170      2054 total<\/pre>\n<p>Finally, at the moment of this write up, let\u2019s say that Microsoft recommends enabling the trace flag 3979 as well as changing the default values of <em>writethrough<\/em> and a<em>lternatewritethrough<\/em> options to 0 to revert back to old behavior before CU6 illustrated in the first section of this blog post but only in the case your storage guarantees your writes will be \u201cO_DIRECT\u201d safe. I think you may understand why now &#8211; if my understanding of Linux I\/O is obviously correct- \ud83d\ude42<\/p>\n<p>See you!<\/p>\n<p><span style=\"float: none; background-color: #ffffff; color: #333333; cursor: text; font-family: Georgia,'Times New Roman','Bitstream Charter',Times,serif; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none;\">By David Barbarin<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Let\u2019s start the story from the beginning with some funny testing I tried to perform with SQL Server on Linux a couple of months ago. At that time, I wanted to get some pictures of syscalls from SQL Server as I already did in a past on Windows side with sysinternal tools as procmon and [&hellip;]<\/p>\n","protected":false},"author":26,"featured_media":11478,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[198,368,99],"tags":[1404,1355,73,1405,1406,1346],"type_dbi":[],"class_list":["post-11476","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-database-management","category-development-performance","category-sql-server","tag-fdatasync","tag-fsync","tag-linux","tag-o_direct","tag-o_dsync","tag-sqlserver"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>SQL Server on Linux - I\/O internal thoughts<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"SQL Server on Linux - I\/O internal thoughts\" \/>\n<meta property=\"og:description\" content=\"Let\u2019s start the story from the beginning with some funny testing I tried to perform with SQL Server on Linux a couple of months ago. At that time, I wanted to get some pictures of syscalls from SQL Server as I already did in a past on Windows side with sysinternal tools as procmon and [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-07-24T10:55:26+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-07-17T09:09:32+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-140-0-2-strace-stack-twitter.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"485\" \/>\n\t<meta property=\"og:image:height\" content=\"259\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Microsoft Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Microsoft Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-on-linux-io-internal-thoughts\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-on-linux-io-internal-thoughts\\\/\"},\"author\":{\"name\":\"Microsoft Team\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/bfab48333280d616e1170e7369df90a4\"},\"headline\":\"SQL Server on Linux &#8211; I\\\/O internal thoughts\",\"datePublished\":\"2018-07-24T10:55:26+00:00\",\"dateModified\":\"2023-07-17T09:09:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-on-linux-io-internal-thoughts\\\/\"},\"wordCount\":1228,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-on-linux-io-internal-thoughts\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2022\\\/04\\\/blog-140-0-2-strace-stack-twitter.jpg\",\"keywords\":[\"fdatasync\",\"fsync\",\"Linux\",\"O_DIRECT\",\"O_DSYNC\",\"SQLServer\"],\"articleSection\":[\"Database management\",\"Development &amp; Performance\",\"SQL Server\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-on-linux-io-internal-thoughts\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-on-linux-io-internal-thoughts\\\/\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-on-linux-io-internal-thoughts\\\/\",\"name\":\"SQL Server on Linux - I\\\/O internal thoughts\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-on-linux-io-internal-thoughts\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-on-linux-io-internal-thoughts\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2022\\\/04\\\/blog-140-0-2-strace-stack-twitter.jpg\",\"datePublished\":\"2018-07-24T10:55:26+00:00\",\"dateModified\":\"2023-07-17T09:09:32+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/bfab48333280d616e1170e7369df90a4\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-on-linux-io-internal-thoughts\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-on-linux-io-internal-thoughts\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-on-linux-io-internal-thoughts\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2022\\\/04\\\/blog-140-0-2-strace-stack-twitter.jpg\",\"contentUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2022\\\/04\\\/blog-140-0-2-strace-stack-twitter.jpg\",\"width\":485,\"height\":259},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-on-linux-io-internal-thoughts\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"SQL Server on Linux &#8211; I\\\/O internal thoughts\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/bfab48333280d616e1170e7369df90a4\",\"name\":\"Microsoft Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c44a1a792c059f24055763aa77d80a244467f6eef724a8bd13db8d4a350b7a4c?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c44a1a792c059f24055763aa77d80a244467f6eef724a8bd13db8d4a350b7a4c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c44a1a792c059f24055763aa77d80a244467f6eef724a8bd13db8d4a350b7a4c?s=96&d=mm&r=g\",\"caption\":\"Microsoft Team\"},\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/author\\\/microsoft-team\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"SQL Server on Linux - I\/O internal thoughts","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/","og_locale":"en_US","og_type":"article","og_title":"SQL Server on Linux - I\/O internal thoughts","og_description":"Let\u2019s start the story from the beginning with some funny testing I tried to perform with SQL Server on Linux a couple of months ago. At that time, I wanted to get some pictures of syscalls from SQL Server as I already did in a past on Windows side with sysinternal tools as procmon and [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/","og_site_name":"dbi Blog","article_published_time":"2018-07-24T10:55:26+00:00","article_modified_time":"2023-07-17T09:09:32+00:00","og_image":[{"width":485,"height":259,"url":"http:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-140-0-2-strace-stack-twitter.jpg","type":"image\/jpeg"}],"author":"Microsoft Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Microsoft Team","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/"},"author":{"name":"Microsoft Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/bfab48333280d616e1170e7369df90a4"},"headline":"SQL Server on Linux &#8211; I\/O internal thoughts","datePublished":"2018-07-24T10:55:26+00:00","dateModified":"2023-07-17T09:09:32+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/"},"wordCount":1228,"commentCount":0,"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-140-0-2-strace-stack-twitter.jpg","keywords":["fdatasync","fsync","Linux","O_DIRECT","O_DSYNC","SQLServer"],"articleSection":["Database management","Development &amp; Performance","SQL Server"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/","url":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/","name":"SQL Server on Linux - I\/O internal thoughts","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/#primaryimage"},"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-140-0-2-strace-stack-twitter.jpg","datePublished":"2018-07-24T10:55:26+00:00","dateModified":"2023-07-17T09:09:32+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/bfab48333280d616e1170e7369df90a4"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/#primaryimage","url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-140-0-2-strace-stack-twitter.jpg","contentUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-140-0-2-strace-stack-twitter.jpg","width":485,"height":259},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-on-linux-io-internal-thoughts\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"SQL Server on Linux &#8211; I\/O internal thoughts"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/bfab48333280d616e1170e7369df90a4","name":"Microsoft Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/c44a1a792c059f24055763aa77d80a244467f6eef724a8bd13db8d4a350b7a4c?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/c44a1a792c059f24055763aa77d80a244467f6eef724a8bd13db8d4a350b7a4c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c44a1a792c059f24055763aa77d80a244467f6eef724a8bd13db8d4a350b7a4c?s=96&d=mm&r=g","caption":"Microsoft Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/microsoft-team\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/11476","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/26"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=11476"}],"version-history":[{"count":2,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/11476\/revisions"}],"predecessor-version":[{"id":26712,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/11476\/revisions\/26712"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media\/11478"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=11476"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=11476"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=11476"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=11476"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}