Commit 9fbbbd7f authored by Nick Thomas's avatar Nick Thomas

Merge branch 'tc-geo-fdw-configurable' into 'master'

Make Geo FDW configurable

Closes #4558

See merge request gitlab-org/gitlab-ee!4020
parents 706a9b3f f1e2fdb0
---
title: Make it possible to enable/disable PostgreSQL FDW for Geo
merge_request: 4020
author:
type: added
...@@ -9,6 +9,7 @@ production: ...@@ -9,6 +9,7 @@ production:
username: git username: git
password: "secure password" password: "secure password"
host: localhost host: localhost
fdw: true
# #
# Development specific # Development specific
...@@ -21,6 +22,7 @@ development: ...@@ -21,6 +22,7 @@ development:
username: postgres username: postgres
password: "secure password" password: "secure password"
host: localhost host: localhost
fdw: true
# #
# Staging specific # Staging specific
...@@ -33,6 +35,7 @@ staging: ...@@ -33,6 +35,7 @@ staging:
username: git username: git
password: "secure password" password: "secure password"
host: localhost host: localhost
fdw: true
# Warning: The database defined as "test" will be erased and # Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake". # re-generated from your development database when you run "rake".
...@@ -45,3 +48,4 @@ test: &test ...@@ -45,3 +48,4 @@ test: &test
username: postgres username: postgres
password: password:
host: localhost host: localhost
fdw: true
...@@ -39,9 +39,9 @@ recover. See below for more details. ...@@ -39,9 +39,9 @@ recover. See below for more details.
The following guide assumes that: The following guide assumes that:
- You are using Omnibus and therefore you are using PostgreSQL 9.6 or later - You are using Omnibus and therefore you are using PostgreSQL 9.6 or later
which includes the [`pg_basebackup` tool][pgback] and improved which includes the [`pg_basebackup` tool][pgback] and improved
[Foreign Data Wrapper][FDW] support. [Foreign Data Wrapper][FDW] support.
- You have a primary node already set up (the GitLab server you are - You have a primary node already set up (the GitLab server you are
replicating from), running Omnibus' PostgreSQL (or equivalent version), and replicating from), running Omnibus' PostgreSQL (or equivalent version), and
you have a new secondary server set up with the same versions of the OS, you have a new secondary server set up with the same versions of the OS,
...@@ -67,22 +67,22 @@ The following guide assumes that: ...@@ -67,22 +67,22 @@ The following guide assumes that:
``` ```
This command will use your defined `external_url` in `/etc/gitlab/gitlab.rb`. This command will use your defined `external_url` in `/etc/gitlab/gitlab.rb`.
1. GitLab 10.4 and up only: Do the following to make sure the `gitlab` database user has a password defined 1. GitLab 10.4 and up only: Do the following to make sure the `gitlab` database user has a password defined
Generate a MD5 hash of the desired password: Generate a MD5 hash of the desired password:
```bash ```bash
gitlab-ctl pg-password-md5 gitlab gitlab-ctl pg-password-md5 gitlab
# Enter password: mypassword # Enter password: mypassword
# Confirm password: mypassword # Confirm password: mypassword
# fca0b89a972d69f00eb3ec98a5838484 # fca0b89a972d69f00eb3ec98a5838484
``` ```
Edit `/etc/gitlab/gitlab.rb`: Edit `/etc/gitlab/gitlab.rb`:
```ruby ```ruby
# Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab` # Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab`
postgresql['sql_user_password'] = 'fca0b89a972d69f00eb3ec98a5838484' postgresql['sql_user_password'] = 'fca0b89a972d69f00eb3ec98a5838484'
# If you have HA setup, this must be present in all nodes as well # If you have HA setup, this must be present in all nodes as well
...@@ -304,25 +304,25 @@ because we have not yet configured the secondary server. This is the next step. ...@@ -304,25 +304,25 @@ because we have not yet configured the secondary server. This is the next step.
connections. The certificate can only be replicated by someone with access connections. The certificate can only be replicated by someone with access
to the private key, which is **only** present on the primary node. to the private key, which is **only** present on the primary node.
1. Configure PostgreSQL to listen on network interfaces on secondary 1. Configure PostreSQL to enable FDW support
This step is similar to how we configured the primary instance. This step is similar to how we configured the primary instance.
We need to enable this, even if using a single node, to enable FDW support. We need to enable this, to enable FDW support, even if using a single node.
Edit `/etc/gitlab/gitlab.rb` and add the following, replacing the IP Edit `/etc/gitlab/gitlab.rb` and add the following, replacing the IP
addresses with addresses appropriate to your network configuration: addresses with addresses appropriate to your network configuration:
```ruby ```ruby
geo_primary_role['enable'] = true
# Secondary addresses # Secondary addresses
# - replace '5.6.7.8' with the secondary public address # - replace '5.6.7.8' with the secondary private address
postgresql['listen_address'] = '5.6.7.8' postgresql['listen_address'] = '5.6.7.8'
postgresql['trust_auth_cidr_addresses'] = ['127.0.0.1/32','5.6.7.8/32'] postgresql['trust_auth_cidr_addresses'] = ['127.0.0.1/32','5.6.7.8/32']
postgresql['md5_auth_cidr_addresses'] = ['5.6.7.8/32']
# gitlab database user's password (defined previously) # gitlab database user's password (defined previously)
gitlab_rails['db_password'] = 'mypassword' gitlab_rails['db_password'] = 'mypassword'
# enable fdw for the geo tracking database
geo_secondary['db_fdw'] = true
``` ```
1. Test that the `gitlab-psql` user can connect to the primary's database: 1. Test that the `gitlab-psql` user can connect to the primary's database:
...@@ -477,4 +477,5 @@ Read the [troubleshooting document](troubleshooting.md). ...@@ -477,4 +477,5 @@ Read the [troubleshooting document](troubleshooting.md).
[pgback]: http://www.postgresql.org/docs/9.2/static/app-pgbasebackup.html [pgback]: http://www.postgresql.org/docs/9.2/static/app-pgbasebackup.html
[external postgresql]: #external-postgresql-instances [external postgresql]: #external-postgresql-instances
[tracking]: database_source.md#enable-tracking-database-on-the-secondary-server [tracking]: database_source.md#enable-tracking-database-on-the-secondary-server
[FDW]: https://www.postgresql.org/docs/9.6/static/postgres-fdw.html
[toc]: README.md#using-omnibus-gitlab [toc]: README.md#using-omnibus-gitlab
...@@ -33,9 +33,8 @@ recover. See below for more details. ...@@ -33,9 +33,8 @@ recover. See below for more details.
The following guide assumes that: The following guide assumes that:
- You are using PostgreSQL 9.6 or later - You are using PostgreSQL 9.6 or later which includes the
which includes the [`pg_basebackup` tool][pgback] and improved [Foreign Data Wrapper][FDW] support.
[`pg_basebackup` tool][pgback] and improved [Foreign Data Wrapper][FDW] support.
- You have a primary node already set up (the GitLab server you are - You have a primary node already set up (the GitLab server you are
replicating from), running PostgreSQL 9.6 or later, and replicating from), running PostgreSQL 9.6 or later, and
you have a new secondary server set up with the same versions of the OS, you have a new secondary server set up with the same versions of the OS,
...@@ -291,6 +290,9 @@ node. ...@@ -291,6 +290,9 @@ node.
sudo -u postgres psql -h $GEO_DB_HOST -d $GEO_DB_NAME -p $GEO_DB_PORT -c "GRANT USAGE ON FOREIGN SERVER gitlab_secondary TO $(GEO_DB_USER);" sudo -u postgres psql -h $GEO_DB_HOST -d $GEO_DB_NAME -p $GEO_DB_PORT -c "GRANT USAGE ON FOREIGN SERVER gitlab_secondary TO $(GEO_DB_USER);"
``` ```
And edit the content of `database_geo.yml` and to add `fdw: true` to
the `production:` block.
### Step 4. Initiate the replication process ### Step 4. Initiate the replication process
Below we provide a script that connects the database on the secondary node to Below we provide a script that connects the database on the secondary node to
......
...@@ -65,14 +65,22 @@ module Gitlab ...@@ -65,14 +65,22 @@ module Gitlab
::License.feature_available?(:geo) ::License.feature_available?(:geo)
end end
def self.fdw? def self.fdw_capable?
self.cache_value(:geo_fdw?) do self.cache_value(:geo_fdw_capable?) do
::Geo::BaseRegistry.connection.execute( ::Geo::TrackingBase.connection.execute(
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '#{FDW_SCHEMA}' AND table_type = 'FOREIGN TABLE'" "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '#{FDW_SCHEMA}' AND table_type = 'FOREIGN TABLE'"
).first.fetch('count').to_i.positive? ).first.fetch('count').to_i.positive?
end end
end end
def self.fdw?
return false unless self.fdw_capable?
# FDW is enabled by default, disable it by setting `fdw: false` in config/database_geo.yml
value = Rails.configuration.geo_database['fdw']
value.nil? ? true : value
end
def self.fdw_table(table_name) def self.fdw_table(table_name)
FDW_SCHEMA + ".#{table_name}" FDW_SCHEMA + ".#{table_name}"
end end
......
...@@ -8,3 +8,8 @@ CREATE SCHEMA gitlab_secondary; ...@@ -8,3 +8,8 @@ CREATE SCHEMA gitlab_secondary;
IMPORT FOREIGN SCHEMA public FROM SERVER gitlab_secondary INTO gitlab_secondary; IMPORT FOREIGN SCHEMA public FROM SERVER gitlab_secondary INTO gitlab_secondary;
GRANT USAGE ON FOREIGN SERVER gitlab_secondary TO current_user; GRANT USAGE ON FOREIGN SERVER gitlab_secondary TO current_user;
EOF EOF
# Ensure the FDW setting is enabled
sed -i '/fdw:/d' config/database_geo.yml
sed -i '/gitlabhq_geo_test/a\
\ \ fdw: true' config/database_geo.yml
...@@ -18,24 +18,57 @@ describe Gitlab::Geo, :geo do ...@@ -18,24 +18,57 @@ describe Gitlab::Geo, :geo do
end end
end end
describe 'fdw?' do describe 'fdw_capable?' do
let(:fdw_check) { "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'gitlab_secondary' AND table_type = 'FOREIGN TABLE'" } let(:fdw_check) { "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'gitlab_secondary' AND table_type = 'FOREIGN TABLE'" }
before do before do
allow(::Geo::BaseRegistry.connection).to receive(:execute).with(anything).and_call_original allow(::Geo::TrackingBase.connection).to receive(:execute).with(anything).and_call_original
end end
it 'returns true when PostgreSQL FDW is enabled' do it 'returns true when PostgreSQL FDW is enabled' do
expect(::Geo::BaseRegistry.connection).to receive(:execute).with(fdw_check).and_return([{ 'count' => 1 }]) expect(::Geo::TrackingBase.connection).to receive(:execute).with(fdw_check).and_return([{ 'count' => 1 }])
expect(described_class.fdw_capable?).to be_truthy
end
it 'returns false when PostgreSQL FDW is not enabled' do
expect(::Geo::TrackingBase.connection).to receive(:execute).with(fdw_check).and_return([{ 'count' => 0 }])
expect(described_class.fdw?).to be_truthy expect(described_class.fdw_capable?).to be_falsey
end end
end
describe 'fdw?' do
it 'returns false when PostgreSQL FDW is not enabled' do it 'returns false when PostgreSQL FDW is not enabled' do
expect(::Geo::BaseRegistry.connection).to receive(:execute).with(fdw_check).and_return([{ 'count' => 0 }]) allow(::Geo::TrackingBase.connection).to receive(:execute).and_return([{ 'count' => 0 }])
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => true)
expect(described_class.fdw?).to be_falsey expect(described_class.fdw?).to be_falsey
end end
context 'with fdw capable' do
before do
allow(described_class).to receive(:fdw_capable?).and_return(true)
end
it 'returns true by default' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => nil)
expect(described_class.fdw?).to be_truthy
end
it 'returns false if configured in `config/database_geo.yml`' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => false)
expect(described_class.fdw?).to be_falsey
end
it 'returns true if configured in `config/database_geo.yml`' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => true)
expect(described_class.fdw?).to be_truthy
end
end
end end
describe 'primary?' do describe 'primary?' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment