Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 563d014

Browse files
Merge branch '88-lvm-support' into 'master'
feat: LVM snapshots/clone as an alternative to ZFS Closes #88 and #103 See merge request postgres-ai/database-lab!82
2 parents c015cb1 + c8f76e5 commit 563d014

File tree

20 files changed

+1248
-847
lines changed

20 files changed

+1248
-847
lines changed

.gitlab-ci.yml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ build-binary-alpine:
2020
stage: build-binary
2121
only:
2222
refs:
23-
- master
23+
- branches
2424
- tags
2525
artifacts:
2626
paths:
@@ -67,6 +67,38 @@ build-binary-generic:
6767
only:
6868
- master
6969

70+
.only_var_template: &only_feature
71+
only:
72+
variables:
73+
- $CI_COMMIT_TAG == null
74+
- $CI_COMMIT_REF_SLUG != "master"
75+
76+
build-image-feature-server:
77+
<<: *build_image_definition
78+
<<: *only_feature
79+
variables:
80+
REGISTRY_USER: "${CI_REGISTRY_USER}"
81+
REGISTRY_PASSWORD: "${CI_REGISTRY_PASSWORD}"
82+
REGISTRY: "${CI_REGISTRY}"
83+
DOCKER_FILE: "Dockerfile.dblab-server"
84+
DOCKER_NAME: "registry.gitlab.com/postgres-ai/database-lab/dblab-server"
85+
TAGS: "${DOCKER_NAME}:${CI_COMMIT_REF_SLUG}"
86+
before_script:
87+
- cp ./bin/dblab-server-alpine ./bin/dblab-server
88+
89+
build-image-feature-client:
90+
<<: *build_image_definition
91+
<<: *only_feature
92+
variables:
93+
REGISTRY_USER: "${CI_REGISTRY_USER}"
94+
REGISTRY_PASSWORD: "${CI_REGISTRY_PASSWORD}"
95+
REGISTRY: "${CI_REGISTRY}"
96+
DOCKER_FILE: "Dockerfile.dblab"
97+
DOCKER_NAME: "registry.gitlab.com/postgres-ai/database-lab/dblab"
98+
TAGS: "${DOCKER_NAME}:${CI_COMMIT_REF_SLUG}"
99+
before_script:
100+
- cp ./bin/dblab-alpine ./bin/dblab
101+
70102
build-image-master-server:
71103
<<: *build_image_definition
72104
<<: *only_master

Dockerfile.dblab-server

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
FROM docker:19
3333

3434
# Install dependecies.
35-
RUN apk update && apk add --no-cache zfs bash
35+
RUN apk update && apk add --no-cache zfs lvm2 bash
3636

3737
WORKDIR /home/dblab
3838

cmd/database-lab/main.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ func main() {
5757

5858
// TODO(anatoly): Annotate envs in configs. Use different lib for flags/configs?
5959
if len(opts.MountDir) > 0 {
60-
cfg.Provision.ModeZfs.MountDir = opts.MountDir
60+
cfg.Provision.ModeLocal.MountDir = opts.MountDir
6161
}
6262

6363
if len(opts.UnixSocketDir) > 0 {
64-
cfg.Provision.ModeZfs.UnixSocketDir = opts.UnixSocketDir
64+
cfg.Provision.ModeLocal.UnixSocketDir = opts.UnixSocketDir
6565
}
6666

6767
if len(opts.DockerImage) > 0 {
68-
cfg.Provision.ModeZfs.DockerImage = opts.DockerImage
68+
cfg.Provision.ModeLocal.DockerImage = opts.DockerImage
6969
}
7070

7171
provisionSvc, err := provision.NewProvision(ctx, cfg.Provision)

configs/config.sample.yml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ server:
66
port: 3000
77

88
provision:
9-
# Provision mode to use. More comming soon (e.g., LVM, Ceph).
10-
mode: "zfs"
9+
# Provision mode to use.
10+
mode: "local"
1111

1212
# Subdir where PGDATA located relative to the pool root dir.
1313
pgDataSubdir: "/"
@@ -16,9 +16,12 @@ provision:
1616
# The user should exist.
1717
pgMgmtUsername: "postgres"
1818

19-
# ZFS mode related parameters.
20-
zfs:
21-
# Name of your ZFS pool.
19+
# "Local" mode related parameters.
20+
local:
21+
# Which volume manager to use. Available options: "zfs", "lvm".
22+
volumeManager: "zfs"
23+
24+
# Name of your pool or volume group with logic volume name (e.g. "dblab_vg/pg1_lv").
2225
pool: "dblab_pool"
2326

2427
# Pool of ports for Postgres clones.
@@ -45,7 +48,7 @@ provision:
4548
# is recommended in case if customization is needed.
4649
dockerImage: "postgres:12-alpine"
4750

48-
# Use sudo for ZFS and Docker commands if Database Lab server running
51+
# Use sudo for ZFS/LVM and Docker commands if Database Lab server running
4952
# outside a container.
5053
useSudo: false
5154

pkg/services/cloning/cloning.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"gitlab.com/postgres-ai/database-lab/pkg/log"
1515
"gitlab.com/postgres-ai/database-lab/pkg/models"
1616
"gitlab.com/postgres-ai/database-lab/pkg/services/provision"
17+
"gitlab.com/postgres-ai/database-lab/pkg/services/provision/resources"
1718
)
1819

