summaryrefslogtreecommitdiff
path: root/lib/gitlab/database/gitlab_schema.rb
blob: baf4cc48424be160e10abc3b29969c8e76d18fd2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# frozen_string_literal: true

# This module gathers information about table to schema mapping
# to understand table affinity
#
# Each table / view needs to have assigned gitlab_schema. Names supported today:
#
# - gitlab_shared - defines a set of tables that are found on all databases (data accessed is dependent on connection)
# - gitlab_main / gitlab_ci - defines a set of tables that can only exist on a given database
#
# Tables for the purpose of tests should be prefixed with `_test_my_table_name`

module Gitlab
  module Database
    module GitlabSchema
      # These tables are deleted/renamed, but still referenced by migrations.
      # This is needed for now, but should be removed in the future
      DELETED_TABLES = {
        # main tables
        'alerts_service_data' => :gitlab_main,
        'analytics_devops_adoption_segment_selections' => :gitlab_main,
        'analytics_repository_file_commits' => :gitlab_main,
        'analytics_repository_file_edits' => :gitlab_main,
        'analytics_repository_files' => :gitlab_main,
        'audit_events_archived' => :gitlab_main,
        'backup_labels' => :gitlab_main,
        'clusters_applications_fluentd' => :gitlab_main,
        'forked_project_links' => :gitlab_main,
        'issue_milestones' => :gitlab_main,
        'merge_request_milestones' => :gitlab_main,
        'namespace_onboarding_actions' => :gitlab_main,
        'services' => :gitlab_main,
        'terraform_state_registry' => :gitlab_main,
        'tmp_fingerprint_sha256_migration' => :gitlab_main, # used by lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys.rb
        'web_hook_logs_archived' => :gitlab_main,
        'vulnerability_export_registry' => :gitlab_main,
        'vulnerability_finding_fingerprints' => :gitlab_main,
        'vulnerability_export_verification_status' => :gitlab_main,

        # CI tables
        'ci_build_trace_sections' => :gitlab_ci,
        'ci_build_trace_section_names' => :gitlab_ci,
        'ci_daily_report_results' => :gitlab_ci,
        'ci_test_cases' => :gitlab_ci,
        'ci_test_case_failures' => :gitlab_ci,

        # leftovers from early implementation of partitioning
        'audit_events_part_5fc467ac26' => :gitlab_main,
        'web_hook_logs_part_0c5294f417' => :gitlab_main
      }.freeze

      def self.table_schemas(tables)
        tables.map { |table| table_schema(table) }.to_set
      end

      def self.table_schema(name)
        schema_name, table_name = name.split('.', 2) # Strip schema name like: `public.`

        # Most of names do not have schemas, ensure that this is table
        unless table_name
          table_name = schema_name
          schema_name = nil
        end

        # strip partition number of a form `loose_foreign_keys_deleted_records_1`
        table_name.gsub!(/_[0-9]+$/, '')

        # Tables that are properly mapped
        if gitlab_schema = tables_to_schema[table_name]
          return gitlab_schema
        end

        # Tables that are deleted, but we still need to reference them
        if gitlab_schema = DELETED_TABLES[table_name]
          return gitlab_schema
        end

        # All tables from `information_schema.` are marked as `internal`
        return :gitlab_internal if schema_name == 'information_schema'

        return :gitlab_main if table_name.start_with?('_test_gitlab_main_')

        return :gitlab_ci if table_name.start_with?('_test_gitlab_ci_')

        # All tables that start with `_test_` without a following schema are shared and ignored
        return :gitlab_shared if table_name.start_with?('_test_')

        # All `pg_` tables are marked as `internal`
        return :gitlab_internal if table_name.start_with?('pg_')

        # When undefined it's best to return a unique name so that we don't incorrectly assume that 2 undefined schemas belong on the same database
        :"undefined_#{table_name}"
      end

      def self.tables_to_schema
        @tables_to_schema ||= YAML.load_file(Rails.root.join('lib/gitlab/database/gitlab_schemas.yml'))
      end

      def self.schema_names
        @schema_names ||= self.tables_to_schema.values.to_set
      end
    end
  end
end