github.com/tuhaihe/gpbackup@v1.0.3/backup/postdata.go (about) 1 package backup 2 3 /* 4 * This file contains structs and functions related to backing up "post-data" metadata 5 * on the coordinator, which is any metadata that needs to be restored after data is 6 * restored, such as indexes and rules. 7 */ 8 9 import ( 10 "strings" 11 12 "github.com/tuhaihe/gp-common-go-libs/gplog" 13 "github.com/tuhaihe/gpbackup/toc" 14 "github.com/tuhaihe/gpbackup/utils" 15 "github.com/pkg/errors" 16 ) 17 18 func PrintCreateIndexStatements(metadataFile *utils.FileWithByteCount, toc *toc.TOC, indexes []IndexDefinition, indexMetadata MetadataMap) { 19 for _, index := range indexes { 20 start := metadataFile.ByteCount 21 if !index.SupportsConstraint { 22 section, entry := index.GetMetadataEntry() 23 24 metadataFile.MustPrintf("\n\n%s;", index.Def.String) 25 toc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount) 26 27 // Start INDEX metadata 28 entry.ReferenceObject = index.FQN() 29 entry.ObjectType = "INDEX METADATA" 30 if index.Tablespace != "" { 31 start := metadataFile.ByteCount 32 metadataFile.MustPrintf("\nALTER INDEX %s SET TABLESPACE %s;", index.FQN(), index.Tablespace) 33 toc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount) 34 } 35 if index.ParentIndexFQN != "" { 36 start := metadataFile.ByteCount 37 metadataFile.MustPrintf("\nALTER INDEX %s ATTACH PARTITION %s;", index.ParentIndexFQN, index.FQN()) 38 toc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount) 39 } 40 tableFQN := utils.MakeFQN(index.OwningSchema, index.OwningTable) 41 if index.IsClustered { 42 start := metadataFile.ByteCount 43 metadataFile.MustPrintf("\nALTER TABLE %s CLUSTER ON %s;", tableFQN, index.Name) 44 toc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount) 45 } 46 if index.IsReplicaIdentity { 47 start := metadataFile.ByteCount 48 metadataFile.MustPrintf("\nALTER TABLE %s REPLICA IDENTITY USING INDEX %s;", tableFQN, index.Name) 49 toc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount) 50 } 51 if index.StatisticsColumns != "" && index.StatisticsValues != "" { 52 cols := strings.Split(index.StatisticsColumns, ",") 53 vals := strings.Split(index.StatisticsValues, ",") 54 if len(cols) != len(vals) { 55 gplog.Fatal(errors.Errorf("Index StatisticsColumns(%d) and StatisticsValues(%d) count don't match\n", len(cols), len(vals)), "") 56 } 57 for i := 0; i < len(cols); i++ { 58 start := metadataFile.ByteCount 59 metadataFile.MustPrintf("\nALTER INDEX %s ALTER COLUMN %s SET STATISTICS %s;", index.FQN(), cols[i], vals[i]) 60 toc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount) 61 } 62 } 63 } 64 PrintObjectMetadata(metadataFile, toc, indexMetadata[index.GetUniqueID()], index, "") 65 } 66 } 67 68 func PrintCreateRuleStatements(metadataFile *utils.FileWithByteCount, toc *toc.TOC, rules []RuleDefinition, ruleMetadata MetadataMap) { 69 for _, rule := range rules { 70 start := metadataFile.ByteCount 71 metadataFile.MustPrintf("\n\n%s", rule.Def.String) 72 73 section, entry := rule.GetMetadataEntry() 74 toc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount) 75 tableFQN := utils.MakeFQN(rule.OwningSchema, rule.OwningTable) 76 PrintObjectMetadata(metadataFile, toc, ruleMetadata[rule.GetUniqueID()], rule, tableFQN) 77 } 78 } 79 80 func PrintCreateTriggerStatements(metadataFile *utils.FileWithByteCount, toc *toc.TOC, triggers []TriggerDefinition, triggerMetadata MetadataMap) { 81 for _, trigger := range triggers { 82 start := metadataFile.ByteCount 83 metadataFile.MustPrintf("\n\n%s;", trigger.Def.String) 84 85 section, entry := trigger.GetMetadataEntry() 86 toc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount) 87 tableFQN := utils.MakeFQN(trigger.OwningSchema, trigger.OwningTable) 88 PrintObjectMetadata(metadataFile, toc, triggerMetadata[trigger.GetUniqueID()], trigger, tableFQN) 89 } 90 } 91 92 func PrintCreateEventTriggerStatements(metadataFile *utils.FileWithByteCount, toc *toc.TOC, eventTriggers []EventTrigger, eventTriggerMetadata MetadataMap) { 93 for _, eventTrigger := range eventTriggers { 94 start := metadataFile.ByteCount 95 section, entry := eventTrigger.GetMetadataEntry() 96 97 metadataFile.MustPrintf("\n\nCREATE EVENT TRIGGER %s\nON %s", eventTrigger.Name, eventTrigger.Event) 98 if eventTrigger.EventTags != "" { 99 metadataFile.MustPrintf("\nWHEN TAG IN (%s)", eventTrigger.EventTags) 100 } 101 if true { 102 metadataFile.MustPrintf("\nEXECUTE FUNCTION %s();", eventTrigger.FunctionName) 103 } else { 104 metadataFile.MustPrintf("\nEXECUTE PROCEDURE %s();", eventTrigger.FunctionName) 105 } 106 toc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount) 107 108 // Start EVENT TRIGGER metadata 109 entry.ReferenceObject = eventTrigger.Name 110 entry.ObjectType = "EVENT TRIGGER METADATA" 111 if eventTrigger.Enabled != "O" { 112 var enableOption string 113 switch eventTrigger.Enabled { 114 case "D": 115 enableOption = "DISABLE" 116 case "A": 117 enableOption = "ENABLE ALWAYS" 118 case "R": 119 enableOption = "ENABLE REPLICA" 120 default: 121 enableOption = "ENABLE" 122 } 123 start := metadataFile.ByteCount 124 metadataFile.MustPrintf("\nALTER EVENT TRIGGER %s %s;", eventTrigger.Name, enableOption) 125 toc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount) 126 } 127 PrintObjectMetadata(metadataFile, toc, eventTriggerMetadata[eventTrigger.GetUniqueID()], eventTrigger, "") 128 } 129 } 130 131 func PrintCreatePolicyStatements(metadataFile *utils.FileWithByteCount, toc *toc.TOC, policies []RLSPolicy, policyMetadata MetadataMap) { 132 for _, policy := range policies { 133 start := metadataFile.ByteCount 134 section, entry := policy.GetMetadataEntry() 135 136 tableFQN := utils.MakeFQN(policy.Schema, policy.Table) 137 metadataFile.MustPrintf("\n\nALTER TABLE %s ENABLE ROW LEVEL SECURITY;", tableFQN) 138 toc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount) 139 140 permissiveOption := "" 141 if policy.Permissive == "false" { 142 permissiveOption = " AS RESTRICTIVE" 143 } 144 cmdOption := "" 145 if policy.Cmd != "" { 146 switch policy.Cmd { 147 case "*": 148 cmdOption = "" 149 case "r": 150 cmdOption = " FOR SELECT" 151 case "a": 152 cmdOption = " FOR INSERT" 153 case "w": 154 cmdOption = " FOR UPDATE" 155 case "d": 156 cmdOption = " FOR DELETE" 157 default: 158 gplog.Fatal(errors.Errorf("Unexpected policy command: expected '*|r|a|w|d' got '%s'\n", policy.Cmd), "") 159 } 160 } 161 start = metadataFile.ByteCount 162 metadataFile.MustPrintf("\nCREATE POLICY %s\nON %s%s%s", policy.Name, tableFQN, permissiveOption, cmdOption) 163 164 if policy.Roles != "" { 165 metadataFile.MustPrintf("\n TO %s", policy.Roles) 166 } 167 if policy.Qual != "" { 168 metadataFile.MustPrintf("\n USING (%s)", policy.Qual) 169 } 170 if policy.WithCheck != "" { 171 metadataFile.MustPrintf("\n WITH CHECK (%s)", policy.WithCheck) 172 } 173 metadataFile.MustPrintf(";\n") 174 toc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount) 175 PrintObjectMetadata(metadataFile, toc, policyMetadata[policy.GetUniqueID()], policy, "") 176 } 177 } 178 179 func PrintCreateExtendedStatistics(metadataFile *utils.FileWithByteCount, toc *toc.TOC, statExtObjects []StatisticExt, statMetadata MetadataMap) { 180 for _, stat := range statExtObjects { 181 start := metadataFile.ByteCount 182 metadataFile.MustPrintln() 183 184 metadataFile.MustPrintf("\n%s;", stat.Definition) 185 section, entry := stat.GetMetadataEntry() 186 toc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount) 187 PrintObjectMetadata(metadataFile, toc, statMetadata[stat.GetUniqueID()], stat, "") 188 } 189 }