• H
    Use normal hash operator classes for data distribution. · 242783ae
    Heikki Linnakangas 提交于
    Replace the use of the built-in hashing support for built-in datatypes, in
    cdbhash.c, with the normal PostgreSQL hash functions. Now is a good time
    to do this, since we've already made the change to use jump consistent
    hashing in GPDB 6, so we'll need to deal with the upgrade problems
    associated with changing the hash functions, anyway.
    
    It is no longer enough to track which columns/expressions are used to
    distribute data. You also need to know the hash function used. For that,
    a new field is added to gp_distribution_policy, to record the hash
    operator class used for each distribution key column. In the planner,
    a new opfamily field is added to DistributionKey, to track that throughout
    the planning.
    
    Normally, if you do "CREATE TABLE ... DISTRIBUTED BY (column)", the
    default hash operator class for the datatype is used. But this patch
    extends the syntax so that you can specify the operator class explicitly,
    like "... DISTRIBUTED BY (column opclass)". This is similar to how an
    operator class can be specified for each column in CREATE INDEX.
    
    To support upgrade, the old hash functions have been converted to special
    (non-default) operator classes, named cdbhash_*_ops. For example, if you
    want to use the old hash function for an integer column, you could do
    "DISTRIBUTED BY (intcol cdbhash_int4_ops)". The old hard-coded whitelist
    of operators that have "compatible" cdbhash functions has been replaced
    by putting the compatible hash opclasses in the same operator family. For
    example, all legacy integer operator classes, cdbhash_int2_ops,
    cdbhash_int4_ops and cdbhash_int8_ops, are all part of the
    cdbhash_integer_ops operator family).
    
    This removes the pg_database.hashmethod field. The hash method is now
    tracked on a per-table and per-column basis, using the opclasses, so it's
    not needed anymore.
    
    To help with upgrade from GPDB 5, this introduces a new GUC called
    'gp_use_legacy_hashops'. If it's set, CREATE TABLE uses the legacy hash
    opclasses, instead of the default hash opclasses, if the opclass is not
    specified explicitly. pg_upgrade will set the new GUC, to force the use of
    legacy hashops, when restoring the schema dump. It will also set the GUC
    on all upgraded databases, as a per-database option, so any new tables
    created after upgrade will also use the legacy opclasses. It seems better
    to be consistent after upgrade, so that collocation between old and new
    tables work for example. The idea is that some time after the upgrade, the
    admin can reorganize all tables to use the default opclasses instead. At
    that point, he should also clear the GUC on the converted databases. (Or
    rather, the automated tool that hasn't been written yet, should do that.)
    
    ORCA doesn't know about hash operator classes, or the possibility that we
    might need to use a different hash function for two columns with the same
    datatype. Therefore, it cannot produce correct plans for queries that mix
    different distribution hash opclasses for the same datatype, in the same
    query. There are checks in the Query->DXL translation, to detect that
    case, and fall back to planner. As long as you stick to the default
    opclasses in all tables, we let ORCA to create the plan without any regard
    to them, and use the default opclasses when translating the DXL plan to a
    Plan tree. We also allow the case that all tables in the query use the
    "legacy" opclasses, so that ORCA works after pg_upgrade. But a mix of the
    two, or using any non-default opclasses, forces ORCA to fall back.
    
    One curiosity with this is the "int2vector" and "aclitem" datatypes. They
    have a hash opclass, but no b-tree operators. GPDB 4 used to allow them
    as DISTRIBUTED BY columns, but we forbid that in GPDB 5, in commit
    56e7c16b. Now they are allowed again, so you can specify an int2vector
    or aclitem column in DISTRIBUTED BY, but it's still pretty useless,
    because the planner still can't form EquivalenceClasses on it, and will
    treat it as "strewn" distribution, and won't co-locate joins.
    
    Abstime, reltime, tinterval datatypes don't have default hash opclasses.
    They are being removed completely on PostgreSQL v12, and users shouldn't
    be using them in the first place, so instead of adding hash opclasses for
    them now, we accept that they can't be used as distribution key columns
    anymore. Add a check to pg_upgrade, to refuse upgrade if they are used
    as distribution keys in the old cluster. Do the same for 'money' datatype
    as well, although that's not being removed in upstream.
    
    The legacy hashing code for anyarray in GPDB 5 was actually broken. It
    could produce a different hash value for two arrays that are considered
    equal, according to the = operator, if there were differences in e.g.
    whether the null bitmap was stored or not. Add a check to pg_upgrade, to
    reject the upgrade if array types were used as distribution keys. The
    upstream hash opclass for anyarray works, though, so it is OK to use
    arrays as distribution keys in new tables. We just don't support binary
    upgrading them from GPDB 5. (See github issue
    https://github.com/greenplum-db/gpdb/issues/5467). The legacy hashing of
    'anyrange' had the same problem, but that was new in GPDB 6, so we don't
    need a pg_upgrade check for that.
    
    This also tightens the checks ALTER TABLE ALTER COLUMN and CREATE UNIQUE
    INDEX, so that you can no longer create a situation where a non-hashable
    column becomes the distribution key. (Fixes github issue
    https://github.com/greenplum-db/gpdb/issues/6317)
    
    Discussion: https://groups.google.com/a/greenplum.org/forum/#!topic/gpdb-dev/4fZVeOpXllQCo-authored-by: NMel Kiyama <mkiyama@pivotal.io>
    Co-authored-by: NAbhijit Subramanya <asubramanya@pivotal.io>
    Co-authored-by: NPengzhou Tang <ptang@pivotal.io>
    Co-authored-by: NChris Hajas <chajas@pivotal.io>
    Reviewed-by: NBhuvnesh Chaudhary <bchaudhary@pivotal.io>
    Reviewed-by: NNing Yu <nyu@pivotal.io>
    Reviewed-by: NSimon Gao <sgao@pivotal.io>
    Reviewed-by: NJesse Zhang <jzhang@pivotal.io>
    Reviewed-by: NZhenghua Lyu <zlv@pivotal.io>
    Reviewed-by: NMelanie Plageman <mplageman@pivotal.io>
    Reviewed-by: NYandong Yao <yyao@pivotal.io>
    242783ae
CREATE_TABLE.xml 54.3 KB