in automation/tinc/main/ext/qautils/gppylib/gparray.py [0:0]
def initFromCatalog(dbURL, utility=False):
"""
Factory method, initializes a GpArray from provided database URL
"""
conn = dbconn.connect(dbURL, utility)
# Get the version from the database:
version_str = None
for row in dbconn.execSQL(conn, "SELECT version()"):
version_str = row[0]
version = GpVersion(version_str)
if version.getVersionRelease() in ("3.0", "3.1", "3.2", "3.3"):
# In older releases we get the fault strategy using the
# gp_fault_action guc.
strategy_rows = dbconn.execSQL(conn, "show gp_fault_action")
# Note: Mode may not be "right", certainly 4.0 concepts of mirroring
# mode do not apply to 3.x, so it depends on how the scripts are
# making use of mode. For now it is initialized to synchronized.
#
# Note: hostname is initialized to null since the catalog does not
# contain this information. Initializing a hostcache using the
# resulting gparray will automatically fill in a value for hostname.
#
# Note: this should be kept in sync with the code in
# GpDB.InitFromString() code for initializing old catalog formats.
config_rows = dbconn.execSQL(conn, '''
SELECT dbid, content,
case when isprimary then 'p' else 'm' end as role,
case when definedprimary then 'p' else 'm' end as preferred_role,
's' as mode,
case when valid then 'u' else 'd' end as status,
null as hostname,
hostname as address,
port,
null as replication_port,
%s as fsoid,
datadir as fselocation
FROM pg_catalog.gp_configuration
ORDER BY content, preferred_role DESC
''' % str(SYSTEM_FILESPACE))
# No SAN support in these older releases.
san_segs_rows = []
san_rows = []
# no filespace support in older releases.
filespaceArr = []
else:
strategy_rows = dbconn.execSQL(conn, '''
SELECT fault_strategy FROM gp_fault_strategy
''')
config_rows = dbconn.execSQL(conn, '''
SELECT dbid, content, role, preferred_role, mode, status,
hostname, address, port, replication_port, fs.oid,
fselocation
FROM pg_catalog.gp_segment_configuration
JOIN pg_catalog.pg_filespace_entry on (dbid = fsedbid)
JOIN pg_catalog.pg_filespace fs on (fsefsoid = fs.oid)
ORDER BY content, preferred_role DESC, fs.oid
''')
san_segs_rows = dbconn.execSQL(conn, '''
SELECT dbid, content, status, unnest(san_mounts)
FROM pg_catalog.gp_segment_configuration
WHERE content >= 0
ORDER BY content, dbid
''')
san_rows = dbconn.execSQL(conn, '''
SELECT mountid, active_host, san_type,
primary_host, primary_mountpoint, primary_device,
mirror_host, mirror_mountpoint, mirror_device
FROM pg_catalog.gp_san_configuration
ORDER BY mountid
''')
filespaceRows = dbconn.execSQL(conn, '''
SELECT oid, fsname
FROM pg_filespace
ORDER BY fsname;
''')
filespaceArr = [GpFilespaceObj(fsRow[0], fsRow[1]) for fsRow in filespaceRows]
# Todo: add checks that all segments should have the same filespaces?
recoveredSegmentDbids = []
segments = []
seg = None
for row in config_rows:
# Extract fields from the row
(dbid, content, role, preferred_role, mode, status, hostname,
address, port, replicationPort, fsoid, fslocation) = row
# If we have segments which have recovered, record them.
if preferred_role != role and content >= 0:
if mode == MODE_SYNCHRONIZED and status == STATUS_UP:
recoveredSegmentDbids.append(dbid)
# The query returns all the filespaces for a segment on separate
# rows. If this row is the same dbid as the previous row simply
# add this filespace to the existing list, otherwise create a
# new segment.
if seg and seg.getSegmentDbId() == dbid:
seg.addSegmentFilespace(fsoid, fslocation)
else:
seg = GpDB(content, preferred_role, dbid, role, mode, status,
hostname, address, port, fslocation, replicationPort)
segments.append(seg)
for seg in segments:
datcatloc = dbconn.execSQL(conn, '''
select fsloc.fselocation || '/' ||
case when db.dattablespace = 1663
then 'base'
else db.dattablespace::text
end || '/'||db.oid as catloc
from pg_Database db, pg_tablespace ts,
(SELECT dbid, fs.oid, fselocation
FROM pg_catalog.gp_segment_configuration
JOIN pg_catalog.pg_filespace_entry on (dbid = fsedbid)
JOIN pg_catalog.pg_filespace fs on (fsefsoid = fs.oid)) fsloc
where db.dattablespace = ts.oid
and ts.spcfsoid = fsloc.oid
and fsloc.dbid = %d
''' % seg.dbid)
seg.catdirs = []
for row in datcatloc:
seg.catdirs.append(row[0])
conn.close()
origSegments = [seg.copy() for seg in segments]
if strategy_rows.rowcount == 0:
raise Exception("Database does not contain gp_fault_strategy entry")
if strategy_rows.rowcount > 1:
raise Exception("Database does too many gp_fault_strategy entries")
strategy = strategy_rows.fetchone()[0]
array = GpArray(segments, origSegments, strategy)
array.__version = version
array.recoveredSegmentDbids = recoveredSegmentDbids
array.setFaultStrategy(strategy)
array.setSanConfig(san_rows, san_segs_rows)
array.setFilespaces(filespaceArr)
return array