<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Abhishek Mishra</title>
    <description>The latest articles on DEV Community by Abhishek Mishra (@golu360).</description>
    <link>https://dev.to/golu360</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F758875%2F61fa4cdb-486b-4c93-8bb9-6cf92d466761.jpeg</url>
      <title>DEV Community: Abhishek Mishra</title>
      <link>https://dev.to/golu360</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/golu360"/>
    <language>en</language>
    <item>
      <title>SQLite3 Replication: A Wizard's Guide🧙🏽</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Tue, 27 Feb 2024 19:57:05 +0000</pubDate>
      <link>https://dev.to/golu360/sqlite3-replication-a-wizards-guide-1bnn</link>
      <guid>https://dev.to/golu360/sqlite3-replication-a-wizards-guide-1bnn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;Let's admit it – SQLite often doesn't receive the credit it deserves as a  database. I mean, it has no configuration overhead, no external dependencies, doesn't need a server or a process to run on, can also run "in-memory"⚡.&lt;/p&gt;

&lt;p&gt;Often, with databases something that comes up is "Replication". Other databases such as Postgres, MySQL offer their own replication mechanisms. SQLite does not offer something natively when it comes to replication.&lt;/p&gt;

&lt;p&gt;This post intends to help you setup replication for SQLite using &lt;a href="https://litestream.io/"&gt;Litestream&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What do you need?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Any Cloud Storage (AWS S3 for this Tutorial)&lt;/li&gt;
&lt;li&gt;A SQLite Database&lt;/li&gt;
&lt;li&gt;Litestream&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Installing SQLite and Litestream:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  SQLite:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Execute the below commands on your terminal:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt install sqlite3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then verify the installation using &lt;code&gt;sqlite3 --version&lt;/code&gt; command.&lt;/p&gt;

&lt;h4&gt;
  
  
  Litestream:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Download the &lt;code&gt;.deb&lt;/code&gt; file for Litestream ,which contains Litestream and it's systemd service using below command and install it:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wget https://github.com/benbjohnson/litestream/releases/download/v0.3.13/litestream-v0.3.13-linux-amd64.deb
sudo dpkg -i litestream-v0.3.13-linux-amd64.deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should install Litestream on your system, to verify the installation, execute &lt;code&gt;litestream --version&lt;/code&gt; command.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a SQLite Database &amp;amp; Tables:
&lt;/h3&gt;

