analytics/Plausible.Purge.html

369 lines
13 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="ExDoc v0.31.1">
<meta name="project" content="Plausible v0.0.1">
<title>Plausible.Purge — Plausible v0.0.1</title>
<link rel="stylesheet" href="dist/html-elixir-FM2CSD74.css" />
<script src="dist/handlebars.runtime-NWIB6V2M.js"></script>
<script src="dist/handlebars.templates-43PMFBC7.js"></script>
<script src="dist/sidebar_items-04905ADA.js"></script>
<script src="docs_config.js"></script>
<script async src="dist/html-L4O5OK2K.js"></script>
</head>
<body data-type="modules" class="page-module">
<script>
try {
var settings = JSON.parse(localStorage.getItem('ex_doc:settings') || '{}');
if (settings.theme === 'dark' ||
((settings.theme === 'system' || settings.theme == null) &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
document.body.classList.add('dark')
}
} catch (error) { }
</script>
<div class="main">
<button id="sidebar-menu" class="sidebar-button sidebar-toggle" aria-label="toggle sidebar" aria-controls="sidebar">
<i class="ri-menu-line ri-lg" title="Collapse/expand sidebar"></i>
</button>
<div class="background-layer"></div>
<nav id="sidebar" class="sidebar">
<div class="sidebar-header">
<div class="sidebar-projectInfo">
<a href="readme.html" class="sidebar-projectImage">
<img src="assets/logo.png" alt="Plausible" />
</a>
<div>
<a href="readme.html" class="sidebar-projectName" translate="no">
Plausible
</a>
<div class="sidebar-projectVersion" translate="no">
v0.0.1
</div>
</div>
</div>
<ul id="sidebar-listNav" class="sidebar-listNav" role="tablist">
<li>
<button id="extras-list-tab-button" role="tab" data-type="extras" aria-controls="extras-tab-panel" aria-selected="true" tabindex="0">
Pages
</button>
</li>
<li>
<button id="modules-list-tab-button" role="tab" data-type="modules" aria-controls="modules-tab-panel" aria-selected="false" tabindex="-1">
Modules
</button>
</li>
<li>
<button id="tasks-list-tab-button" role="tab" data-type="tasks" aria-controls="tasks-tab-panel" aria-selected="false" tabindex="-1">
<span translate="no">Mix</span> Tasks
</button>
</li>
</ul>
</div>
<div id="extras-tab-panel" class="sidebar-tabpanel" role="tabpanel" aria-labelledby="extras-list-tab-button">
<ul id="extras-full-list" class="full-list"></ul>
</div>
<div id="modules-tab-panel" class="sidebar-tabpanel" role="tabpanel" aria-labelledby="modules-list-tab-button" hidden>
<ul id="modules-full-list" class="full-list"></ul>
</div>
<div id="tasks-tab-panel" class="sidebar-tabpanel" role="tabpanel" aria-labelledby="tasks-list-tab-button" hidden>
<ul id="tasks-full-list" class="full-list"></ul>
</div>
</nav>
<main class="content">
<output role="status" id="toast"></output>
<div class="content-outer">
<div id="content" class="content-inner">
<div class="top-search">
<div class="search-settings">
<form class="search-bar" action="search.html">
<label class="search-label">
<span class="sr-only">Search documentation of Plausible</span>
<input name="q" type="text" class="search-input" placeholder="Search Documentation (press /)" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" />
</label>
<button type="submit" class="search-button" aria-label="Submit Search">
<i class="ri-search-2-line ri-lg" aria-hidden="true" title="Submit search"></i>
</button>
<button type="button" tabindex="-1" class="search-close-button" aria-hidden="true">
<i class="ri-close-line ri-lg" title="Cancel search"></i>
</button>
</form>
<div class="autocomplete">
</div>
<button class="icon-settings display-settings">
<i class="ri-settings-3-line"></i>
<span class="sr-only">Settings</span>
</button>
</div>
</div>
<h1>
<a href="https://github.com/plausible/analytics/blob/main/lib/plausible/purge.ex#L1" title="View Source" class="icon-action" rel="help">
<i class="ri-code-s-slash-line" aria-hidden="true"></i>
<span class="sr-only">View Source</span>
</a>
<span translate="no">Plausible.Purge</span>
<small class="app-vsn" translate="no">(Plausible v0.0.1)</small>
</h1>
<section id="moduledoc">
<p>Deletes data from a site.</p><p>Stats are stored on Clickhouse, and unlike other databases data deletion is
done asynchronously.</p><p>All import tables have MergeTree's deduplication mechanism <em>disabled</em> by setting
<code class="inline">replicated_deduplication_window</code> from default 100 to 0. When enabled, every insert
into a given table is compared against hashes of 100 previous inserts (as complete
parts, not concrete rows) and ignored when match is found. The prupose of that
mechanism is making inserts of exact same batches idempotent when retrying them
shortly after - for instance due to timeout, when the client can't easily tell if
previous insert succeeded or not. Deduplication, however, only considers inserts,
not mutations. Deletions do not affect stored hashes, so further inserts of parts
that were deleted will still be treated as duplicates. That's why this feature
is disabled for import tables.</p><p>Although deletions are asynchronous, the parts to delete are &quot;remembered&quot;, so there's
no risk of overlapping deletion causing problems with import following right after it.</p><p>IMPORTANT: Deletion requires revision if/when import tables get moved to sharded CH
cluster setup. Mutation queries, which have to be run with <code class="inline">ON CLUSTER</code> in such setup,
dispatch independent queries across shards and those queries can start at different
times. This in turn means risk of deletions corrupting data of follow-up inserts
in some edge cases. Ideally, imported entries should be unique for a given import</p><ul><li><p>an extra <code class="inline">import_id</code> column can be introduced, holding identifier. Last processed
import identifier should be stored with other site data and should be used for scoping
imported stats queries. No longer used imports can then be safely removed fully
asynchronously.</p></li><li><p><a href="https://clickhouse.com/docs/en/sql-reference/statements/alter/delete">Clickhouse <code class="inline">ALTER TABLE ... DELETE</code> Statement</a></p></li><li><p><a href="https://clickhouse.com/docs/en/sql-reference/statements/alter/#synchronicity-of-alter-queries">Synchronicity of <code class="inline">ALTER</code> Queries</a></p></li></ul>
</section>
<section id="summary" class="details-list">
<h1 class="section-heading">
<a class="hover-link" href="#summary">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Summary</span>
</h1>
<div class="summary-functions summary">
<h2>
<a href="#functions">Functions</a>
</h2>
<div class="summary-row">
<div class="summary-signature">
<a href="#delete_imported_stats!/1" translate="no">delete_imported_stats!(site)</a>
</div>
<div class="summary-synopsis"><p>Deletes imported stats from and clears the <code class="inline">stats_start_date</code> field.</p></div>
</div>
<div class="summary-row">
<div class="summary-signature">
<a href="#delete_imported_stats!/2" translate="no">delete_imported_stats!(site, import_id)</a>
</div>
</div>
<div class="summary-row">
<div class="summary-signature">
<a href="#delete_native_stats!/1" translate="no">delete_native_stats!(site)</a>
</div>
<div class="summary-synopsis"><p>Move stats pointers so that no historical stats are available.</p></div>
</div>
<div class="summary-row">
<div class="summary-signature">
<a href="#reset!/1" translate="no">reset!(site)</a>
</div>
</div>
</div>
</section>
<section id="functions" class="details-list">
<h1 class="section-heading">
<a class="hover-link" href="#functions">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Functions</span>
</h1>
<div class="functions-list">
<section class="detail" id="delete_imported_stats!/1">
<div class="detail-header">
<a href="#delete_imported_stats!/1" class="detail-link" title="Link to this function">
<i class="ri-link-m" aria-hidden="true"></i>
<span class="sr-only">Link to this function</span>
</a>
<h1 class="signature" translate="no">delete_imported_stats!(site)</h1>
<a href="https://github.com/plausible/analytics/blob/main/lib/plausible/purge.ex#L48" class="icon-action" rel="help" title="View Source">
<i class="ri-code-s-slash-line" aria-hidden="true"></i>
<span class="sr-only">View Source</span>
</a>
</div>
<section class="docstring">
<div class="specs">
<pre translate="no"><span class="attribute">@spec</span> delete_imported_stats!(<a href="Plausible.Site.html#t:t/0">Plausible.Site.t</a>() | <a href="Plausible.Imported.SiteImport.html#t:t/0">Plausible.Imported.SiteImport.t</a>()) ::
:ok</pre>
</div>
<p>Deletes imported stats from and clears the <code class="inline">stats_start_date</code> field.</p><p>The <code class="inline">stats_start_date</code> is expected to get repopulated the next time
<a href="Plausible.Sites.html#stats_start_date/1"><code class="inline">Plausible.Sites.stats_start_date/1</code></a> is called.</p><p>If the input argument is a site, all imported stats are deleted. If it's a site import,
only imported stats for that import are deleted.</p>
</section>
</section>
<section class="detail" id="delete_imported_stats!/2">
<div class="detail-header">
<a href="#delete_imported_stats!/2" class="detail-link" title="Link to this function">
<i class="ri-link-m" aria-hidden="true"></i>
<span class="sr-only">Link to this function</span>
</a>
<h1 class="signature" translate="no">delete_imported_stats!(site, import_id)</h1>
<a href="https://github.com/plausible/analytics/blob/main/lib/plausible/purge.ex#L70" class="icon-action" rel="help" title="View Source">
<i class="ri-code-s-slash-line" aria-hidden="true"></i>
<span class="sr-only">View Source</span>
</a>
</div>
<section class="docstring">
</section>
</section>
<section class="detail" id="delete_native_stats!/1">
<div class="detail-header">
<a href="#delete_native_stats!/1" class="detail-link" title="Link to this function">
<i class="ri-link-m" aria-hidden="true"></i>
<span class="sr-only">Link to this function</span>
</a>
<h1 class="signature" translate="no">delete_native_stats!(site)</h1>
<a href="https://github.com/plausible/analytics/blob/main/lib/plausible/purge.ex#L86" class="icon-action" rel="help" title="View Source">
<i class="ri-code-s-slash-line" aria-hidden="true"></i>
<span class="sr-only">View Source</span>
</a>
</div>
<section class="docstring">
<div class="specs">
<pre translate="no"><span class="attribute">@spec</span> delete_native_stats!(<a href="Plausible.Site.html#t:t/0">Plausible.Site.t</a>()) :: :ok</pre>
</div>
<p>Move stats pointers so that no historical stats are available.</p>
</section>
</section>
<section class="detail" id="reset!/1">
<div class="detail-header">
<a href="#reset!/1" class="detail-link" title="Link to this function">
<i class="ri-link-m" aria-hidden="true"></i>
<span class="sr-only">Link to this function</span>
</a>
<h1 class="signature" translate="no">reset!(site)</h1>
<a href="https://github.com/plausible/analytics/blob/main/lib/plausible/purge.ex#L92" class="icon-action" rel="help" title="View Source">
<i class="ri-code-s-slash-line" aria-hidden="true"></i>
<span class="sr-only">View Source</span>
</a>
</div>
<section class="docstring">
</section>
</section>
</div>
</section>
<footer class="footer">
<p>
<span class="line">
<button class="a-main footer-button display-quick-switch" title="Search HexDocs packages">
Search HexDocs
</button>
<a href="Plausible.epub" title="ePub version">
Download ePub version
</a>
</span>
</p>
<p class="built-using">
Built using
<a href="https://github.com/elixir-lang/ex_doc" title="ExDoc" target="_blank" rel="help noopener" translate="no">ExDoc</a> (v0.31.1) for the
<a href="https://elixir-lang.org" title="Elixir" target="_blank" translate="no">Elixir programming language</a>
</p>
</footer>
</div>
</div>
</main>
</div>
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>mermaid.initialize({startOnLoad: true})</script>
</body>
</html>