<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Databases on vnykmshr</title><link>https://blog.vnykmshr.com/writing/tags/databases/</link><description>Recent content in Databases on vnykmshr</description><generator>Hugo</generator><language>en</language><lastBuildDate>Tue, 05 Nov 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.vnykmshr.com/writing/tags/databases/index.xml" rel="self" type="application/rss+xml"/><item><title>Primary PII</title><link>https://blog.vnykmshr.com/writing/primary-pii/</link><pubDate>Tue, 05 Nov 2024 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/primary-pii/</guid><description>&lt;p&gt;A regulation arrives. Or an auditor. Or a new market with stricter rules. PII is a thing the application was always sloppy about, and now it is a thing the application has to be careful with. This is how PII externalization begins: as someone else&amp;rsquo;s deadline, landing on the engineering team as an initiative.&lt;/p&gt;
&lt;p&gt;The work looks like encryption at first. It is not.&lt;/p&gt;
&lt;h2 id="identify"&gt;Identify&lt;/h2&gt;
&lt;p&gt;The first question is not how to encrypt. The first question is what to encrypt.&lt;/p&gt;</description></item><item><title>Redis caching patterns</title><link>https://blog.vnykmshr.com/writing/redis-caching-patterns/</link><pubDate>Thu, 20 Jun 2024 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/redis-caching-patterns/</guid><description>&lt;p&gt;Put Redis in front of a database and reads get fast. The cost is a cache layer that&amp;rsquo;s now load-bearing, and a set of failure modes that come with that.&lt;/p&gt;
&lt;p&gt;Three write patterns, three hard problems. The patterns determine consistency. The problems determine whether your cache layer is a net positive or a source of outages.&lt;/p&gt;
&lt;h2 id="write-patterns"&gt;Write patterns&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Cache-aside&lt;/strong&gt; (lazy loading). The application checks cache on read. On miss, it reads from the database and populates cache. Writes go directly to the database; cache entries are either invalidated or left to expire.&lt;/p&gt;</description></item><item><title>PostgreSQL HA</title><link>https://blog.vnykmshr.com/writing/postgres-ha/</link><pubDate>Mon, 15 Mar 2021 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/postgres-ha/</guid><description>&lt;p&gt;PostgreSQL&amp;rsquo;s streaming replication is straightforward to set up. The documentation is clear, the configuration is well-understood, and base backups with &lt;code&gt;pg_basebackup&lt;/code&gt; work reliably.&lt;/p&gt;
&lt;p&gt;The operational problems are the hard part. They show up when the primary goes down and the automated failover does the wrong thing. Or when you promote a replica that&amp;rsquo;s silently been two hours behind. Or when you discover that backups you&amp;rsquo;ve been taking for months don&amp;rsquo;t actually restore.&lt;/p&gt;</description></item><item><title>The week pgbouncer stopped being news</title><link>https://blog.vnykmshr.com/writing/pgbouncer-stopped-being-news/</link><pubDate>Thu, 12 Jul 2018 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/pgbouncer-stopped-being-news/</guid><description>&lt;p&gt;The connection count climbs faster than our instance classes can keep up. Ops is hot. Every few weeks the same thread resurfaces: we need a pool in front of Postgres before the next scale event.&lt;/p&gt;
&lt;p&gt;We move on pgbouncer.&lt;/p&gt;
&lt;h2 id="the-choice"&gt;The choice&lt;/h2&gt;
&lt;p&gt;Two modes on the table. Session pooling hands a connection to a client and gives it back when the client disconnects. Transaction pooling hands one out per transaction. Transaction is tighter &amp;ndash; the pool stretches further, the math gets better &amp;ndash; but the client loses everything a session holds. Server-side prepared statements. Advisory locks. Temp tables. &lt;code&gt;SET&lt;/code&gt; commands that expect to persist.&lt;/p&gt;</description></item><item><title>MySQL on XFS</title><link>https://blog.vnykmshr.com/writing/mysql-xfs/</link><pubDate>Thu, 11 Apr 2013 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/mysql-xfs/</guid><description>&lt;p&gt;XFS handles database workloads better than ext4 &amp;ndash; better concurrent I/O, more efficient metadata operations for tables-heavy schemas, and delayed allocation that improves write throughput. The obvious approach is to change MySQL&amp;rsquo;s &lt;code&gt;datadir&lt;/code&gt; in the config. The less obvious approach is bind mounts, which keep every path where the system expects it.&lt;/p&gt;
&lt;h2 id="setup"&gt;Setup&lt;/h2&gt;
&lt;p&gt;Install XFS utilities alongside MySQL:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install -y xfsprogs mysql-server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create the filesystem on the dedicated volume:&lt;/p&gt;</description></item><item><title>Rolling your own search</title><link>https://blog.vnykmshr.com/writing/rolling-your-own-search/</link><pubDate>Wed, 14 Mar 2012 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/rolling-your-own-search/</guid><description>&lt;p&gt;The shop needed catalog search. Users type something, products come back. Sounds trivial until you start building it.&lt;/p&gt;
&lt;p&gt;Our stack is Node.js, MySQL for the primary data store, MongoDB for everything else we need to go fast. The catalog lives in MySQL &amp;ndash; products, categories, attributes, prices. Normalized, relational, correct. But relational isn&amp;rsquo;t searchable. Try finding &amp;ldquo;blue cotton kurta&amp;rdquo; across five joined tables with MySQL FULLTEXT on MyISAM. It sort of works. The relevance is terrible.&lt;/p&gt;</description></item></channel></rss>