<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Sysadmin on davepedu.com</title><link>https://davepedu.com/tags/sysadmin/</link><description>Recent content in Sysadmin on davepedu.com</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><managingEditor>dave@davepedu.com (dave)</managingEditor><webMaster>dave@davepedu.com (dave)</webMaster><lastBuildDate>Fri, 14 Dec 2018 00:00:00 +0000</lastBuildDate><atom:link href="https://davepedu.com/tags/sysadmin/index.xml" rel="self" type="application/rss+xml"/><item><title>nginx upload size behavior</title><link>https://davepedu.com/blog/2018/12/14/nginx-upload-size-behavior/</link><pubDate>Fri, 14 Dec 2018 00:00:00 +0000</pubDate><author>dave@davepedu.com (dave)</author><guid>https://davepedu.com/blog/2018/12/14/nginx-upload-size-behavior/</guid><description>&lt;p&gt;I recently encountered some odd behavior in nginx involving file upload sizes. Nginx has long had a
&lt;code&gt;client_max_body_size&lt;/code&gt; setting which controls how large of an HTTP POST or file upload the server will accept by
comparing to the &lt;code&gt;Content-Length&lt;/code&gt; header. Attempting to send a request larger than this results in a
&lt;code&gt;413 Request Entity Too Large&lt;/code&gt; error from the server. But is this always the case?&lt;/p&gt;
&lt;p&gt;For starters, here&amp;rsquo;s the description of &lt;code&gt;client_max_body_size&lt;/code&gt;. From
&lt;a href="https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size"&gt;nginx&amp;rsquo;s docs&lt;/a&gt;:&lt;/p&gt;</description><content>&lt;p&gt;I recently encountered some odd behavior in nginx involving file upload sizes. Nginx has long had a
&lt;code&gt;client_max_body_size&lt;/code&gt; setting which controls how large of an HTTP POST or file upload the server will accept by
comparing to the &lt;code&gt;Content-Length&lt;/code&gt; header. Attempting to send a request larger than this results in a
&lt;code&gt;413 Request Entity Too Large&lt;/code&gt; error from the server. But is this always the case?&lt;/p&gt;
&lt;p&gt;For starters, here&amp;rsquo;s the description of &lt;code&gt;client_max_body_size&lt;/code&gt;. From
&lt;a href="https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size"&gt;nginx&amp;rsquo;s docs&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sets the maximum allowed size of the client request body, specified in the “Content-Length” request header field. If
the size in a request exceeds the configured value, the 413 (Request Entity Too Large) error is returned to the
client. Please be aware that browsers cannot correctly display this error. Setting size to 0 disables checking of
client request body size.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While this sounds pretty obvious, there&amp;rsquo;s some hidden behavior one might not expect.&lt;/p&gt;
&lt;p&gt;Take the following server configuration block for example:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-clike"&gt;server {
server_name subdomain.somehostname.com listen 443 ssl;
ssl_certificate "/some/file.crt";
ssl_certificate_key "/some/other/file.key";
ssl_protocols ...;
ssl_ciphers ...;
client_max_body_size 64m;
location / {
return 307 https://anothersubdomain.somehostname.com$request_uri;
}
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function of this configuration is obvious - it&amp;rsquo;s an ssl server that will issue a 307 redirect to all requests,
redirecting them to another location. In my case this location would receive file uploads from legacy software; the 307
was needed to cause clients to retry the upload elsewhere. Of course, if the upload is larger than 64m, a 413 error is
returned instead.&lt;/p&gt;
&lt;p&gt;But what happens if we remove the location block?&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-clike"&gt;server {
server_name subdomain.somehostname.com listen 443 ssl;
ssl_certificate "/some/file.crt";
ssl_certificate_key "/some/other/file.key";
ssl_protocols ...;
ssl_ciphers ...;
client_max_body_size 64m;
return 307 https://anothersubdomain.somehostname.com$request_uri;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;While this looks like it would function identically (and it does for the most part), there&amp;rsquo;s a subtle difference. Nginx
will no longer enforce the &lt;code&gt;client_max_body_size&lt;/code&gt; directive! Requests containing uploads of any size will be issued
a redirect.&lt;/p&gt;
&lt;p&gt;This is of course a relatively minor issue, as a redirecting server does not process any upload content. In other words,
the client is redirected before the upload process begins. In my case, I was moving from the latter config above to the
former due to needing some additional location blocks in the config.&lt;/p&gt;
&lt;p&gt;As it turns out, this behavior is &lt;a href="https://mailman.nginx.org/pipermail/nginx/2018-December/057293.html"&gt;likely undocumented&lt;/a&gt;.
Lesson learned - be careful how you set a &lt;code&gt;client_max_body_size&lt;/code&gt;!&lt;/p&gt;</content></item><item><title>subsonic database bloat &amp; corruption</title><link>https://davepedu.com/blog/2015/08/01/subsonic-database-bloat-corruption/</link><pubDate>Sat, 01 Aug 2015 00:00:00 +0000</pubDate><author>dave@davepedu.com (dave)</author><guid>https://davepedu.com/blog/2015/08/01/subsonic-database-bloat-corruption/</guid><description>&lt;p&gt;&lt;strong&gt;Update 04/08/2019:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve had trouble with this method on newer versions of Subsonic and since the original technique was kind of bad - it
more or less triggers crash recovery - I decided to take another look. I ended up finding the
&lt;a href="https://packages.ubuntu.com/search?keywords=hsqldb-utils"&gt;hsqldb-utils&lt;/a&gt; package, which includes some command-line
utilities to manage HSQLDB databases.&lt;/p&gt;
&lt;p&gt;Unfortunately, this package doesn&amp;rsquo;t use the same version of HSQLDB as Subsonic - my Subsonic instance is using 1.8.0.5
(it lists this in the database&amp;rsquo;s &amp;lsquo;subsonic.properties&amp;rsquo; file), whereas the tools included in hsqldb-utils (on Ubuntu
Bionic, at least) are well past 2.0. But, this is at least a step in the right direction. We can download an older
version of the tools.&lt;/p&gt;</description><content>&lt;p&gt;&lt;strong&gt;Update 04/08/2019:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve had trouble with this method on newer versions of Subsonic and since the original technique was kind of bad - it
more or less triggers crash recovery - I decided to take another look. I ended up finding the
&lt;a href="https://packages.ubuntu.com/search?keywords=hsqldb-utils"&gt;hsqldb-utils&lt;/a&gt; package, which includes some command-line
utilities to manage HSQLDB databases.&lt;/p&gt;
&lt;p&gt;Unfortunately, this package doesn&amp;rsquo;t use the same version of HSQLDB as Subsonic - my Subsonic instance is using 1.8.0.5
(it lists this in the database&amp;rsquo;s &amp;lsquo;subsonic.properties&amp;rsquo; file), whereas the tools included in hsqldb-utils (on Ubuntu
Bionic, at least) are well past 2.0. But, this is at least a step in the right direction. We can download an older
version of the tools.&lt;/p&gt;
&lt;p&gt;I found the following jars by scouring the internet, downloading them into /tools/ on my system.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;hsqldb-sqltool-jdk1.5-2.0.jar&lt;/li&gt;
&lt;li&gt;hsqldb-1.8.0.5.jar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Without further ado, here&amp;rsquo;s the happy-path way to de-bloat your database:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install Java. You probably already have this since you&amp;rsquo;re running Subsonic, right?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stop Subsonic. Subsonic must NOT be running while is operation is performed or database corruption is likely.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change directories into the database dir. The path below could be different for you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cd /var/subsonic/db/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the database using hsqldb-sqltool. Take note of the classpath (&lt;code&gt;-cp&lt;/code&gt;), this needs to be pointed at the two jars above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;java -cp :/tools/hsqldb-sqltool-jdk1.5-2.0.jar:/tools/hsqldb-1.8.0.5.jar org.hsqldb.cmdline.SqlTool --inlineRc=url=jdbc:hsqldb:file:subsonic --driver org.hsqldb.jdbcDriver&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the compact function:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sql&amp;gt; &lt;code&gt;SHUTDOWN COMPACT;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Exit hsqldb-sqltool by pressing control-d.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At this point, Subsonic&amp;rsquo;s database should be drastically smaller. In my case:&lt;/p&gt;
&lt;p&gt;Before:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-clike"&gt;# du -sh /srv/subsonic
3.2G /srv/subsonic&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-clike"&gt;# du -sh /srv/subsonic
14M /srv/subsonic&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As insert/update/deletes queries are performed data moves around inside of HSQLDB&amp;rsquo;s data files. Over time, and similar
to a hard drive, data becomes fragmented and the database file size grows despite much of the space within it being &amp;ldquo;not
in use&amp;rdquo;. What we&amp;rsquo;ve done is rewrite the database file in an optimized way such that there is no &amp;ldquo;unused&amp;rdquo; space left
within the file; all the data is contiguous. It will bloat again over time, but that&amp;rsquo;s a concern for later. Do take a
look at &lt;a href="http://www.hsqldb.org/doc/1.8/guide/guide.html#N101DB"&gt;HSQLDB&amp;rsquo;s docs&lt;/a&gt; on the subject.&lt;/p&gt;
&lt;p&gt;I maintain a &lt;a href="https://git.davepedu.com/dave/docker-subsonic"&gt;Dockerfile for Subsonic&lt;/a&gt; and will eventually add this
database compression method as an automated task within the image. This should solve Subsonic database bloat &lt;a href="https://www.youtube.com/watch?v=gONcDfFrPis"&gt;once and
for all&lt;/a&gt;! Edit: This is complete! As start of the
&lt;a href="https://git.davepedu.com/dave/docker-subsonic/src/branch/master/start#L8"&gt;startup procedure&lt;/a&gt;, my Docker image will
compress the database at every startup.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Original article below. I highly recommend NOT doing this; it is here for posterity:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I use &lt;a href="http://www.subsonic.org/"&gt;Subsonic&lt;/a&gt; media streamer install to stream my music library on my mobile phone, media
center, laptop etc. Recently, my web UI and other client apps stopped working and I noticed the subsonic server was
spewing database errors.&lt;/p&gt;
&lt;p&gt;Ugly things like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-"&gt;87431 [btpool0-6] WARN org.mortbay.log - Nested in org.springframework.dao.TransientDataAccessResourceException: PreparedStatementCallback; SQL [ &lt;snip&gt; ]:
java.sql.SQLException: java.io.IOException:** S1000 Data file size limit is reached in statement** [update media_file set &lt;snip&gt;]
at org.hsqldb.jdbc.Util.throwError(Unknown Source)
at org.hsqldb.jdbc.jdbcPreparedStatement.executeUpdate(Unknown Source)
at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:798)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:591)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:792)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:850)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;hellip;With hundreds and hundreds of lines in each stack trace. Subsonic is written in Java and uses a database called
HSQLDB which has some sort of size-limiting upper limit that&amp;rsquo;s being hit. Since it is similar to SQLite, we can check
the size of the database files on disk. Inspecting these revealed it had grown to 2 gigabytes! Considering it holds only
a list of media files, a few playlists and some settings, there&amp;rsquo;s no reason it should be that large.&lt;/p&gt;
&lt;p&gt;Buried in HSQLDB&amp;rsquo;s docs I found a description of it&amp;rsquo;s startup procedure,
&lt;a href="http://www.hsqldb.org/doc/1.8/guide/apc.html"&gt;here&lt;/a&gt;. It turns out by simply changing the &amp;ldquo;modified&amp;rdquo; setting to &amp;ldquo;yes&amp;rdquo; in
the database&amp;rsquo;s property file, the engine triggers a database recovery routine (which actually restores an internal
backup). On Ubuntu linux, the database property file is &lt;code&gt;/var/subsonic/db/subsonic.properties&lt;/code&gt;. After starting subsonic
and letting it grind for a few minutes, I just needed to subsonic re-scan my media files and it was back in business!
Not one setting or play count was lost. After the cleanup, the database is all of 44 MB. Nice!&lt;/p&gt;
&lt;p&gt;I thought this was a pretty easy fix, but tricky to find. If anyone finds this helpful,
&lt;a href="https://davepedu.com/contact/"&gt;Let me know&lt;/a&gt;!&lt;/p&gt;</content></item></channel></rss>