github.com/tuhaihe/gpbackup@v1.0.3/backup/queries_incremental.go (about)

     1  package backup
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/tuhaihe/gp-common-go-libs/dbconn"
     7  	"github.com/tuhaihe/gp-common-go-libs/gplog"
     8  	"github.com/tuhaihe/gpbackup/toc"
     9  )
    10  
    11  func GetAOIncrementalMetadata(connectionPool *dbconn.DBConn) map[string]toc.AOEntry {
    12  	gplog.Verbose("Querying table row mod counts")
    13  	var modCounts = getAllModCounts(connectionPool)
    14  	gplog.Verbose("Querying last DDL modification timestamp for tables")
    15  	var lastDDLTimestamps = getLastDDLTimestamps(connectionPool)
    16  	aoTableEntries := make(map[string]toc.AOEntry)
    17  	for aoTableFQN := range modCounts {
    18  		aoTableEntries[aoTableFQN] = toc.AOEntry{
    19  			Modcount:         modCounts[aoTableFQN],
    20  			LastDDLTimestamp: lastDDLTimestamps[aoTableFQN],
    21  		}
    22  	}
    23  
    24  	return aoTableEntries
    25  }
    26  
    27  func getAllModCounts(connectionPool *dbconn.DBConn) map[string]int64 {
    28  	var segTableFQNs = getAOSegTableFQNs(connectionPool)
    29  	modCounts := make(map[string]int64)
    30  	for aoTableFQN, segTableFQN := range segTableFQNs {
    31  		modCounts[aoTableFQN] = getModCount(connectionPool, segTableFQN)
    32  	}
    33  	return modCounts
    34  }
    35  
    36  func getAOSegTableFQNs(connectionPool *dbconn.DBConn) map[string]string {
    37  
    38  
    39  	atLeast7Query := fmt.Sprintf(`
    40  		SELECT seg.aotablefqn,
    41  			'pg_aoseg.' || quote_ident(aoseg_c.relname) AS aosegtablefqn
    42  		FROM pg_class aoseg_c
    43  			JOIN (SELECT pg_ao.relid AS aooid,
    44  					pg_ao.segrelid,
    45  					aotables.aotablefqn
    46  				FROM pg_appendonly pg_ao
    47  					JOIN (SELECT c.oid,
    48  							quote_ident(n.nspname) || '.' || quote_ident(c.relname) AS aotablefqn
    49  						FROM pg_class c
    50  							JOIN pg_namespace n ON c.relnamespace = n.oid
    51  							JOIN pg_am a ON c.relam = a.oid
    52  						WHERE a.amname in ('ao_row', 'ao_column')
    53  							AND %s
    54  					) aotables ON pg_ao.relid = aotables.oid
    55  			) seg ON aoseg_c.oid = seg.segrelid`, relationAndSchemaFilterClause())
    56  
    57  	query := atLeast7Query
    58  
    59  	results := make([]struct {
    60  		AOTableFQN    string
    61  		AOSegTableFQN string
    62  	}, 0)
    63  	err := connectionPool.Select(&results, query)
    64  	gplog.FatalOnError(err)
    65  	resultMap := make(map[string]string)
    66  	for _, result := range results {
    67  		resultMap[result.AOTableFQN] = result.AOSegTableFQN
    68  	}
    69  	return resultMap
    70  }
    71  
    72  func getModCount(connectionPool *dbconn.DBConn, aosegtablefqn string) int64 {
    73  
    74  	// In GPDB 7+, the coordinator no longer stores AO segment data so we must
    75  	// query the modcount from the segments. Unfortunately, this does give a
    76  	// false positive if a VACUUM FULL compaction happens on the AO table.
    77  	atLeast7Query := fmt.Sprintf(`SELECT COALESCE(pg_catalog.sum(modcount), 0) AS modcount FROM gp_dist_random('%s')`,
    78  		aosegtablefqn)
    79  
    80  	query := atLeast7Query
    81  
    82  	var results []struct {
    83  		Modcount int64
    84  	}
    85  	err := connectionPool.Select(&results, query)
    86  	gplog.FatalOnError(err)
    87  
    88  	return results[0].Modcount
    89  }
    90  
    91  func getLastDDLTimestamps(connectionPool *dbconn.DBConn) map[string]string {
    92  
    93  	atLeast7Query := fmt.Sprintf(`
    94  		SELECT quote_ident(aoschema) || '.' || quote_ident(aorelname) as aotablefqn,
    95  			lastddltimestamp
    96  		FROM ( SELECT c.oid AS aooid,
    97  					n.nspname AS aoschema,
    98  					c.relname AS aorelname
    99  				FROM pg_class c
   100  					JOIN pg_namespace n ON c.relnamespace = n.oid
   101  					JOIN pg_am a ON c.relam = a.oid
   102  				WHERE a.amname in ('ao_row', 'ao_column')
   103  					AND %s
   104  			) aotables
   105  		JOIN ( SELECT lo.objid,
   106  					MAX(lo.statime) AS lastddltimestamp
   107  				FROM pg_stat_last_operation lo
   108  				WHERE lo.staactionname IN ('CREATE', 'ALTER', 'TRUNCATE')
   109  				GROUP BY lo.objid
   110  			) lastop
   111  		ON aotables.aooid = lastop.objid`, relationAndSchemaFilterClause())
   112  
   113  	query := atLeast7Query
   114  
   115  	var results []struct {
   116  		AOTableFQN       string
   117  		LastDDLTimestamp string
   118  	}
   119  	err := connectionPool.Select(&results, query)
   120  	gplog.FatalOnError(err)
   121  	resultMap := make(map[string]string)
   122  	for _, result := range results {
   123  		resultMap[result.AOTableFQN] = result.LastDDLTimestamp
   124  	}
   125  	return resultMap
   126  }