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:
username: git
password: "secure password"
host: localhost
fdw: true
#
# Development specific
......@@ -21,6 +22,7 @@ development:
username: postgres
password: "secure password"
host: localhost
fdw: true
#
# Staging specific
......@@ -33,6 +35,7 @@ staging:
username: git
password: "secure password"
host: localhost
fdw: true
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
......@@ -45,3 +48,4 @@ test: &test
username: postgres
password:
host: localhost
fdw: true
......@@ -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
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.
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
addresses with addresses appropriate to your network configuration:
```ruby
geo_primary_role['enable'] = true
# 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['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_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:
......@@ -477,4 +477,5 @@ Read the [troubleshooting document](troubleshooting.md).
[pgback]: http://www.postgresql.org/docs/9.2/static/app-pgbasebackup.html
[external postgresql]: #external-postgresql-instances
[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
......@@ -33,8 +33,7 @@ recover. See below for more details.
The following guide assumes that:
- You are using PostgreSQL 9.6 or later
which includes the
- You are using PostgreSQL 9.6 or later which includes the
[`pg_basebackup` tool][pgback] and improved [Foreign Data Wrapper][FDW] support.
- You have a primary node already set up (the GitLab server you are
replicating from), running PostgreSQL 9.6 or later, and
......@@ -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);"
```
And edit the content of `database_geo.yml` and to add `fdw: true` to
the `production:` block.
### Step 4. Initiate the replication process
Below we provide a script that connects the database on the secondary node to
......
......@@ -65,14 +65,22 @@ module Gitlab
::License.feature_available?(:geo)
end
def self.fdw?
self.cache_value(:geo_fdw?) do
::Geo::BaseRegistry.connection.execute(
def self.fdw_capable?
self.cache_value(:geo_fdw_capable?) do
::Geo::TrackingBase.connection.execute(
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '#{FDW_SCHEMA}' AND table_type = 'FOREIGN TABLE'"
).first.fetch('count').to_i.positive?
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)
FDW_SCHEMA + ".#{table_name}"
end
......
......@@ -8,3 +8,8 @@ CREATE SCHEMA gitlab_secondary;
IMPORT FOREIGN SCHEMA public FROM SERVER gitlab_secondary INTO gitlab_secondary;
GRANT USAGE ON FOREIGN SERVER gitlab_secondary TO current_user;
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
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'" }
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
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?).to be_truthy
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_capable?).to be_falsey
end
end
describe 'fdw?' 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
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
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