Repository navigation
Clickhouse backup #520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
aagbsn
wants to merge
27
commits into
main
Choose a base branch
from
clickhouse-backup
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Clickhouse backup #520
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
50ae7c1
Back up the ClickHouse cluster to Cloudflare R2
aagbsn de4e8a3
clickhouse_backup: start a new full backup each calendar month
aagbsn 1077400
clickhouse_backup: don't start a backup when the timer starts
aagbsn 979eba2
clickhouse_backup: alert when a job's run completes
aagbsn c76e14e
clickhouse_backup: word the completion notice for any number of tables
aagbsn fee921b
clickhouse_backup: test the role end to end in containers, in CI when…
aagbsn 7857e1c
clickhouse_backup tests: use Debian's python3-boto3, not pip
aagbsn 294ef54
clickhouse_backup: cap backups at 50 MB/s until the real rate is meas…
aagbsn caf6d7d
clickhouse_backup: stop excluding counters_test_list, which is detached
aagbsn 69bc63b
clickhouse_backup: say which RocksDB tables are and aren't backed up
aagbsn 2447141
clickhouse_backup: stop excluding fastpath_tuning, which is dropped
aagbsn 113451d
clickhouse_backup: say why list prints instead of logging
aagbsn 7cab3dc
clickhouse_backup: back up weekly, on Sundays
aagbsn f1305c6
clickhouse_backup: allow a week between backups before ClickHouseBack…
aagbsn 83fe34e
clickhouse_backup: hold back ClickHouseBackupStale only for a recent …
aagbsn 6ea1f2f
clickhouse_backup: run --table runs only the jobs that back up those …
aagbsn 61ff892
clickhouse_backup: don't let a brief ClickHouse outage abort a run
aagbsn 2e2fa2e
clickhouse_backup: wait 8 days before ClickHouseBackupMissing
aagbsn 79660f2
clickhouse_backup runbook: start the post-upgrade full as a service, …
aagbsn a16960b
prometheus: make TextfileJam's exclusion match the backup file's path…
aagbsn d45700e
clickhouse_backup: "*" selects every table, an empty include_tables none
aagbsn d2a98d8
clickhouse_backup: forget the results of tables and jobs no longer ba…
aagbsn 862b236
clickhouse_backup: match only this bucket's running backups, check de…
aagbsn c29e2b5
clickhouse_backup tests: interrupt the full deterministically, show o…
aagbsn d5e7611
clickhouse_backup tests: restore the full and each incremental, the R…
aagbsn 18cd226
clickhouse_backup: report the tables on the cluster that no backup co…
aagbsn 70ba6e7
clickhouse_backup tests: a second ClickHouse node, and a table on it …
aagbsn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| # Tests the ClickHouse backup role, its alerts and their Alertmanager routes | ||
| # (ansible/roles/clickhouse_backup/tests), only when one of them changes | ||
| name: Test ClickHouse backups | ||
| on: | ||
| pull_request: | ||
| paths: | ||
| - "ansible/roles/clickhouse_backup/**" | ||
| - "ansible/roles/prometheus/files/alert_rules.yml" | ||
| - "ansible/roles/prometheus_alertmanager/**" | ||
| - ".github/workflows/test_clickhouse_backup.yml" | ||
| push: | ||
| branches: [main] | ||
| paths: | ||
| - "ansible/roles/clickhouse_backup/**" | ||
| - "ansible/roles/prometheus/files/alert_rules.yml" | ||
| - "ansible/roles/prometheus_alertmanager/**" | ||
| - ".github/workflows/test_clickhouse_backup.yml" | ||
|
|
||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 30 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - run: sudo apt-get update && sudo apt-get install -y --no-install-recommends ansible-core python3-boto3 | ||
| - run: ansible/roles/clickhouse_backup/tests/run.sh |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -411,6 +411,27 @@ clickhouse_prometheus: | |
| asynchronous_metrics: true | ||
| status_info: true | ||
|
|
||
| # For textfile metrics, e.g. from clickhouse_backup | ||
| node_exporter_textfile_dir: /var/lib/node_exporter/textfile_collector | ||
|
|
||
| # clickhouse_backup: Cloudflare R2. The endpoint names the account, so it's | ||
| # kept in SSM with the token's keys. | ||
| clickhouse_backup_s3_endpoint: "{{ lookup('amazon.aws.aws_ssm', '/oonidevops/secrets/clickhouse_backup_r2_endpoint', profile='oonidevops_user_prod') }}" | ||
| clickhouse_backup_s3_access_key_id: "{{ lookup('amazon.aws.aws_ssm', '/oonidevops/secrets/clickhouse_backup_r2_access_key_id', profile='oonidevops_user_prod') }}" | ||
| clickhouse_backup_s3_secret_access_key: "{{ lookup('amazon.aws.aws_ssm', '/oonidevops/secrets/clickhouse_backup_r2_secret_access_key', profile='oonidevops_user_prod') }}" | ||
| # Tables with personal or unpublished data, backed up to the private bucket | ||
| clickhouse_backup_private_tables: | ||
| - msmt_feedback # account ids and free-text comments | ||
| - faulty_measurements # until its contents are reviewed | ||
| - url_priorities # until it's decided whether it's published | ||
| # Plain MergeTree tables whose data only data1 holds (2026-10-20). Remove a | ||
| # table from here once it's replicated, and data3 picks it up. | ||
| clickhouse_backup_data1_tables: | ||
| - labeling_frames | ||
| - event_detector_cusums | ||
| - event_detector_v2_changepoints | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be replicated so that backup jobs can run from any cluster node |
||
| - changepoint_label | ||
|
|
||
| prometheus_nginx_proxy_config: | ||
| - location: /metrics/node_exporter | ||
| proxy_pass: http://127.0.0.1:8100/metrics | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,20 @@ | ||
| non_admin_usernames: [] | ||
| clickhouse_base_path: /data/clickhouse | ||
|
|
||
| # The replicated tables, minus the ones only data1 holds data for. Private | ||
| # tables go to their own bucket: R2 tokens grant access per bucket, and | ||
| # researchers may be given read access to the measurement tables. | ||
| clickhouse_backup_jobs: | ||
| - name: measurements | ||
| s3_bucket: ooni-clickhouse-backup | ||
| include_tables: ["*"] | ||
| exclude_tables: "{{ clickhouse_backup_private_tables + clickhouse_backup_data1_tables }}" | ||
| - name: private | ||
| s3_bucket: ooni-clickhouse-backup-private | ||
| include_tables: "{{ clickhouse_backup_private_tables }}" | ||
| exclude_tables: [] | ||
|
|
||
| # After each run, report the tables on data1-3 that no backup covers; | ||
| # data1's own tables are backed up by data1 | ||
| clickhouse_backup_check_cluster: oonidata_cluster | ||
| clickhouse_backup_backed_up_elsewhere: "{{ clickhouse_backup_data1_tables }}" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| --- | ||
| # Back up the ooni ClickHouse database to S3-compatible object storage | ||
| # (Cloudflare R2) with ClickHouse's native BACKUP. Deploy where the data is: | ||
| # data3 for the replicated tables, data1 for the tables only data1 holds | ||
| # (see deploy-clickhouse.yml and host_vars). | ||
| # Restore and upgrade procedure: docs/Runbooks.md, "ClickHouse backup". | ||
|
|
||
| # false stops and disables the timer, e.g. while upgrading the cluster | ||
| clickhouse_backup_enabled: true | ||
| # Weekly, on Sundays at a quiet time (UTC): a full backup of everything takes | ||
| # more than a day. A run backs up every job's tables, one job after the other; | ||
| # a run still going delays the next one instead of overlapping it. | ||
| clickhouse_backup_on_calendar: "Sun *-*-* 02:30:00" | ||
|
|
||
| clickhouse_backup_database: ooni | ||
| clickhouse_backup_clickhouse_url: "http://127.0.0.1:8123/" | ||
| clickhouse_backup_clickhouse_user: "{{ clickhouse_admin_user }}" | ||
| clickhouse_backup_clickhouse_password: "{{ clickhouse_admin_password }}" | ||
|
|
||
| # Cloudflare R2: the endpoint names the account, | ||
| # https://<account id>.r2.cloudflarestorage.com. One API token with Object | ||
| # Read & Write on every bucket the jobs below use. | ||
| clickhouse_backup_s3_endpoint: "" | ||
| clickhouse_backup_s3_region: auto | ||
| clickhouse_backup_s3_prefix: prod | ||
| clickhouse_backup_s3_access_key_id: "" | ||
| clickhouse_backup_s3_secret_access_key: "" | ||
|
|
||
| # Query settings for ClickHouse's uploads. R2 rejects a multipart upload | ||
| # whose parts (all but the last) differ in size, and ClickHouse grows the | ||
| # part size as an upload goes on unless the factor is 1. R2 also allows at | ||
| # most 10,000 parts, so with 128 MiB parts one file can reach 1.25 TiB. | ||
| clickhouse_backup_s3_settings: | ||
| s3_upload_part_size_multiply_factor: 1 | ||
| s3_min_upload_part_size: 134217728 | ||
| s3_max_upload_part_size: 134217728 | ||
|
|
||
| # One job per bucket. A job backs up the tables matching include_tables ("*" | ||
| # for every table; an empty list backs up none) minus the excludes below and | ||
| # its own. | ||
| clickhouse_backup_jobs: | ||
| - name: measurements | ||
| s3_bucket: "" | ||
| include_tables: ["*"] | ||
| exclude_tables: [] | ||
|
|
||
| # Complete chains kept per table, besides chains pinned with --keep: the | ||
| # current one and the one before, so a month or two of restore points | ||
| clickhouse_backup_keep_chains: 2 | ||
| # Bytes/s passed to ClickHouse as max_backup_bandwidth: at most 50 MB/s, 40% | ||
| # of the 1 Gbit/s link, leaving the rest for replication and queries. | ||
| # Against MinIO in testing, 24.8 uploaded at about a third of this value; check | ||
| # the real rate on the first backups (ooni_clickhouse_backup_last_size_bytes / | ||
| # ooni_clickhouse_backup_last_duration_seconds) and raise it if they're too slow. | ||
| clickhouse_backup_max_bandwidth: 50000000 | ||
|
|
||
| # fnmatch patterns, for every job. Materialized views' .inner tables are | ||
| # always skipped: they're backed up with their view. | ||
| # Tables that are never backed up, for every job, and why | ||
| clickhouse_backup_exclude_tables: | ||
| - "*_tmp" # updater staging tables | ||
| - msmt_feedback_old | ||
| - fingerprints_dns # the hourly fingerprints updater rebuilds them | ||
| - fingerprints_http | ||
| - session_expunge # empty, no longer used (backend #972) | ||
|
|
||
| # The cluster whose tables are checked after each run: any table on any of its | ||
| # nodes that no job here backs up, that isn't excluded above and that isn't in | ||
| # clickhouse_backup_backed_up_elsewhere is reported (ClickHouseTableNotBackedUp). | ||
| # Set on one host, the one taking most backups; empty checks nothing. | ||
| clickhouse_backup_check_cluster: "" | ||
| # fnmatch patterns of the tables another host backs up | ||
| clickhouse_backup_backed_up_elsewhere: [] | ||
|
|
||
| # Results for Prometheus, read by node_exporter's textfile collector | ||
| # (node_exporter_textfile_dir in the prometheus_node_exporter role) | ||
| clickhouse_backup_metrics_file: "{{ node_exporter_textfile_dir | default('/var/lib/node_exporter/textfile_collector') }}/ooni_clickhouse_backup.prom" | ||
| clickhouse_backup_state_file: /var/lib/ooni-clickhouse-backup/state.json |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these don't actually need to be private