Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9fdd5dd
Initial commit
bimboterminator1 Dec 20, 2024
4668879
Merge branch 'adb-7.2.0' into feature/ADBDEV-6608
bimboterminator1 Jan 29, 2025
dc117b2
[ADBDEV-6847] Implement cluster validation possibility (#1164)
bimboterminator1 Jan 29, 2025
9a64377
gprebalance skeleton (#1201)
bimboterminator1 Feb 3, 2025
47b225a
Rebalance algorithm (#1204)
bimboterminator1 Feb 18, 2025
5dc85b0
Rebalance automation (#1236)
bimboterminator1 Mar 13, 2025
fcc28c4
Rollback handler (#1265)
bimboterminator1 Mar 20, 2025
0ecac16
Partial implementation of gprecoverseg state recovery (#1527)
bimboterminator1 May 6, 2025
5b3f506
Support 'ALTER TABLE REBALANCE' MVP (#1845)
whitehawk Jul 15, 2025
c4ebcff
Use shared variable for default number of segments (#1941)
bimboterminator1 Aug 8, 2025
69fb3e9
Implement skeleton for basic shrink scenario (#1971)
whitehawk Sep 23, 2025
1134de6
Add gp_rebalance_numsegments reset check (#1977)
bimboterminator1 Oct 16, 2025
14f4669
Implement cleanup and rollback options for the cluster shrink (#1979)
whitehawk Oct 24, 2025
62c583a
Add basic shrink/rebalance algorithm (#2002)
bimboterminator1 Dec 2, 2025
4b13164
Add basic support of resource planning (#2167)
bimboterminator1 Dec 29, 2025
1a89824
Implement cluster rebalance for ggrebalance utility (#2240)
whitehawk Jan 23, 2026
28ebc24
Implement proper parallel flow of the rebalance execution (#2243)
whitehawk Feb 5, 2026
804cd8b
Add a batch of ggrebalance behave tests (#2244)
whitehawk Feb 7, 2026
730af79
Implement miscellaneous minor options for rebalance execution (#2245)
whitehawk Feb 11, 2026
a3eb478
Fix ALTER MATERIALIZED VIEW ... REBALANCE (#2246)
whitehawk Feb 13, 2026
0385d97
Use CTAS approach for rebalancing the materialized view (#2249)
whitehawk Feb 24, 2026
a57039b
Implement cluster shrink (2nd phase) (#2247)
whitehawk Feb 25, 2026
0c8cb58
[GG-181] Use intermediate host for swap moves (#2248)
bimboterminator1 Mar 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.Ubuntu.bash
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ apt-get install -y \
python3-psycopg2 \
python3-psutil \
python3-yaml \
python3-transitions \
zlib1g-dev

tee -a /etc/sysctl.conf << EOF
Expand Down
8 changes: 5 additions & 3 deletions gpMgmt/bin/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ifneq "$(wildcard $(top_builddir)/src/Makefile.global)" ""
include $(top_builddir)/src/Makefile.global
endif

SUBDIRS = stream gpcheckcat_modules gpconfig_modules gpssh_modules gppylib lib
SUBDIRS = stream gpcheckcat_modules gpconfig_modules gpssh_modules gppylib lib gprebalance_modules
SUBDIRS += ifaddrs

$(recurse)
Expand All @@ -16,7 +16,8 @@ PROGRAMS= analyzedb gpactivatestandby gpaddmirrors gpcheckcat gpcheckperf \
gpcheckresgroupimpl gpconfig gpdeletesystem gpexpand gpinitstandby \
gpinitsystem gpload gpload.py gplogfilter gpmovemirrors \
gprecoverseg gpreload gpsync gpsd gpssh gpssh-exkeys gpstart \
gpstate gpstop minirepro gpmemwatcher gpmemreport gpcheckresgroupv2impl
gpstate gpstop minirepro gpmemwatcher gpmemreport gpcheckresgroupv2impl \
gprebalance ggrebalance

installdirs:
$(MKDIR_P) '$(DESTDIR)$(bindir)/lib'
Expand Down Expand Up @@ -109,7 +110,8 @@ unitdevel:
@echo "Running pure unit tests..."
PYTHONPATH=$(SERVER_SRC):$(SERVER_SBIN):$(PYTHONPATH):$(PYTHONSRC_INSTALL_PYTHON_PATH):$(SRC)/ext:$(SBIN_DIR):$(LIB_DIR):$(PYLIB_DIR)/mock-1.0.1 \
python3 -m unittest discover --verbose -s $(SRC)/gppylib -p "test_unit*.py"

PYTHONPATH=$(SERVER_SRC):$(SERVER_SBIN):$(PYTHONPATH):$(PYTHONSRC_INSTALL_PYTHON_PATH):$(SRC)/ext:$(SBIN_DIR):$(LIB_DIR):$(PYLIB_DIR)/mock-1.0.1 \
python3 -m unittest discover --verbose -s $(SRC)/gprebalance_modules -t $(SRC)

.PHONY: installcheck-bash
installcheck-bash:
Expand Down
365 changes: 365 additions & 0 deletions gpMgmt/bin/ggrebalance

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion gpMgmt/bin/gpmovemirrors
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ try:
recoversegOptions = "-i " + newConfig.inputFile + " -B " + str(options.batch_size) + \
" -b " + str(options.segment_batch_size) + " -v -a -d " + options.coordinator_data_directory
if options.logfile_directory != None:
recoversegOptions = recoversegOptions + " -l " + str(options.logfile_directory)
recoversegOptions = recoversegOptions + f' -l "{str(options.logfile_directory)}"'
logger.info('About to run gprecoverseg with options: ' + recoversegOptions)
cmd = GpRecoverSeg("Running gprecoverseg", options=recoversegOptions)
cmd.run(validateAfter=True)
Expand Down
1 change: 1 addition & 0 deletions gpMgmt/bin/gppylib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ $(recurse)
PROGRAMS= gparray.py gpunit unit2

DATA= __init__.py \
fault_injection.py \
datetimeutils.py \
gp_era.py \
gpcatalog.py \
Expand Down
16 changes: 15 additions & 1 deletion gpMgmt/bin/gppylib/commands/gp.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ def __init__(self,name,directory,ctxt=LOCAL,remoteHost=None):
def is_shutdown(self):
for key, value in self.results.split_stdout():
if key == 'Database cluster state':
return value.strip() == 'shut down'
return value.strip() == 'shut down' or value.strip() == 'shut down in recovery'
return False

@staticmethod
Expand Down Expand Up @@ -1688,6 +1688,20 @@ def __init__(self, name, options = "", ctxt = LOCAL, remoteHost = None):
cmdStr = "$GPHOME/bin/gprecoverseg %s" % (options)
Command.__init__(self,name,cmdStr,ctxt,remoteHost)

class GpMoveMirrors(Command):
"""
This command will execute the gpmovemirror utility
"""

def __init__(self, name, options = "", ctxt = LOCAL, remoteHost = None):
self.name = name
self.options = options
self.ctxt = ctxt
self.remoteHost = remoteHost

cmdStr = "$GPHOME/bin/gpmovemirrors %s" % (options)
Command.__init__(self,name,cmdStr,ctxt,remoteHost)

class IfAddrs:
@staticmethod
def list_addrs(hostname=None, include_loopback=False):
Expand Down
23 changes: 23 additions & 0 deletions gpMgmt/bin/gppylib/commands/unix.py
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,29 @@ def get_hostname(self):
raise Exception('Command not yet executed')
return self.results.stdout.strip()

# --------------port is not busy--------------------
class PortIsAvailable(Command):
def __init__(self, name, port, ctxt=REMOTE, remoteHost=None):
self.port = port
# Check if port is listening: return code 0 if is in use,
# 1 if is available
cmdStr = (
f"(command -v ss >/dev/null 2>&1 && "
f"ss -tuln | grep -q ':{port} ') && "
f"echo 'IN_USE' || echo 'AVAILABLE'"
)
Command.__init__(self, name, cmdStr, ctxt, remoteHost)

def is_port_available(self) -> bool:
"""
Check if port is available based on command results
"""
if not self.results:
return False

output = self.results.stdout.strip()

return output == 'AVAILABLE'

# --------------tcp port is active -----------------------
class PgPortIsActive(Command):
Expand Down
41 changes: 41 additions & 0 deletions gpMgmt/bin/gppylib/fault_injection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env python3

import os
import threading
import time
import signal

GPMGMT_FAULT_POINT = 'GPMGMT_FAULT_POINT'
GPMGMT_FAULT_DELAY_MS = 'GPMGMT_FAULT_DELAY_MS'
GPMGMT_FAULT_TYPE = 'GPMGMT_FAULT_TYPE'
GPMGMT_FAULT_FILE_FLAG = 'GPMGMT_FAULT_FILE_FLAG'

GPMGMT_FAULT_TYPE_SYSPEND = 'suspend'

def inject_fault(fault_point):
if GPMGMT_FAULT_POINT in os.environ and fault_point == os.environ[GPMGMT_FAULT_POINT]:
if GPMGMT_FAULT_TYPE in os.environ and os.environ[GPMGMT_FAULT_TYPE] == GPMGMT_FAULT_TYPE_SYSPEND:
while GPMGMT_FAULT_FILE_FLAG in os.environ and os.path.exists(os.environ[GPMGMT_FAULT_FILE_FLAG]):
time.sleep(0.1)
return
if GPMGMT_FAULT_DELAY_MS in os.environ and int(os.environ[GPMGMT_FAULT_DELAY_MS]) > 0:
delay_ms = int(os.environ[GPMGMT_FAULT_DELAY_MS])

def raise_exception(delay: int):
time.sleep(delay / 1000)
print('Fault Injection %s' % os.environ[GPMGMT_FAULT_POINT])
os.kill(os.getpid(), signal.SIGINT)

thread = threading.Thread(target=raise_exception, kwargs={"delay": delay_ms})
thread.daemon = True
thread.start()
else:
raise Exception('Fault Injection %s' % os.environ[GPMGMT_FAULT_POINT])

# decorator for test purposes
def wrap_state_func_with_faults(func):
def func_with_faults(*args):
inject_fault(f'{func.__name__}_begin')
func(*args)
inject_fault(f'{func.__name__}_end')
return func_with_faults
Loading