&lt;p&gt;For the sake of the tutorial, I will create a database named &lt;code&gt;pokedex.db&lt;/code&gt; which contains information about different Pokemon speicies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create the SQLite Database using &lt;code&gt;sqlite3 pokedex.db&lt;/code&gt; command. It will invoke the sqlite3 shell and allow you to modify &lt;code&gt;pokedex.db&lt;/code&gt; which we just created.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;golu360@ip-127-0-0-1:~$ sqlite3 pokedex.db
SQLite version 3.39.5 2022-10-14 20:58:05
Enter ".help" for usage hints.
sqlite&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create the Pokemon Table using below query:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE Pokemon (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    type TEXT NOT NULL,
    level INTEGER,
    evolution_stage INTEGER
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Insert some data into this table:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSERT INTO Pokemon (name, type, level, evolution_stage) VALUES ('Bulbasaur', 'Grass', 5, 1);
INSERT INTO Pokemon (name, type, level, evolution_stage) VALUES ('Ivysaur', 'Grass', 16, 2);
INSERT INTO Pokemon (name, type, level, evolution_stage) VALUES ('Venusaur', 'Grass', 32, 3);
INSERT INTO Pokemon (name, type, level, evolution_stage) VALUES ('Charmander', 'Fire', 5, 1);
INSERT INTO Pokemon (name, type, level, evolution_stage) VALUES ('Charmeleon', 'Fire', 16, 2);
INSERT INTO Pokemon (name, type, level, evolution_stage) VALUES ('Charizard', 'Fire', 36, 3);
INSERT INTO Pokemon (name, type, level, evolution_stage) VALUES ('Squirtle', 'Water', 5, 1);
INSERT INTO Pokemon (name, type, level, evolution_stage) VALUES ('Wartortle', 'Water', 16, 2);
INSERT INTO Pokemon (name, type, level, evolution_stage) VALUES ('Blastoise', 'Water', 36, 3);
INSERT INTO Pokemon (name, type, level, evolution_stage) VALUES ('Caterpie', 'Bug', 3, 1);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, we have an SQLite Database with some data setup. Now we can replicate this into our S3 Bucket.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Good Part:
&lt;/h4&gt;

&lt;p&gt;Litestream runs as a background service on your machine which uses a configuration file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable Litestream to run as a background service
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl enable litestream
sudo systemctl start litestream
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then verify if the service is running or not using &lt;code&gt;sudo journalctl -u litestream -f&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;The Litestream config path is &lt;code&gt;/etc/litestream.yml&lt;/code&gt;. Use &lt;code&gt;cat /etc/litestream.yml&lt;/code&gt; to checkout the contents of this file and ensure it is present in the mentioned path.&lt;/p&gt;

&lt;p&gt;The config file contents should look like :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#access-key-id: AKIAxxxxxxxxxxxxxxxx
#secret-access-key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxx

#dbs:
#  - path: /path/to/local/db
#    replicas:
#      - url: s3://BUCKETNAME/PATHNAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;access-key-id&lt;/code&gt; and &lt;code&gt;secret-access-key&lt;/code&gt; mention your AWS Access Key and Secret Access Keys. Ensure that this user has needed permissions on the S3 bucket you want to replicate to.&lt;/p&gt;

&lt;p&gt;Mention the DB Path of your Database and the S3 Bucket URL in which you want to replicate the database into. For our &lt;code&gt;pokedex.db&lt;/code&gt;, it should look something like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;access-key-id: AKIA12345GGF
secret-access-key: EXAMPLESECRET-key

dbs:
  - path: /home/golu360/pokedex.db
    replicas:
      - url: s3://pokedex-replica/db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we have changed the Litestream config, you can simply restart the Litestream service using &lt;code&gt;sudo systemctl restart litestream&lt;/code&gt; command. To ensure all is running fine, check the service status using &lt;code&gt;sudo systemctl status litestream&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Voila&lt;/strong&gt;! Litestream should now start replicating your DB into S3.&lt;/p&gt;

&lt;h4&gt;
  
  
  Simulating a Disaster and Restoring the DB:
&lt;/h4&gt;

&lt;p&gt;To simulate the worst possible disaster for a SQLite Database, just &lt;em&gt;delete the database file&lt;/em&gt;. Yes, delete it. Wield the &lt;code&gt;rm pokedex.db&lt;/code&gt; spell, and cast it on your terminal screen.&lt;/p&gt;

&lt;p&gt;Now onto the restoration of this database.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;litestream restore -o pokedex.db s3://pokedex-replica/db&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Above command should simply restore your database to it's state prior to deletion. Your database is back to life. &lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion:
&lt;/h4&gt;

&lt;p&gt;We just setup a replication setup for SQLite using Litestream to add replication and point in-time failure recovery, without any code changes to your application code. &lt;/p&gt;

&lt;p&gt;Litestream also supports  replication to Azure Blob Storage, Google Cloud Storage and more.&lt;/p&gt;

&lt;h5&gt;
  
  
  References :
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://litestream.io/guides/"&gt;https://litestream.io/guides/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sqlite.org/index.html"&gt;https://www.sqlite.org/index.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/library/sqlite3.html"&gt;https://docs.python.org/3/library/sqlite3.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.infoworld.com/article/3331923/why-you-should-use-sqlite.html"&gt;https://www.infoworld.com/article/3331923/why-you-should-use-sqlite.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>database</category>
      <category>sqlite</category>
      <category>sql</category>
    </item>
  </channel>
</rss>