1920
const (
@@ -56,7 +57,7 @@ type Cloning interface {
5657
// CloneWrapper represents a cloning service wrapper.
5758
type CloneWrapper struct {
5859
clone *models.Clone
59-
session *provision.Session
60+
session *resources.Session
6061

6162
timeCreatedAt time.Time
6263
timeStartedAt time.Time

pkg/services/cloning/mode_base.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"gitlab.com/postgres-ai/database-lab/pkg/log"
2121
"gitlab.com/postgres-ai/database-lab/pkg/models"
2222
"gitlab.com/postgres-ai/database-lab/pkg/services/provision"
23+
"gitlab.com/postgres-ai/database-lab/pkg/services/provision/resources"
2324
"gitlab.com/postgres-ai/database-lab/pkg/util"
2425
"gitlab.com/postgres-ai/database-lab/pkg/util/pglog"
2526
)
@@ -122,11 +123,13 @@ func (c *baseCloning) CreateClone(clone *models.Clone) error {
122123
session, err := c.provision.StartSession(w.username, w.password, w.snapshot.ID)
123124
if err != nil {
124125
// TODO(anatoly): Empty room case.
126+
log.Errf("Failed to create a clone: %+v.", err)
127+
125128
if err := c.updateCloneStatus(cloneID, models.Status{
126129
Code: models.StatusFatal,
127130
Message: models.CloneMessageFatal,
128131
}); err != nil {
129-
log.Errf("failed to update clone status: %v", err)
132+
log.Errf("Failed to update clone status: %v", err)
130133
}
131134

132135
return
@@ -193,15 +196,15 @@ func (c *baseCloning) DestroyClone(cloneID string) error {
193196

194197
go func() {
195198
if err := c.provision.StopSession(w.session); err != nil {
199+
log.Errf("Failed to delete a clone: %+v.", err)
200+
196201
if err := c.updateCloneStatus(cloneID, models.Status{
197202
Code: models.StatusFatal,
198203
Message: models.CloneMessageFatal,
199204
}); err != nil {
200205
log.Errf("Failed to update clone status: %v", err)
201206
}
202207

203-
log.Errf("Failed to delete clone: %+v.", err)
204-
205208
return
206209
}
207210

@@ -304,15 +307,15 @@ func (c *baseCloning) ResetClone(cloneID string) error {
304307
go func() {
305308
err := c.provision.ResetSession(w.session, w.snapshot.ID)
306309
if err != nil {
310+
log.Errf("Failed to reset a clone: %+v.", err)
311+
307312
if err := c.updateCloneStatus(cloneID, models.Status{
308313
Code: models.StatusFatal,
309314
Message: models.CloneMessageFatal,
310315
}); err != nil {
311316
log.Errf("failed to update clone status: %v", err)
312317
}
313318

314-
log.Errf("Failed to reset session: %+v.", err)
315-
316319
return
317320
}
318321

@@ -541,7 +544,7 @@ func (c *baseCloning) isIdleClone(wrapper *CloneWrapper) (bool, error) {
541544
const pgDriverName = "postgres"
542545

543546
// hasNotQueryActivity opens connection and checks if there is no any query running by a user.
544-
func hasNotQueryActivity(session *provision.Session) (bool, error) {
547+
func hasNotQueryActivity(session *resources.Session) (bool, error) {
545548
log.Dbg(fmt.Sprintf("Check an active query for: %q.", session.ID))
546549

547550
db, err := sql.Open(pgDriverName, getSocketConnStr(session))
@@ -560,7 +563,7 @@ func hasNotQueryActivity(session *provision.Session) (bool, error) {
560563
}
561564

562565
// TODO(akartasov): Move the function to the provision service.
563-
func getSocketConnStr(session *provision.Session) string {
566+
func getSocketConnStr(session *resources.Session) string {
564567
return fmt.Sprintf("host=%s user=%s dbname=postgres", session.SocketHost, session.User)
565568
}
566569

@@ -569,8 +572,8 @@ func checkActiveQueryNotExists(db *sql.DB) (bool, error) {
569572
var isRunningQueryNotExists bool
570573

571574
query := `select not exists (
572-
select * from pg_stat_activity
573-
where state <> 'idle' and query not like 'autovacuum: %' and pid <> pg_backend_pid()
575+
select * from pg_stat_activity
576+
where state <> 'idle' and query not like 'autovacuum: %' and pid <> pg_backend_pid()
574577
)`
575578
err := db.QueryRow(query).Scan(&isRunningQueryNotExists)
576579

0 commit comments

Comments
 (0)